diff --git a/src/compiler/OWNERS b/src/compiler/OWNERS
new file mode 100644
index 0000000..1257e23
--- /dev/null
+++ b/src/compiler/OWNERS
@@ -0,0 +1,7 @@
+set noparent
+
+bmeurer@chromium.org
+jarin@chromium.org
+mstarzinger@chromium.org
+mtrofin@chromium.org
+titzer@chromium.org
diff --git a/src/compiler/STYLE b/src/compiler/STYLE
new file mode 100644
index 0000000..ae41e3f
--- /dev/null
+++ b/src/compiler/STYLE
@@ -0,0 +1,29 @@
+Compiler Coding Style
+=====================
+
+Coding style for the TurboFan compiler generally follows the Google C++ Style
+Guide and the Chromium Coding Style. The notes below are usually just extensions
+beyond what the Google style guide already says. If this document doesn't
+mention a rule, follow the Google C++ style.
+
+
+TODOs
+-----
+We use the following convention for putting TODOs into the code:
+
+  * A TODO(turbofan) implies a performance improvement opportunity.
+  * A TODO(name) implies an incomplete implementation.
+
+
+Use of C++11 auto keyword
+-------------------------
+Use auto to avoid type names that are just clutter. Continue to use manifest
+type declarations when it helps readability, and never use auto for anything
+but local variables, in particular auto should only be used where it is obvious
+from context what the type is:
+
+  for (auto block : x->blocks())  // clearly a Block of some kind
+  for (auto instr : x->instructions())  // clearly an Instruction of some kind
+
+  for (auto b : x->predecessors()) // less clear, better to make it explicit
+  for (BasicBlock* b : x->predecessors()) // now clear
diff --git a/src/compiler/access-builder.cc b/src/compiler/access-builder.cc
index 8c8e530..ebd2789 100644
--- a/src/compiler/access-builder.cc
+++ b/src/compiler/access-builder.cc
@@ -3,6 +3,11 @@
 // found in the LICENSE file.
 
 #include "src/compiler/access-builder.h"
+
+#include "src/contexts.h"
+#include "src/frames.h"
+#include "src/heap/heap.h"
+#include "src/type-cache.h"
 #include "src/types-inl.h"
 
 namespace v8 {
@@ -11,64 +16,282 @@
 
 // static
 FieldAccess AccessBuilder::ForMap() {
-  return {kTaggedBase, HeapObject::kMapOffset, MaybeHandle<Name>(), Type::Any(),
-          kMachAnyTagged};
+  FieldAccess access = {kTaggedBase, HeapObject::kMapOffset,
+                        MaybeHandle<Name>(), Type::Any(),
+                        MachineType::AnyTagged()};
+  return access;
+}
+
+
+// static
+FieldAccess AccessBuilder::ForHeapNumberValue() {
+  FieldAccess access = {kTaggedBase, HeapNumber::kValueOffset,
+                        MaybeHandle<Name>(), TypeCache().Get().kFloat64,
+                        MachineType::Float64()};
+  return access;
 }
 
 
 // static
 FieldAccess AccessBuilder::ForJSObjectProperties() {
-  return {kTaggedBase, JSObject::kPropertiesOffset, MaybeHandle<Name>(),
-          Type::Any(), kMachAnyTagged};
+  FieldAccess access = {kTaggedBase, JSObject::kPropertiesOffset,
+                        MaybeHandle<Name>(), Type::Internal(),
+                        MachineType::AnyTagged()};
+  return access;
 }
 
 
 // static
 FieldAccess AccessBuilder::ForJSObjectElements() {
-  return {kTaggedBase, JSObject::kElementsOffset, MaybeHandle<Name>(),
-          Type::Internal(), kMachAnyTagged};
+  FieldAccess access = {kTaggedBase, JSObject::kElementsOffset,
+                        MaybeHandle<Name>(), Type::Internal(),
+                        MachineType::AnyTagged()};
+  return access;
+}
+
+
+// static
+FieldAccess AccessBuilder::ForJSObjectInObjectProperty(Handle<Map> map,
+                                                       int index) {
+  int const offset = map->GetInObjectPropertyOffset(index);
+  FieldAccess access = {kTaggedBase, offset, MaybeHandle<Name>(),
+                        Type::Tagged(), MachineType::AnyTagged()};
+  return access;
 }
 
 
 // static
 FieldAccess AccessBuilder::ForJSFunctionContext() {
-  return {kTaggedBase, JSFunction::kContextOffset, MaybeHandle<Name>(),
-          Type::Internal(), kMachAnyTagged};
+  FieldAccess access = {kTaggedBase, JSFunction::kContextOffset,
+                        MaybeHandle<Name>(), Type::Internal(),
+                        MachineType::AnyTagged()};
+  return access;
+}
+
+
+// static
+FieldAccess AccessBuilder::ForJSFunctionSharedFunctionInfo() {
+  FieldAccess access = {kTaggedBase, JSFunction::kSharedFunctionInfoOffset,
+                        Handle<Name>(), Type::Any(), MachineType::AnyTagged()};
+  return access;
+}
+
+
+// static
+FieldAccess AccessBuilder::ForJSArrayLength(ElementsKind elements_kind) {
+  TypeCache const& type_cache = TypeCache::Get();
+  FieldAccess access = {kTaggedBase, JSArray::kLengthOffset, Handle<Name>(),
+                        type_cache.kJSArrayLengthType,
+                        MachineType::AnyTagged()};
+  if (IsFastDoubleElementsKind(elements_kind)) {
+    access.type = type_cache.kFixedDoubleArrayLengthType;
+  } else if (IsFastElementsKind(elements_kind)) {
+    access.type = type_cache.kFixedArrayLengthType;
+  }
+  return access;
 }
 
 
 // static
 FieldAccess AccessBuilder::ForJSArrayBufferBackingStore() {
-  return {kTaggedBase, JSArrayBuffer::kBackingStoreOffset, MaybeHandle<Name>(),
-          Type::UntaggedPointer(), kMachPtr};
+  FieldAccess access = {kTaggedBase, JSArrayBuffer::kBackingStoreOffset,
+                        MaybeHandle<Name>(), Type::UntaggedPointer(),
+                        MachineType::Pointer()};
+  return access;
 }
 
 
 // static
-FieldAccess AccessBuilder::ForExternalArrayPointer() {
-  return {kTaggedBase, ExternalArray::kExternalPointerOffset,
-          MaybeHandle<Name>(), Type::UntaggedPointer(), kMachPtr};
+FieldAccess AccessBuilder::ForJSArrayBufferBitField() {
+  FieldAccess access = {kTaggedBase, JSArrayBuffer::kBitFieldOffset,
+                        MaybeHandle<Name>(), TypeCache::Get().kInt8,
+                        MachineType::Int8()};
+  return access;
+}
+
+
+// static
+FieldAccess AccessBuilder::ForJSArrayBufferViewBuffer() {
+  FieldAccess access = {kTaggedBase, JSArrayBufferView::kBufferOffset,
+                        MaybeHandle<Name>(), Type::TaggedPointer(),
+                        MachineType::AnyTagged()};
+  return access;
+}
+
+
+// static
+FieldAccess AccessBuilder::ForJSDateField(JSDate::FieldIndex index) {
+  FieldAccess access = {
+      kTaggedBase, JSDate::kValueOffset + index * kPointerSize,
+      MaybeHandle<Name>(), Type::Number(), MachineType::AnyTagged()};
+  return access;
+}
+
+
+// static
+FieldAccess AccessBuilder::ForJSIteratorResultDone() {
+  FieldAccess access = {kTaggedBase, JSIteratorResult::kDoneOffset,
+                        MaybeHandle<Name>(), Type::Any(),
+                        MachineType::AnyTagged()};
+  return access;
+}
+
+
+// static
+FieldAccess AccessBuilder::ForJSIteratorResultValue() {
+  FieldAccess access = {kTaggedBase, JSIteratorResult::kValueOffset,
+                        MaybeHandle<Name>(), Type::Any(),
+                        MachineType::AnyTagged()};
+  return access;
+}
+
+
+// static
+FieldAccess AccessBuilder::ForJSRegExpFlags() {
+  FieldAccess access = {kTaggedBase, JSRegExp::kFlagsOffset,
+                        MaybeHandle<Name>(), Type::Tagged(),
+                        MachineType::AnyTagged()};
+  return access;
+}
+
+
+// static
+FieldAccess AccessBuilder::ForJSRegExpSource() {
+  FieldAccess access = {kTaggedBase, JSRegExp::kSourceOffset,
+                        MaybeHandle<Name>(), Type::Tagged(),
+                        MachineType::AnyTagged()};
+  return access;
+}
+
+
+// static
+FieldAccess AccessBuilder::ForFixedArrayLength() {
+  FieldAccess access = {
+      kTaggedBase, FixedArray::kLengthOffset, MaybeHandle<Name>(),
+      TypeCache::Get().kFixedArrayLengthType, MachineType::AnyTagged()};
+  return access;
+}
+
+
+// static
+FieldAccess AccessBuilder::ForDescriptorArrayEnumCache() {
+  FieldAccess access = {kTaggedBase, DescriptorArray::kEnumCacheOffset,
+                        Handle<Name>(), Type::TaggedPointer(),
+                        MachineType::AnyTagged()};
+  return access;
+}
+
+
+// static
+FieldAccess AccessBuilder::ForDescriptorArrayEnumCacheBridgeCache() {
+  FieldAccess access = {
+      kTaggedBase, DescriptorArray::kEnumCacheBridgeCacheOffset, Handle<Name>(),
+      Type::TaggedPointer(), MachineType::AnyTagged()};
+  return access;
+}
+
+
+// static
+FieldAccess AccessBuilder::ForMapBitField() {
+  FieldAccess access = {kTaggedBase, Map::kBitFieldOffset, Handle<Name>(),
+                        TypeCache::Get().kUint8, MachineType::Uint8()};
+  return access;
+}
+
+
+// static
+FieldAccess AccessBuilder::ForMapBitField3() {
+  FieldAccess access = {kTaggedBase, Map::kBitField3Offset, Handle<Name>(),
+                        TypeCache::Get().kInt32, MachineType::Int32()};
+  return access;
+}
+
+
+// static
+FieldAccess AccessBuilder::ForMapDescriptors() {
+  FieldAccess access = {kTaggedBase, Map::kDescriptorsOffset, Handle<Name>(),
+                        Type::TaggedPointer(), MachineType::AnyTagged()};
+  return access;
 }
 
 
 // static
 FieldAccess AccessBuilder::ForMapInstanceType() {
-  return {kTaggedBase, Map::kInstanceTypeOffset, Handle<Name>(),
-          Type::UntaggedUnsigned8(), kMachUint8};
+  FieldAccess access = {kTaggedBase, Map::kInstanceTypeOffset, Handle<Name>(),
+                        TypeCache::Get().kUint8, MachineType::Uint8()};
+  return access;
+}
+
+
+// static
+FieldAccess AccessBuilder::ForMapPrototype() {
+  FieldAccess access = {kTaggedBase, Map::kPrototypeOffset, Handle<Name>(),
+                        Type::TaggedPointer(), MachineType::AnyTagged()};
+  return access;
 }
 
 
 // static
 FieldAccess AccessBuilder::ForStringLength() {
-  return {kTaggedBase, String::kLengthOffset, Handle<Name>(),
-          Type::SignedSmall(), kMachAnyTagged};
+  FieldAccess access = {kTaggedBase, String::kLengthOffset, Handle<Name>(),
+                        TypeCache::Get().kStringLengthType,
+                        MachineType::AnyTagged()};
+  return access;
+}
+
+
+// static
+FieldAccess AccessBuilder::ForJSGlobalObjectGlobalProxy() {
+  FieldAccess access = {kTaggedBase, JSGlobalObject::kGlobalProxyOffset,
+                        Handle<Name>(), Type::Receiver(),
+                        MachineType::AnyTagged()};
+  return access;
+}
+
+
+// static
+FieldAccess AccessBuilder::ForJSGlobalObjectNativeContext() {
+  FieldAccess access = {kTaggedBase, JSGlobalObject::kNativeContextOffset,
+                        Handle<Name>(), Type::Internal(),
+                        MachineType::AnyTagged()};
+  return access;
 }
 
 
 // static
 FieldAccess AccessBuilder::ForValue() {
-  return {kTaggedBase, JSValue::kValueOffset, Handle<Name>(), Type::Any(),
-          kMachAnyTagged};
+  FieldAccess access = {kTaggedBase, JSValue::kValueOffset, Handle<Name>(),
+                        Type::Any(), MachineType::AnyTagged()};
+  return access;
+}
+
+
+// static
+FieldAccess AccessBuilder::ForArgumentsLength() {
+  int offset =
+      JSObject::kHeaderSize + Heap::kArgumentsLengthIndex * kPointerSize;
+  FieldAccess access = {kTaggedBase, offset, Handle<Name>(), Type::Any(),
+                        MachineType::AnyTagged()};
+  return access;
+}
+
+
+// static
+FieldAccess AccessBuilder::ForArgumentsCallee() {
+  int offset =
+      JSObject::kHeaderSize + Heap::kArgumentsCalleeIndex * kPointerSize;
+  FieldAccess access = {kTaggedBase, offset, Handle<Name>(), Type::Any(),
+                        MachineType::AnyTagged()};
+  return access;
+}
+
+
+// static
+FieldAccess AccessBuilder::ForFixedArraySlot(size_t index) {
+  int offset = FixedArray::OffsetOfElementAt(static_cast<int>(index));
+  FieldAccess access = {kTaggedBase, offset, Handle<Name>(), Type::Any(),
+                        MachineType::AnyTagged()};
+  return access;
 }
 
 
@@ -77,13 +300,47 @@
   int offset = Context::kHeaderSize + static_cast<int>(index) * kPointerSize;
   DCHECK_EQ(offset,
             Context::SlotOffset(static_cast<int>(index)) + kHeapObjectTag);
-  return {kTaggedBase, offset, Handle<Name>(), Type::Any(), kMachAnyTagged};
+  FieldAccess access = {kTaggedBase, offset, Handle<Name>(), Type::Any(),
+                        MachineType::AnyTagged()};
+  return access;
+}
+
+
+// static
+FieldAccess AccessBuilder::ForPropertyCellValue() {
+  return ForPropertyCellValue(Type::Tagged());
+}
+
+
+// static
+FieldAccess AccessBuilder::ForPropertyCellValue(Type* type) {
+  FieldAccess access = {kTaggedBase, PropertyCell::kValueOffset, Handle<Name>(),
+                        type, MachineType::AnyTagged()};
+  return access;
+}
+
+
+// static
+FieldAccess AccessBuilder::ForSharedFunctionInfoTypeFeedbackVector() {
+  FieldAccess access = {kTaggedBase, SharedFunctionInfo::kFeedbackVectorOffset,
+                        Handle<Name>(), Type::Any(), MachineType::AnyTagged()};
+  return access;
 }
 
 
 // static
 ElementAccess AccessBuilder::ForFixedArrayElement() {
-  return {kTaggedBase, FixedArray::kHeaderSize, Type::Any(), kMachAnyTagged};
+  ElementAccess access = {kTaggedBase, FixedArray::kHeaderSize, Type::Tagged(),
+                          MachineType::AnyTagged()};
+  return access;
+}
+
+
+// static
+ElementAccess AccessBuilder::ForFixedDoubleArrayElement() {
+  ElementAccess access = {kTaggedBase, FixedDoubleArray::kHeaderSize,
+                          TypeCache::Get().kFloat64, MachineType::Float64()};
+  return access;
 }
 
 
@@ -93,26 +350,59 @@
   BaseTaggedness taggedness = is_external ? kUntaggedBase : kTaggedBase;
   int header_size = is_external ? 0 : FixedTypedArrayBase::kDataOffset;
   switch (type) {
-    case kExternalInt8Array:
-      return {taggedness, header_size, Type::Signed32(), kMachInt8};
+    case kExternalInt8Array: {
+      ElementAccess access = {taggedness, header_size, Type::Signed32(),
+                              MachineType::Int8()};
+      return access;
+    }
     case kExternalUint8Array:
-    case kExternalUint8ClampedArray:
-      return {taggedness, header_size, Type::Unsigned32(), kMachUint8};
-    case kExternalInt16Array:
-      return {taggedness, header_size, Type::Signed32(), kMachInt16};
-    case kExternalUint16Array:
-      return {taggedness, header_size, Type::Unsigned32(), kMachUint16};
-    case kExternalInt32Array:
-      return {taggedness, header_size, Type::Signed32(), kMachInt32};
-    case kExternalUint32Array:
-      return {taggedness, header_size, Type::Unsigned32(), kMachUint32};
-    case kExternalFloat32Array:
-      return {taggedness, header_size, Type::Number(), kMachFloat32};
-    case kExternalFloat64Array:
-      return {taggedness, header_size, Type::Number(), kMachFloat64};
+    case kExternalUint8ClampedArray: {
+      ElementAccess access = {taggedness, header_size, Type::Unsigned32(),
+                              MachineType::Uint8()};
+      return access;
+    }
+    case kExternalInt16Array: {
+      ElementAccess access = {taggedness, header_size, Type::Signed32(),
+                              MachineType::Int16()};
+      return access;
+    }
+    case kExternalUint16Array: {
+      ElementAccess access = {taggedness, header_size, Type::Unsigned32(),
+                              MachineType::Uint16()};
+      return access;
+    }
+    case kExternalInt32Array: {
+      ElementAccess access = {taggedness, header_size, Type::Signed32(),
+                              MachineType::Int32()};
+      return access;
+    }
+    case kExternalUint32Array: {
+      ElementAccess access = {taggedness, header_size, Type::Unsigned32(),
+                              MachineType::Uint32()};
+      return access;
+    }
+    case kExternalFloat32Array: {
+      ElementAccess access = {taggedness, header_size, Type::Number(),
+                              MachineType::Float32()};
+      return access;
+    }
+    case kExternalFloat64Array: {
+      ElementAccess access = {taggedness, header_size, Type::Number(),
+                              MachineType::Float64()};
+      return access;
+    }
   }
   UNREACHABLE();
-  return {kUntaggedBase, 0, Type::None(), kMachNone};
+  ElementAccess access = {kUntaggedBase, 0, Type::None(), MachineType::None()};
+  return access;
+}
+
+
+// static
+FieldAccess AccessBuilder::ForStatsCounter() {
+  FieldAccess access = {kUntaggedBase, 0, MaybeHandle<Name>(),
+                        TypeCache::Get().kInt32, MachineType::Int32()};
+  return access;
 }
 
 }  // namespace compiler
diff --git a/src/compiler/access-builder.h b/src/compiler/access-builder.h
index d6385e4..8375d37 100644
--- a/src/compiler/access-builder.h
+++ b/src/compiler/access-builder.h
@@ -12,47 +12,130 @@
 namespace compiler {
 
 // This access builder provides a set of static methods constructing commonly
-// used FieldAccess and ElementAccess descriptors. These descriptors server as
+// used FieldAccess and ElementAccess descriptors. These descriptors serve as
 // parameters to simplified load/store operators.
-class AccessBuilder FINAL : public AllStatic {
+class AccessBuilder final : public AllStatic {
  public:
+  // ===========================================================================
+  // Access to heap object fields and elements (based on tagged pointer).
+
   // Provides access to HeapObject::map() field.
   static FieldAccess ForMap();
 
+  // Provides access to HeapNumber::value() field.
+  static FieldAccess ForHeapNumberValue();
+
   // Provides access to JSObject::properties() field.
   static FieldAccess ForJSObjectProperties();
 
   // Provides access to JSObject::elements() field.
   static FieldAccess ForJSObjectElements();
 
+  // Provides access to JSObject inobject property fields.
+  static FieldAccess ForJSObjectInObjectProperty(Handle<Map> map, int index);
+
   // Provides access to JSFunction::context() field.
   static FieldAccess ForJSFunctionContext();
 
+  // Provides access to JSFunction::shared() field.
+  static FieldAccess ForJSFunctionSharedFunctionInfo();
+
+  // Provides access to JSArray::length() field.
+  static FieldAccess ForJSArrayLength(ElementsKind elements_kind);
+
   // Provides access to JSArrayBuffer::backing_store() field.
   static FieldAccess ForJSArrayBufferBackingStore();
 
-  // Provides access to ExternalArray::external_pointer() field.
-  static FieldAccess ForExternalArrayPointer();
+  // Provides access to JSArrayBuffer::bit_field() field.
+  static FieldAccess ForJSArrayBufferBitField();
+
+  // Provides access to JSArrayBufferView::buffer() field.
+  static FieldAccess ForJSArrayBufferViewBuffer();
+
+  // Provides access to JSDate fields.
+  static FieldAccess ForJSDateField(JSDate::FieldIndex index);
+
+  // Provides access to JSIteratorResult::done() field.
+  static FieldAccess ForJSIteratorResultDone();
+
+  // Provides access to JSIteratorResult::value() field.
+  static FieldAccess ForJSIteratorResultValue();
+
+  // Provides access to JSRegExp::flags() field.
+  static FieldAccess ForJSRegExpFlags();
+
+  // Provides access to JSRegExp::source() field.
+  static FieldAccess ForJSRegExpSource();
+
+  // Provides access to FixedArray::length() field.
+  static FieldAccess ForFixedArrayLength();
+
+  // Provides access to DescriptorArray::enum_cache() field.
+  static FieldAccess ForDescriptorArrayEnumCache();
+
+  // Provides access to DescriptorArray::enum_cache_bridge_cache() field.
+  static FieldAccess ForDescriptorArrayEnumCacheBridgeCache();
+
+  // Provides access to Map::bit_field() byte.
+  static FieldAccess ForMapBitField();
+
+  // Provides access to Map::bit_field3() field.
+  static FieldAccess ForMapBitField3();
+
+  // Provides access to Map::descriptors() field.
+  static FieldAccess ForMapDescriptors();
 
   // Provides access to Map::instance_type() field.
   static FieldAccess ForMapInstanceType();
 
+  // Provides access to Map::prototype() field.
+  static FieldAccess ForMapPrototype();
+
   // Provides access to String::length() field.
   static FieldAccess ForStringLength();
 
+  // Provides access to JSGlobalObject::global_proxy() field.
+  static FieldAccess ForJSGlobalObjectGlobalProxy();
+
+  // Provides access to JSGlobalObject::native_context() field.
+  static FieldAccess ForJSGlobalObjectNativeContext();
+
   // Provides access to JSValue::value() field.
   static FieldAccess ForValue();
 
-  // Provides access Context slots.
+  // Provides access to arguments object fields.
+  static FieldAccess ForArgumentsLength();
+  static FieldAccess ForArgumentsCallee();
+
+  // Provides access to FixedArray slots.
+  static FieldAccess ForFixedArraySlot(size_t index);
+
+  // Provides access to Context slots.
   static FieldAccess ForContextSlot(size_t index);
 
+  // Provides access to PropertyCell::value() field.
+  static FieldAccess ForPropertyCellValue();
+  static FieldAccess ForPropertyCellValue(Type* type);
+
+  // Provides access to SharedFunctionInfo::feedback_vector() field.
+  static FieldAccess ForSharedFunctionInfoTypeFeedbackVector();
+
   // Provides access to FixedArray elements.
   static ElementAccess ForFixedArrayElement();
 
+  // Provides access to FixedDoubleArray elements.
+  static ElementAccess ForFixedDoubleArrayElement();
+
   // Provides access to Fixed{type}TypedArray and External{type}Array elements.
   static ElementAccess ForTypedArrayElement(ExternalArrayType type,
                                             bool is_external);
 
+  // ===========================================================================
+  // Access to global per-isolate variables (based on external reference).
+
+  // Provides access to the backing store of a StatsCounter.
+  static FieldAccess ForStatsCounter();
+
  private:
   DISALLOW_IMPLICIT_CONSTRUCTORS(AccessBuilder);
 };
diff --git a/src/compiler/access-info.cc b/src/compiler/access-info.cc
new file mode 100644
index 0000000..612170e
--- /dev/null
+++ b/src/compiler/access-info.cc
@@ -0,0 +1,488 @@
+// Copyright 2015 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 <ostream>
+
+#include "src/accessors.h"
+#include "src/compilation-dependencies.h"
+#include "src/compiler/access-info.h"
+#include "src/field-index-inl.h"
+#include "src/objects-inl.h"  // TODO(mstarzinger): Temporary cycle breaker!
+#include "src/type-cache.h"
+#include "src/types-inl.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+namespace {
+
+bool CanInlineElementAccess(Handle<Map> map) {
+  if (!map->IsJSObjectMap()) return false;
+  if (map->is_access_check_needed()) return false;
+  if (map->has_indexed_interceptor()) return false;
+  ElementsKind const elements_kind = map->elements_kind();
+  if (IsFastElementsKind(elements_kind)) return true;
+  // TODO(bmeurer): Add support for other elements kind.
+  return false;
+}
+
+
+bool CanInlinePropertyAccess(Handle<Map> map) {
+  // We can inline property access to prototypes of all primitives, except
+  // the special Oddball ones that have no wrapper counterparts (i.e. Null,
+  // Undefined and TheHole).
+  STATIC_ASSERT(ODDBALL_TYPE == LAST_PRIMITIVE_TYPE);
+  if (map->IsBooleanMap()) return true;
+  if (map->instance_type() < LAST_PRIMITIVE_TYPE) return true;
+  return map->IsJSObjectMap() && !map->is_dictionary_map() &&
+         !map->has_named_interceptor() &&
+         // TODO(verwaest): Whitelist contexts to which we have access.
+         !map->is_access_check_needed();
+}
+
+}  // namespace
+
+
+std::ostream& operator<<(std::ostream& os, AccessMode access_mode) {
+  switch (access_mode) {
+    case AccessMode::kLoad:
+      return os << "Load";
+    case AccessMode::kStore:
+      return os << "Store";
+  }
+  UNREACHABLE();
+  return os;
+}
+
+
+// static
+PropertyAccessInfo PropertyAccessInfo::NotFound(Type* receiver_type,
+                                                MaybeHandle<JSObject> holder) {
+  return PropertyAccessInfo(holder, receiver_type);
+}
+
+
+// static
+PropertyAccessInfo PropertyAccessInfo::DataConstant(
+    Type* receiver_type, Handle<Object> constant,
+    MaybeHandle<JSObject> holder) {
+  return PropertyAccessInfo(holder, constant, receiver_type);
+}
+
+
+// static
+PropertyAccessInfo PropertyAccessInfo::DataField(
+    Type* receiver_type, FieldIndex field_index, Type* field_type,
+    FieldCheck field_check, MaybeHandle<JSObject> holder,
+    MaybeHandle<Map> transition_map) {
+  return PropertyAccessInfo(holder, transition_map, field_index, field_check,
+                            field_type, receiver_type);
+}
+
+
+ElementAccessInfo::ElementAccessInfo() : receiver_type_(Type::None()) {}
+
+
+ElementAccessInfo::ElementAccessInfo(Type* receiver_type,
+                                     ElementsKind elements_kind,
+                                     MaybeHandle<JSObject> holder)
+    : elements_kind_(elements_kind),
+      holder_(holder),
+      receiver_type_(receiver_type) {}
+
+
+PropertyAccessInfo::PropertyAccessInfo()
+    : kind_(kInvalid), receiver_type_(Type::None()), field_type_(Type::Any()) {}
+
+
+PropertyAccessInfo::PropertyAccessInfo(MaybeHandle<JSObject> holder,
+                                       Type* receiver_type)
+    : kind_(kNotFound),
+      receiver_type_(receiver_type),
+      holder_(holder),
+      field_type_(Type::Any()) {}
+
+
+PropertyAccessInfo::PropertyAccessInfo(MaybeHandle<JSObject> holder,
+                                       Handle<Object> constant,
+                                       Type* receiver_type)
+    : kind_(kDataConstant),
+      receiver_type_(receiver_type),
+      constant_(constant),
+      holder_(holder),
+      field_type_(Type::Any()) {}
+
+
+PropertyAccessInfo::PropertyAccessInfo(MaybeHandle<JSObject> holder,
+                                       MaybeHandle<Map> transition_map,
+                                       FieldIndex field_index,
+                                       FieldCheck field_check, Type* field_type,
+                                       Type* receiver_type)
+    : kind_(kDataField),
+      receiver_type_(receiver_type),
+      transition_map_(transition_map),
+      holder_(holder),
+      field_index_(field_index),
+      field_check_(field_check),
+      field_type_(field_type) {}
+
+
+AccessInfoFactory::AccessInfoFactory(CompilationDependencies* dependencies,
+                                     Handle<Context> native_context, Zone* zone)
+    : dependencies_(dependencies),
+      native_context_(native_context),
+      isolate_(native_context->GetIsolate()),
+      type_cache_(TypeCache::Get()),
+      zone_(zone) {
+  DCHECK(native_context->IsNativeContext());
+}
+
+
+bool AccessInfoFactory::ComputeElementAccessInfo(
+    Handle<Map> map, AccessMode access_mode, ElementAccessInfo* access_info) {
+  // Check if it is safe to inline element access for the {map}.
+  if (!CanInlineElementAccess(map)) return false;
+
+  ElementsKind const elements_kind = map->elements_kind();
+
+  // Certain (monomorphic) stores need a prototype chain check because shape
+  // changes could allow callbacks on elements in the chain that are not
+  // compatible with monomorphic keyed stores.
+  MaybeHandle<JSObject> holder;
+  if (access_mode == AccessMode::kStore && map->prototype()->IsJSObject()) {
+    for (PrototypeIterator i(map); !i.IsAtEnd(); i.Advance()) {
+      Handle<JSReceiver> prototype =
+          PrototypeIterator::GetCurrent<JSReceiver>(i);
+      if (!prototype->IsJSObject()) return false;
+      // TODO(bmeurer): We do not currently support unstable prototypes.
+      // We might want to revisit the way we handle certain keyed stores
+      // because this whole prototype chain check is essential a hack,
+      // and I'm not sure that it is correct at all with dictionaries in
+      // the prototype chain.
+      if (!prototype->map()->is_stable()) return false;
+      holder = Handle<JSObject>::cast(prototype);
+    }
+  }
+
+  *access_info =
+      ElementAccessInfo(Type::Class(map, zone()), elements_kind, holder);
+  return true;
+}
+
+
+bool AccessInfoFactory::ComputeElementAccessInfos(
+    MapHandleList const& maps, AccessMode access_mode,
+    ZoneVector<ElementAccessInfo>* access_infos) {
+  // Collect possible transition targets.
+  MapHandleList possible_transition_targets(maps.length());
+  for (Handle<Map> map : maps) {
+    if (Map::TryUpdate(map).ToHandle(&map)) {
+      if (CanInlineElementAccess(map) &&
+          IsFastElementsKind(map->elements_kind()) &&
+          GetInitialFastElementsKind() != map->elements_kind()) {
+        possible_transition_targets.Add(map);
+      }
+    }
+  }
+
+  // Separate the actual receiver maps and the possible transition sources.
+  MapHandleList receiver_maps(maps.length());
+  MapTransitionList transitions(maps.length());
+  for (Handle<Map> map : maps) {
+    if (Map::TryUpdate(map).ToHandle(&map)) {
+      Handle<Map> transition_target =
+          Map::FindTransitionedMap(map, &possible_transition_targets);
+      if (transition_target.is_null()) {
+        receiver_maps.Add(map);
+      } else {
+        transitions.push_back(std::make_pair(map, transition_target));
+      }
+    }
+  }
+
+  for (Handle<Map> receiver_map : receiver_maps) {
+    // Compute the element access information.
+    ElementAccessInfo access_info;
+    if (!ComputeElementAccessInfo(receiver_map, access_mode, &access_info)) {
+      return false;
+    }
+
+    // Collect the possible transitions for the {receiver_map}.
+    for (auto transition : transitions) {
+      if (transition.second.is_identical_to(receiver_map)) {
+        access_info.transitions().push_back(transition);
+      }
+    }
+
+    // Schedule the access information.
+    access_infos->push_back(access_info);
+  }
+  return true;
+}
+
+
+bool AccessInfoFactory::ComputePropertyAccessInfo(
+    Handle<Map> map, Handle<Name> name, AccessMode access_mode,
+    PropertyAccessInfo* access_info) {
+  // Check if it is safe to inline property access for the {map}.
+  if (!CanInlinePropertyAccess(map)) return false;
+
+  // Compute the receiver type.
+  Handle<Map> receiver_map = map;
+
+  // We support fast inline cases for certain JSObject getters.
+  if (access_mode == AccessMode::kLoad &&
+      LookupSpecialFieldAccessor(map, name, access_info)) {
+    return true;
+  }
+
+  MaybeHandle<JSObject> holder;
+  do {
+    // Lookup the named property on the {map}.
+    Handle<DescriptorArray> descriptors(map->instance_descriptors(), isolate());
+    int const number = descriptors->SearchWithCache(*name, *map);
+    if (number != DescriptorArray::kNotFound) {
+      PropertyDetails const details = descriptors->GetDetails(number);
+      if (access_mode == AccessMode::kStore) {
+        // Don't bother optimizing stores to read-only properties.
+        if (details.IsReadOnly()) {
+          return false;
+        }
+        // Check for store to data property on a prototype.
+        if (details.kind() == kData && !holder.is_null()) {
+          // Store to property not found on the receiver but on a prototype, we
+          // need to transition to a new data property.
+          // Implemented according to ES6 section 9.1.9 [[Set]] (P, V, Receiver)
+          return LookupTransition(receiver_map, name, holder, access_info);
+        }
+      }
+      if (details.type() == DATA_CONSTANT) {
+        *access_info = PropertyAccessInfo::DataConstant(
+            Type::Class(receiver_map, zone()),
+            handle(descriptors->GetValue(number), isolate()), holder);
+        return true;
+      } else if (details.type() == DATA) {
+        int index = descriptors->GetFieldIndex(number);
+        Representation field_representation = details.representation();
+        FieldIndex field_index = FieldIndex::ForPropertyIndex(
+            *map, index, field_representation.IsDouble());
+        Type* field_type = Type::Tagged();
+        if (field_representation.IsSmi()) {
+          field_type = type_cache_.kSmi;
+        } else if (field_representation.IsDouble()) {
+          field_type = type_cache_.kFloat64;
+        } else if (field_representation.IsHeapObject()) {
+          // Extract the field type from the property details (make sure its
+          // representation is TaggedPointer to reflect the heap object case).
+          field_type = Type::Intersect(
+              Type::Convert<HeapType>(
+                  handle(descriptors->GetFieldType(number), isolate()), zone()),
+              Type::TaggedPointer(), zone());
+          if (field_type->Is(Type::None())) {
+            // Store is not safe if the field type was cleared.
+            if (access_mode == AccessMode::kStore) return false;
+
+            // The field type was cleared by the GC, so we don't know anything
+            // about the contents now.
+            // TODO(bmeurer): It would be awesome to make this saner in the
+            // runtime/GC interaction.
+            field_type = Type::TaggedPointer();
+          } else if (!Type::Any()->Is(field_type)) {
+            // Add proper code dependencies in case of stable field map(s).
+            Handle<Map> field_owner_map(map->FindFieldOwner(number), isolate());
+            dependencies()->AssumeFieldType(field_owner_map);
+          }
+          DCHECK(field_type->Is(Type::TaggedPointer()));
+        }
+        *access_info = PropertyAccessInfo::DataField(
+            Type::Class(receiver_map, zone()), field_index, field_type,
+            FieldCheck::kNone, holder);
+        return true;
+      } else {
+        // TODO(bmeurer): Add support for accessors.
+        return false;
+      }
+    }
+
+    // Don't search on the prototype chain for special indices in case of
+    // integer indexed exotic objects (see ES6 section 9.4.5).
+    if (map->IsJSTypedArrayMap() && name->IsString() &&
+        IsSpecialIndex(isolate()->unicode_cache(), String::cast(*name))) {
+      return false;
+    }
+
+    // Don't lookup private symbols on the prototype chain.
+    if (name->IsPrivate()) return false;
+
+    // Walk up the prototype chain.
+    if (!map->prototype()->IsJSObject()) {
+      // Perform the implicit ToObject for primitives here.
+      // Implemented according to ES6 section 7.3.2 GetV (V, P).
+      Handle<JSFunction> constructor;
+      if (Map::GetConstructorFunction(map, native_context())
+              .ToHandle(&constructor)) {
+        map = handle(constructor->initial_map(), isolate());
+        DCHECK(map->prototype()->IsJSObject());
+      } else if (map->prototype()->IsNull()) {
+        // Store to property not found on the receiver or any prototype, we need
+        // to transition to a new data property.
+        // Implemented according to ES6 section 9.1.9 [[Set]] (P, V, Receiver)
+        if (access_mode == AccessMode::kStore) {
+          return LookupTransition(receiver_map, name, holder, access_info);
+        }
+        // The property was not found, return undefined or throw depending
+        // on the language mode of the load operation.
+        // Implemented according to ES6 section 9.1.8 [[Get]] (P, Receiver)
+        *access_info = PropertyAccessInfo::NotFound(
+            Type::Class(receiver_map, zone()), holder);
+        return true;
+      } else {
+        return false;
+      }
+    }
+    Handle<JSObject> map_prototype(JSObject::cast(map->prototype()), isolate());
+    if (map_prototype->map()->is_deprecated()) {
+      // Try to migrate the prototype object so we don't embed the deprecated
+      // map into the optimized code.
+      JSObject::TryMigrateInstance(map_prototype);
+    }
+    map = handle(map_prototype->map(), isolate());
+    holder = map_prototype;
+  } while (CanInlinePropertyAccess(map));
+  return false;
+}
+
+
+bool AccessInfoFactory::ComputePropertyAccessInfos(
+    MapHandleList const& maps, Handle<Name> name, AccessMode access_mode,
+    ZoneVector<PropertyAccessInfo>* access_infos) {
+  for (Handle<Map> map : maps) {
+    if (Map::TryUpdate(map).ToHandle(&map)) {
+      PropertyAccessInfo access_info;
+      if (!ComputePropertyAccessInfo(map, name, access_mode, &access_info)) {
+        return false;
+      }
+      access_infos->push_back(access_info);
+    }
+  }
+  return true;
+}
+
+
+bool AccessInfoFactory::LookupSpecialFieldAccessor(
+    Handle<Map> map, Handle<Name> name, PropertyAccessInfo* access_info) {
+  // Check for special JSObject field accessors.
+  int offset;
+  if (Accessors::IsJSObjectFieldAccessor(map, name, &offset)) {
+    FieldIndex field_index = FieldIndex::ForInObjectOffset(offset);
+    Type* field_type = Type::Tagged();
+    if (map->IsStringMap()) {
+      DCHECK(Name::Equals(factory()->length_string(), name));
+      // The String::length property is always a smi in the range
+      // [0, String::kMaxLength].
+      field_type = type_cache_.kStringLengthType;
+    } else if (map->IsJSArrayMap()) {
+      DCHECK(Name::Equals(factory()->length_string(), name));
+      // The JSArray::length property is a smi in the range
+      // [0, FixedDoubleArray::kMaxLength] in case of fast double
+      // elements, a smi in the range [0, FixedArray::kMaxLength]
+      // in case of other fast elements, and [0, kMaxUInt32] in
+      // case of other arrays.
+      if (IsFastDoubleElementsKind(map->elements_kind())) {
+        field_type = type_cache_.kFixedDoubleArrayLengthType;
+      } else if (IsFastElementsKind(map->elements_kind())) {
+        field_type = type_cache_.kFixedArrayLengthType;
+      } else {
+        field_type = type_cache_.kJSArrayLengthType;
+      }
+    }
+    *access_info = PropertyAccessInfo::DataField(Type::Class(map, zone()),
+                                                 field_index, field_type);
+    return true;
+  }
+  // Check for special JSArrayBufferView field accessors.
+  if (Accessors::IsJSArrayBufferViewFieldAccessor(map, name, &offset)) {
+    FieldIndex field_index = FieldIndex::ForInObjectOffset(offset);
+    Type* field_type = Type::Tagged();
+    if (Name::Equals(factory()->byte_length_string(), name) ||
+        Name::Equals(factory()->byte_offset_string(), name)) {
+      // The JSArrayBufferView::byte_length and JSArrayBufferView::byte_offset
+      // properties are always numbers in the range [0, kMaxSafeInteger].
+      field_type = type_cache_.kPositiveSafeInteger;
+    } else if (map->IsJSTypedArrayMap()) {
+      DCHECK(Name::Equals(factory()->length_string(), name));
+      // The JSTypedArray::length property is always a number in the range
+      // [0, kMaxSafeInteger].
+      field_type = type_cache_.kPositiveSafeInteger;
+    }
+    *access_info = PropertyAccessInfo::DataField(
+        Type::Class(map, zone()), field_index, field_type,
+        FieldCheck::kJSArrayBufferViewBufferNotNeutered);
+    return true;
+  }
+  return false;
+}
+
+
+bool AccessInfoFactory::LookupTransition(Handle<Map> map, Handle<Name> name,
+                                         MaybeHandle<JSObject> holder,
+                                         PropertyAccessInfo* access_info) {
+  // Check if the {map} has a data transition with the given {name}.
+  if (map->unused_property_fields() == 0) return false;
+  Handle<Map> transition_map;
+  if (TransitionArray::SearchTransition(map, kData, name, NONE)
+          .ToHandle(&transition_map)) {
+    int const number = transition_map->LastAdded();
+    PropertyDetails const details =
+        transition_map->instance_descriptors()->GetDetails(number);
+    // Don't bother optimizing stores to read-only properties.
+    if (details.IsReadOnly()) return false;
+    // TODO(bmeurer): Handle transition to data constant?
+    if (details.type() != DATA) return false;
+    int const index = details.field_index();
+    Representation field_representation = details.representation();
+    FieldIndex field_index = FieldIndex::ForPropertyIndex(
+        *transition_map, index, field_representation.IsDouble());
+    Type* field_type = Type::Tagged();
+    if (field_representation.IsSmi()) {
+      field_type = type_cache_.kSmi;
+    } else if (field_representation.IsDouble()) {
+      field_type = type_cache_.kFloat64;
+    } else if (field_representation.IsHeapObject()) {
+      // Extract the field type from the property details (make sure its
+      // representation is TaggedPointer to reflect the heap object case).
+      field_type = Type::Intersect(
+          Type::Convert<HeapType>(
+              handle(
+                  transition_map->instance_descriptors()->GetFieldType(number),
+                  isolate()),
+              zone()),
+          Type::TaggedPointer(), zone());
+      if (field_type->Is(Type::None())) {
+        // Store is not safe if the field type was cleared.
+        return false;
+      } else if (!Type::Any()->Is(field_type)) {
+        // Add proper code dependencies in case of stable field map(s).
+        Handle<Map> field_owner_map(transition_map->FindFieldOwner(number),
+                                    isolate());
+        dependencies()->AssumeFieldType(field_owner_map);
+      }
+      DCHECK(field_type->Is(Type::TaggedPointer()));
+    }
+    dependencies()->AssumeMapNotDeprecated(transition_map);
+    *access_info = PropertyAccessInfo::DataField(
+        Type::Class(map, zone()), field_index, field_type, FieldCheck::kNone,
+        holder, transition_map);
+    return true;
+  }
+  return false;
+}
+
+
+Factory* AccessInfoFactory::factory() const { return isolate()->factory(); }
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/access-info.h b/src/compiler/access-info.h
new file mode 100644
index 0000000..cae1191
--- /dev/null
+++ b/src/compiler/access-info.h
@@ -0,0 +1,164 @@
+// Copyright 2015 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.
+
+#ifndef V8_COMPILER_ACCESS_INFO_H_
+#define V8_COMPILER_ACCESS_INFO_H_
+
+#include <iosfwd>
+
+#include "src/field-index.h"
+#include "src/objects.h"
+#include "src/zone-containers.h"
+
+namespace v8 {
+namespace internal {
+
+// Forward declarations.
+class CompilationDependencies;
+class Factory;
+class TypeCache;
+
+
+namespace compiler {
+
+// Whether we are loading a property or storing to a property.
+enum class AccessMode { kLoad, kStore };
+
+std::ostream& operator<<(std::ostream&, AccessMode);
+
+
+// Mapping of transition source to transition target.
+typedef std::vector<std::pair<Handle<Map>, Handle<Map>>> MapTransitionList;
+
+
+// This class encapsulates all information required to access a certain element.
+class ElementAccessInfo final {
+ public:
+  ElementAccessInfo();
+  ElementAccessInfo(Type* receiver_type, ElementsKind elements_kind,
+                    MaybeHandle<JSObject> holder);
+
+  MaybeHandle<JSObject> holder() const { return holder_; }
+  ElementsKind elements_kind() const { return elements_kind_; }
+  Type* receiver_type() const { return receiver_type_; }
+  MapTransitionList& transitions() { return transitions_; }
+  MapTransitionList const& transitions() const { return transitions_; }
+
+ private:
+  ElementsKind elements_kind_;
+  MaybeHandle<JSObject> holder_;
+  Type* receiver_type_;
+  MapTransitionList transitions_;
+};
+
+
+// Additional checks that need to be perform for data field accesses.
+enum class FieldCheck : uint8_t {
+  // No additional checking needed.
+  kNone,
+  // Check that the [[ViewedArrayBuffer]] of {JSArrayBufferView}s
+  // was not neutered.
+  kJSArrayBufferViewBufferNotNeutered,
+};
+
+
+// This class encapsulates all information required to access a certain
+// object property, either on the object itself or on the prototype chain.
+class PropertyAccessInfo final {
+ public:
+  enum Kind { kInvalid, kNotFound, kDataConstant, kDataField };
+
+  static PropertyAccessInfo NotFound(Type* receiver_type,
+                                     MaybeHandle<JSObject> holder);
+  static PropertyAccessInfo DataConstant(Type* receiver_type,
+                                         Handle<Object> constant,
+                                         MaybeHandle<JSObject> holder);
+  static PropertyAccessInfo DataField(
+      Type* receiver_type, FieldIndex field_index, Type* field_type,
+      FieldCheck field_check = FieldCheck::kNone,
+      MaybeHandle<JSObject> holder = MaybeHandle<JSObject>(),
+      MaybeHandle<Map> transition_map = MaybeHandle<Map>());
+
+  PropertyAccessInfo();
+
+  bool IsNotFound() const { return kind() == kNotFound; }
+  bool IsDataConstant() const { return kind() == kDataConstant; }
+  bool IsDataField() const { return kind() == kDataField; }
+
+  bool HasTransitionMap() const { return !transition_map().is_null(); }
+
+  Kind kind() const { return kind_; }
+  MaybeHandle<JSObject> holder() const { return holder_; }
+  MaybeHandle<Map> transition_map() const { return transition_map_; }
+  Handle<Object> constant() const { return constant_; }
+  FieldCheck field_check() const { return field_check_; }
+  FieldIndex field_index() const { return field_index_; }
+  Type* field_type() const { return field_type_; }
+  Type* receiver_type() const { return receiver_type_; }
+
+ private:
+  PropertyAccessInfo(MaybeHandle<JSObject> holder, Type* receiver_type);
+  PropertyAccessInfo(MaybeHandle<JSObject> holder, Handle<Object> constant,
+                     Type* receiver_type);
+  PropertyAccessInfo(MaybeHandle<JSObject> holder,
+                     MaybeHandle<Map> transition_map, FieldIndex field_index,
+                     FieldCheck field_check, Type* field_type,
+                     Type* receiver_type);
+
+  Kind kind_;
+  Type* receiver_type_;
+  Handle<Object> constant_;
+  MaybeHandle<Map> transition_map_;
+  MaybeHandle<JSObject> holder_;
+  FieldIndex field_index_;
+  FieldCheck field_check_;
+  Type* field_type_;
+};
+
+
+// Factory class for {ElementAccessInfo}s and {PropertyAccessInfo}s.
+class AccessInfoFactory final {
+ public:
+  AccessInfoFactory(CompilationDependencies* dependencies,
+                    Handle<Context> native_context, Zone* zone);
+
+  bool ComputeElementAccessInfo(Handle<Map> map, AccessMode access_mode,
+                                ElementAccessInfo* access_info);
+  bool ComputeElementAccessInfos(MapHandleList const& maps,
+                                 AccessMode access_mode,
+                                 ZoneVector<ElementAccessInfo>* access_infos);
+  bool ComputePropertyAccessInfo(Handle<Map> map, Handle<Name> name,
+                                 AccessMode access_mode,
+                                 PropertyAccessInfo* access_info);
+  bool ComputePropertyAccessInfos(MapHandleList const& maps, Handle<Name> name,
+                                  AccessMode access_mode,
+                                  ZoneVector<PropertyAccessInfo>* access_infos);
+
+ private:
+  bool LookupSpecialFieldAccessor(Handle<Map> map, Handle<Name> name,
+                                  PropertyAccessInfo* access_info);
+  bool LookupTransition(Handle<Map> map, Handle<Name> name,
+                        MaybeHandle<JSObject> holder,
+                        PropertyAccessInfo* access_info);
+
+  CompilationDependencies* dependencies() const { return dependencies_; }
+  Factory* factory() const;
+  Isolate* isolate() const { return isolate_; }
+  Handle<Context> native_context() const { return native_context_; }
+  Zone* zone() const { return zone_; }
+
+  CompilationDependencies* const dependencies_;
+  Handle<Context> const native_context_;
+  Isolate* const isolate_;
+  TypeCache const& type_cache_;
+  Zone* const zone_;
+
+  DISALLOW_COPY_AND_ASSIGN(AccessInfoFactory);
+};
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_ACCESS_INFO_H_
diff --git a/src/compiler/all-nodes.cc b/src/compiler/all-nodes.cc
new file mode 100644
index 0000000..ed4a218
--- /dev/null
+++ b/src/compiler/all-nodes.cc
@@ -0,0 +1,39 @@
+// 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/all-nodes.h"
+
+#include "src/compiler/graph.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+AllNodes::AllNodes(Zone* local_zone, const Graph* graph)
+    : live(local_zone), is_live(graph->NodeCount(), false, local_zone) {
+  Node* end = graph->end();
+  is_live[end->id()] = true;
+  live.push_back(end);
+  // Find all live nodes reachable from end.
+  for (size_t i = 0; i < live.size(); i++) {
+    for (Node* const input : live[i]->inputs()) {
+      if (input == nullptr) {
+        // TODO(titzer): print a warning.
+        continue;
+      }
+      if (input->id() >= graph->NodeCount()) {
+        // TODO(titzer): print a warning.
+        continue;
+      }
+      if (!is_live[input->id()]) {
+        is_live[input->id()] = true;
+        live.push_back(input);
+      }
+    }
+  }
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/all-nodes.h b/src/compiler/all-nodes.h
new file mode 100644
index 0000000..700f007
--- /dev/null
+++ b/src/compiler/all-nodes.h
@@ -0,0 +1,38 @@
+// Copyright 2015 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.
+
+#ifndef V8_COMPILER_ALL_NODES_H_
+#define V8_COMPILER_ALL_NODES_H_
+
+#include "src/compiler/node.h"
+#include "src/zone-containers.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+// A helper utility that traverses the graph and gathers all nodes reachable
+// from end.
+class AllNodes {
+ public:
+  // Constructor. Traverses the graph and builds the {live} sets.
+  AllNodes(Zone* local_zone, const Graph* graph);
+
+  bool IsLive(Node* node) {
+    if (!node) return false;
+    size_t id = node->id();
+    return id < is_live.size() && is_live[id];
+  }
+
+  NodeVector live;  // Nodes reachable from end.
+
+ private:
+  BoolVector is_live;
+};
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_ALL_NODES_H_
diff --git a/src/compiler/arm/code-generator-arm.cc b/src/compiler/arm/code-generator-arm.cc
index cfa4de9..9b074b0 100644
--- a/src/compiler/arm/code-generator-arm.cc
+++ b/src/compiler/arm/code-generator-arm.cc
@@ -5,11 +5,11 @@
 #include "src/compiler/code-generator.h"
 
 #include "src/arm/macro-assembler-arm.h"
+#include "src/ast/scopes.h"
 #include "src/compiler/code-generator-impl.h"
 #include "src/compiler/gap-resolver.h"
 #include "src/compiler/node-matchers.h"
-#include "src/compiler/node-properties-inl.h"
-#include "src/scopes.h"
+#include "src/compiler/osr.h"
 
 namespace v8 {
 namespace internal {
@@ -22,16 +22,16 @@
 
 
 // Adds Arm-specific methods to convert InstructionOperands.
-class ArmOperandConverter FINAL : public InstructionOperandConverter {
+class ArmOperandConverter final : public InstructionOperandConverter {
  public:
   ArmOperandConverter(CodeGenerator* gen, Instruction* instr)
       : InstructionOperandConverter(gen, instr) {}
 
-  SwVfpRegister OutputFloat32Register(int index = 0) {
+  SwVfpRegister OutputFloat32Register(size_t index = 0) {
     return ToFloat32Register(instr_->OutputAt(index));
   }
 
-  SwVfpRegister InputFloat32Register(int index) {
+  SwVfpRegister InputFloat32Register(size_t index) {
     return ToFloat32Register(instr_->InputAt(index));
   }
 
@@ -39,11 +39,11 @@
     return ToFloat64Register(op).low();
   }
 
-  LowDwVfpRegister OutputFloat64Register(int index = 0) {
+  LowDwVfpRegister OutputFloat64Register(size_t index = 0) {
     return ToFloat64Register(instr_->OutputAt(index));
   }
 
-  LowDwVfpRegister InputFloat64Register(int index) {
+  LowDwVfpRegister InputFloat64Register(size_t index) {
     return ToFloat64Register(instr_->InputAt(index));
   }
 
@@ -63,7 +63,7 @@
     return LeaveCC;
   }
 
-  Operand InputImmediate(int index) {
+  Operand InputImmediate(size_t index) {
     Constant constant = ToConstant(instr_->InputAt(index));
     switch (constant.type()) {
       case Constant::kInt32:
@@ -84,8 +84,8 @@
     return Operand::Zero();
   }
 
-  Operand InputOperand2(int first_index) {
-    const int index = first_index;
+  Operand InputOperand2(size_t first_index) {
+    const size_t index = first_index;
     switch (AddressingModeField::decode(instr_->opcode())) {
       case kMode_None:
       case kMode_Offset_RI:
@@ -116,8 +116,8 @@
     return Operand::Zero();
   }
 
-  MemOperand InputOffset(int* first_index) {
-    const int index = *first_index;
+  MemOperand InputOffset(size_t* first_index) {
+    const size_t index = *first_index;
     switch (AddressingModeField::decode(instr_->opcode())) {
       case kMode_None:
       case kMode_Operand2_I:
@@ -142,17 +142,15 @@
     return MemOperand(r0);
   }
 
-  MemOperand InputOffset(int first_index = 0) {
+  MemOperand InputOffset(size_t first_index = 0) {
     return InputOffset(&first_index);
   }
 
   MemOperand ToMemOperand(InstructionOperand* op) const {
-    DCHECK(op != NULL);
-    DCHECK(!op->IsRegister());
-    DCHECK(!op->IsDoubleRegister());
+    DCHECK_NOT_NULL(op);
     DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot());
-    // The linkage computes where all spill slots are located.
-    FrameOffset offset = linkage()->GetFrameOffset(op->index(), frame(), 0);
+    FrameOffset offset = frame_access_state()->GetFrameOffset(
+        AllocatedOperand::cast(op)->index());
     return MemOperand(offset.from_stack_pointer() ? sp : fp, offset.offset());
   }
 };
@@ -160,12 +158,12 @@
 
 namespace {
 
-class OutOfLineLoadFloat32 FINAL : public OutOfLineCode {
+class OutOfLineLoadFloat32 final : public OutOfLineCode {
  public:
   OutOfLineLoadFloat32(CodeGenerator* gen, SwVfpRegister result)
       : OutOfLineCode(gen), result_(result) {}
 
-  void Generate() FINAL {
+  void Generate() final {
     __ vmov(result_, std::numeric_limits<float>::quiet_NaN());
   }
 
@@ -174,12 +172,12 @@
 };
 
 
-class OutOfLineLoadFloat64 FINAL : public OutOfLineCode {
+class OutOfLineLoadFloat64 final : public OutOfLineCode {
  public:
   OutOfLineLoadFloat64(CodeGenerator* gen, DwVfpRegister result)
       : OutOfLineCode(gen), result_(result) {}
 
-  void Generate() FINAL {
+  void Generate() final {
     __ vmov(result_, std::numeric_limits<double>::quiet_NaN(), kScratchReg);
   }
 
@@ -188,17 +186,109 @@
 };
 
 
-class OutOfLineLoadInteger FINAL : public OutOfLineCode {
+class OutOfLineLoadInteger final : public OutOfLineCode {
  public:
   OutOfLineLoadInteger(CodeGenerator* gen, Register result)
       : OutOfLineCode(gen), result_(result) {}
 
-  void Generate() FINAL { __ mov(result_, Operand::Zero()); }
+  void Generate() final { __ mov(result_, Operand::Zero()); }
 
  private:
   Register const result_;
 };
 
+
+class OutOfLineRecordWrite final : public OutOfLineCode {
+ public:
+  OutOfLineRecordWrite(CodeGenerator* gen, Register object, Register index,
+                       Register value, Register scratch0, Register scratch1,
+                       RecordWriteMode mode)
+      : OutOfLineCode(gen),
+        object_(object),
+        index_(index),
+        value_(value),
+        scratch0_(scratch0),
+        scratch1_(scratch1),
+        mode_(mode) {}
+
+  void Generate() final {
+    if (mode_ > RecordWriteMode::kValueIsPointer) {
+      __ JumpIfSmi(value_, exit());
+    }
+    if (mode_ > RecordWriteMode::kValueIsMap) {
+      __ CheckPageFlag(value_, scratch0_,
+                       MemoryChunk::kPointersToHereAreInterestingMask, eq,
+                       exit());
+    }
+    SaveFPRegsMode const save_fp_mode =
+        frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs;
+    // TODO(turbofan): Once we get frame elision working, we need to save
+    // and restore lr properly here if the frame was elided.
+    RecordWriteStub stub(isolate(), object_, scratch0_, scratch1_,
+                         EMIT_REMEMBERED_SET, save_fp_mode);
+    __ add(scratch1_, object_, index_);
+    __ CallStub(&stub);
+  }
+
+ private:
+  Register const object_;
+  Register const index_;
+  Register const value_;
+  Register const scratch0_;
+  Register const scratch1_;
+  RecordWriteMode const mode_;
+};
+
+
+Condition FlagsConditionToCondition(FlagsCondition condition) {
+  switch (condition) {
+    case kEqual:
+      return eq;
+    case kNotEqual:
+      return ne;
+    case kSignedLessThan:
+      return lt;
+    case kSignedGreaterThanOrEqual:
+      return ge;
+    case kSignedLessThanOrEqual:
+      return le;
+    case kSignedGreaterThan:
+      return gt;
+    case kUnsignedLessThan:
+      return lo;
+    case kUnsignedGreaterThanOrEqual:
+      return hs;
+    case kUnsignedLessThanOrEqual:
+      return ls;
+    case kUnsignedGreaterThan:
+      return hi;
+    case kFloatLessThanOrUnordered:
+      return lt;
+    case kFloatGreaterThanOrEqual:
+      return ge;
+    case kFloatLessThanOrEqual:
+      return ls;
+    case kFloatGreaterThanOrUnordered:
+      return hi;
+    case kFloatLessThan:
+      return lo;
+    case kFloatGreaterThanOrEqualOrUnordered:
+      return hs;
+    case kFloatLessThanOrEqualOrUnordered:
+      return le;
+    case kFloatGreaterThan:
+      return gt;
+    case kOverflow:
+      return vs;
+    case kNotOverflow:
+      return vc;
+    default:
+      break;
+  }
+  UNREACHABLE();
+  return kNoCondition;
+}
+
 }  // namespace
 
 
@@ -264,10 +354,38 @@
   } while (0)
 
 
+void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) {
+  int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta);
+  if (sp_slot_delta > 0) {
+    __ add(sp, sp, Operand(sp_slot_delta * kPointerSize));
+  }
+  frame_access_state()->SetFrameAccessToDefault();
+}
+
+
+void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) {
+  int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta);
+  if (sp_slot_delta < 0) {
+    __ sub(sp, sp, Operand(-sp_slot_delta * kPointerSize));
+    frame_access_state()->IncreaseSPDelta(-sp_slot_delta);
+  }
+  if (frame()->needs_frame()) {
+    if (FLAG_enable_embedded_constant_pool) {
+      __ ldr(cp, MemOperand(fp, StandardFrameConstants::kConstantPoolOffset));
+    }
+    __ ldr(lr, MemOperand(fp, StandardFrameConstants::kCallerPCOffset));
+    __ ldr(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
+  }
+  frame_access_state()->SetFrameAccessToSP();
+}
+
+
 // Assembles an instruction after register allocation, producing machine code.
 void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
   ArmOperandConverter i(this, instr);
 
+  masm()->MaybeCheckConstPool();
+
   switch (ArchOpcodeField::decode(instr->opcode())) {
     case kArchCallCodeObject: {
       EnsureSpaceForLazyDeopt();
@@ -279,8 +397,24 @@
                Operand(Code::kHeaderSize - kHeapObjectTag));
         __ Call(ip);
       }
-      AddSafepointAndDeopt(instr);
+      RecordCallPosition(instr);
       DCHECK_EQ(LeaveCC, i.OutputSBit());
+      frame_access_state()->ClearSPDelta();
+      break;
+    }
+    case kArchTailCallCodeObject: {
+      int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
+      AssembleDeconstructActivationRecord(stack_param_delta);
+      if (instr->InputAt(0)->IsImmediate()) {
+        __ Jump(Handle<Code>::cast(i.InputHeapObject(0)),
+                RelocInfo::CODE_TARGET);
+      } else {
+        __ add(ip, i.InputRegister(0),
+               Operand(Code::kHeaderSize - kHeapObjectTag));
+        __ Jump(ip);
+      }
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      frame_access_state()->ClearSPDelta();
       break;
     }
     case kArchCallJSFunction: {
@@ -294,18 +428,80 @@
       }
       __ ldr(ip, FieldMemOperand(func, JSFunction::kCodeEntryOffset));
       __ Call(ip);
-      AddSafepointAndDeopt(instr);
+      RecordCallPosition(instr);
       DCHECK_EQ(LeaveCC, i.OutputSBit());
+      frame_access_state()->ClearSPDelta();
+      break;
+    }
+    case kArchTailCallJSFunction: {
+      Register func = i.InputRegister(0);
+      if (FLAG_debug_code) {
+        // Check the function's context matches the context argument.
+        __ ldr(kScratchReg, FieldMemOperand(func, JSFunction::kContextOffset));
+        __ cmp(cp, kScratchReg);
+        __ Assert(eq, kWrongFunctionContext);
+      }
+      int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
+      AssembleDeconstructActivationRecord(stack_param_delta);
+      __ ldr(ip, FieldMemOperand(func, JSFunction::kCodeEntryOffset));
+      __ Jump(ip);
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      frame_access_state()->ClearSPDelta();
+      break;
+    }
+    case kArchLazyBailout: {
+      EnsureSpaceForLazyDeopt();
+      RecordCallPosition(instr);
+      break;
+    }
+    case kArchPrepareCallCFunction: {
+      int const num_parameters = MiscField::decode(instr->opcode());
+      __ PrepareCallCFunction(num_parameters, kScratchReg);
+      // Frame alignment requires using FP-relative frame addressing.
+      frame_access_state()->SetFrameAccessToFP();
+      break;
+    }
+    case kArchPrepareTailCall:
+      AssemblePrepareTailCall(i.InputInt32(instr->InputCount() - 1));
+      break;
+    case kArchCallCFunction: {
+      int const num_parameters = MiscField::decode(instr->opcode());
+      if (instr->InputAt(0)->IsImmediate()) {
+        ExternalReference ref = i.InputExternalReference(0);
+        __ CallCFunction(ref, num_parameters);
+      } else {
+        Register func = i.InputRegister(0);
+        __ CallCFunction(func, num_parameters);
+      }
+      frame_access_state()->SetFrameAccessToDefault();
+      frame_access_state()->ClearSPDelta();
       break;
     }
     case kArchJmp:
       AssembleArchJump(i.InputRpo(0));
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
+    case kArchLookupSwitch:
+      AssembleArchLookupSwitch(instr);
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    case kArchTableSwitch:
+      AssembleArchTableSwitch(instr);
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
     case kArchNop:
+    case kArchThrowTerminator:
       // don't emit code for nops.
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
+    case kArchDeoptimize: {
+      int deopt_state_id =
+          BuildTranslation(instr, -1, 0, OutputFrameStateCombine::Ignore());
+      Deoptimizer::BailoutType bailout_type =
+          Deoptimizer::BailoutType(MiscField::decode(instr->opcode()));
+      AssembleDeoptimizerCall(deopt_state_id, bailout_type);
+      break;
+    }
     case kArchRet:
       AssembleReturn();
       DCHECK_EQ(LeaveCC, i.OutputSBit());
@@ -314,10 +510,31 @@
       __ mov(i.OutputRegister(), sp);
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
+    case kArchFramePointer:
+      __ mov(i.OutputRegister(), fp);
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
     case kArchTruncateDoubleToI:
       __ TruncateDoubleToI(i.OutputRegister(), i.InputFloat64Register(0));
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
+    case kArchStoreWithWriteBarrier: {
+      RecordWriteMode mode =
+          static_cast<RecordWriteMode>(MiscField::decode(instr->opcode()));
+      Register object = i.InputRegister(0);
+      Register index = i.InputRegister(1);
+      Register value = i.InputRegister(2);
+      Register scratch0 = i.TempRegister(0);
+      Register scratch1 = i.TempRegister(1);
+      auto ool = new (zone()) OutOfLineRecordWrite(this, object, index, value,
+                                                   scratch0, scratch1, mode);
+      __ str(value, MemOperand(object, index));
+      __ CheckPageFlag(object, scratch0,
+                       MemoryChunk::kPointersFromHereAreInterestingMask, ne,
+                       ool->entry());
+      __ bind(ool->exit());
+      break;
+    }
     case kArmAdd:
       __ add(i.OutputRegister(), i.InputRegister(0), i.InputOperand2(1),
              i.OutputSBit());
@@ -441,6 +658,10 @@
                i.InputInt32(2));
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
+    case kArmClz:
+      __ clz(i.OutputRegister(), i.InputRegister(0));
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
     case kArmCmp:
       __ cmp(i.InputRegister(0), i.InputOperand2(1));
       DCHECK_EQ(SetCC, i.OutputSBit());
@@ -457,9 +678,67 @@
       __ teq(i.InputRegister(0), i.InputOperand2(1));
       DCHECK_EQ(SetCC, i.OutputSBit());
       break;
+    case kArmVcmpF32:
+      if (instr->InputAt(1)->IsDoubleRegister()) {
+        __ VFPCompareAndSetFlags(i.InputFloat32Register(0),
+                                 i.InputFloat32Register(1));
+      } else {
+        DCHECK(instr->InputAt(1)->IsImmediate());
+        // 0.0 is the only immediate supported by vcmp instructions.
+        DCHECK(i.InputFloat32(1) == 0.0f);
+        __ VFPCompareAndSetFlags(i.InputFloat32Register(0), i.InputFloat32(1));
+      }
+      DCHECK_EQ(SetCC, i.OutputSBit());
+      break;
+    case kArmVaddF32:
+      __ vadd(i.OutputFloat32Register(), i.InputFloat32Register(0),
+              i.InputFloat32Register(1));
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    case kArmVsubF32:
+      __ vsub(i.OutputFloat32Register(), i.InputFloat32Register(0),
+              i.InputFloat32Register(1));
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    case kArmVmulF32:
+      __ vmul(i.OutputFloat32Register(), i.InputFloat32Register(0),
+              i.InputFloat32Register(1));
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    case kArmVmlaF32:
+      __ vmla(i.OutputFloat32Register(), i.InputFloat32Register(1),
+              i.InputFloat32Register(2));
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    case kArmVmlsF32:
+      __ vmls(i.OutputFloat32Register(), i.InputFloat32Register(1),
+              i.InputFloat32Register(2));
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    case kArmVdivF32:
+      __ vdiv(i.OutputFloat32Register(), i.InputFloat32Register(0),
+              i.InputFloat32Register(1));
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    case kArmVsqrtF32:
+      __ vsqrt(i.OutputFloat32Register(), i.InputFloat32Register(0));
+      break;
+    case kArmVabsF32:
+      __ vabs(i.OutputFloat32Register(), i.InputFloat32Register(0));
+      break;
+    case kArmVnegF32:
+      __ vneg(i.OutputFloat32Register(), i.InputFloat32Register(0));
+      break;
     case kArmVcmpF64:
-      __ VFPCompareAndSetFlags(i.InputFloat64Register(0),
-                               i.InputFloat64Register(1));
+      if (instr->InputAt(1)->IsDoubleRegister()) {
+        __ VFPCompareAndSetFlags(i.InputFloat64Register(0),
+                                 i.InputFloat64Register(1));
+      } else {
+        DCHECK(instr->InputAt(1)->IsImmediate());
+        // 0.0 is the only immediate supported by vcmp instructions.
+        DCHECK(i.InputDouble(1) == 0.0);
+        __ VFPCompareAndSetFlags(i.InputFloat64Register(0), i.InputDouble(1));
+      }
       DCHECK_EQ(SetCC, i.OutputSBit());
       break;
     case kArmVaddF64:
@@ -509,21 +788,39 @@
     case kArmVsqrtF64:
       __ vsqrt(i.OutputFloat64Register(), i.InputFloat64Register(0));
       break;
-    case kArmVfloorF64:
-      __ vrintm(i.OutputFloat64Register(), i.InputFloat64Register(0));
-      break;
-    case kArmVceilF64:
-      __ vrintp(i.OutputFloat64Register(), i.InputFloat64Register(0));
-      break;
-    case kArmVroundTruncateF64:
-      __ vrintz(i.OutputFloat64Register(), i.InputFloat64Register(0));
-      break;
-    case kArmVroundTiesAwayF64:
-      __ vrinta(i.OutputFloat64Register(), i.InputFloat64Register(0));
+    case kArmVabsF64:
+      __ vabs(i.OutputFloat64Register(), i.InputFloat64Register(0));
       break;
     case kArmVnegF64:
       __ vneg(i.OutputFloat64Register(), i.InputFloat64Register(0));
       break;
+    case kArmVrintmF32:
+      __ vrintm(i.OutputFloat32Register(), i.InputFloat32Register(0));
+      break;
+    case kArmVrintmF64:
+      __ vrintm(i.OutputFloat64Register(), i.InputFloat64Register(0));
+      break;
+    case kArmVrintpF32:
+      __ vrintp(i.OutputFloat32Register(), i.InputFloat32Register(0));
+      break;
+    case kArmVrintpF64:
+      __ vrintp(i.OutputFloat64Register(), i.InputFloat64Register(0));
+      break;
+    case kArmVrintzF32:
+      __ vrintz(i.OutputFloat32Register(), i.InputFloat32Register(0));
+      break;
+    case kArmVrintzF64:
+      __ vrintz(i.OutputFloat64Register(), i.InputFloat64Register(0));
+      break;
+    case kArmVrintaF64:
+      __ vrinta(i.OutputFloat64Register(), i.InputFloat64Register(0));
+      break;
+    case kArmVrintnF32:
+      __ vrintn(i.OutputFloat32Register(), i.InputFloat32Register(0));
+      break;
+    case kArmVrintnF64:
+      __ vrintn(i.OutputFloat64Register(), i.InputFloat64Register(0));
+      break;
     case kArmVcvtF32F64: {
       __ vcvt_f32_f64(i.OutputFloat32Register(), i.InputFloat64Register(0));
       DCHECK_EQ(LeaveCC, i.OutputSBit());
@@ -562,6 +859,27 @@
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
     }
+    case kArmVmovLowU32F64:
+      __ VmovLow(i.OutputRegister(), i.InputFloat64Register(0));
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    case kArmVmovLowF64U32:
+      __ VmovLow(i.OutputFloat64Register(), i.InputRegister(1));
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    case kArmVmovHighU32F64:
+      __ VmovHigh(i.OutputRegister(), i.InputFloat64Register(0));
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    case kArmVmovHighF64U32:
+      __ VmovHigh(i.OutputFloat64Register(), i.InputRegister(1));
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    case kArmVmovF64U32U32:
+      __ vmov(i.OutputFloat64Register(), i.InputRegister(0),
+              i.InputRegister(1));
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
     case kArmLdrb:
       __ ldrb(i.OutputRegister(), i.InputOffset());
       DCHECK_EQ(LeaveCC, i.OutputSBit());
@@ -571,7 +889,7 @@
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
     case kArmStrb: {
-      int index = 0;
+      size_t index = 0;
       MemOperand operand = i.InputOffset(&index);
       __ strb(i.InputRegister(index), operand);
       DCHECK_EQ(LeaveCC, i.OutputSBit());
@@ -584,7 +902,7 @@
       __ ldrsh(i.OutputRegister(), i.InputOffset());
       break;
     case kArmStrh: {
-      int index = 0;
+      size_t index = 0;
       MemOperand operand = i.InputOffset(&index);
       __ strh(i.InputRegister(index), operand);
       DCHECK_EQ(LeaveCC, i.OutputSBit());
@@ -594,7 +912,7 @@
       __ ldr(i.OutputRegister(), i.InputOffset());
       break;
     case kArmStr: {
-      int index = 0;
+      size_t index = 0;
       MemOperand operand = i.InputOffset(&index);
       __ str(i.InputRegister(index), operand);
       DCHECK_EQ(LeaveCC, i.OutputSBit());
@@ -606,7 +924,7 @@
       break;
     }
     case kArmVstrF32: {
-      int index = 0;
+      size_t index = 0;
       MemOperand operand = i.InputOffset(&index);
       __ vstr(i.InputFloat32Register(index), operand);
       DCHECK_EQ(LeaveCC, i.OutputSBit());
@@ -617,26 +935,25 @@
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
     case kArmVstrF64: {
-      int index = 0;
+      size_t index = 0;
       MemOperand operand = i.InputOffset(&index);
       __ vstr(i.InputFloat64Register(index), operand);
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
     }
     case kArmPush:
-      __ Push(i.InputRegister(0));
+      if (instr->InputAt(0)->IsDoubleRegister()) {
+        __ vpush(i.InputDoubleRegister(0));
+        frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize);
+      } else {
+        __ push(i.InputRegister(0));
+        frame_access_state()->IncreaseSPDelta(1);
+      }
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
-    case kArmStoreWriteBarrier: {
-      Register object = i.InputRegister(0);
-      Register index = i.InputRegister(1);
-      Register value = i.InputRegister(2);
-      __ add(index, object, index);
-      __ str(value, MemOperand(index));
-      SaveFPRegsMode mode =
-          frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs;
-      LinkRegisterStatus lr_status = kLRHasNotBeenSaved;
-      __ RecordWrite(object, index, value, lr_status, mode);
+    case kArmPoke: {
+      int const slot = MiscField::decode(instr->opcode());
+      __ str(i.InputRegister(0), MemOperand(sp, slot * kPointerSize));
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
     }
@@ -676,8 +993,12 @@
     case kCheckedStoreFloat64:
       ASSEMBLE_CHECKED_STORE_FLOAT(64);
       break;
+    case kCheckedLoadWord64:
+    case kCheckedStoreWord64:
+      UNREACHABLE();  // currently unsupported checked int64 load/store.
+      break;
   }
-}
+}  // NOLINT(readability/fn_size)
 
 
 // Assembles branches after an instruction.
@@ -685,70 +1006,13 @@
   ArmOperandConverter i(this, instr);
   Label* tlabel = branch->true_label;
   Label* flabel = branch->false_label;
-  switch (branch->condition) {
-    case kUnorderedEqual:
-      // The "eq" condition will not catch the unordered case.
-      // The jump/fall through to false label will be used if the comparison
-      // was unordered.
-    case kEqual:
-      __ b(eq, tlabel);
-      break;
-    case kUnorderedNotEqual:
-      // Unordered or not equal can be tested with "ne" condtion.
-      // See ARMv7 manual A8.3 - Conditional execution.
-    case kNotEqual:
-      __ b(ne, tlabel);
-      break;
-    case kSignedLessThan:
-      __ b(lt, tlabel);
-      break;
-    case kSignedGreaterThanOrEqual:
-      __ b(ge, tlabel);
-      break;
-    case kSignedLessThanOrEqual:
-      __ b(le, tlabel);
-      break;
-    case kSignedGreaterThan:
-      __ b(gt, tlabel);
-      break;
-    case kUnorderedLessThan:
-      // The "lo" condition will not catch the unordered case.
-      // The jump/fall through to false label will be used if the comparison
-      // was unordered.
-    case kUnsignedLessThan:
-      __ b(lo, tlabel);
-      break;
-    case kUnorderedGreaterThanOrEqual:
-      // Unordered, greater than or equal can be tested with "hs" condtion.
-      // See ARMv7 manual A8.3 - Conditional execution.
-    case kUnsignedGreaterThanOrEqual:
-      __ b(hs, tlabel);
-      break;
-    case kUnorderedLessThanOrEqual:
-      // The "ls" condition will not catch the unordered case.
-      // The jump/fall through to false label will be used if the comparison
-      // was unordered.
-    case kUnsignedLessThanOrEqual:
-      __ b(ls, tlabel);
-      break;
-    case kUnorderedGreaterThan:
-      // Unordered or greater than can be tested with "hi" condtion.
-      // See ARMv7 manual A8.3 - Conditional execution.
-    case kUnsignedGreaterThan:
-      __ b(hi, tlabel);
-      break;
-    case kOverflow:
-      __ b(vs, tlabel);
-      break;
-    case kNotOverflow:
-      __ b(vc, tlabel);
-      break;
-  }
+  Condition cc = FlagsConditionToCondition(branch->condition);
+  __ b(cc, tlabel);
   if (!branch->fallthru) __ b(flabel);  // no fallthru to flabel.
 }
 
 
-void CodeGenerator::AssembleArchJump(BasicBlock::RpoNumber target) {
+void CodeGenerator::AssembleArchJump(RpoNumber target) {
   if (!IsNextInAssemblyOrder(target)) __ b(GetLabel(target));
 }
 
@@ -757,169 +1021,160 @@
 void CodeGenerator::AssembleArchBoolean(Instruction* instr,
                                         FlagsCondition condition) {
   ArmOperandConverter i(this, instr);
-  Label done;
 
   // Materialize a full 32-bit 1 or 0 value. The result register is always the
   // last output of the instruction.
-  Label check;
-  DCHECK_NE(0, instr->OutputCount());
+  DCHECK_NE(0u, instr->OutputCount());
   Register reg = i.OutputRegister(instr->OutputCount() - 1);
-  Condition cc = kNoCondition;
-  switch (condition) {
-    case kUnorderedEqual:
-      __ b(vc, &check);
-      __ mov(reg, Operand(0));
-      __ b(&done);
-    // Fall through.
-    case kEqual:
-      cc = eq;
-      break;
-    case kUnorderedNotEqual:
-      __ b(vc, &check);
-      __ mov(reg, Operand(1));
-      __ b(&done);
-    // Fall through.
-    case kNotEqual:
-      cc = ne;
-      break;
-    case kSignedLessThan:
-      cc = lt;
-      break;
-    case kSignedGreaterThanOrEqual:
-      cc = ge;
-      break;
-    case kSignedLessThanOrEqual:
-      cc = le;
-      break;
-    case kSignedGreaterThan:
-      cc = gt;
-      break;
-    case kUnorderedLessThan:
-      __ b(vc, &check);
-      __ mov(reg, Operand(0));
-      __ b(&done);
-    // Fall through.
-    case kUnsignedLessThan:
-      cc = lo;
-      break;
-    case kUnorderedGreaterThanOrEqual:
-      __ b(vc, &check);
-      __ mov(reg, Operand(1));
-      __ b(&done);
-    // Fall through.
-    case kUnsignedGreaterThanOrEqual:
-      cc = hs;
-      break;
-    case kUnorderedLessThanOrEqual:
-      __ b(vc, &check);
-      __ mov(reg, Operand(0));
-      __ b(&done);
-    // Fall through.
-    case kUnsignedLessThanOrEqual:
-      cc = ls;
-      break;
-    case kUnorderedGreaterThan:
-      __ b(vc, &check);
-      __ mov(reg, Operand(1));
-      __ b(&done);
-    // Fall through.
-    case kUnsignedGreaterThan:
-      cc = hi;
-      break;
-    case kOverflow:
-      cc = vs;
-      break;
-    case kNotOverflow:
-      cc = vc;
-      break;
-  }
-  __ bind(&check);
+  Condition cc = FlagsConditionToCondition(condition);
   __ mov(reg, Operand(0));
   __ mov(reg, Operand(1), LeaveCC, cc);
-  __ bind(&done);
 }
 
 
-void CodeGenerator::AssembleDeoptimizerCall(int deoptimization_id) {
+void CodeGenerator::AssembleArchLookupSwitch(Instruction* instr) {
+  ArmOperandConverter i(this, instr);
+  Register input = i.InputRegister(0);
+  for (size_t index = 2; index < instr->InputCount(); index += 2) {
+    __ cmp(input, Operand(i.InputInt32(index + 0)));
+    __ b(eq, GetLabel(i.InputRpo(index + 1)));
+  }
+  AssembleArchJump(i.InputRpo(1));
+}
+
+
+void CodeGenerator::AssembleArchTableSwitch(Instruction* instr) {
+  ArmOperandConverter i(this, instr);
+  Register input = i.InputRegister(0);
+  size_t const case_count = instr->InputCount() - 2;
+  // Ensure to emit the constant pool first if necessary.
+  __ CheckConstPool(true, true);
+  __ cmp(input, Operand(case_count));
+  __ BlockConstPoolFor(case_count + 2);
+  __ add(pc, pc, Operand(input, LSL, 2), LeaveCC, lo);
+  __ b(GetLabel(i.InputRpo(1)));
+  for (size_t index = 0; index < case_count; ++index) {
+    __ b(GetLabel(i.InputRpo(index + 2)));
+  }
+}
+
+
+void CodeGenerator::AssembleDeoptimizerCall(
+    int deoptimization_id, Deoptimizer::BailoutType bailout_type) {
   Address deopt_entry = Deoptimizer::GetDeoptimizationEntry(
-      isolate(), deoptimization_id, Deoptimizer::LAZY);
+      isolate(), deoptimization_id, bailout_type);
   __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY);
 }
 
 
 void CodeGenerator::AssemblePrologue() {
   CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
-  if (descriptor->kind() == CallDescriptor::kCallAddress) {
-    bool saved_pp;
-    if (FLAG_enable_ool_constant_pool) {
+  if (descriptor->IsCFunctionCall()) {
+    if (FLAG_enable_embedded_constant_pool) {
       __ Push(lr, fp, pp);
       // Adjust FP to point to saved FP.
       __ sub(fp, sp, Operand(StandardFrameConstants::kConstantPoolOffset));
-      saved_pp = true;
     } else {
       __ Push(lr, fp);
       __ mov(fp, sp);
-      saved_pp = false;
-    }
-    const RegList saves = descriptor->CalleeSavedRegisters();
-    if (saves != 0 || saved_pp) {
-      // Save callee-saved registers.
-      int register_save_area_size = saved_pp ? kPointerSize : 0;
-      for (int i = Register::kNumRegisters - 1; i >= 0; i--) {
-        if (!((1 << i) & saves)) continue;
-        register_save_area_size += kPointerSize;
-      }
-      frame()->SetRegisterSaveAreaSize(register_save_area_size);
-      __ stm(db_w, sp, saves);
     }
   } else if (descriptor->IsJSFunctionCall()) {
-    CompilationInfo* info = this->info();
-    __ Prologue(info->IsCodePreAgingActive());
-    frame()->SetRegisterSaveAreaSize(
-        StandardFrameConstants::kFixedFrameSizeFromFp);
-  } else {
+    __ Prologue(this->info()->GeneratePreagedPrologue());
+  } else if (frame()->needs_frame()) {
     __ StubPrologue();
-    frame()->SetRegisterSaveAreaSize(
-        StandardFrameConstants::kFixedFrameSizeFromFp);
+  } else {
+    frame()->SetElidedFrameSizeInSlots(0);
   }
-  int stack_slots = frame()->GetSpillSlotCount();
-  if (stack_slots > 0) {
-    __ sub(sp, sp, Operand(stack_slots * kPointerSize));
+  frame_access_state()->SetFrameAccessToDefault();
+
+  int stack_shrink_slots = frame()->GetSpillSlotCount();
+  if (info()->is_osr()) {
+    // TurboFan OSR-compiled functions cannot be entered directly.
+    __ Abort(kShouldNotDirectlyEnterOsrFunction);
+
+    // Unoptimized code jumps directly to this entrypoint while the unoptimized
+    // frame is still on the stack. Optimized code uses OSR values directly from
+    // the unoptimized frame. Thus, all that needs to be done is to allocate the
+    // remaining stack slots.
+    if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --");
+    osr_pc_offset_ = __ pc_offset();
+    // TODO(titzer): cannot address target function == local #-1
+    __ ldr(r1, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
+    stack_shrink_slots -= OsrHelper(info()).UnoptimizedFrameSlots();
+  }
+
+  const RegList saves_fp = descriptor->CalleeSavedFPRegisters();
+  if (saves_fp != 0) {
+    stack_shrink_slots += frame()->AlignSavedCalleeRegisterSlots();
+  }
+  if (stack_shrink_slots > 0) {
+    __ sub(sp, sp, Operand(stack_shrink_slots * kPointerSize));
+  }
+
+  if (saves_fp != 0) {
+    // Save callee-saved FP registers.
+    STATIC_ASSERT(DwVfpRegister::kMaxNumRegisters == 32);
+    uint32_t last = base::bits::CountLeadingZeros32(saves_fp) - 1;
+    uint32_t first = base::bits::CountTrailingZeros32(saves_fp);
+    DCHECK_EQ((last - first + 1), base::bits::CountPopulation32(saves_fp));
+    __ vstm(db_w, sp, DwVfpRegister::from_code(first),
+            DwVfpRegister::from_code(last));
+    frame()->AllocateSavedCalleeRegisterSlots((last - first + 1) *
+                                              (kDoubleSize / kPointerSize));
+  }
+  const RegList saves = FLAG_enable_embedded_constant_pool
+                            ? (descriptor->CalleeSavedRegisters() & ~pp.bit())
+                            : descriptor->CalleeSavedRegisters();
+  if (saves != 0) {
+    // Save callee-saved registers.
+    __ stm(db_w, sp, saves);
+    frame()->AllocateSavedCalleeRegisterSlots(
+        base::bits::CountPopulation32(saves));
   }
 }
 
 
 void CodeGenerator::AssembleReturn() {
   CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
-  if (descriptor->kind() == CallDescriptor::kCallAddress) {
-    if (frame()->GetRegisterSaveAreaSize() > 0) {
-      // Remove this frame's spill slots first.
-      int stack_slots = frame()->GetSpillSlotCount();
-      if (stack_slots > 0) {
-        __ add(sp, sp, Operand(stack_slots * kPointerSize));
-      }
-      // Restore registers.
-      const RegList saves = descriptor->CalleeSavedRegisters();
-      if (saves != 0) {
-        __ ldm(ia_w, sp, saves);
-      }
-    }
-    __ LeaveFrame(StackFrame::MANUAL);
-    __ Ret();
-  } else {
-    __ LeaveFrame(StackFrame::MANUAL);
-    int pop_count = descriptor->IsJSFunctionCall()
-                        ? static_cast<int>(descriptor->JSParameterCount())
-                        : 0;
-    __ Drop(pop_count);
-    __ Ret();
+  int pop_count = static_cast<int>(descriptor->StackParameterCount());
+
+  // Restore registers.
+  const RegList saves = FLAG_enable_embedded_constant_pool
+                            ? (descriptor->CalleeSavedRegisters() & ~pp.bit())
+                            : descriptor->CalleeSavedRegisters();
+  if (saves != 0) {
+    __ ldm(ia_w, sp, saves);
   }
+
+  // Restore FP registers.
+  const RegList saves_fp = descriptor->CalleeSavedFPRegisters();
+  if (saves_fp != 0) {
+    STATIC_ASSERT(DwVfpRegister::kMaxNumRegisters == 32);
+    uint32_t last = base::bits::CountLeadingZeros32(saves_fp) - 1;
+    uint32_t first = base::bits::CountTrailingZeros32(saves_fp);
+    __ vldm(ia_w, sp, DwVfpRegister::from_code(first),
+            DwVfpRegister::from_code(last));
+  }
+
+  if (descriptor->IsCFunctionCall()) {
+    __ LeaveFrame(StackFrame::MANUAL);
+  } else if (frame()->needs_frame()) {
+    // Canonicalize JSFunction return sites for now.
+    if (return_label_.is_bound()) {
+      __ b(&return_label_);
+      return;
+    } else {
+      __ bind(&return_label_);
+      __ LeaveFrame(StackFrame::MANUAL);
+    }
+  }
+  __ Ret(pop_count);
 }
 
 
 void CodeGenerator::AssembleMove(InstructionOperand* source,
                                  InstructionOperand* destination) {
-  ArmOperandConverter g(this, NULL);
+  ArmOperandConverter g(this, nullptr);
   // Dispatch on the source and destination operand kinds.  Not all
   // combinations are possible.
   if (source->IsRegister()) {
@@ -963,9 +1218,19 @@
         case Constant::kExternalReference:
           __ mov(dst, Operand(src.ToExternalReference()));
           break;
-        case Constant::kHeapObject:
-          __ Move(dst, src.ToHeapObject());
+        case Constant::kHeapObject: {
+          Handle<HeapObject> src_object = src.ToHeapObject();
+          Heap::RootListIndex index;
+          int offset;
+          if (IsMaterializableFromFrame(src_object, &offset)) {
+            __ ldr(dst, MemOperand(fp, offset));
+          } else if (IsMaterializableFromRoot(src_object, &index)) {
+            __ LoadRoot(dst, index);
+          } else {
+            __ Move(dst, src_object);
+          }
           break;
+        }
         case Constant::kRpoNumber:
           UNREACHABLE();  // TODO(dcarney): loading RPO constants on arm.
           break;
@@ -1017,7 +1282,7 @@
 
 void CodeGenerator::AssembleSwap(InstructionOperand* source,
                                  InstructionOperand* destination) {
-  ArmOperandConverter g(this, NULL);
+  ArmOperandConverter g(this, nullptr);
   // Dispatch on the source and destination operand kinds.  Not all
   // combinations are possible.
   if (source->IsRegister()) {
@@ -1082,29 +1347,36 @@
 }
 
 
+void CodeGenerator::AssembleJumpTable(Label** targets, size_t target_count) {
+  // On 32-bit ARM we emit the jump tables inline.
+  UNREACHABLE();
+}
+
+
 void CodeGenerator::AddNopForSmiCodeInlining() {
   // On 32-bit ARM we do not insert nops for inlined Smi code.
 }
 
 
 void CodeGenerator::EnsureSpaceForLazyDeopt() {
+  if (!info()->ShouldEnsureSpaceForLazyDeopt()) {
+    return;
+  }
+
   int space_needed = Deoptimizer::patch_size();
-  if (!info()->IsStub()) {
-    // Ensure that we have enough space after the previous lazy-bailout
-    // instruction for patching the code here.
-    int current_pc = masm()->pc_offset();
-    if (current_pc < last_lazy_deopt_pc_ + space_needed) {
-      // Block literal pool emission for duration of padding.
-      v8::internal::Assembler::BlockConstPoolScope block_const_pool(masm());
-      int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc;
-      DCHECK_EQ(0, padding_size % v8::internal::Assembler::kInstrSize);
-      while (padding_size > 0) {
-        __ nop();
-        padding_size -= v8::internal::Assembler::kInstrSize;
-      }
+  // Ensure that we have enough space after the previous lazy-bailout
+  // instruction for patching the code here.
+  int current_pc = masm()->pc_offset();
+  if (current_pc < last_lazy_deopt_pc_ + space_needed) {
+    // Block literal pool emission for duration of padding.
+    v8::internal::Assembler::BlockConstPoolScope block_const_pool(masm());
+    int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc;
+    DCHECK_EQ(0, padding_size % v8::internal::Assembler::kInstrSize);
+    while (padding_size > 0) {
+      __ nop();
+      padding_size -= v8::internal::Assembler::kInstrSize;
     }
   }
-  MarkLazyDeoptSite();
 }
 
 #undef __
diff --git a/src/compiler/arm/instruction-codes-arm.h b/src/compiler/arm/instruction-codes-arm.h
index ecd0b2d..401100b 100644
--- a/src/compiler/arm/instruction-codes-arm.h
+++ b/src/compiler/arm/instruction-codes-arm.h
@@ -15,6 +15,7 @@
   V(ArmAdd)                        \
   V(ArmAnd)                        \
   V(ArmBic)                        \
+  V(ArmClz)                        \
   V(ArmCmp)                        \
   V(ArmCmn)                        \
   V(ArmTst)                        \
@@ -43,6 +44,16 @@
   V(ArmUxth)                       \
   V(ArmUxtab)                      \
   V(ArmUxtah)                      \
+  V(ArmVcmpF32)                    \
+  V(ArmVaddF32)                    \
+  V(ArmVsubF32)                    \
+  V(ArmVmulF32)                    \
+  V(ArmVmlaF32)                    \
+  V(ArmVmlsF32)                    \
+  V(ArmVdivF32)                    \
+  V(ArmVabsF32)                    \
+  V(ArmVnegF32)                    \
+  V(ArmVsqrtF32)                   \
   V(ArmVcmpF64)                    \
   V(ArmVaddF64)                    \
   V(ArmVsubF64)                    \
@@ -51,18 +62,29 @@
   V(ArmVmlsF64)                    \
   V(ArmVdivF64)                    \
   V(ArmVmodF64)                    \
+  V(ArmVabsF64)                    \
   V(ArmVnegF64)                    \
   V(ArmVsqrtF64)                   \
-  V(ArmVfloorF64)                  \
-  V(ArmVceilF64)                   \
-  V(ArmVroundTruncateF64)          \
-  V(ArmVroundTiesAwayF64)          \
+  V(ArmVrintmF32)                  \
+  V(ArmVrintmF64)                  \
+  V(ArmVrintpF32)                  \
+  V(ArmVrintpF64)                  \
+  V(ArmVrintzF32)                  \
+  V(ArmVrintzF64)                  \
+  V(ArmVrintaF64)                  \
+  V(ArmVrintnF32)                  \
+  V(ArmVrintnF64)                  \
   V(ArmVcvtF32F64)                 \
   V(ArmVcvtF64F32)                 \
   V(ArmVcvtF64S32)                 \
   V(ArmVcvtF64U32)                 \
   V(ArmVcvtS32F64)                 \
   V(ArmVcvtU32F64)                 \
+  V(ArmVmovLowU32F64)              \
+  V(ArmVmovLowF64U32)              \
+  V(ArmVmovHighU32F64)             \
+  V(ArmVmovHighF64U32)             \
+  V(ArmVmovF64U32U32)              \
   V(ArmVldrF32)                    \
   V(ArmVstrF32)                    \
   V(ArmVldrF64)                    \
@@ -76,7 +98,7 @@
   V(ArmLdr)                        \
   V(ArmStr)                        \
   V(ArmPush)                       \
-  V(ArmStoreWriteBarrier)
+  V(ArmPoke)
 
 
 // Addressing modes represent the "shape" of inputs to an instruction.
diff --git a/src/compiler/arm/instruction-scheduler-arm.cc b/src/compiler/arm/instruction-scheduler-arm.cc
new file mode 100644
index 0000000..f36802c
--- /dev/null
+++ b/src/compiler/arm/instruction-scheduler-arm.cc
@@ -0,0 +1,129 @@
+// Copyright 2015 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/instruction-scheduler.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+bool InstructionScheduler::SchedulerSupported() { return true; }
+
+
+int InstructionScheduler::GetTargetInstructionFlags(
+    const Instruction* instr) const {
+  switch (instr->arch_opcode()) {
+    case kArmAdd:
+    case kArmAnd:
+    case kArmBic:
+    case kArmClz:
+    case kArmCmp:
+    case kArmCmn:
+    case kArmTst:
+    case kArmTeq:
+    case kArmOrr:
+    case kArmEor:
+    case kArmSub:
+    case kArmRsb:
+    case kArmMul:
+    case kArmMla:
+    case kArmMls:
+    case kArmSmmul:
+    case kArmSmmla:
+    case kArmUmull:
+    case kArmSdiv:
+    case kArmUdiv:
+    case kArmMov:
+    case kArmMvn:
+    case kArmBfc:
+    case kArmUbfx:
+    case kArmSxtb:
+    case kArmSxth:
+    case kArmSxtab:
+    case kArmSxtah:
+    case kArmUxtb:
+    case kArmUxth:
+    case kArmUxtab:
+    case kArmUxtah:
+    case kArmVcmpF32:
+    case kArmVaddF32:
+    case kArmVsubF32:
+    case kArmVmulF32:
+    case kArmVmlaF32:
+    case kArmVmlsF32:
+    case kArmVdivF32:
+    case kArmVabsF32:
+    case kArmVnegF32:
+    case kArmVsqrtF32:
+    case kArmVcmpF64:
+    case kArmVaddF64:
+    case kArmVsubF64:
+    case kArmVmulF64:
+    case kArmVmlaF64:
+    case kArmVmlsF64:
+    case kArmVdivF64:
+    case kArmVmodF64:
+    case kArmVabsF64:
+    case kArmVnegF64:
+    case kArmVsqrtF64:
+    case kArmVrintmF32:
+    case kArmVrintmF64:
+    case kArmVrintpF32:
+    case kArmVrintpF64:
+    case kArmVrintzF32:
+    case kArmVrintzF64:
+    case kArmVrintaF64:
+    case kArmVrintnF32:
+    case kArmVrintnF64:
+    case kArmVcvtF32F64:
+    case kArmVcvtF64F32:
+    case kArmVcvtF64S32:
+    case kArmVcvtF64U32:
+    case kArmVcvtS32F64:
+    case kArmVcvtU32F64:
+    case kArmVmovLowU32F64:
+    case kArmVmovLowF64U32:
+    case kArmVmovHighU32F64:
+    case kArmVmovHighF64U32:
+    case kArmVmovF64U32U32:
+      return kNoOpcodeFlags;
+
+    case kArmVldrF32:
+    case kArmVldrF64:
+    case kArmLdrb:
+    case kArmLdrsb:
+    case kArmLdrh:
+    case kArmLdrsh:
+    case kArmLdr:
+      return kIsLoadOperation;
+
+    case kArmVstrF32:
+    case kArmVstrF64:
+    case kArmStrb:
+    case kArmStrh:
+    case kArmStr:
+    case kArmPush:
+    case kArmPoke:
+      return kHasSideEffect;
+
+#define CASE(Name) case k##Name:
+    COMMON_ARCH_OPCODE_LIST(CASE)
+#undef CASE
+      // Already covered in architecture independent code.
+      UNREACHABLE();
+  }
+
+  UNREACHABLE();
+  return kNoOpcodeFlags;
+}
+
+
+int InstructionScheduler::GetInstructionLatency(const Instruction* instr) {
+  // TODO(all): Add instruction cost modeling.
+  return 1;
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/arm/instruction-selector-arm.cc b/src/compiler/arm/instruction-selector-arm.cc
index ef9e89e..f3deae7 100644
--- a/src/compiler/arm/instruction-selector-arm.cc
+++ b/src/compiler/arm/instruction-selector-arm.cc
@@ -2,9 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "src/base/adapters.h"
 #include "src/base/bits.h"
 #include "src/compiler/instruction-selector-impl.h"
 #include "src/compiler/node-matchers.h"
+#include "src/compiler/node-properties.h"
 
 namespace v8 {
 namespace internal {
@@ -59,7 +61,6 @@
       case kArmStrb:
       case kArmLdr:
       case kArmStr:
-      case kArmStoreWriteBarrier:
         return value >= -4095 && value <= 4095;
 
       case kArmLdrh:
@@ -77,16 +78,14 @@
 
 namespace {
 
-void VisitRRFloat64(InstructionSelector* selector, ArchOpcode opcode,
-                    Node* node) {
+void VisitRR(InstructionSelector* selector, ArchOpcode opcode, Node* node) {
   ArmOperandGenerator g(selector);
   selector->Emit(opcode, g.DefineAsRegister(node),
                  g.UseRegister(node->InputAt(0)));
 }
 
 
-void VisitRRRFloat64(InstructionSelector* selector, ArchOpcode opcode,
-                     Node* node) {
+void VisitRRR(InstructionSelector* selector, ArchOpcode opcode, Node* node) {
   ArmOperandGenerator g(selector);
   selector->Emit(opcode, g.DefineAsRegister(node),
                  g.UseRegister(node->InputAt(0)),
@@ -98,8 +97,8 @@
           AddressingMode kImmMode, AddressingMode kRegMode>
 bool TryMatchShift(InstructionSelector* selector,
                    InstructionCode* opcode_return, Node* node,
-                   InstructionOperand** value_return,
-                   InstructionOperand** shift_return) {
+                   InstructionOperand* value_return,
+                   InstructionOperand* shift_return) {
   ArmOperandGenerator g(selector);
   if (node->opcode() == kOpcode) {
     Int32BinopMatcher m(node);
@@ -118,8 +117,8 @@
 
 
 bool TryMatchROR(InstructionSelector* selector, InstructionCode* opcode_return,
-                 Node* node, InstructionOperand** value_return,
-                 InstructionOperand** shift_return) {
+                 Node* node, InstructionOperand* value_return,
+                 InstructionOperand* shift_return) {
   return TryMatchShift<IrOpcode::kWord32Ror, 1, 31, kMode_Operand2_R_ROR_I,
                        kMode_Operand2_R_ROR_R>(selector, opcode_return, node,
                                                value_return, shift_return);
@@ -127,8 +126,8 @@
 
 
 bool TryMatchASR(InstructionSelector* selector, InstructionCode* opcode_return,
-                 Node* node, InstructionOperand** value_return,
-                 InstructionOperand** shift_return) {
+                 Node* node, InstructionOperand* value_return,
+                 InstructionOperand* shift_return) {
   return TryMatchShift<IrOpcode::kWord32Sar, 1, 32, kMode_Operand2_R_ASR_I,
                        kMode_Operand2_R_ASR_R>(selector, opcode_return, node,
                                                value_return, shift_return);
@@ -136,8 +135,8 @@
 
 
 bool TryMatchLSL(InstructionSelector* selector, InstructionCode* opcode_return,
-                 Node* node, InstructionOperand** value_return,
-                 InstructionOperand** shift_return) {
+                 Node* node, InstructionOperand* value_return,
+                 InstructionOperand* shift_return) {
   return TryMatchShift<IrOpcode::kWord32Shl, 0, 31, kMode_Operand2_R_LSL_I,
                        kMode_Operand2_R_LSL_R>(selector, opcode_return, node,
                                                value_return, shift_return);
@@ -145,8 +144,8 @@
 
 
 bool TryMatchLSR(InstructionSelector* selector, InstructionCode* opcode_return,
-                 Node* node, InstructionOperand** value_return,
-                 InstructionOperand** shift_return) {
+                 Node* node, InstructionOperand* value_return,
+                 InstructionOperand* shift_return) {
   return TryMatchShift<IrOpcode::kWord32Shr, 1, 32, kMode_Operand2_R_LSR_I,
                        kMode_Operand2_R_LSR_R>(selector, opcode_return, node,
                                                value_return, shift_return);
@@ -155,8 +154,8 @@
 
 bool TryMatchShift(InstructionSelector* selector,
                    InstructionCode* opcode_return, Node* node,
-                   InstructionOperand** value_return,
-                   InstructionOperand** shift_return) {
+                   InstructionOperand* value_return,
+                   InstructionOperand* shift_return) {
   return (
       TryMatchASR(selector, opcode_return, node, value_return, shift_return) ||
       TryMatchLSL(selector, opcode_return, node, value_return, shift_return) ||
@@ -168,7 +167,7 @@
 bool TryMatchImmediateOrShift(InstructionSelector* selector,
                               InstructionCode* opcode_return, Node* node,
                               size_t* input_count_return,
-                              InstructionOperand** inputs) {
+                              InstructionOperand* inputs) {
   ArmOperandGenerator g(selector);
   if (g.CanBeImmediate(node, *opcode_return)) {
     *opcode_return |= AddressingModeField::encode(kMode_Operand2_I);
@@ -189,9 +188,9 @@
                 FlagsContinuation* cont) {
   ArmOperandGenerator g(selector);
   Int32BinopMatcher m(node);
-  InstructionOperand* inputs[5];
+  InstructionOperand inputs[5];
   size_t input_count = 0;
-  InstructionOperand* outputs[2];
+  InstructionOperand outputs[2];
   size_t output_count = 0;
 
   if (m.left().node() == m.right().node()) {
@@ -202,7 +201,7 @@
     //   mov r0, r1, asr #16
     //   adds r0, r0, r1, asr #16
     //   bvs label
-    InstructionOperand* const input = g.UseRegister(m.left().node());
+    InstructionOperand const input = g.UseRegister(m.left().node());
     opcode |= AddressingModeField::encode(kMode_Operand2_R);
     inputs[input_count++] = input;
     inputs[input_count++] = input;
@@ -232,15 +231,14 @@
     outputs[output_count++] = g.DefineAsRegister(cont->result());
   }
 
-  DCHECK_NE(0, input_count);
-  DCHECK_NE(0, output_count);
+  DCHECK_NE(0u, input_count);
+  DCHECK_NE(0u, output_count);
   DCHECK_GE(arraysize(inputs), input_count);
   DCHECK_GE(arraysize(outputs), output_count);
   DCHECK_NE(kMode_None, AddressingModeField::decode(opcode));
 
-  Instruction* instr = selector->Emit(cont->Encode(opcode), output_count,
-                                      outputs, input_count, inputs);
-  if (cont->IsBranch()) instr->MarkAsControl();
+  selector->Emit(cont->Encode(opcode), output_count, outputs, input_count,
+                 inputs);
 }
 
 
@@ -251,36 +249,86 @@
 }
 
 
+void EmitDiv(InstructionSelector* selector, ArchOpcode div_opcode,
+             ArchOpcode f64i32_opcode, ArchOpcode i32f64_opcode,
+             InstructionOperand result_operand, InstructionOperand left_operand,
+             InstructionOperand right_operand) {
+  ArmOperandGenerator g(selector);
+  if (selector->IsSupported(SUDIV)) {
+    selector->Emit(div_opcode, result_operand, left_operand, right_operand);
+    return;
+  }
+  InstructionOperand left_double_operand = g.TempDoubleRegister();
+  InstructionOperand right_double_operand = g.TempDoubleRegister();
+  InstructionOperand result_double_operand = g.TempDoubleRegister();
+  selector->Emit(f64i32_opcode, left_double_operand, left_operand);
+  selector->Emit(f64i32_opcode, right_double_operand, right_operand);
+  selector->Emit(kArmVdivF64, result_double_operand, left_double_operand,
+                 right_double_operand);
+  selector->Emit(i32f64_opcode, result_operand, result_double_operand);
+}
+
+
+void VisitDiv(InstructionSelector* selector, Node* node, ArchOpcode div_opcode,
+              ArchOpcode f64i32_opcode, ArchOpcode i32f64_opcode) {
+  ArmOperandGenerator g(selector);
+  Int32BinopMatcher m(node);
+  EmitDiv(selector, div_opcode, f64i32_opcode, i32f64_opcode,
+          g.DefineAsRegister(node), g.UseRegister(m.left().node()),
+          g.UseRegister(m.right().node()));
+}
+
+
+void VisitMod(InstructionSelector* selector, Node* node, ArchOpcode div_opcode,
+              ArchOpcode f64i32_opcode, ArchOpcode i32f64_opcode) {
+  ArmOperandGenerator g(selector);
+  Int32BinopMatcher m(node);
+  InstructionOperand div_operand = g.TempRegister();
+  InstructionOperand result_operand = g.DefineAsRegister(node);
+  InstructionOperand left_operand = g.UseRegister(m.left().node());
+  InstructionOperand right_operand = g.UseRegister(m.right().node());
+  EmitDiv(selector, div_opcode, f64i32_opcode, i32f64_opcode, div_operand,
+          left_operand, right_operand);
+  if (selector->IsSupported(MLS)) {
+    selector->Emit(kArmMls, result_operand, div_operand, right_operand,
+                   left_operand);
+  } else {
+    InstructionOperand mul_operand = g.TempRegister();
+    selector->Emit(kArmMul, mul_operand, div_operand, right_operand);
+    selector->Emit(kArmSub, result_operand, left_operand, mul_operand);
+  }
+}
+
 }  // namespace
 
 
 void InstructionSelector::VisitLoad(Node* node) {
-  MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node));
-  MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node));
+  LoadRepresentation load_rep = LoadRepresentationOf(node->op());
   ArmOperandGenerator g(this);
   Node* base = node->InputAt(0);
   Node* index = node->InputAt(1);
 
-  ArchOpcode opcode;
-  switch (rep) {
-    case kRepFloat32:
+  ArchOpcode opcode = kArchNop;
+  switch (load_rep.representation()) {
+    case MachineRepresentation::kFloat32:
       opcode = kArmVldrF32;
       break;
-    case kRepFloat64:
+    case MachineRepresentation::kFloat64:
       opcode = kArmVldrF64;
       break;
-    case kRepBit:  // Fall through.
-    case kRepWord8:
-      opcode = typ == kTypeUint32 ? kArmLdrb : kArmLdrsb;
+    case MachineRepresentation::kBit:  // Fall through.
+    case MachineRepresentation::kWord8:
+      opcode = load_rep.IsUnsigned() ? kArmLdrb : kArmLdrsb;
       break;
-    case kRepWord16:
-      opcode = typ == kTypeUint32 ? kArmLdrh : kArmLdrsh;
+    case MachineRepresentation::kWord16:
+      opcode = load_rep.IsUnsigned() ? kArmLdrh : kArmLdrsh;
       break;
-    case kRepTagged:  // Fall through.
-    case kRepWord32:
+    case MachineRepresentation::kTagged:  // Fall through.
+    case MachineRepresentation::kWord32:
       opcode = kArmLdr;
       break;
-    default:
+    case MachineRepresentation::kNone:  // Fall through.
+    case MachineRepresentation::kWord64:
       UNREACHABLE();
       return;
   }
@@ -301,87 +349,110 @@
   Node* index = node->InputAt(1);
   Node* value = node->InputAt(2);
 
-  StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node);
-  MachineType rep = RepresentationOf(store_rep.machine_type());
-  if (store_rep.write_barrier_kind() == kFullWriteBarrier) {
-    DCHECK(rep == kRepTagged);
-    // TODO(dcarney): refactor RecordWrite function to take temp registers
-    //                and pass them here instead of using fixed regs
-    // TODO(dcarney): handle immediate indices.
-    InstructionOperand* temps[] = {g.TempRegister(r5), g.TempRegister(r6)};
-    Emit(kArmStoreWriteBarrier, NULL, g.UseFixed(base, r4),
-         g.UseFixed(index, r5), g.UseFixed(value, r6), arraysize(temps),
-         temps);
-    return;
-  }
-  DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind());
+  StoreRepresentation store_rep = StoreRepresentationOf(node->op());
+  WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind();
+  MachineRepresentation rep = store_rep.representation();
 
-  ArchOpcode opcode;
-  switch (rep) {
-    case kRepFloat32:
-      opcode = kArmVstrF32;
-      break;
-    case kRepFloat64:
-      opcode = kArmVstrF64;
-      break;
-    case kRepBit:  // Fall through.
-    case kRepWord8:
-      opcode = kArmStrb;
-      break;
-    case kRepWord16:
-      opcode = kArmStrh;
-      break;
-    case kRepTagged:  // Fall through.
-    case kRepWord32:
-      opcode = kArmStr;
-      break;
-    default:
-      UNREACHABLE();
-      return;
-  }
-
-  if (g.CanBeImmediate(index, opcode)) {
-    Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), NULL,
-         g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value));
+  if (write_barrier_kind != kNoWriteBarrier) {
+    DCHECK_EQ(MachineRepresentation::kTagged, rep);
+    InstructionOperand inputs[3];
+    size_t input_count = 0;
+    inputs[input_count++] = g.UseUniqueRegister(base);
+    inputs[input_count++] = g.UseUniqueRegister(index);
+    inputs[input_count++] = (write_barrier_kind == kMapWriteBarrier)
+                                ? g.UseRegister(value)
+                                : g.UseUniqueRegister(value);
+    RecordWriteMode record_write_mode = RecordWriteMode::kValueIsAny;
+    switch (write_barrier_kind) {
+      case kNoWriteBarrier:
+        UNREACHABLE();
+        break;
+      case kMapWriteBarrier:
+        record_write_mode = RecordWriteMode::kValueIsMap;
+        break;
+      case kPointerWriteBarrier:
+        record_write_mode = RecordWriteMode::kValueIsPointer;
+        break;
+      case kFullWriteBarrier:
+        record_write_mode = RecordWriteMode::kValueIsAny;
+        break;
+    }
+    InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()};
+    size_t const temp_count = arraysize(temps);
+    InstructionCode code = kArchStoreWithWriteBarrier;
+    code |= MiscField::encode(static_cast<int>(record_write_mode));
+    Emit(code, 0, nullptr, input_count, inputs, temp_count, temps);
   } else {
-    Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), NULL,
-         g.UseRegister(base), g.UseRegister(index), g.UseRegister(value));
+    ArchOpcode opcode = kArchNop;
+    switch (rep) {
+      case MachineRepresentation::kFloat32:
+        opcode = kArmVstrF32;
+        break;
+      case MachineRepresentation::kFloat64:
+        opcode = kArmVstrF64;
+        break;
+      case MachineRepresentation::kBit:  // Fall through.
+      case MachineRepresentation::kWord8:
+        opcode = kArmStrb;
+        break;
+      case MachineRepresentation::kWord16:
+        opcode = kArmStrh;
+        break;
+      case MachineRepresentation::kTagged:  // Fall through.
+      case MachineRepresentation::kWord32:
+        opcode = kArmStr;
+        break;
+      case MachineRepresentation::kNone:  // Fall through.
+      case MachineRepresentation::kWord64:
+        UNREACHABLE();
+        return;
+    }
+
+    if (g.CanBeImmediate(index, opcode)) {
+      Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), g.NoOutput(),
+           g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value));
+    } else {
+      Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), g.NoOutput(),
+           g.UseRegister(base), g.UseRegister(index), g.UseRegister(value));
+    }
   }
 }
 
 
 void InstructionSelector::VisitCheckedLoad(Node* node) {
-  MachineType rep = RepresentationOf(OpParameter<MachineType>(node));
-  MachineType typ = TypeOf(OpParameter<MachineType>(node));
+  CheckedLoadRepresentation load_rep = CheckedLoadRepresentationOf(node->op());
   ArmOperandGenerator g(this);
   Node* const buffer = node->InputAt(0);
   Node* const offset = node->InputAt(1);
   Node* const length = node->InputAt(2);
-  ArchOpcode opcode;
-  switch (rep) {
-    case kRepWord8:
-      opcode = typ == kTypeInt32 ? kCheckedLoadInt8 : kCheckedLoadUint8;
+  ArchOpcode opcode = kArchNop;
+  switch (load_rep.representation()) {
+    case MachineRepresentation::kWord8:
+      opcode = load_rep.IsSigned() ? kCheckedLoadInt8 : kCheckedLoadUint8;
       break;
-    case kRepWord16:
-      opcode = typ == kTypeInt32 ? kCheckedLoadInt16 : kCheckedLoadUint16;
+    case MachineRepresentation::kWord16:
+      opcode = load_rep.IsSigned() ? kCheckedLoadInt16 : kCheckedLoadUint16;
       break;
-    case kRepWord32:
+    case MachineRepresentation::kWord32:
       opcode = kCheckedLoadWord32;
       break;
-    case kRepFloat32:
+    case MachineRepresentation::kFloat32:
       opcode = kCheckedLoadFloat32;
       break;
-    case kRepFloat64:
+    case MachineRepresentation::kFloat64:
       opcode = kCheckedLoadFloat64;
       break;
-    default:
+    case MachineRepresentation::kBit:     // Fall through.
+    case MachineRepresentation::kTagged:  // Fall through.
+    case MachineRepresentation::kWord64:  // Fall through.
+    case MachineRepresentation::kNone:
       UNREACHABLE();
       return;
   }
-  InstructionOperand* offset_operand = g.UseRegister(offset);
-  InstructionOperand* length_operand = g.CanBeImmediate(length, kArmCmp)
-                                           ? g.UseImmediate(length)
-                                           : g.UseRegister(length);
+  InstructionOperand offset_operand = g.UseRegister(offset);
+  InstructionOperand length_operand = g.CanBeImmediate(length, kArmCmp)
+                                          ? g.UseImmediate(length)
+                                          : g.UseRegister(length);
   Emit(opcode | AddressingModeField::encode(kMode_Offset_RR),
        g.DefineAsRegister(node), offset_operand, length_operand,
        g.UseRegister(buffer), offset_operand);
@@ -389,38 +460,41 @@
 
 
 void InstructionSelector::VisitCheckedStore(Node* node) {
-  MachineType rep = RepresentationOf(OpParameter<MachineType>(node));
+  MachineRepresentation rep = CheckedStoreRepresentationOf(node->op());
   ArmOperandGenerator g(this);
   Node* const buffer = node->InputAt(0);
   Node* const offset = node->InputAt(1);
   Node* const length = node->InputAt(2);
   Node* const value = node->InputAt(3);
-  ArchOpcode opcode;
+  ArchOpcode opcode = kArchNop;
   switch (rep) {
-    case kRepWord8:
+    case MachineRepresentation::kWord8:
       opcode = kCheckedStoreWord8;
       break;
-    case kRepWord16:
+    case MachineRepresentation::kWord16:
       opcode = kCheckedStoreWord16;
       break;
-    case kRepWord32:
+    case MachineRepresentation::kWord32:
       opcode = kCheckedStoreWord32;
       break;
-    case kRepFloat32:
+    case MachineRepresentation::kFloat32:
       opcode = kCheckedStoreFloat32;
       break;
-    case kRepFloat64:
+    case MachineRepresentation::kFloat64:
       opcode = kCheckedStoreFloat64;
       break;
-    default:
+    case MachineRepresentation::kBit:     // Fall through.
+    case MachineRepresentation::kTagged:  // Fall through.
+    case MachineRepresentation::kWord64:  // Fall through.
+    case MachineRepresentation::kNone:
       UNREACHABLE();
       return;
   }
-  InstructionOperand* offset_operand = g.UseRegister(offset);
-  InstructionOperand* length_operand = g.CanBeImmediate(length, kArmCmp)
-                                           ? g.UseImmediate(length)
-                                           : g.UseRegister(length);
-  Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), nullptr,
+  InstructionOperand offset_operand = g.UseRegister(offset);
+  InstructionOperand length_operand = g.CanBeImmediate(length, kArmCmp)
+                                          ? g.UseImmediate(length)
+                                          : g.UseRegister(length);
+  Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), g.NoOutput(),
        offset_operand, length_operand, g.UseRegister(value),
        g.UseRegister(buffer), offset_operand);
 }
@@ -432,8 +506,8 @@
              Node* right) {
   ArmOperandGenerator g(selector);
   InstructionCode opcode = kArmBic;
-  InstructionOperand* value_operand;
-  InstructionOperand* shift_operand;
+  InstructionOperand value_operand;
+  InstructionOperand shift_operand;
   if (TryMatchShift(selector, &opcode, right, &value_operand, &shift_operand)) {
     selector->Emit(opcode, g.DefineAsRegister(node), g.UseRegister(left),
                    value_operand, shift_operand);
@@ -447,8 +521,8 @@
 
 void EmitUbfx(InstructionSelector* selector, Node* node, Node* left,
               uint32_t lsb, uint32_t width) {
-  DCHECK_LE(1, width);
-  DCHECK_LE(width, 32 - lsb);
+  DCHECK_LE(1u, width);
+  DCHECK_LE(width, 32u - lsb);
   ArmOperandGenerator g(selector);
   selector->Emit(kArmUbfx, g.DefineAsRegister(node), g.UseRegister(left),
                  g.TempImmediate(lsb), g.TempImmediate(width));
@@ -480,7 +554,7 @@
     uint32_t msb = base::bits::CountLeadingZeros32(value);
     // Try to interpret this AND as UBFX.
     if (IsSupported(ARMv7) && width != 0 && msb + width == 32) {
-      DCHECK_EQ(0, base::bits::CountTrailingZeros32(value));
+      DCHECK_EQ(0u, base::bits::CountTrailingZeros32(value));
       if (m.left().IsWord32Shr()) {
         Int32BinopMatcher mleft(m.left().node());
         if (mleft.right().IsInRange(0, 31)) {
@@ -534,8 +608,8 @@
   Int32BinopMatcher m(node);
   if (m.right().Is(-1)) {
     InstructionCode opcode = kArmMvn;
-    InstructionOperand* value_operand;
-    InstructionOperand* shift_operand;
+    InstructionOperand value_operand;
+    InstructionOperand shift_operand;
     if (TryMatchShift(this, &opcode, m.left().node(), &value_operand,
                       &shift_operand)) {
       Emit(opcode, g.DefineAsRegister(node), value_operand, shift_operand);
@@ -549,15 +623,16 @@
 }
 
 
+namespace {
+
 template <typename TryMatchShift>
-static inline void VisitShift(InstructionSelector* selector, Node* node,
-                              TryMatchShift try_match_shift,
-                              FlagsContinuation* cont) {
+void VisitShift(InstructionSelector* selector, Node* node,
+                TryMatchShift try_match_shift, FlagsContinuation* cont) {
   ArmOperandGenerator g(selector);
   InstructionCode opcode = kArmMov;
-  InstructionOperand* inputs[4];
+  InstructionOperand inputs[4];
   size_t input_count = 2;
-  InstructionOperand* outputs[2];
+  InstructionOperand outputs[2];
   size_t output_count = 0;
 
   CHECK(try_match_shift(selector, &opcode, node, &inputs[0], &inputs[1]));
@@ -572,25 +647,26 @@
     outputs[output_count++] = g.DefineAsRegister(cont->result());
   }
 
-  DCHECK_NE(0, input_count);
-  DCHECK_NE(0, output_count);
+  DCHECK_NE(0u, input_count);
+  DCHECK_NE(0u, output_count);
   DCHECK_GE(arraysize(inputs), input_count);
   DCHECK_GE(arraysize(outputs), output_count);
   DCHECK_NE(kMode_None, AddressingModeField::decode(opcode));
 
-  Instruction* instr = selector->Emit(cont->Encode(opcode), output_count,
-                                      outputs, input_count, inputs);
-  if (cont->IsBranch()) instr->MarkAsControl();
+  selector->Emit(cont->Encode(opcode), output_count, outputs, input_count,
+                 inputs);
 }
 
 
 template <typename TryMatchShift>
-static inline void VisitShift(InstructionSelector* selector, Node* node,
+void VisitShift(InstructionSelector* selector, Node* node,
                               TryMatchShift try_match_shift) {
   FlagsContinuation cont;
   VisitShift(selector, node, try_match_shift, &cont);
 }
 
+}  // namespace
+
 
 void InstructionSelector::VisitWord32Shl(Node* node) {
   VisitShift(this, node, TryMatchLSL);
@@ -602,7 +678,7 @@
   Int32BinopMatcher m(node);
   if (IsSupported(ARMv7) && m.left().IsWord32And() &&
       m.right().IsInRange(0, 31)) {
-    int32_t lsb = m.right().Value();
+    uint32_t lsb = m.right().Value();
     Int32BinopMatcher mleft(m.left().node());
     if (mleft.right().HasValue()) {
       uint32_t value = (mleft.right().Value() >> lsb) << lsb;
@@ -642,6 +718,17 @@
 }
 
 
+void InstructionSelector::VisitWord32Clz(Node* node) {
+  VisitRR(this, kArmClz, node);
+}
+
+
+void InstructionSelector::VisitWord32Ctz(Node* node) { UNREACHABLE(); }
+
+
+void InstructionSelector::VisitWord32Popcnt(Node* node) { UNREACHABLE(); }
+
+
 void InstructionSelector::VisitInt32Add(Node* node) {
   ArmOperandGenerator g(this);
   Int32BinopMatcher m(node);
@@ -791,59 +878,24 @@
       return;
     }
   }
-  Emit(kArmMul, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
-       g.UseRegister(m.right().node()));
+  VisitRRR(this, kArmMul, node);
 }
 
 
 void InstructionSelector::VisitInt32MulHigh(Node* node) {
-  ArmOperandGenerator g(this);
-  Emit(kArmSmmul, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)),
-       g.UseRegister(node->InputAt(1)));
+  VisitRRR(this, kArmSmmul, node);
 }
 
 
 void InstructionSelector::VisitUint32MulHigh(Node* node) {
   ArmOperandGenerator g(this);
-  InstructionOperand* outputs[] = {g.TempRegister(), g.DefineAsRegister(node)};
-  InstructionOperand* inputs[] = {g.UseRegister(node->InputAt(0)),
-                                  g.UseRegister(node->InputAt(1))};
+  InstructionOperand outputs[] = {g.TempRegister(), g.DefineAsRegister(node)};
+  InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0)),
+                                 g.UseRegister(node->InputAt(1))};
   Emit(kArmUmull, arraysize(outputs), outputs, arraysize(inputs), inputs);
 }
 
 
-static void EmitDiv(InstructionSelector* selector, ArchOpcode div_opcode,
-                    ArchOpcode f64i32_opcode, ArchOpcode i32f64_opcode,
-                    InstructionOperand* result_operand,
-                    InstructionOperand* left_operand,
-                    InstructionOperand* right_operand) {
-  ArmOperandGenerator g(selector);
-  if (selector->IsSupported(SUDIV)) {
-    selector->Emit(div_opcode, result_operand, left_operand, right_operand);
-    return;
-  }
-  InstructionOperand* left_double_operand = g.TempDoubleRegister();
-  InstructionOperand* right_double_operand = g.TempDoubleRegister();
-  InstructionOperand* result_double_operand = g.TempDoubleRegister();
-  selector->Emit(f64i32_opcode, left_double_operand, left_operand);
-  selector->Emit(f64i32_opcode, right_double_operand, right_operand);
-  selector->Emit(kArmVdivF64, result_double_operand, left_double_operand,
-                 right_double_operand);
-  selector->Emit(i32f64_opcode, result_operand, result_double_operand);
-}
-
-
-static void VisitDiv(InstructionSelector* selector, Node* node,
-                     ArchOpcode div_opcode, ArchOpcode f64i32_opcode,
-                     ArchOpcode i32f64_opcode) {
-  ArmOperandGenerator g(selector);
-  Int32BinopMatcher m(node);
-  EmitDiv(selector, div_opcode, f64i32_opcode, i32f64_opcode,
-          g.DefineAsRegister(node), g.UseRegister(m.left().node()),
-          g.UseRegister(m.right().node()));
-}
-
-
 void InstructionSelector::VisitInt32Div(Node* node) {
   VisitDiv(this, node, kArmSdiv, kArmVcvtF64S32, kArmVcvtS32F64);
 }
@@ -854,28 +906,6 @@
 }
 
 
-static void VisitMod(InstructionSelector* selector, Node* node,
-                     ArchOpcode div_opcode, ArchOpcode f64i32_opcode,
-                     ArchOpcode i32f64_opcode) {
-  ArmOperandGenerator g(selector);
-  Int32BinopMatcher m(node);
-  InstructionOperand* div_operand = g.TempRegister();
-  InstructionOperand* result_operand = g.DefineAsRegister(node);
-  InstructionOperand* left_operand = g.UseRegister(m.left().node());
-  InstructionOperand* right_operand = g.UseRegister(m.right().node());
-  EmitDiv(selector, div_opcode, f64i32_opcode, i32f64_opcode, div_operand,
-          left_operand, right_operand);
-  if (selector->IsSupported(MLS)) {
-    selector->Emit(kArmMls, result_operand, div_operand, right_operand,
-                   left_operand);
-    return;
-  }
-  InstructionOperand* mul_operand = g.TempRegister();
-  selector->Emit(kArmMul, mul_operand, div_operand, right_operand);
-  selector->Emit(kArmSub, result_operand, left_operand, mul_operand);
-}
-
-
 void InstructionSelector::VisitInt32Mod(Node* node) {
   VisitMod(this, node, kArmSdiv, kArmVcvtF64S32, kArmVcvtS32F64);
 }
@@ -887,47 +917,80 @@
 
 
 void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) {
-  ArmOperandGenerator g(this);
-  Emit(kArmVcvtF64F32, g.DefineAsRegister(node),
-       g.UseRegister(node->InputAt(0)));
+  VisitRR(this, kArmVcvtF64F32, node);
 }
 
 
 void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) {
-  ArmOperandGenerator g(this);
-  Emit(kArmVcvtF64S32, g.DefineAsRegister(node),
-       g.UseRegister(node->InputAt(0)));
+  VisitRR(this, kArmVcvtF64S32, node);
 }
 
 
 void InstructionSelector::VisitChangeUint32ToFloat64(Node* node) {
-  ArmOperandGenerator g(this);
-  Emit(kArmVcvtF64U32, g.DefineAsRegister(node),
-       g.UseRegister(node->InputAt(0)));
+  VisitRR(this, kArmVcvtF64U32, node);
 }
 
 
 void InstructionSelector::VisitChangeFloat64ToInt32(Node* node) {
-  ArmOperandGenerator g(this);
-  Emit(kArmVcvtS32F64, g.DefineAsRegister(node),
-       g.UseRegister(node->InputAt(0)));
+  VisitRR(this, kArmVcvtS32F64, node);
 }
 
 
 void InstructionSelector::VisitChangeFloat64ToUint32(Node* node) {
-  ArmOperandGenerator g(this);
-  Emit(kArmVcvtU32F64, g.DefineAsRegister(node),
-       g.UseRegister(node->InputAt(0)));
+  VisitRR(this, kArmVcvtU32F64, node);
 }
 
 
 void InstructionSelector::VisitTruncateFloat64ToFloat32(Node* node) {
+  VisitRR(this, kArmVcvtF32F64, node);
+}
+
+
+void InstructionSelector::VisitTruncateFloat64ToInt32(Node* node) {
+  switch (TruncationModeOf(node->op())) {
+    case TruncationMode::kJavaScript:
+      return VisitRR(this, kArchTruncateDoubleToI, node);
+    case TruncationMode::kRoundToZero:
+      return VisitRR(this, kArmVcvtS32F64, node);
+  }
+  UNREACHABLE();
+}
+
+
+void InstructionSelector::VisitBitcastFloat32ToInt32(Node* node) {
+  VisitRR(this, kArmVmovLowU32F64, node);
+}
+
+
+void InstructionSelector::VisitBitcastInt32ToFloat32(Node* node) {
   ArmOperandGenerator g(this);
-  Emit(kArmVcvtF32F64, g.DefineAsRegister(node),
+  Emit(kArmVmovLowF64U32, g.DefineAsRegister(node),
+       ImmediateOperand(ImmediateOperand::INLINE, 0),
        g.UseRegister(node->InputAt(0)));
 }
 
 
+void InstructionSelector::VisitFloat32Add(Node* node) {
+  ArmOperandGenerator g(this);
+  Float32BinopMatcher m(node);
+  if (m.left().IsFloat32Mul() && CanCover(node, m.left().node())) {
+    Float32BinopMatcher mleft(m.left().node());
+    Emit(kArmVmlaF32, g.DefineSameAsFirst(node),
+         g.UseRegister(m.right().node()), g.UseRegister(mleft.left().node()),
+         g.UseRegister(mleft.right().node()));
+    return;
+  }
+  if (m.right().IsFloat32Mul() && CanCover(node, m.right().node())) {
+    Float32BinopMatcher mright(m.right().node());
+    Emit(kArmVmlaF32, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()),
+         g.UseRegister(mright.left().node()),
+         g.UseRegister(mright.right().node()));
+    return;
+  }
+  VisitRRR(this, kArmVaddF32, node);
+}
+
+
 void InstructionSelector::VisitFloat64Add(Node* node) {
   ArmOperandGenerator g(this);
   Float64BinopMatcher m(node);
@@ -945,7 +1008,26 @@
          g.UseRegister(mright.right().node()));
     return;
   }
-  VisitRRRFloat64(this, kArmVaddF64, node);
+  VisitRRR(this, kArmVaddF64, node);
+}
+
+
+void InstructionSelector::VisitFloat32Sub(Node* node) {
+  ArmOperandGenerator g(this);
+  Float32BinopMatcher m(node);
+  if (m.left().IsMinusZero()) {
+    Emit(kArmVnegF32, g.DefineAsRegister(node),
+         g.UseRegister(m.right().node()));
+    return;
+  }
+  if (m.right().IsFloat32Mul() && CanCover(node, m.right().node())) {
+    Float32BinopMatcher mright(m.right().node());
+    Emit(kArmVmlsF32, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()),
+         g.UseRegister(mright.left().node()),
+         g.UseRegister(mright.right().node()));
+    return;
+  }
+  VisitRRR(this, kArmVsubF32, node);
 }
 
 
@@ -953,6 +1035,18 @@
   ArmOperandGenerator g(this);
   Float64BinopMatcher m(node);
   if (m.left().IsMinusZero()) {
+    if (m.right().IsFloat64RoundDown() &&
+        CanCover(m.node(), m.right().node())) {
+      if (m.right().InputAt(0)->opcode() == IrOpcode::kFloat64Sub &&
+          CanCover(m.right().node(), m.right().InputAt(0))) {
+        Float64BinopMatcher mright0(m.right().InputAt(0));
+        if (mright0.left().IsMinusZero()) {
+          Emit(kArmVrintpF64, g.DefineAsRegister(node),
+               g.UseRegister(mright0.right().node()));
+          return;
+        }
+      }
+    }
     Emit(kArmVnegF64, g.DefineAsRegister(node),
          g.UseRegister(m.right().node()));
     return;
@@ -964,17 +1058,27 @@
          g.UseRegister(mright.right().node()));
     return;
   }
-  VisitRRRFloat64(this, kArmVsubF64, node);
+  VisitRRR(this, kArmVsubF64, node);
+}
+
+
+void InstructionSelector::VisitFloat32Mul(Node* node) {
+  VisitRRR(this, kArmVmulF32, node);
 }
 
 
 void InstructionSelector::VisitFloat64Mul(Node* node) {
-  VisitRRRFloat64(this, kArmVmulF64, node);
+  VisitRRR(this, kArmVmulF64, node);
+}
+
+
+void InstructionSelector::VisitFloat32Div(Node* node) {
+  VisitRRR(this, kArmVdivF32, node);
 }
 
 
 void InstructionSelector::VisitFloat64Div(Node* node) {
-  VisitRRRFloat64(this, kArmVdivF64, node);
+  VisitRRR(this, kArmVdivF64, node);
 }
 
 
@@ -985,104 +1089,169 @@
 }
 
 
+void InstructionSelector::VisitFloat32Max(Node* node) { UNREACHABLE(); }
+
+
+void InstructionSelector::VisitFloat64Max(Node* node) { UNREACHABLE(); }
+
+
+void InstructionSelector::VisitFloat32Min(Node* node) { UNREACHABLE(); }
+
+
+void InstructionSelector::VisitFloat64Min(Node* node) { UNREACHABLE(); }
+
+
+void InstructionSelector::VisitFloat32Abs(Node* node) {
+  VisitRR(this, kArmVabsF32, node);
+}
+
+
+void InstructionSelector::VisitFloat64Abs(Node* node) {
+  VisitRR(this, kArmVabsF64, node);
+}
+
+
+void InstructionSelector::VisitFloat32Sqrt(Node* node) {
+  VisitRR(this, kArmVsqrtF32, node);
+}
+
+
 void InstructionSelector::VisitFloat64Sqrt(Node* node) {
-  ArmOperandGenerator g(this);
-  Emit(kArmVsqrtF64, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)));
+  VisitRR(this, kArmVsqrtF64, node);
 }
 
 
-void InstructionSelector::VisitFloat64Floor(Node* node) {
-  DCHECK(CpuFeatures::IsSupported(ARMv8));
-  VisitRRFloat64(this, kArmVfloorF64, node);
+void InstructionSelector::VisitFloat32RoundDown(Node* node) {
+  VisitRR(this, kArmVrintmF32, node);
 }
 
 
-void InstructionSelector::VisitFloat64Ceil(Node* node) {
-  DCHECK(CpuFeatures::IsSupported(ARMv8));
-  VisitRRFloat64(this, kArmVceilF64, node);
+void InstructionSelector::VisitFloat64RoundDown(Node* node) {
+  VisitRR(this, kArmVrintmF64, node);
+}
+
+
+void InstructionSelector::VisitFloat32RoundUp(Node* node) {
+  VisitRR(this, kArmVrintpF32, node);
+}
+
+
+void InstructionSelector::VisitFloat64RoundUp(Node* node) {
+  VisitRR(this, kArmVrintpF64, node);
+}
+
+
+void InstructionSelector::VisitFloat32RoundTruncate(Node* node) {
+  VisitRR(this, kArmVrintzF32, node);
 }
 
 
 void InstructionSelector::VisitFloat64RoundTruncate(Node* node) {
-  DCHECK(CpuFeatures::IsSupported(ARMv8));
-  VisitRRFloat64(this, kArmVroundTruncateF64, node);
+  VisitRR(this, kArmVrintzF64, node);
 }
 
 
 void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) {
-  DCHECK(CpuFeatures::IsSupported(ARMv8));
-  VisitRRFloat64(this, kArmVroundTiesAwayF64, node);
+  VisitRR(this, kArmVrintaF64, node);
 }
 
 
-void InstructionSelector::VisitCall(Node* node) {
+void InstructionSelector::VisitFloat32RoundTiesEven(Node* node) {
+  VisitRR(this, kArmVrintnF32, node);
+}
+
+
+void InstructionSelector::VisitFloat64RoundTiesEven(Node* node) {
+  VisitRR(this, kArmVrintnF64, node);
+}
+
+
+void InstructionSelector::EmitPrepareArguments(
+    ZoneVector<PushParameter>* arguments, const CallDescriptor* descriptor,
+    Node* node) {
   ArmOperandGenerator g(this);
-  const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(node);
 
-  FrameStateDescriptor* frame_state_descriptor = NULL;
-  if (descriptor->NeedsFrameState()) {
-    frame_state_descriptor =
-        GetFrameStateDescriptor(node->InputAt(descriptor->InputCount()));
-  }
+  // Prepare for C function call.
+  if (descriptor->IsCFunctionCall()) {
+    Emit(kArchPrepareCallCFunction |
+             MiscField::encode(static_cast<int>(descriptor->CParameterCount())),
+         0, nullptr, 0, nullptr);
 
-  CallBuffer buffer(zone(), descriptor, frame_state_descriptor);
-
-  // Compute InstructionOperands for inputs and outputs.
-  // TODO(turbofan): on ARM64 it's probably better to use the code object in a
-  // register if there are multiple uses of it. Improve constant pool and the
-  // heuristics in the register allocator for where to emit constants.
-  InitializeCallBuffer(node, &buffer, true, false);
-
-  // TODO(dcarney): might be possible to use claim/poke instead
-  // Push any stack arguments.
-  for (NodeVectorRIter input = buffer.pushed_nodes.rbegin();
-       input != buffer.pushed_nodes.rend(); input++) {
-    Emit(kArmPush, NULL, g.UseRegister(*input));
-  }
-
-  // Select the appropriate opcode based on the call type.
-  InstructionCode opcode;
-  switch (descriptor->kind()) {
-    case CallDescriptor::kCallCodeObject: {
-      opcode = kArchCallCodeObject;
-      break;
+    // Poke any stack arguments.
+    for (size_t n = 0; n < arguments->size(); ++n) {
+      PushParameter input = (*arguments)[n];
+      if (input.node()) {
+        int slot = static_cast<int>(n);
+        Emit(kArmPoke | MiscField::encode(slot), g.NoOutput(),
+             g.UseRegister(input.node()));
+      }
     }
-    case CallDescriptor::kCallJSFunction:
-      opcode = kArchCallJSFunction;
-      break;
-    default:
-      UNREACHABLE();
-      return;
+  } else {
+    // Push any stack arguments.
+    for (PushParameter input : base::Reversed(*arguments)) {
+      // Skip any alignment holes in pushed nodes.
+      if (input.node() == nullptr) continue;
+      Emit(kArmPush, g.NoOutput(), g.UseRegister(input.node()));
+    }
   }
-  opcode |= MiscField::encode(descriptor->flags());
-
-  // Emit the call instruction.
-  InstructionOperand** first_output =
-      buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL;
-  Instruction* call_instr =
-      Emit(opcode, buffer.outputs.size(), first_output,
-           buffer.instruction_args.size(), &buffer.instruction_args.front());
-  call_instr->MarkAsCall();
 }
 
 
+bool InstructionSelector::IsTailCallAddressImmediate() { return false; }
+
+
 namespace {
 
-// Shared routine for multiple float compare operations.
+// Shared routine for multiple compare operations.
+void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
+                  InstructionOperand left, InstructionOperand right,
+                  FlagsContinuation* cont) {
+  ArmOperandGenerator g(selector);
+  opcode = cont->Encode(opcode);
+  if (cont->IsBranch()) {
+    selector->Emit(opcode, g.NoOutput(), left, right,
+                   g.Label(cont->true_block()), g.Label(cont->false_block()));
+  } else {
+    DCHECK(cont->IsSet());
+    selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right);
+  }
+}
+
+
+// Shared routine for multiple float32 compare operations.
+void VisitFloat32Compare(InstructionSelector* selector, Node* node,
+                         FlagsContinuation* cont) {
+  ArmOperandGenerator g(selector);
+  Float32BinopMatcher m(node);
+  if (m.right().Is(0.0f)) {
+    VisitCompare(selector, kArmVcmpF32, g.UseRegister(m.left().node()),
+                 g.UseImmediate(m.right().node()), cont);
+  } else if (m.left().Is(0.0f)) {
+    cont->Commute();
+    VisitCompare(selector, kArmVcmpF32, g.UseRegister(m.right().node()),
+                 g.UseImmediate(m.left().node()), cont);
+  } else {
+    VisitCompare(selector, kArmVcmpF32, g.UseRegister(m.left().node()),
+                 g.UseRegister(m.right().node()), cont);
+  }
+}
+
+
+// Shared routine for multiple float64 compare operations.
 void VisitFloat64Compare(InstructionSelector* selector, Node* node,
                          FlagsContinuation* cont) {
   ArmOperandGenerator g(selector);
   Float64BinopMatcher m(node);
-  if (cont->IsBranch()) {
-    selector->Emit(cont->Encode(kArmVcmpF64), nullptr,
-                   g.UseRegister(m.left().node()),
-                   g.UseRegister(m.right().node()), g.Label(cont->true_block()),
-                   g.Label(cont->false_block()))->MarkAsControl();
+  if (m.right().Is(0.0)) {
+    VisitCompare(selector, kArmVcmpF64, g.UseRegister(m.left().node()),
+                 g.UseImmediate(m.right().node()), cont);
+  } else if (m.left().Is(0.0)) {
+    cont->Commute();
+    VisitCompare(selector, kArmVcmpF64, g.UseRegister(m.right().node()),
+                 g.UseImmediate(m.left().node()), cont);
   } else {
-    DCHECK(cont->IsSet());
-    selector->Emit(
-        cont->Encode(kArmVcmpF64), g.DefineAsRegister(cont->result()),
-        g.UseRegister(m.left().node()), g.UseRegister(m.right().node()));
+    VisitCompare(selector, kArmVcmpF64, g.UseRegister(m.left().node()),
+                 g.UseRegister(m.right().node()), cont);
   }
 }
 
@@ -1092,9 +1261,9 @@
                       InstructionCode opcode, FlagsContinuation* cont) {
   ArmOperandGenerator g(selector);
   Int32BinopMatcher m(node);
-  InstructionOperand* inputs[5];
+  InstructionOperand inputs[5];
   size_t input_count = 0;
-  InstructionOperand* outputs[1];
+  InstructionOperand outputs[1];
   size_t output_count = 0;
 
   if (TryMatchImmediateOrShift(selector, &opcode, m.right().node(),
@@ -1120,13 +1289,12 @@
     outputs[output_count++] = g.DefineAsRegister(cont->result());
   }
 
-  DCHECK_NE(0, input_count);
+  DCHECK_NE(0u, input_count);
   DCHECK_GE(arraysize(inputs), input_count);
   DCHECK_GE(arraysize(outputs), output_count);
 
-  Instruction* instr = selector->Emit(cont->Encode(opcode), output_count,
-                                      outputs, input_count, inputs);
-  if (cont->IsBranch()) instr->MarkAsControl();
+  selector->Emit(cont->Encode(opcode), output_count, outputs, input_count,
+                 inputs);
 }
 
 
@@ -1166,26 +1334,35 @@
       case IrOpcode::kUint32LessThanOrEqual:
         cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
         return VisitWordCompare(selector, value, cont);
+      case IrOpcode::kFloat32Equal:
+        cont->OverwriteAndNegateIfEqual(kEqual);
+        return VisitFloat32Compare(selector, value, cont);
+      case IrOpcode::kFloat32LessThan:
+        cont->OverwriteAndNegateIfEqual(kFloatLessThan);
+        return VisitFloat32Compare(selector, value, cont);
+      case IrOpcode::kFloat32LessThanOrEqual:
+        cont->OverwriteAndNegateIfEqual(kFloatLessThanOrEqual);
+        return VisitFloat32Compare(selector, value, cont);
       case IrOpcode::kFloat64Equal:
-        cont->OverwriteAndNegateIfEqual(kUnorderedEqual);
+        cont->OverwriteAndNegateIfEqual(kEqual);
         return VisitFloat64Compare(selector, value, cont);
       case IrOpcode::kFloat64LessThan:
-        cont->OverwriteAndNegateIfEqual(kUnorderedLessThan);
+        cont->OverwriteAndNegateIfEqual(kFloatLessThan);
         return VisitFloat64Compare(selector, value, cont);
       case IrOpcode::kFloat64LessThanOrEqual:
-        cont->OverwriteAndNegateIfEqual(kUnorderedLessThanOrEqual);
+        cont->OverwriteAndNegateIfEqual(kFloatLessThanOrEqual);
         return VisitFloat64Compare(selector, value, cont);
       case IrOpcode::kProjection:
         // Check if this is the overflow output projection of an
         // <Operation>WithOverflow node.
-        if (OpParameter<size_t>(value) == 1u) {
+        if (ProjectionIndexOf(value->op()) == 1u) {
           // We cannot combine the <Operation>WithOverflow with this branch
           // unless the 0th projection (the use of the actual value of the
-          // <Operation> is either NULL, which means there's no use of the
+          // <Operation> is either nullptr, which means there's no use of the
           // actual value, or was already defined, which means it is scheduled
           // *AFTER* this branch).
           Node* const node = value->InputAt(0);
-          Node* const result = node->FindProjection(0);
+          Node* const result = NodeProperties::FindProjection(node, 0);
           if (!result || selector->IsDefined(result)) {
             switch (node->opcode()) {
               case IrOpcode::kInt32AddWithOverflow:
@@ -1228,11 +1405,10 @@
   ArmOperandGenerator g(selector);
   InstructionCode const opcode =
       cont->Encode(kArmTst) | AddressingModeField::encode(kMode_Operand2_R);
-  InstructionOperand* const value_operand = g.UseRegister(value);
+  InstructionOperand const value_operand = g.UseRegister(value);
   if (cont->IsBranch()) {
-    selector->Emit(opcode, nullptr, value_operand, value_operand,
-                   g.Label(cont->true_block()),
-                   g.Label(cont->false_block()))->MarkAsControl();
+    selector->Emit(opcode, g.NoOutput(), value_operand, value_operand,
+                   g.Label(cont->true_block()), g.Label(cont->false_block()));
   } else {
     selector->Emit(opcode, g.DefineAsRegister(cont->result()), value_operand,
                    value_operand);
@@ -1249,6 +1425,34 @@
 }
 
 
+void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) {
+  ArmOperandGenerator g(this);
+  InstructionOperand value_operand = g.UseRegister(node->InputAt(0));
+
+  // Emit either ArchTableSwitch or ArchLookupSwitch.
+  size_t table_space_cost = 4 + sw.value_range;
+  size_t table_time_cost = 3;
+  size_t lookup_space_cost = 3 + 2 * sw.case_count;
+  size_t lookup_time_cost = sw.case_count;
+  if (sw.case_count > 0 &&
+      table_space_cost + 3 * table_time_cost <=
+          lookup_space_cost + 3 * lookup_time_cost &&
+      sw.min_value > std::numeric_limits<int32_t>::min()) {
+    InstructionOperand index_operand = value_operand;
+    if (sw.min_value) {
+      index_operand = g.TempRegister();
+      Emit(kArmSub | AddressingModeField::encode(kMode_Operand2_I),
+           index_operand, value_operand, g.TempImmediate(sw.min_value));
+    }
+    // Generate a table lookup.
+    return EmitTableSwitch(sw, index_operand);
+  }
+
+  // Generate a sequence of conditional jumps.
+  return EmitLookupSwitch(sw, value_operand);
+}
+
+
 void InstructionSelector::VisitWord32Equal(Node* const node) {
   FlagsContinuation cont(kEqual, node);
   Int32BinopMatcher m(node);
@@ -1284,7 +1488,7 @@
 
 
 void InstructionSelector::VisitInt32AddWithOverflow(Node* node) {
-  if (Node* ovf = node->FindProjection(1)) {
+  if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
     FlagsContinuation cont(kOverflow, ovf);
     return VisitBinop(this, node, kArmAdd, kArmAdd, &cont);
   }
@@ -1294,7 +1498,7 @@
 
 
 void InstructionSelector::VisitInt32SubWithOverflow(Node* node) {
-  if (Node* ovf = node->FindProjection(1)) {
+  if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
     FlagsContinuation cont(kOverflow, ovf);
     return VisitBinop(this, node, kArmSub, kArmRsb, &cont);
   }
@@ -1303,36 +1507,100 @@
 }
 
 
+void InstructionSelector::VisitFloat32Equal(Node* node) {
+  FlagsContinuation cont(kEqual, node);
+  VisitFloat32Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitFloat32LessThan(Node* node) {
+  FlagsContinuation cont(kFloatLessThan, node);
+  VisitFloat32Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitFloat32LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kFloatLessThanOrEqual, node);
+  VisitFloat32Compare(this, node, &cont);
+}
+
+
 void InstructionSelector::VisitFloat64Equal(Node* node) {
-  FlagsContinuation cont(kUnorderedEqual, node);
+  FlagsContinuation cont(kEqual, node);
   VisitFloat64Compare(this, node, &cont);
 }
 
 
 void InstructionSelector::VisitFloat64LessThan(Node* node) {
-  FlagsContinuation cont(kUnorderedLessThan, node);
+  FlagsContinuation cont(kFloatLessThan, node);
   VisitFloat64Compare(this, node, &cont);
 }
 
 
 void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
-  FlagsContinuation cont(kUnorderedLessThanOrEqual, node);
+  FlagsContinuation cont(kFloatLessThanOrEqual, node);
   VisitFloat64Compare(this, node, &cont);
 }
 
 
+void InstructionSelector::VisitFloat64ExtractLowWord32(Node* node) {
+  VisitRR(this, kArmVmovLowU32F64, node);
+}
+
+
+void InstructionSelector::VisitFloat64ExtractHighWord32(Node* node) {
+  VisitRR(this, kArmVmovHighU32F64, node);
+}
+
+
+void InstructionSelector::VisitFloat64InsertLowWord32(Node* node) {
+  ArmOperandGenerator g(this);
+  Node* left = node->InputAt(0);
+  Node* right = node->InputAt(1);
+  if (left->opcode() == IrOpcode::kFloat64InsertHighWord32 &&
+      CanCover(node, left)) {
+    left = left->InputAt(1);
+    Emit(kArmVmovF64U32U32, g.DefineAsRegister(node), g.UseRegister(right),
+         g.UseRegister(left));
+    return;
+  }
+  Emit(kArmVmovLowF64U32, g.DefineSameAsFirst(node), g.UseRegister(left),
+       g.UseRegister(right));
+}
+
+
+void InstructionSelector::VisitFloat64InsertHighWord32(Node* node) {
+  ArmOperandGenerator g(this);
+  Node* left = node->InputAt(0);
+  Node* right = node->InputAt(1);
+  if (left->opcode() == IrOpcode::kFloat64InsertLowWord32 &&
+      CanCover(node, left)) {
+    left = left->InputAt(1);
+    Emit(kArmVmovF64U32U32, g.DefineAsRegister(node), g.UseRegister(left),
+         g.UseRegister(right));
+    return;
+  }
+  Emit(kArmVmovHighF64U32, g.DefineSameAsFirst(node), g.UseRegister(left),
+       g.UseRegister(right));
+}
+
+
 // static
 MachineOperatorBuilder::Flags
 InstructionSelector::SupportedMachineOperatorFlags() {
   MachineOperatorBuilder::Flags flags =
       MachineOperatorBuilder::kInt32DivIsSafe |
       MachineOperatorBuilder::kUint32DivIsSafe;
-
   if (CpuFeatures::IsSupported(ARMv8)) {
-    flags |= MachineOperatorBuilder::kFloat64Floor |
-             MachineOperatorBuilder::kFloat64Ceil |
+    flags |= MachineOperatorBuilder::kFloat32RoundDown |
+             MachineOperatorBuilder::kFloat64RoundDown |
+             MachineOperatorBuilder::kFloat32RoundUp |
+             MachineOperatorBuilder::kFloat64RoundUp |
+             MachineOperatorBuilder::kFloat32RoundTruncate |
              MachineOperatorBuilder::kFloat64RoundTruncate |
-             MachineOperatorBuilder::kFloat64RoundTiesAway;
+             MachineOperatorBuilder::kFloat64RoundTiesAway |
+             MachineOperatorBuilder::kFloat32RoundTiesEven |
+             MachineOperatorBuilder::kFloat64RoundTiesEven;
   }
   return flags;
 }
diff --git a/src/compiler/arm/linkage-arm.cc b/src/compiler/arm/linkage-arm.cc
deleted file mode 100644
index 3fca76f..0000000
--- a/src/compiler/arm/linkage-arm.cc
+++ /dev/null
@@ -1,67 +0,0 @@
-// 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/v8.h"
-
-#include "src/assembler.h"
-#include "src/code-stubs.h"
-#include "src/compiler/linkage.h"
-#include "src/compiler/linkage-impl.h"
-#include "src/zone.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-struct ArmLinkageHelperTraits {
-  static Register ReturnValueReg() { return r0; }
-  static Register ReturnValue2Reg() { return r1; }
-  static Register JSCallFunctionReg() { return r1; }
-  static Register ContextReg() { return cp; }
-  static Register RuntimeCallFunctionReg() { return r1; }
-  static Register RuntimeCallArgCountReg() { return r0; }
-  static RegList CCalleeSaveRegisters() {
-    return r4.bit() | r5.bit() | r6.bit() | r7.bit() | r8.bit() | r9.bit() |
-           r10.bit();
-  }
-  static Register CRegisterParameter(int i) {
-    static Register register_parameters[] = {r0, r1, r2, r3};
-    return register_parameters[i];
-  }
-  static int CRegisterParametersLength() { return 4; }
-};
-
-
-typedef LinkageHelper<ArmLinkageHelperTraits> LH;
-
-CallDescriptor* Linkage::GetJSCallDescriptor(int parameter_count, Zone* zone,
-                                             CallDescriptor::Flags flags) {
-  return LH::GetJSCallDescriptor(zone, parameter_count, flags);
-}
-
-
-CallDescriptor* Linkage::GetRuntimeCallDescriptor(
-    Runtime::FunctionId function, int parameter_count,
-    Operator::Properties properties, Zone* zone) {
-  return LH::GetRuntimeCallDescriptor(zone, function, parameter_count,
-                                      properties);
-}
-
-
-CallDescriptor* Linkage::GetStubCallDescriptor(
-    const CallInterfaceDescriptor& descriptor, int stack_parameter_count,
-    CallDescriptor::Flags flags, Operator::Properties properties, Zone* zone) {
-  return LH::GetStubCallDescriptor(zone, descriptor, stack_parameter_count,
-                                   flags, properties);
-}
-
-
-CallDescriptor* Linkage::GetSimplifiedCDescriptor(Zone* zone,
-                                                  MachineSignature* sig) {
-  return LH::GetSimplifiedCDescriptor(zone, sig);
-}
-
-}  // namespace compiler
-}  // namespace internal
-}  // namespace v8
diff --git a/src/compiler/arm64/code-generator-arm64.cc b/src/compiler/arm64/code-generator-arm64.cc
index e025236..d356195 100644
--- a/src/compiler/arm64/code-generator-arm64.cc
+++ b/src/compiler/arm64/code-generator-arm64.cc
@@ -4,12 +4,13 @@
 
 #include "src/compiler/code-generator.h"
 
+#include "src/arm64/frames-arm64.h"
 #include "src/arm64/macro-assembler-arm64.h"
+#include "src/ast/scopes.h"
 #include "src/compiler/code-generator-impl.h"
 #include "src/compiler/gap-resolver.h"
 #include "src/compiler/node-matchers.h"
-#include "src/compiler/node-properties-inl.h"
-#include "src/scopes.h"
+#include "src/compiler/osr.h"
 
 namespace v8 {
 namespace internal {
@@ -19,38 +20,60 @@
 
 
 // Adds Arm64-specific methods to convert InstructionOperands.
-class Arm64OperandConverter FINAL : public InstructionOperandConverter {
+class Arm64OperandConverter final : public InstructionOperandConverter {
  public:
   Arm64OperandConverter(CodeGenerator* gen, Instruction* instr)
       : InstructionOperandConverter(gen, instr) {}
 
-  DoubleRegister InputFloat32Register(int index) {
+  DoubleRegister InputFloat32Register(size_t index) {
     return InputDoubleRegister(index).S();
   }
 
-  DoubleRegister InputFloat64Register(int index) {
+  DoubleRegister InputFloat64Register(size_t index) {
     return InputDoubleRegister(index);
   }
 
+  size_t OutputCount() { return instr_->OutputCount(); }
+
   DoubleRegister OutputFloat32Register() { return OutputDoubleRegister().S(); }
 
   DoubleRegister OutputFloat64Register() { return OutputDoubleRegister(); }
 
-  Register InputRegister32(int index) {
+  Register InputRegister32(size_t index) {
     return ToRegister(instr_->InputAt(index)).W();
   }
 
-  Register InputRegister64(int index) { return InputRegister(index); }
+  Register InputOrZeroRegister32(size_t index) {
+    DCHECK(instr_->InputAt(index)->IsRegister() ||
+           (instr_->InputAt(index)->IsImmediate() && (InputInt32(index) == 0)));
+    if (instr_->InputAt(index)->IsImmediate()) {
+      return wzr;
+    }
+    return InputRegister32(index);
+  }
 
-  Operand InputImmediate(int index) {
+  Register InputRegister64(size_t index) { return InputRegister(index); }
+
+  Register InputOrZeroRegister64(size_t index) {
+    DCHECK(instr_->InputAt(index)->IsRegister() ||
+           (instr_->InputAt(index)->IsImmediate() && (InputInt64(index) == 0)));
+    if (instr_->InputAt(index)->IsImmediate()) {
+      return xzr;
+    }
+    return InputRegister64(index);
+  }
+
+  Operand InputImmediate(size_t index) {
     return ToImmediate(instr_->InputAt(index));
   }
 
-  Operand InputOperand(int index) { return ToOperand(instr_->InputAt(index)); }
+  Operand InputOperand(size_t index) {
+    return ToOperand(instr_->InputAt(index));
+  }
 
-  Operand InputOperand64(int index) { return InputOperand(index); }
+  Operand InputOperand64(size_t index) { return InputOperand(index); }
 
-  Operand InputOperand32(int index) {
+  Operand InputOperand32(size_t index) {
     return ToOperand32(instr_->InputAt(index));
   }
 
@@ -58,7 +81,7 @@
 
   Register OutputRegister32() { return ToRegister(instr_->Output()).W(); }
 
-  Operand InputOperand2_32(int index) {
+  Operand InputOperand2_32(size_t index) {
     switch (AddressingModeField::decode(instr_->opcode())) {
       case kMode_None:
         return InputOperand32(index);
@@ -70,6 +93,14 @@
         return Operand(InputRegister32(index), ASR, InputInt5(index + 1));
       case kMode_Operand2_R_ROR_I:
         return Operand(InputRegister32(index), ROR, InputInt5(index + 1));
+      case kMode_Operand2_R_UXTB:
+        return Operand(InputRegister32(index), UXTB);
+      case kMode_Operand2_R_UXTH:
+        return Operand(InputRegister32(index), UXTH);
+      case kMode_Operand2_R_SXTB:
+        return Operand(InputRegister32(index), SXTB);
+      case kMode_Operand2_R_SXTH:
+        return Operand(InputRegister32(index), SXTH);
       case kMode_MRI:
       case kMode_MRR:
         break;
@@ -78,7 +109,7 @@
     return Operand(-1);
   }
 
-  Operand InputOperand2_64(int index) {
+  Operand InputOperand2_64(size_t index) {
     switch (AddressingModeField::decode(instr_->opcode())) {
       case kMode_None:
         return InputOperand64(index);
@@ -90,6 +121,14 @@
         return Operand(InputRegister64(index), ASR, InputInt6(index + 1));
       case kMode_Operand2_R_ROR_I:
         return Operand(InputRegister64(index), ROR, InputInt6(index + 1));
+      case kMode_Operand2_R_UXTB:
+        return Operand(InputRegister64(index), UXTB);
+      case kMode_Operand2_R_UXTH:
+        return Operand(InputRegister64(index), UXTH);
+      case kMode_Operand2_R_SXTB:
+        return Operand(InputRegister64(index), SXTB);
+      case kMode_Operand2_R_SXTH:
+        return Operand(InputRegister64(index), SXTH);
       case kMode_MRI:
       case kMode_MRR:
         break;
@@ -98,14 +137,18 @@
     return Operand(-1);
   }
 
-  MemOperand MemoryOperand(int* first_index) {
-    const int index = *first_index;
+  MemOperand MemoryOperand(size_t* first_index) {
+    const size_t index = *first_index;
     switch (AddressingModeField::decode(instr_->opcode())) {
       case kMode_None:
       case kMode_Operand2_R_LSL_I:
       case kMode_Operand2_R_LSR_I:
       case kMode_Operand2_R_ASR_I:
       case kMode_Operand2_R_ROR_I:
+      case kMode_Operand2_R_UXTB:
+      case kMode_Operand2_R_UXTH:
+      case kMode_Operand2_R_SXTB:
+      case kMode_Operand2_R_SXTH:
         break;
       case kMode_MRI:
         *first_index += 2;
@@ -118,7 +161,7 @@
     return MemOperand(no_reg);
   }
 
-  MemOperand MemoryOperand(int first_index = 0) {
+  MemOperand MemoryOperand(size_t first_index = 0) {
     return MemoryOperand(&first_index);
   }
 
@@ -162,12 +205,21 @@
   }
 
   MemOperand ToMemOperand(InstructionOperand* op, MacroAssembler* masm) const {
-    DCHECK(op != NULL);
-    DCHECK(!op->IsRegister());
-    DCHECK(!op->IsDoubleRegister());
+    DCHECK_NOT_NULL(op);
     DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot());
-    // The linkage computes where all spill slots are located.
-    FrameOffset offset = linkage()->GetFrameOffset(op->index(), frame(), 0);
+    FrameOffset offset = frame_access_state()->GetFrameOffset(
+        AllocatedOperand::cast(op)->index());
+    if (offset.from_frame_pointer()) {
+      int from_sp =
+          offset.offset() +
+          ((frame()->GetSpToFpSlotCount() + frame_access_state()->sp_delta()) *
+           kPointerSize);
+      // Convert FP-offsets to SP-offsets if it results in better code.
+      if (Assembler::IsImmLSUnscaled(from_sp) ||
+          Assembler::IsImmLSScaled(from_sp, LSDoubleWord)) {
+        offset = FrameOffset::FromStackPointer(from_sp);
+      }
+    }
     return MemOperand(offset.from_stack_pointer() ? masm->StackPointer() : fp,
                       offset.offset());
   }
@@ -176,12 +228,12 @@
 
 namespace {
 
-class OutOfLineLoadNaN32 FINAL : public OutOfLineCode {
+class OutOfLineLoadNaN32 final : public OutOfLineCode {
  public:
   OutOfLineLoadNaN32(CodeGenerator* gen, DoubleRegister result)
       : OutOfLineCode(gen), result_(result) {}
 
-  void Generate() FINAL {
+  void Generate() final {
     __ Fmov(result_, std::numeric_limits<float>::quiet_NaN());
   }
 
@@ -190,12 +242,12 @@
 };
 
 
-class OutOfLineLoadNaN64 FINAL : public OutOfLineCode {
+class OutOfLineLoadNaN64 final : public OutOfLineCode {
  public:
   OutOfLineLoadNaN64(CodeGenerator* gen, DoubleRegister result)
       : OutOfLineCode(gen), result_(result) {}
 
-  void Generate() FINAL {
+  void Generate() final {
     __ Fmov(result_, std::numeric_limits<double>::quiet_NaN());
   }
 
@@ -204,17 +256,110 @@
 };
 
 
-class OutOfLineLoadZero FINAL : public OutOfLineCode {
+class OutOfLineLoadZero final : public OutOfLineCode {
  public:
   OutOfLineLoadZero(CodeGenerator* gen, Register result)
       : OutOfLineCode(gen), result_(result) {}
 
-  void Generate() FINAL { __ Mov(result_, 0); }
+  void Generate() final { __ Mov(result_, 0); }
 
  private:
   Register const result_;
 };
 
+
+class OutOfLineRecordWrite final : public OutOfLineCode {
+ public:
+  OutOfLineRecordWrite(CodeGenerator* gen, Register object, Register index,
+                       Register value, Register scratch0, Register scratch1,
+                       RecordWriteMode mode)
+      : OutOfLineCode(gen),
+        object_(object),
+        index_(index),
+        value_(value),
+        scratch0_(scratch0),
+        scratch1_(scratch1),
+        mode_(mode) {}
+
+  void Generate() final {
+    if (mode_ > RecordWriteMode::kValueIsPointer) {
+      __ JumpIfSmi(value_, exit());
+    }
+    if (mode_ > RecordWriteMode::kValueIsMap) {
+      __ CheckPageFlagClear(value_, scratch0_,
+                            MemoryChunk::kPointersToHereAreInterestingMask,
+                            exit());
+    }
+    SaveFPRegsMode const save_fp_mode =
+        frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs;
+    // TODO(turbofan): Once we get frame elision working, we need to save
+    // and restore lr properly here if the frame was elided.
+    RecordWriteStub stub(isolate(), object_, scratch0_, scratch1_,
+                         EMIT_REMEMBERED_SET, save_fp_mode);
+    __ Add(scratch1_, object_, index_);
+    __ CallStub(&stub);
+  }
+
+ private:
+  Register const object_;
+  Register const index_;
+  Register const value_;
+  Register const scratch0_;
+  Register const scratch1_;
+  RecordWriteMode const mode_;
+};
+
+
+Condition FlagsConditionToCondition(FlagsCondition condition) {
+  switch (condition) {
+    case kEqual:
+      return eq;
+    case kNotEqual:
+      return ne;
+    case kSignedLessThan:
+      return lt;
+    case kSignedGreaterThanOrEqual:
+      return ge;
+    case kSignedLessThanOrEqual:
+      return le;
+    case kSignedGreaterThan:
+      return gt;
+    case kUnsignedLessThan:
+      return lo;
+    case kUnsignedGreaterThanOrEqual:
+      return hs;
+    case kUnsignedLessThanOrEqual:
+      return ls;
+    case kUnsignedGreaterThan:
+      return hi;
+    case kFloatLessThanOrUnordered:
+      return lt;
+    case kFloatGreaterThanOrEqual:
+      return ge;
+    case kFloatLessThanOrEqual:
+      return ls;
+    case kFloatGreaterThanOrUnordered:
+      return hi;
+    case kFloatLessThan:
+      return lo;
+    case kFloatGreaterThanOrEqualOrUnordered:
+      return hs;
+    case kFloatLessThanOrEqualOrUnordered:
+      return le;
+    case kFloatGreaterThan:
+      return gt;
+    case kOverflow:
+      return vs;
+    case kNotOverflow:
+      return vc;
+    case kUnorderedEqual:
+    case kUnorderedNotEqual:
+      break;
+  }
+  UNREACHABLE();
+  return nv;
+}
+
 }  // namespace
 
 
@@ -246,6 +391,20 @@
   } while (0)
 
 
+#define ASSEMBLE_CHECKED_LOAD_INTEGER_64(asm_instr)          \
+  do {                                                       \
+    auto result = i.OutputRegister();                        \
+    auto buffer = i.InputRegister(0);                        \
+    auto offset = i.InputRegister32(1);                      \
+    auto length = i.InputOperand32(2);                       \
+    __ Cmp(offset, length);                                  \
+    auto ool = new (zone()) OutOfLineLoadZero(this, result); \
+    __ B(hs, ool->entry());                                  \
+    __ asm_instr(result, MemOperand(buffer, offset, UXTW));  \
+    __ Bind(ool->exit());                                    \
+  } while (0)
+
+
 #define ASSEMBLE_CHECKED_STORE_FLOAT(width)          \
   do {                                               \
     auto buffer = i.InputRegister(0);                \
@@ -274,18 +433,57 @@
   } while (0)
 
 
-#define ASSEMBLE_SHIFT(asm_instr, width)                                       \
-  do {                                                                         \
-    if (instr->InputAt(1)->IsRegister()) {                                     \
-      __ asm_instr(i.OutputRegister##width(), i.InputRegister##width(0),       \
-                   i.InputRegister##width(1));                                 \
-    } else {                                                                   \
-      int64_t imm = i.InputOperand##width(1).immediate().value();              \
-      __ asm_instr(i.OutputRegister##width(), i.InputRegister##width(0), imm); \
-    }                                                                          \
+#define ASSEMBLE_CHECKED_STORE_INTEGER_64(asm_instr)       \
+  do {                                                     \
+    auto buffer = i.InputRegister(0);                      \
+    auto offset = i.InputRegister32(1);                    \
+    auto length = i.InputOperand32(2);                     \
+    auto value = i.InputRegister(3);                       \
+    __ Cmp(offset, length);                                \
+    Label done;                                            \
+    __ B(hs, &done);                                       \
+    __ asm_instr(value, MemOperand(buffer, offset, UXTW)); \
+    __ Bind(&done);                                        \
   } while (0)
 
 
+#define ASSEMBLE_SHIFT(asm_instr, width)                                    \
+  do {                                                                      \
+    if (instr->InputAt(1)->IsRegister()) {                                  \
+      __ asm_instr(i.OutputRegister##width(), i.InputRegister##width(0),    \
+                   i.InputRegister##width(1));                              \
+    } else {                                                                \
+      uint32_t imm =                                                        \
+          static_cast<uint32_t>(i.InputOperand##width(1).ImmediateValue()); \
+      __ asm_instr(i.OutputRegister##width(), i.InputRegister##width(0),    \
+                   imm % (width));                                          \
+    }                                                                       \
+  } while (0)
+
+
+void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) {
+  int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta);
+  if (sp_slot_delta > 0) {
+    __ Drop(sp_slot_delta);
+  }
+  frame_access_state()->SetFrameAccessToDefault();
+}
+
+
+void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) {
+  int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta);
+  if (sp_slot_delta < 0) {
+    __ Claim(-sp_slot_delta);
+    frame_access_state()->IncreaseSPDelta(-sp_slot_delta);
+  }
+  if (frame()->needs_frame()) {
+    __ Ldr(lr, MemOperand(fp, StandardFrameConstants::kCallerPCOffset));
+    __ Ldr(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
+  }
+  frame_access_state()->SetFrameAccessToSP();
+}
+
+
 // Assembles an instruction after register allocation, producing machine code.
 void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
   Arm64OperandConverter i(this, instr);
@@ -301,7 +499,22 @@
         __ Add(target, target, Code::kHeaderSize - kHeapObjectTag);
         __ Call(target);
       }
-      AddSafepointAndDeopt(instr);
+      frame_access_state()->ClearSPDelta();
+      RecordCallPosition(instr);
+      break;
+    }
+    case kArchTailCallCodeObject: {
+      int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
+      AssembleDeconstructActivationRecord(stack_param_delta);
+      if (instr->InputAt(0)->IsImmediate()) {
+        __ Jump(Handle<Code>::cast(i.InputHeapObject(0)),
+                RelocInfo::CODE_TARGET);
+      } else {
+        Register target = i.InputRegister(0);
+        __ Add(target, target, Code::kHeaderSize - kHeapObjectTag);
+        __ Jump(target);
+      }
+      frame_access_state()->ClearSPDelta();
       break;
     }
     case kArchCallJSFunction: {
@@ -317,59 +530,165 @@
       }
       __ Ldr(x10, FieldMemOperand(func, JSFunction::kCodeEntryOffset));
       __ Call(x10);
-      AddSafepointAndDeopt(instr);
+      frame_access_state()->ClearSPDelta();
+      RecordCallPosition(instr);
+      break;
+    }
+    case kArchTailCallJSFunction: {
+      Register func = i.InputRegister(0);
+      if (FLAG_debug_code) {
+        // Check the function's context matches the context argument.
+        UseScratchRegisterScope scope(masm());
+        Register temp = scope.AcquireX();
+        __ Ldr(temp, FieldMemOperand(func, JSFunction::kContextOffset));
+        __ cmp(cp, temp);
+        __ Assert(eq, kWrongFunctionContext);
+      }
+      int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
+      AssembleDeconstructActivationRecord(stack_param_delta);
+      __ Ldr(x10, FieldMemOperand(func, JSFunction::kCodeEntryOffset));
+      __ Jump(x10);
+      frame_access_state()->ClearSPDelta();
+      break;
+    }
+    case kArchLazyBailout: {
+      EnsureSpaceForLazyDeopt();
+      RecordCallPosition(instr);
+      break;
+    }
+    case kArchPrepareCallCFunction:
+      // We don't need kArchPrepareCallCFunction on arm64 as the instruction
+      // selector already perform a Claim to reserve space on the stack and
+      // guarantee correct alignment of stack pointer.
+      UNREACHABLE();
+      break;
+    case kArchPrepareTailCall:
+      AssemblePrepareTailCall(i.InputInt32(instr->InputCount() - 1));
+      break;
+    case kArchCallCFunction: {
+      int const num_parameters = MiscField::decode(instr->opcode());
+      if (instr->InputAt(0)->IsImmediate()) {
+        ExternalReference ref = i.InputExternalReference(0);
+        __ CallCFunction(ref, num_parameters, 0);
+      } else {
+        Register func = i.InputRegister(0);
+        __ CallCFunction(func, num_parameters, 0);
+      }
+      // CallCFunction only supports register arguments so we never need to call
+      // frame()->ClearOutgoingParameterSlots() here.
+      DCHECK(frame_access_state()->sp_delta() == 0);
       break;
     }
     case kArchJmp:
       AssembleArchJump(i.InputRpo(0));
       break;
+    case kArchTableSwitch:
+      AssembleArchTableSwitch(instr);
+      break;
+    case kArchLookupSwitch:
+      AssembleArchLookupSwitch(instr);
+      break;
     case kArchNop:
+    case kArchThrowTerminator:
       // don't emit code for nops.
       break;
+    case kArchDeoptimize: {
+      int deopt_state_id =
+          BuildTranslation(instr, -1, 0, OutputFrameStateCombine::Ignore());
+      Deoptimizer::BailoutType bailout_type =
+          Deoptimizer::BailoutType(MiscField::decode(instr->opcode()));
+      AssembleDeoptimizerCall(deopt_state_id, bailout_type);
+      break;
+    }
     case kArchRet:
       AssembleReturn();
       break;
     case kArchStackPointer:
       __ mov(i.OutputRegister(), masm()->StackPointer());
       break;
+    case kArchFramePointer:
+      __ mov(i.OutputRegister(), fp);
+      break;
     case kArchTruncateDoubleToI:
       __ TruncateDoubleToI(i.OutputRegister(), i.InputDoubleRegister(0));
       break;
-    case kArm64Float64Ceil:
-      __ Frintp(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
+    case kArchStoreWithWriteBarrier: {
+      RecordWriteMode mode =
+          static_cast<RecordWriteMode>(MiscField::decode(instr->opcode()));
+      Register object = i.InputRegister(0);
+      Register index = i.InputRegister(1);
+      Register value = i.InputRegister(2);
+      Register scratch0 = i.TempRegister(0);
+      Register scratch1 = i.TempRegister(1);
+      auto ool = new (zone()) OutOfLineRecordWrite(this, object, index, value,
+                                                   scratch0, scratch1, mode);
+      __ Str(value, MemOperand(object, index));
+      __ CheckPageFlagSet(object, scratch0,
+                          MemoryChunk::kPointersFromHereAreInterestingMask,
+                          ool->entry());
+      __ Bind(ool->exit());
       break;
-    case kArm64Float64Floor:
+    }
+    case kArm64Float32RoundDown:
+      __ Frintm(i.OutputFloat32Register(), i.InputFloat32Register(0));
+      break;
+    case kArm64Float64RoundDown:
       __ Frintm(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
       break;
-    case kArm64Float64RoundTruncate:
-      __ Frintz(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
+    case kArm64Float32RoundUp:
+      __ Frintp(i.OutputFloat32Register(), i.InputFloat32Register(0));
+      break;
+    case kArm64Float64RoundUp:
+      __ Frintp(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
       break;
     case kArm64Float64RoundTiesAway:
       __ Frinta(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
       break;
+    case kArm64Float32RoundTruncate:
+      __ Frintz(i.OutputFloat32Register(), i.InputFloat32Register(0));
+      break;
+    case kArm64Float64RoundTruncate:
+      __ Frintz(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
+      break;
+    case kArm64Float32RoundTiesEven:
+      __ Frintn(i.OutputFloat32Register(), i.InputFloat32Register(0));
+      break;
+    case kArm64Float64RoundTiesEven:
+      __ Frintn(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
+      break;
     case kArm64Add:
-      __ Add(i.OutputRegister(), i.InputRegister(0), i.InputOperand2_64(1));
+      if (FlagsModeField::decode(opcode) != kFlags_none) {
+        __ Adds(i.OutputRegister(), i.InputOrZeroRegister64(0),
+                i.InputOperand2_64(1));
+      } else {
+      __ Add(i.OutputRegister(), i.InputOrZeroRegister64(0),
+             i.InputOperand2_64(1));
+      }
       break;
     case kArm64Add32:
       if (FlagsModeField::decode(opcode) != kFlags_none) {
-        __ Adds(i.OutputRegister32(), i.InputRegister32(0),
+        __ Adds(i.OutputRegister32(), i.InputOrZeroRegister32(0),
                 i.InputOperand2_32(1));
       } else {
-        __ Add(i.OutputRegister32(), i.InputRegister32(0),
+        __ Add(i.OutputRegister32(), i.InputOrZeroRegister32(0),
                i.InputOperand2_32(1));
       }
       break;
     case kArm64And:
-      __ And(i.OutputRegister(), i.InputRegister(0), i.InputOperand2_64(1));
+      __ And(i.OutputRegister(), i.InputOrZeroRegister64(0),
+             i.InputOperand2_64(1));
       break;
     case kArm64And32:
-      __ And(i.OutputRegister32(), i.InputRegister32(0), i.InputOperand2_32(1));
+      __ And(i.OutputRegister32(), i.InputOrZeroRegister32(0),
+             i.InputOperand2_32(1));
       break;
     case kArm64Bic:
-      __ Bic(i.OutputRegister(), i.InputRegister(0), i.InputOperand2_64(1));
+      __ Bic(i.OutputRegister(), i.InputOrZeroRegister64(0),
+             i.InputOperand2_64(1));
       break;
     case kArm64Bic32:
-      __ Bic(i.OutputRegister32(), i.InputRegister32(0), i.InputOperand2_32(1));
+      __ Bic(i.OutputRegister32(), i.InputOrZeroRegister32(0),
+             i.InputOperand2_32(1));
       break;
     case kArm64Mul:
       __ Mul(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
@@ -447,52 +766,59 @@
               i.InputRegister32(0));
       break;
     }
-    // TODO(dcarney): use mvn instr??
     case kArm64Not:
-      __ Orn(i.OutputRegister(), xzr, i.InputOperand(0));
+      __ Mvn(i.OutputRegister(), i.InputOperand(0));
       break;
     case kArm64Not32:
-      __ Orn(i.OutputRegister32(), wzr, i.InputOperand32(0));
-      break;
-    case kArm64Neg:
-      __ Neg(i.OutputRegister(), i.InputOperand(0));
-      break;
-    case kArm64Neg32:
-      __ Neg(i.OutputRegister32(), i.InputOperand32(0));
+      __ Mvn(i.OutputRegister32(), i.InputOperand32(0));
       break;
     case kArm64Or:
-      __ Orr(i.OutputRegister(), i.InputRegister(0), i.InputOperand2_64(1));
+      __ Orr(i.OutputRegister(), i.InputOrZeroRegister64(0),
+             i.InputOperand2_64(1));
       break;
     case kArm64Or32:
-      __ Orr(i.OutputRegister32(), i.InputRegister32(0), i.InputOperand2_32(1));
+      __ Orr(i.OutputRegister32(), i.InputOrZeroRegister32(0),
+             i.InputOperand2_32(1));
       break;
     case kArm64Orn:
-      __ Orn(i.OutputRegister(), i.InputRegister(0), i.InputOperand2_64(1));
+      __ Orn(i.OutputRegister(), i.InputOrZeroRegister64(0),
+             i.InputOperand2_64(1));
       break;
     case kArm64Orn32:
-      __ Orn(i.OutputRegister32(), i.InputRegister32(0), i.InputOperand2_32(1));
+      __ Orn(i.OutputRegister32(), i.InputOrZeroRegister32(0),
+             i.InputOperand2_32(1));
       break;
     case kArm64Eor:
-      __ Eor(i.OutputRegister(), i.InputRegister(0), i.InputOperand2_64(1));
+      __ Eor(i.OutputRegister(), i.InputOrZeroRegister64(0),
+             i.InputOperand2_64(1));
       break;
     case kArm64Eor32:
-      __ Eor(i.OutputRegister32(), i.InputRegister32(0), i.InputOperand2_32(1));
+      __ Eor(i.OutputRegister32(), i.InputOrZeroRegister32(0),
+             i.InputOperand2_32(1));
       break;
     case kArm64Eon:
-      __ Eon(i.OutputRegister(), i.InputRegister(0), i.InputOperand2_64(1));
+      __ Eon(i.OutputRegister(), i.InputOrZeroRegister64(0),
+             i.InputOperand2_64(1));
       break;
     case kArm64Eon32:
-      __ Eon(i.OutputRegister32(), i.InputRegister32(0), i.InputOperand2_32(1));
+      __ Eon(i.OutputRegister32(), i.InputOrZeroRegister32(0),
+             i.InputOperand2_32(1));
       break;
     case kArm64Sub:
-      __ Sub(i.OutputRegister(), i.InputRegister(0), i.InputOperand2_64(1));
+      if (FlagsModeField::decode(opcode) != kFlags_none) {
+        __ Subs(i.OutputRegister(), i.InputOrZeroRegister64(0),
+                i.InputOperand2_64(1));
+      } else {
+      __ Sub(i.OutputRegister(), i.InputOrZeroRegister64(0),
+             i.InputOperand2_64(1));
+      }
       break;
     case kArm64Sub32:
       if (FlagsModeField::decode(opcode) != kFlags_none) {
-        __ Subs(i.OutputRegister32(), i.InputRegister32(0),
+        __ Subs(i.OutputRegister32(), i.InputOrZeroRegister32(0),
                 i.InputOperand2_32(1));
       } else {
-        __ Sub(i.OutputRegister32(), i.InputRegister32(0),
+        __ Sub(i.OutputRegister32(), i.InputOrZeroRegister32(0),
                i.InputOperand2_32(1));
       }
       break;
@@ -532,13 +858,25 @@
     case kArm64Sxtw:
       __ Sxtw(i.OutputRegister(), i.InputRegister32(0));
       break;
+    case kArm64Sbfx32:
+      __ Sbfx(i.OutputRegister32(), i.InputRegister32(0), i.InputInt5(1),
+              i.InputInt5(2));
+      break;
     case kArm64Ubfx:
-      __ Ubfx(i.OutputRegister(), i.InputRegister(0), i.InputInt8(1),
-              i.InputInt8(2));
+      __ Ubfx(i.OutputRegister(), i.InputRegister(0), i.InputInt6(1),
+              i.InputInt6(2));
       break;
     case kArm64Ubfx32:
-      __ Ubfx(i.OutputRegister32(), i.InputRegister32(0), i.InputInt8(1),
-              i.InputInt8(2));
+      __ Ubfx(i.OutputRegister32(), i.InputRegister32(0), i.InputInt5(1),
+              i.InputInt5(2));
+      break;
+    case kArm64Ubfiz32:
+      __ Ubfiz(i.OutputRegister32(), i.InputRegister32(0), i.InputInt5(1),
+               i.InputInt5(2));
+      break;
+    case kArm64Bfi:
+      __ Bfi(i.OutputRegister(), i.InputRegister(1), i.InputInt6(2),
+             i.InputInt6(3));
       break;
     case kArm64TestAndBranch32:
     case kArm64TestAndBranch:
@@ -547,39 +885,48 @@
     case kArm64CompareAndBranch32:
       // Pseudo instruction turned into cbz/cbnz in AssembleArchBranch.
       break;
-    case kArm64Claim: {
-      int words = MiscField::decode(instr->opcode());
-      __ Claim(words);
+    case kArm64ClaimForCallArguments: {
+      __ Claim(i.InputInt32(0));
+      frame_access_state()->IncreaseSPDelta(i.InputInt32(0));
       break;
     }
     case kArm64Poke: {
-      int slot = MiscField::decode(instr->opcode());
-      Operand operand(slot * kPointerSize);
-      __ Poke(i.InputRegister(0), operand);
-      break;
-    }
-    case kArm64PokePairZero: {
-      // TODO(dcarney): test slot offset and register order.
-      int slot = MiscField::decode(instr->opcode()) - 1;
-      __ PokePair(i.InputRegister(0), xzr, slot * kPointerSize);
+      Operand operand(i.InputInt32(1) * kPointerSize);
+      if (instr->InputAt(0)->IsDoubleRegister()) {
+        __ Poke(i.InputFloat64Register(0), operand);
+      } else {
+        __ Poke(i.InputRegister(0), operand);
+      }
       break;
     }
     case kArm64PokePair: {
-      int slot = MiscField::decode(instr->opcode()) - 1;
-      __ PokePair(i.InputRegister(1), i.InputRegister(0), slot * kPointerSize);
+      int slot = i.InputInt32(2) - 1;
+      if (instr->InputAt(0)->IsDoubleRegister()) {
+        __ PokePair(i.InputFloat64Register(1), i.InputFloat64Register(0),
+                    slot * kPointerSize);
+      } else {
+        __ PokePair(i.InputRegister(1), i.InputRegister(0),
+                    slot * kPointerSize);
+      }
       break;
     }
+    case kArm64Clz:
+      __ Clz(i.OutputRegister64(), i.InputRegister64(0));
+      break;
+    case kArm64Clz32:
+      __ Clz(i.OutputRegister32(), i.InputRegister32(0));
+      break;
     case kArm64Cmp:
-      __ Cmp(i.InputRegister(0), i.InputOperand(1));
+      __ Cmp(i.InputOrZeroRegister64(0), i.InputOperand(1));
       break;
     case kArm64Cmp32:
-      __ Cmp(i.InputRegister32(0), i.InputOperand32(1));
+      __ Cmp(i.InputOrZeroRegister32(0), i.InputOperand2_32(1));
       break;
     case kArm64Cmn:
-      __ Cmn(i.InputRegister(0), i.InputOperand(1));
+      __ Cmn(i.InputOrZeroRegister64(0), i.InputOperand(1));
       break;
     case kArm64Cmn32:
-      __ Cmn(i.InputRegister32(0), i.InputOperand32(1));
+      __ Cmn(i.InputOrZeroRegister32(0), i.InputOperand2_32(1));
       break;
     case kArm64Tst:
       __ Tst(i.InputRegister(0), i.InputOperand(1));
@@ -587,8 +934,59 @@
     case kArm64Tst32:
       __ Tst(i.InputRegister32(0), i.InputOperand32(1));
       break;
+    case kArm64Float32Cmp:
+      if (instr->InputAt(1)->IsDoubleRegister()) {
+        __ Fcmp(i.InputFloat32Register(0), i.InputFloat32Register(1));
+      } else {
+        DCHECK(instr->InputAt(1)->IsImmediate());
+        // 0.0 is the only immediate supported by fcmp instructions.
+        DCHECK(i.InputFloat32(1) == 0.0f);
+        __ Fcmp(i.InputFloat32Register(0), i.InputFloat32(1));
+      }
+      break;
+    case kArm64Float32Add:
+      __ Fadd(i.OutputFloat32Register(), i.InputFloat32Register(0),
+              i.InputFloat32Register(1));
+      break;
+    case kArm64Float32Sub:
+      __ Fsub(i.OutputFloat32Register(), i.InputFloat32Register(0),
+              i.InputFloat32Register(1));
+      break;
+    case kArm64Float32Mul:
+      __ Fmul(i.OutputFloat32Register(), i.InputFloat32Register(0),
+              i.InputFloat32Register(1));
+      break;
+    case kArm64Float32Div:
+      __ Fdiv(i.OutputFloat32Register(), i.InputFloat32Register(0),
+              i.InputFloat32Register(1));
+      break;
+    case kArm64Float32Max:
+      // (b < a) ? a : b
+      __ Fcmp(i.InputFloat32Register(1), i.InputFloat32Register(0));
+      __ Fcsel(i.OutputFloat32Register(), i.InputFloat32Register(0),
+               i.InputFloat32Register(1), lo);
+      break;
+    case kArm64Float32Min:
+      // (a < b) ? a : b
+      __ Fcmp(i.InputFloat32Register(0), i.InputFloat32Register(1));
+      __ Fcsel(i.OutputFloat32Register(), i.InputFloat32Register(0),
+               i.InputFloat32Register(1), lo);
+      break;
+    case kArm64Float32Abs:
+      __ Fabs(i.OutputFloat32Register(), i.InputFloat32Register(0));
+      break;
+    case kArm64Float32Sqrt:
+      __ Fsqrt(i.OutputFloat32Register(), i.InputFloat32Register(0));
+      break;
     case kArm64Float64Cmp:
-      __ Fcmp(i.InputDoubleRegister(0), i.InputDoubleRegister(1));
+      if (instr->InputAt(1)->IsDoubleRegister()) {
+        __ Fcmp(i.InputDoubleRegister(0), i.InputDoubleRegister(1));
+      } else {
+        DCHECK(instr->InputAt(1)->IsImmediate());
+        // 0.0 is the only immediate supported by fcmp instructions.
+        DCHECK(i.InputDouble(1) == 0.0);
+        __ Fcmp(i.InputDoubleRegister(0), i.InputDouble(1));
+      }
       break;
     case kArm64Float64Add:
       __ Fadd(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
@@ -617,6 +1015,24 @@
                        0, 2);
       break;
     }
+    case kArm64Float64Max:
+      // (b < a) ? a : b
+      __ Fcmp(i.InputDoubleRegister(1), i.InputDoubleRegister(0));
+      __ Fcsel(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+               i.InputDoubleRegister(1), lo);
+      break;
+    case kArm64Float64Min:
+      // (a < b) ? a : b
+      __ Fcmp(i.InputDoubleRegister(0), i.InputDoubleRegister(1));
+      __ Fcsel(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+               i.InputDoubleRegister(1), lo);
+      break;
+    case kArm64Float64Abs:
+      __ Fabs(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
+      break;
+    case kArm64Float64Neg:
+      __ Fneg(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
+      break;
     case kArm64Float64Sqrt:
       __ Fsqrt(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
       break;
@@ -632,12 +1048,101 @@
     case kArm64Float64ToUint32:
       __ Fcvtzu(i.OutputRegister32(), i.InputDoubleRegister(0));
       break;
+    case kArm64Float32ToInt64:
+      __ Fcvtzs(i.OutputRegister64(), i.InputFloat32Register(0));
+      if (i.OutputCount() > 1) {
+        __ Mov(i.OutputRegister(1), 1);
+        Label done;
+        __ Cmp(i.OutputRegister(0), 1);
+        __ Ccmp(i.OutputRegister(0), -1, VFlag, vc);
+        __ Fccmp(i.InputFloat32Register(0), i.InputFloat32Register(0), VFlag,
+                 vc);
+        __ B(vc, &done);
+        __ Fcmp(i.InputFloat32Register(0), static_cast<float>(INT64_MIN));
+        __ Cset(i.OutputRegister(1), eq);
+        __ Bind(&done);
+      }
+      break;
+    case kArm64Float64ToInt64:
+      __ Fcvtzs(i.OutputRegister(0), i.InputDoubleRegister(0));
+      if (i.OutputCount() > 1) {
+        __ Mov(i.OutputRegister(1), 1);
+        Label done;
+        __ Cmp(i.OutputRegister(0), 1);
+        __ Ccmp(i.OutputRegister(0), -1, VFlag, vc);
+        __ Fccmp(i.InputDoubleRegister(0), i.InputDoubleRegister(0), VFlag, vc);
+        __ B(vc, &done);
+        __ Fcmp(i.InputDoubleRegister(0), static_cast<double>(INT64_MIN));
+        __ Cset(i.OutputRegister(1), eq);
+        __ Bind(&done);
+      }
+      break;
+    case kArm64Float32ToUint64:
+      __ Fcvtzu(i.OutputRegister64(), i.InputFloat32Register(0));
+      if (i.OutputCount() > 1) {
+        __ Fcmp(i.InputFloat32Register(0), -1.0);
+        __ Ccmp(i.OutputRegister(0), -1, ZFlag, gt);
+        __ Cset(i.OutputRegister(1), ne);
+      }
+      break;
+    case kArm64Float64ToUint64:
+      __ Fcvtzu(i.OutputRegister64(), i.InputDoubleRegister(0));
+      if (i.OutputCount() > 1) {
+        __ Fcmp(i.InputDoubleRegister(0), -1.0);
+        __ Ccmp(i.OutputRegister(0), -1, ZFlag, gt);
+        __ Cset(i.OutputRegister(1), ne);
+      }
+      break;
     case kArm64Int32ToFloat64:
       __ Scvtf(i.OutputDoubleRegister(), i.InputRegister32(0));
       break;
+    case kArm64Int64ToFloat32:
+      __ Scvtf(i.OutputDoubleRegister().S(), i.InputRegister64(0));
+      break;
+    case kArm64Int64ToFloat64:
+      __ Scvtf(i.OutputDoubleRegister(), i.InputRegister64(0));
+      break;
     case kArm64Uint32ToFloat64:
       __ Ucvtf(i.OutputDoubleRegister(), i.InputRegister32(0));
       break;
+    case kArm64Uint64ToFloat32:
+      __ Ucvtf(i.OutputDoubleRegister().S(), i.InputRegister64(0));
+      break;
+    case kArm64Uint64ToFloat64:
+      __ Ucvtf(i.OutputDoubleRegister(), i.InputRegister64(0));
+      break;
+    case kArm64Float64ExtractLowWord32:
+      __ Fmov(i.OutputRegister32(), i.InputFloat32Register(0));
+      break;
+    case kArm64Float64ExtractHighWord32:
+      // TODO(arm64): This should use MOV (to general) when NEON is supported.
+      __ Fmov(i.OutputRegister(), i.InputFloat64Register(0));
+      __ Lsr(i.OutputRegister(), i.OutputRegister(), 32);
+      break;
+    case kArm64Float64InsertLowWord32: {
+      // TODO(arm64): This should use MOV (from general) when NEON is supported.
+      UseScratchRegisterScope scope(masm());
+      Register tmp = scope.AcquireX();
+      __ Fmov(tmp, i.InputFloat64Register(0));
+      __ Bfi(tmp, i.InputRegister(1), 0, 32);
+      __ Fmov(i.OutputFloat64Register(), tmp);
+      break;
+    }
+    case kArm64Float64InsertHighWord32: {
+      // TODO(arm64): This should use MOV (from general) when NEON is supported.
+      UseScratchRegisterScope scope(masm());
+      Register tmp = scope.AcquireX();
+      __ Fmov(tmp.W(), i.InputFloat32Register(0));
+      __ Bfi(tmp, i.InputRegister(1), 32, 32);
+      __ Fmov(i.OutputFloat64Register(), tmp);
+      break;
+    }
+    case kArm64Float64MoveU64:
+      __ Fmov(i.OutputFloat64Register(), i.InputRegister(0));
+      break;
+    case kArm64U64MoveFloat64:
+      __ Fmov(i.OutputRegister(), i.InputDoubleRegister(0));
+      break;
     case kArm64Ldrb:
       __ Ldrb(i.OutputRegister(), i.MemoryOperand());
       break;
@@ -680,29 +1185,6 @@
     case kArm64StrD:
       __ Str(i.InputDoubleRegister(2), i.MemoryOperand());
       break;
-    case kArm64StoreWriteBarrier: {
-      Register object = i.InputRegister(0);
-      Register index = i.InputRegister(1);
-      Register value = i.InputRegister(2);
-      __ Add(index, object, Operand(index, SXTW));
-      __ Str(value, MemOperand(index));
-      SaveFPRegsMode mode =
-          frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs;
-      // TODO(dcarney): we shouldn't test write barriers from c calls.
-      LinkRegisterStatus lr_status = kLRHasNotBeenSaved;
-      UseScratchRegisterScope scope(masm());
-      Register temp = no_reg;
-      if (csp.is(masm()->StackPointer())) {
-        temp = scope.AcquireX();
-        lr_status = kLRHasBeenSaved;
-        __ Push(lr, temp);  // Need to push a pair
-      }
-      __ RecordWrite(object, index, value, lr_status, mode);
-      if (csp.is(masm()->StackPointer())) {
-        __ Pop(temp, lr);
-      }
-      break;
-    }
     case kCheckedLoadInt8:
       ASSEMBLE_CHECKED_LOAD_INTEGER(Ldrsb);
       break;
@@ -718,6 +1200,9 @@
     case kCheckedLoadWord32:
       ASSEMBLE_CHECKED_LOAD_INTEGER(Ldr);
       break;
+    case kCheckedLoadWord64:
+      ASSEMBLE_CHECKED_LOAD_INTEGER_64(Ldr);
+      break;
     case kCheckedLoadFloat32:
       ASSEMBLE_CHECKED_LOAD_FLOAT(32);
       break;
@@ -733,6 +1218,9 @@
     case kCheckedStoreWord32:
       ASSEMBLE_CHECKED_STORE_INTEGER(Str);
       break;
+    case kCheckedStoreWord64:
+      ASSEMBLE_CHECKED_STORE_INTEGER_64(Str);
+      break;
     case kCheckedStoreFloat32:
       ASSEMBLE_CHECKED_STORE_FLOAT(32);
       break;
@@ -740,7 +1228,7 @@
       ASSEMBLE_CHECKED_STORE_FLOAT(64);
       break;
   }
-}
+}  // NOLINT(readability/fn_size)
 
 
 // Assemble branches after this instruction.
@@ -785,71 +1273,14 @@
         UNREACHABLE();
     }
   } else {
-    switch (condition) {
-      case kUnorderedEqual:
-        // The "eq" condition will not catch the unordered case.
-        // The jump/fall through to false label will be used if the comparison
-        // was unordered.
-      case kEqual:
-        __ B(eq, tlabel);
-        break;
-      case kUnorderedNotEqual:
-        // Unordered or not equal can be tested with "ne" condtion.
-        // See ARMv8 manual C1.2.3 - Condition Code.
-      case kNotEqual:
-        __ B(ne, tlabel);
-        break;
-      case kSignedLessThan:
-        __ B(lt, tlabel);
-        break;
-      case kSignedGreaterThanOrEqual:
-        __ B(ge, tlabel);
-        break;
-      case kSignedLessThanOrEqual:
-        __ B(le, tlabel);
-        break;
-      case kSignedGreaterThan:
-        __ B(gt, tlabel);
-        break;
-      case kUnorderedLessThan:
-        // The "lo" condition will not catch the unordered case.
-        // The jump/fall through to false label will be used if the comparison
-        // was unordered.
-      case kUnsignedLessThan:
-        __ B(lo, tlabel);
-        break;
-      case kUnorderedGreaterThanOrEqual:
-        // Unordered, greater than or equal can be tested with "hs" condtion.
-        // See ARMv8 manual C1.2.3 - Condition Code.
-      case kUnsignedGreaterThanOrEqual:
-        __ B(hs, tlabel);
-        break;
-      case kUnorderedLessThanOrEqual:
-        // The "ls" condition will not catch the unordered case.
-        // The jump/fall through to false label will be used if the comparison
-        // was unordered.
-      case kUnsignedLessThanOrEqual:
-        __ B(ls, tlabel);
-        break;
-      case kUnorderedGreaterThan:
-        // Unordered or greater than can be tested with "hi" condtion.
-        // See ARMv8 manual C1.2.3 - Condition Code.
-      case kUnsignedGreaterThan:
-        __ B(hi, tlabel);
-        break;
-      case kOverflow:
-        __ B(vs, tlabel);
-        break;
-      case kNotOverflow:
-        __ B(vc, tlabel);
-        break;
-    }
+    Condition cc = FlagsConditionToCondition(condition);
+    __ B(cc, tlabel);
   }
   if (!branch->fallthru) __ B(flabel);  // no fallthru to flabel.
 }
 
 
-void CodeGenerator::AssembleArchJump(BasicBlock::RpoNumber target) {
+void CodeGenerator::AssembleArchJump(RpoNumber target) {
   if (!IsNextInAssemblyOrder(target)) __ B(GetLabel(target));
 }
 
@@ -858,165 +1289,178 @@
 void CodeGenerator::AssembleArchBoolean(Instruction* instr,
                                         FlagsCondition condition) {
   Arm64OperandConverter i(this, instr);
-  Label done;
 
   // Materialize a full 64-bit 1 or 0 value. The result register is always the
   // last output of the instruction.
-  Label check;
-  DCHECK_NE(0, instr->OutputCount());
+  DCHECK_NE(0u, instr->OutputCount());
   Register reg = i.OutputRegister(instr->OutputCount() - 1);
-  Condition cc = nv;
-  switch (condition) {
-    case kUnorderedEqual:
-      __ B(vc, &check);
-      __ Mov(reg, 0);
-      __ B(&done);
-    // Fall through.
-    case kEqual:
-      cc = eq;
-      break;
-    case kUnorderedNotEqual:
-      __ B(vc, &check);
-      __ Mov(reg, 1);
-      __ B(&done);
-    // Fall through.
-    case kNotEqual:
-      cc = ne;
-      break;
-    case kSignedLessThan:
-      cc = lt;
-      break;
-    case kSignedGreaterThanOrEqual:
-      cc = ge;
-      break;
-    case kSignedLessThanOrEqual:
-      cc = le;
-      break;
-    case kSignedGreaterThan:
-      cc = gt;
-      break;
-    case kUnorderedLessThan:
-      __ B(vc, &check);
-      __ Mov(reg, 0);
-      __ B(&done);
-    // Fall through.
-    case kUnsignedLessThan:
-      cc = lo;
-      break;
-    case kUnorderedGreaterThanOrEqual:
-      __ B(vc, &check);
-      __ Mov(reg, 1);
-      __ B(&done);
-    // Fall through.
-    case kUnsignedGreaterThanOrEqual:
-      cc = hs;
-      break;
-    case kUnorderedLessThanOrEqual:
-      __ B(vc, &check);
-      __ Mov(reg, 0);
-      __ B(&done);
-    // Fall through.
-    case kUnsignedLessThanOrEqual:
-      cc = ls;
-      break;
-    case kUnorderedGreaterThan:
-      __ B(vc, &check);
-      __ Mov(reg, 1);
-      __ B(&done);
-    // Fall through.
-    case kUnsignedGreaterThan:
-      cc = hi;
-      break;
-    case kOverflow:
-      cc = vs;
-      break;
-    case kNotOverflow:
-      cc = vc;
-      break;
-  }
-  __ Bind(&check);
+  Condition cc = FlagsConditionToCondition(condition);
   __ Cset(reg, cc);
-  __ Bind(&done);
 }
 
 
-void CodeGenerator::AssembleDeoptimizerCall(int deoptimization_id) {
+void CodeGenerator::AssembleArchLookupSwitch(Instruction* instr) {
+  Arm64OperandConverter i(this, instr);
+  Register input = i.InputRegister32(0);
+  for (size_t index = 2; index < instr->InputCount(); index += 2) {
+    __ Cmp(input, i.InputInt32(index + 0));
+    __ B(eq, GetLabel(i.InputRpo(index + 1)));
+  }
+  AssembleArchJump(i.InputRpo(1));
+}
+
+
+void CodeGenerator::AssembleArchTableSwitch(Instruction* instr) {
+  Arm64OperandConverter i(this, instr);
+  UseScratchRegisterScope scope(masm());
+  Register input = i.InputRegister32(0);
+  Register temp = scope.AcquireX();
+  size_t const case_count = instr->InputCount() - 2;
+  Label table;
+  __ Cmp(input, case_count);
+  __ B(hs, GetLabel(i.InputRpo(1)));
+  __ Adr(temp, &table);
+  __ Add(temp, temp, Operand(input, UXTW, 2));
+  __ Br(temp);
+  __ StartBlockPools();
+  __ Bind(&table);
+  for (size_t index = 0; index < case_count; ++index) {
+    __ B(GetLabel(i.InputRpo(index + 2)));
+  }
+  __ EndBlockPools();
+}
+
+
+void CodeGenerator::AssembleDeoptimizerCall(
+    int deoptimization_id, Deoptimizer::BailoutType bailout_type) {
   Address deopt_entry = Deoptimizer::GetDeoptimizationEntry(
-      isolate(), deoptimization_id, Deoptimizer::LAZY);
+      isolate(), deoptimization_id, bailout_type);
   __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY);
 }
 
 
-// TODO(dcarney): increase stack slots in frame once before first use.
-static int AlignedStackSlots(int stack_slots) {
-  if (stack_slots & 1) stack_slots++;
-  return stack_slots;
-}
-
-
 void CodeGenerator::AssemblePrologue() {
   CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
-  if (descriptor->kind() == CallDescriptor::kCallAddress) {
+  if (descriptor->IsCFunctionCall()) {
     __ SetStackPointer(csp);
     __ Push(lr, fp);
     __ Mov(fp, csp);
-    // TODO(dcarney): correct callee saved registers.
-    __ PushCalleeSavedRegisters();
-    frame()->SetRegisterSaveAreaSize(20 * kPointerSize);
   } else if (descriptor->IsJSFunctionCall()) {
-    CompilationInfo* info = this->info();
     __ SetStackPointer(jssp);
-    __ Prologue(info->IsCodePreAgingActive());
-    frame()->SetRegisterSaveAreaSize(
-        StandardFrameConstants::kFixedFrameSizeFromFp);
-  } else {
-    __ SetStackPointer(jssp);
-    __ StubPrologue();
-    frame()->SetRegisterSaveAreaSize(
-        StandardFrameConstants::kFixedFrameSizeFromFp);
-  }
-  int stack_slots = frame()->GetSpillSlotCount();
-  if (stack_slots > 0) {
-    Register sp = __ StackPointer();
-    if (!sp.Is(csp)) {
-      __ Sub(sp, sp, stack_slots * kPointerSize);
+    __ Prologue(this->info()->GeneratePreagedPrologue());
+  } else if (frame()->needs_frame()) {
+    if (descriptor->UseNativeStack()) {
+      __ SetStackPointer(csp);
+    } else {
+      __ SetStackPointer(jssp);
     }
-    __ Sub(csp, csp, AlignedStackSlots(stack_slots) * kPointerSize);
+    __ StubPrologue();
+  } else {
+    if (descriptor->UseNativeStack()) {
+      __ SetStackPointer(csp);
+    } else {
+      __ SetStackPointer(jssp);
+    }
+    frame()->SetElidedFrameSizeInSlots(0);
+  }
+  frame_access_state()->SetFrameAccessToDefault();
+
+  int stack_shrink_slots = frame()->GetSpillSlotCount();
+  if (info()->is_osr()) {
+    // TurboFan OSR-compiled functions cannot be entered directly.
+    __ Abort(kShouldNotDirectlyEnterOsrFunction);
+
+    // Unoptimized code jumps directly to this entrypoint while the unoptimized
+    // frame is still on the stack. Optimized code uses OSR values directly from
+    // the unoptimized frame. Thus, all that needs to be done is to allocate the
+    // remaining stack slots.
+    if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --");
+    osr_pc_offset_ = __ pc_offset();
+    // TODO(titzer): cannot address target function == local #-1
+    __ ldr(x1, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
+    stack_shrink_slots -= OsrHelper(info()).UnoptimizedFrameSlots();
+  }
+
+  // If frame()->needs_frame() is false, then
+  // frame()->AlignSavedCalleeRegisterSlots() is guaranteed to return 0.
+  if (csp.Is(masm()->StackPointer()) && frame()->needs_frame()) {
+    // The system stack pointer requires 16-byte alignment at function call
+    // boundaries.
+
+    stack_shrink_slots += frame()->AlignSavedCalleeRegisterSlots();
+  }
+  __ Claim(stack_shrink_slots);
+
+  // Save FP registers.
+  CPURegList saves_fp = CPURegList(CPURegister::kFPRegister, kDRegSizeInBits,
+                                   descriptor->CalleeSavedFPRegisters());
+  int saved_count = saves_fp.Count();
+  if (saved_count != 0) {
+    DCHECK(saves_fp.list() == CPURegList::GetCalleeSavedFP().list());
+    __ PushCPURegList(saves_fp);
+    frame()->AllocateSavedCalleeRegisterSlots(saved_count *
+                                              (kDoubleSize / kPointerSize));
+  }
+  // Save registers.
+  // TODO(palfia): TF save list is not in sync with
+  // CPURegList::GetCalleeSaved(): x30 is missing.
+  // DCHECK(saves.list() == CPURegList::GetCalleeSaved().list());
+  CPURegList saves = CPURegList(CPURegister::kRegister, kXRegSizeInBits,
+                                descriptor->CalleeSavedRegisters());
+  saved_count = saves.Count();
+  if (saved_count != 0) {
+    __ PushCPURegList(saves);
+    frame()->AllocateSavedCalleeRegisterSlots(saved_count);
   }
 }
 
 
 void CodeGenerator::AssembleReturn() {
   CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
-  if (descriptor->kind() == CallDescriptor::kCallAddress) {
-    if (frame()->GetRegisterSaveAreaSize() > 0) {
-      // Remove this frame's spill slots first.
-      int stack_slots = frame()->GetSpillSlotCount();
-      if (stack_slots > 0) {
-        __ Add(csp, csp, AlignedStackSlots(stack_slots) * kPointerSize);
-      }
-      // Restore registers.
-      // TODO(dcarney): correct callee saved registers.
-      __ PopCalleeSavedRegisters();
-    }
+
+  // Restore registers.
+  CPURegList saves = CPURegList(CPURegister::kRegister, kXRegSizeInBits,
+                                descriptor->CalleeSavedRegisters());
+  if (saves.Count() != 0) {
+    __ PopCPURegList(saves);
+  }
+
+  // Restore fp registers.
+  CPURegList saves_fp = CPURegList(CPURegister::kFPRegister, kDRegSizeInBits,
+                                   descriptor->CalleeSavedFPRegisters());
+  if (saves_fp.Count() != 0) {
+    __ PopCPURegList(saves_fp);
+  }
+
+  int pop_count = static_cast<int>(descriptor->StackParameterCount());
+  if (descriptor->IsCFunctionCall()) {
     __ Mov(csp, fp);
     __ Pop(fp, lr);
-    __ Ret();
-  } else {
-    __ Mov(jssp, fp);
-    __ Pop(fp, lr);
-    int pop_count = descriptor->IsJSFunctionCall()
-                        ? static_cast<int>(descriptor->JSParameterCount())
-                        : 0;
-    __ Drop(pop_count);
-    __ Ret();
+  } else if (frame()->needs_frame()) {
+    // Canonicalize JSFunction return sites for now.
+    if (return_label_.is_bound()) {
+      __ B(&return_label_);
+      return;
+    } else {
+      __ Bind(&return_label_);
+      if (descriptor->UseNativeStack()) {
+        __ Mov(csp, fp);
+      } else {
+        __ Mov(jssp, fp);
+      }
+      __ Pop(fp, lr);
+    }
+  } else if (descriptor->UseNativeStack()) {
+    pop_count += (pop_count & 1);
   }
+  __ Drop(pop_count);
+  __ Ret();
 }
 
 
 void CodeGenerator::AssembleMove(InstructionOperand* source,
                                  InstructionOperand* destination) {
-  Arm64OperandConverter g(this, NULL);
+  Arm64OperandConverter g(this, nullptr);
   // Dispatch on the source and destination operand kinds.  Not all
   // combinations are possible.
   if (source->IsRegister()) {
@@ -1045,7 +1489,16 @@
       Register dst = destination->IsRegister() ? g.ToRegister(destination)
                                                : scope.AcquireX();
       if (src.type() == Constant::kHeapObject) {
-        __ LoadObject(dst, src.ToHeapObject());
+        Handle<HeapObject> src_object = src.ToHeapObject();
+        Heap::RootListIndex index;
+        int offset;
+        if (IsMaterializableFromFrame(src_object, &offset)) {
+          __ Ldr(dst, MemOperand(fp, offset));
+        } else if (IsMaterializableFromRoot(src_object, &index)) {
+          __ LoadRoot(dst, index);
+        } else {
+          __ LoadObject(dst, src_object);
+        }
       } else {
         __ Mov(dst, g.ToImmediate(source));
       }
@@ -1104,7 +1557,7 @@
 
 void CodeGenerator::AssembleSwap(InstructionOperand* source,
                                  InstructionOperand* destination) {
-  Arm64OperandConverter g(this, NULL);
+  Arm64OperandConverter g(this, nullptr);
   // Dispatch on the source and destination operand kinds.  Not all
   // combinations are possible.
   if (source->IsRegister()) {
@@ -1157,29 +1610,36 @@
 }
 
 
+void CodeGenerator::AssembleJumpTable(Label** targets, size_t target_count) {
+  // On 64-bit ARM we emit the jump tables inline.
+  UNREACHABLE();
+}
+
+
 void CodeGenerator::AddNopForSmiCodeInlining() { __ movz(xzr, 0); }
 
 
 void CodeGenerator::EnsureSpaceForLazyDeopt() {
+  if (!info()->ShouldEnsureSpaceForLazyDeopt()) {
+    return;
+  }
+
   int space_needed = Deoptimizer::patch_size();
-  if (!info()->IsStub()) {
-    // Ensure that we have enough space after the previous lazy-bailout
-    // instruction for patching the code here.
-    intptr_t current_pc = masm()->pc_offset();
+  // Ensure that we have enough space after the previous lazy-bailout
+  // instruction for patching the code here.
+  intptr_t current_pc = masm()->pc_offset();
 
-    if (current_pc < (last_lazy_deopt_pc_ + space_needed)) {
-      intptr_t padding_size = last_lazy_deopt_pc_ + space_needed - current_pc;
-      DCHECK((padding_size % kInstructionSize) == 0);
-      InstructionAccurateScope instruction_accurate(
-          masm(), padding_size / kInstructionSize);
+  if (current_pc < (last_lazy_deopt_pc_ + space_needed)) {
+    intptr_t padding_size = last_lazy_deopt_pc_ + space_needed - current_pc;
+    DCHECK((padding_size % kInstructionSize) == 0);
+    InstructionAccurateScope instruction_accurate(
+        masm(), padding_size / kInstructionSize);
 
-      while (padding_size > 0) {
-        __ nop();
-        padding_size -= kInstructionSize;
-      }
+    while (padding_size > 0) {
+      __ nop();
+      padding_size -= kInstructionSize;
     }
   }
-  MarkLazyDeoptSite();
 }
 
 #undef __
diff --git a/src/compiler/arm64/instruction-codes-arm64.h b/src/compiler/arm64/instruction-codes-arm64.h
index 863451f..ef33348 100644
--- a/src/compiler/arm64/instruction-codes-arm64.h
+++ b/src/compiler/arm64/instruction-codes-arm64.h
@@ -18,6 +18,8 @@
   V(Arm64And32)                    \
   V(Arm64Bic)                      \
   V(Arm64Bic32)                    \
+  V(Arm64Clz)                      \
+  V(Arm64Clz32)                    \
   V(Arm64Cmp)                      \
   V(Arm64Cmp32)                    \
   V(Arm64Cmn)                      \
@@ -54,8 +56,6 @@
   V(Arm64Umod32)                   \
   V(Arm64Not)                      \
   V(Arm64Not32)                    \
-  V(Arm64Neg)                      \
-  V(Arm64Neg32)                    \
   V(Arm64Lsl)                      \
   V(Arm64Lsl32)                    \
   V(Arm64Lsr)                      \
@@ -68,32 +68,66 @@
   V(Arm64Sxtb32)                   \
   V(Arm64Sxth32)                   \
   V(Arm64Sxtw)                     \
+  V(Arm64Sbfx32)                   \
   V(Arm64Ubfx)                     \
   V(Arm64Ubfx32)                   \
+  V(Arm64Ubfiz32)                  \
+  V(Arm64Bfi)                      \
   V(Arm64TestAndBranch32)          \
   V(Arm64TestAndBranch)            \
   V(Arm64CompareAndBranch32)       \
-  V(Arm64Claim)                    \
+  V(Arm64ClaimForCallArguments)    \
   V(Arm64Poke)                     \
-  V(Arm64PokePairZero)             \
   V(Arm64PokePair)                 \
+  V(Arm64Float32Cmp)               \
+  V(Arm64Float32Add)               \
+  V(Arm64Float32Sub)               \
+  V(Arm64Float32Mul)               \
+  V(Arm64Float32Div)               \
+  V(Arm64Float32Max)               \
+  V(Arm64Float32Min)               \
+  V(Arm64Float32Abs)               \
+  V(Arm64Float32Sqrt)              \
+  V(Arm64Float32RoundDown)         \
   V(Arm64Float64Cmp)               \
   V(Arm64Float64Add)               \
   V(Arm64Float64Sub)               \
   V(Arm64Float64Mul)               \
   V(Arm64Float64Div)               \
   V(Arm64Float64Mod)               \
+  V(Arm64Float64Max)               \
+  V(Arm64Float64Min)               \
+  V(Arm64Float64Abs)               \
+  V(Arm64Float64Neg)               \
   V(Arm64Float64Sqrt)              \
-  V(Arm64Float64Floor)             \
-  V(Arm64Float64Ceil)              \
-  V(Arm64Float64RoundTruncate)     \
+  V(Arm64Float64RoundDown)         \
+  V(Arm64Float32RoundUp)           \
+  V(Arm64Float64RoundUp)           \
   V(Arm64Float64RoundTiesAway)     \
+  V(Arm64Float32RoundTruncate)     \
+  V(Arm64Float64RoundTruncate)     \
+  V(Arm64Float32RoundTiesEven)     \
+  V(Arm64Float64RoundTiesEven)     \
   V(Arm64Float32ToFloat64)         \
   V(Arm64Float64ToFloat32)         \
   V(Arm64Float64ToInt32)           \
   V(Arm64Float64ToUint32)          \
+  V(Arm64Float32ToInt64)           \
+  V(Arm64Float64ToInt64)           \
+  V(Arm64Float32ToUint64)          \
+  V(Arm64Float64ToUint64)          \
   V(Arm64Int32ToFloat64)           \
+  V(Arm64Int64ToFloat32)           \
+  V(Arm64Int64ToFloat64)           \
   V(Arm64Uint32ToFloat64)          \
+  V(Arm64Uint64ToFloat32)          \
+  V(Arm64Uint64ToFloat64)          \
+  V(Arm64Float64ExtractLowWord32)  \
+  V(Arm64Float64ExtractHighWord32) \
+  V(Arm64Float64InsertLowWord32)   \
+  V(Arm64Float64InsertHighWord32)  \
+  V(Arm64Float64MoveU64)           \
+  V(Arm64U64MoveFloat64)           \
   V(Arm64LdrS)                     \
   V(Arm64StrS)                     \
   V(Arm64LdrD)                     \
@@ -107,8 +141,7 @@
   V(Arm64LdrW)                     \
   V(Arm64StrW)                     \
   V(Arm64Ldr)                      \
-  V(Arm64Str)                      \
-  V(Arm64StoreWriteBarrier)
+  V(Arm64Str)
 
 
 // Addressing modes represent the "shape" of inputs to an instruction.
@@ -124,16 +157,20 @@
 // I = immediate (handle, external, int32)
 // MRI = [register + immediate]
 // MRR = [register + register]
-#define TARGET_ADDRESSING_MODE_LIST(V)  \
-  V(MRI)              /* [%r0 + K] */   \
-  V(MRR)              /* [%r0 + %r1] */ \
-  V(Operand2_R_LSL_I) /* %r0 LSL K */   \
-  V(Operand2_R_LSR_I) /* %r0 LSR K */   \
-  V(Operand2_R_ASR_I) /* %r0 ASR K */   \
-  V(Operand2_R_ROR_I) /* %r0 ROR K */
+#define TARGET_ADDRESSING_MODE_LIST(V)                          \
+  V(MRI)              /* [%r0 + K] */                           \
+  V(MRR)              /* [%r0 + %r1] */                         \
+  V(Operand2_R_LSL_I) /* %r0 LSL K */                           \
+  V(Operand2_R_LSR_I) /* %r0 LSR K */                           \
+  V(Operand2_R_ASR_I) /* %r0 ASR K */                           \
+  V(Operand2_R_ROR_I) /* %r0 ROR K */                           \
+  V(Operand2_R_UXTB)  /* %r0 UXTB (unsigned extend byte) */     \
+  V(Operand2_R_UXTH)  /* %r0 UXTH (unsigned extend halfword) */ \
+  V(Operand2_R_SXTB)  /* %r0 SXTB (signed extend byte) */       \
+  V(Operand2_R_SXTH)  /* %r0 SXTH (signed extend halfword) */
 
-}  // namespace internal
 }  // namespace compiler
+}  // namespace internal
 }  // namespace v8
 
 #endif  // V8_COMPILER_ARM64_INSTRUCTION_CODES_ARM64_H_
diff --git a/src/compiler/arm64/instruction-scheduler-arm64.cc b/src/compiler/arm64/instruction-scheduler-arm64.cc
new file mode 100644
index 0000000..eb358dd
--- /dev/null
+++ b/src/compiler/arm64/instruction-scheduler-arm64.cc
@@ -0,0 +1,224 @@
+// 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/instruction-scheduler.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+bool InstructionScheduler::SchedulerSupported() { return true; }
+
+
+int InstructionScheduler::GetTargetInstructionFlags(
+    const Instruction* instr) const {
+  switch (instr->arch_opcode()) {
+    case kArm64Add:
+    case kArm64Add32:
+    case kArm64And:
+    case kArm64And32:
+    case kArm64Bic:
+    case kArm64Bic32:
+    case kArm64Clz:
+    case kArm64Clz32:
+    case kArm64Cmp:
+    case kArm64Cmp32:
+    case kArm64Cmn:
+    case kArm64Cmn32:
+    case kArm64Tst:
+    case kArm64Tst32:
+    case kArm64Or:
+    case kArm64Or32:
+    case kArm64Orn:
+    case kArm64Orn32:
+    case kArm64Eor:
+    case kArm64Eor32:
+    case kArm64Eon:
+    case kArm64Eon32:
+    case kArm64Sub:
+    case kArm64Sub32:
+    case kArm64Mul:
+    case kArm64Mul32:
+    case kArm64Smull:
+    case kArm64Umull:
+    case kArm64Madd:
+    case kArm64Madd32:
+    case kArm64Msub:
+    case kArm64Msub32:
+    case kArm64Mneg:
+    case kArm64Mneg32:
+    case kArm64Idiv:
+    case kArm64Idiv32:
+    case kArm64Udiv:
+    case kArm64Udiv32:
+    case kArm64Imod:
+    case kArm64Imod32:
+    case kArm64Umod:
+    case kArm64Umod32:
+    case kArm64Not:
+    case kArm64Not32:
+    case kArm64Lsl:
+    case kArm64Lsl32:
+    case kArm64Lsr:
+    case kArm64Lsr32:
+    case kArm64Asr:
+    case kArm64Asr32:
+    case kArm64Ror:
+    case kArm64Ror32:
+    case kArm64Mov32:
+    case kArm64Sxtb32:
+    case kArm64Sxth32:
+    case kArm64Sxtw:
+    case kArm64Sbfx32:
+    case kArm64Ubfx:
+    case kArm64Ubfx32:
+    case kArm64Ubfiz32:
+    case kArm64Bfi:
+    case kArm64Float32Cmp:
+    case kArm64Float32Add:
+    case kArm64Float32Sub:
+    case kArm64Float32Mul:
+    case kArm64Float32Div:
+    case kArm64Float32Max:
+    case kArm64Float32Min:
+    case kArm64Float32Abs:
+    case kArm64Float32Sqrt:
+    case kArm64Float32RoundDown:
+    case kArm64Float64Cmp:
+    case kArm64Float64Add:
+    case kArm64Float64Sub:
+    case kArm64Float64Mul:
+    case kArm64Float64Div:
+    case kArm64Float64Mod:
+    case kArm64Float64Max:
+    case kArm64Float64Min:
+    case kArm64Float64Abs:
+    case kArm64Float64Neg:
+    case kArm64Float64Sqrt:
+    case kArm64Float64RoundDown:
+    case kArm64Float64RoundTiesAway:
+    case kArm64Float64RoundTruncate:
+    case kArm64Float64RoundTiesEven:
+    case kArm64Float64RoundUp:
+    case kArm64Float32RoundTiesEven:
+    case kArm64Float32RoundTruncate:
+    case kArm64Float32RoundUp:
+    case kArm64Float32ToFloat64:
+    case kArm64Float64ToFloat32:
+    case kArm64Float64ToInt32:
+    case kArm64Float64ToUint32:
+    case kArm64Float32ToInt64:
+    case kArm64Float64ToInt64:
+    case kArm64Float32ToUint64:
+    case kArm64Float64ToUint64:
+    case kArm64Int32ToFloat64:
+    case kArm64Int64ToFloat32:
+    case kArm64Int64ToFloat64:
+    case kArm64Uint32ToFloat64:
+    case kArm64Uint64ToFloat32:
+    case kArm64Uint64ToFloat64:
+    case kArm64Float64ExtractLowWord32:
+    case kArm64Float64ExtractHighWord32:
+    case kArm64Float64InsertLowWord32:
+    case kArm64Float64InsertHighWord32:
+    case kArm64Float64MoveU64:
+    case kArm64U64MoveFloat64:
+      return kNoOpcodeFlags;
+
+    case kArm64TestAndBranch32:
+    case kArm64TestAndBranch:
+    case kArm64CompareAndBranch32:
+      return kIsBlockTerminator;
+
+    case kArm64LdrS:
+    case kArm64LdrD:
+    case kArm64Ldrb:
+    case kArm64Ldrsb:
+    case kArm64Ldrh:
+    case kArm64Ldrsh:
+    case kArm64LdrW:
+    case kArm64Ldr:
+      return kIsLoadOperation;
+
+    case kArm64ClaimForCallArguments:
+    case kArm64Poke:
+    case kArm64PokePair:
+    case kArm64StrS:
+    case kArm64StrD:
+    case kArm64Strb:
+    case kArm64Strh:
+    case kArm64StrW:
+    case kArm64Str:
+      return kHasSideEffect;
+
+#define CASE(Name) case k##Name:
+    COMMON_ARCH_OPCODE_LIST(CASE)
+#undef CASE
+      // Already covered in architecture independent code.
+      UNREACHABLE();
+  }
+
+  UNREACHABLE();
+  return kNoOpcodeFlags;
+}
+
+
+int InstructionScheduler::GetInstructionLatency(const Instruction* instr) {
+  // Basic latency modeling for arm64 instructions. They have been determined
+  // in an empirical way.
+  switch (instr->arch_opcode()) {
+    case kArm64Float32ToFloat64:
+    case kArm64Float64ToFloat32:
+    case kArm64Float64ToInt32:
+    case kArm64Float64ToUint32:
+    case kArm64Int32ToFloat64:
+    case kArm64Uint32ToFloat64:
+      return 3;
+
+    case kArm64Float64Add:
+    case kArm64Float64Sub:
+      return 2;
+
+    case kArm64Float64Mul:
+      return 3;
+
+    case kArm64Float64Div:
+      return 6;
+
+    case kArm64Lsl:
+    case kArm64Lsl32:
+    case kArm64Lsr:
+    case kArm64Lsr32:
+    case kArm64Asr:
+    case kArm64Asr32:
+    case kArm64Ror:
+    case kArm64Ror32:
+      return 3;
+
+    case kCheckedLoadInt8:
+    case kCheckedLoadUint8:
+    case kCheckedLoadInt16:
+    case kCheckedLoadUint16:
+    case kCheckedLoadWord32:
+    case kCheckedLoadWord64:
+    case kCheckedLoadFloat32:
+    case kCheckedLoadFloat64:
+    case kArm64LdrS:
+    case kArm64LdrD:
+    case kArm64Ldrb:
+    case kArm64Ldrsb:
+    case kArm64Ldrh:
+    case kArm64Ldrsh:
+    case kArm64LdrW:
+    case kArm64Ldr:
+      return 5;
+
+    default:
+      return 1;
+  }
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/arm64/instruction-selector-arm64.cc b/src/compiler/arm64/instruction-selector-arm64.cc
index 72661af..1ec5ab4 100644
--- a/src/compiler/arm64/instruction-selector-arm64.cc
+++ b/src/compiler/arm64/instruction-selector-arm64.cc
@@ -4,6 +4,7 @@
 
 #include "src/compiler/instruction-selector-impl.h"
 #include "src/compiler/node-matchers.h"
+#include "src/compiler/node-properties.h"
 
 namespace v8 {
 namespace internal {
@@ -24,27 +25,52 @@
 
 
 // Adds Arm64-specific methods for generating operands.
-class Arm64OperandGenerator FINAL : public OperandGenerator {
+class Arm64OperandGenerator final : public OperandGenerator {
  public:
   explicit Arm64OperandGenerator(InstructionSelector* selector)
       : OperandGenerator(selector) {}
 
-  InstructionOperand* UseOperand(Node* node, ImmediateMode mode) {
+  InstructionOperand UseOperand(Node* node, ImmediateMode mode) {
     if (CanBeImmediate(node, mode)) {
       return UseImmediate(node);
     }
     return UseRegister(node);
   }
 
+  // Use the zero register if the node has the immediate value zero, otherwise
+  // assign a register.
+  InstructionOperand UseRegisterOrImmediateZero(Node* node) {
+    if (IsIntegerConstant(node) && (GetIntegerConstantValue(node) == 0)) {
+      return UseImmediate(node);
+    }
+    return UseRegister(node);
+  }
+
+  // Use the provided node if it has the required value, or create a
+  // TempImmediate otherwise.
+  InstructionOperand UseImmediateOrTemp(Node* node, int32_t value) {
+    if (GetIntegerConstantValue(node) == value) {
+      return UseImmediate(node);
+    }
+    return TempImmediate(value);
+  }
+
+  bool IsIntegerConstant(Node* node) {
+    return (node->opcode() == IrOpcode::kInt32Constant) ||
+           (node->opcode() == IrOpcode::kInt64Constant);
+  }
+
+  int64_t GetIntegerConstantValue(Node* node) {
+    if (node->opcode() == IrOpcode::kInt32Constant) {
+      return OpParameter<int32_t>(node);
+    }
+    DCHECK(node->opcode() == IrOpcode::kInt64Constant);
+    return OpParameter<int64_t>(node);
+  }
+
   bool CanBeImmediate(Node* node, ImmediateMode mode) {
-    int64_t value;
-    if (node->opcode() == IrOpcode::kInt32Constant)
-      value = OpParameter<int32_t>(node);
-    else if (node->opcode() == IrOpcode::kInt64Constant)
-      value = OpParameter<int64_t>(node);
-    else
-      return false;
-    return CanBeImmediate(value, mode);
+    return IsIntegerConstant(node) &&
+           CanBeImmediate(GetIntegerConstantValue(node), mode);
   }
 
   bool CanBeImmediate(int64_t value, ImmediateMode mode) {
@@ -60,10 +86,6 @@
                                        &ignored, &ignored, &ignored);
       case kArithmeticImm:
         return Assembler::IsImmAddSub(value);
-      case kShift32Imm:
-        return 0 <= value && value < 32;
-      case kShift64Imm:
-        return 0 <= value && value < 64;
       case kLoadStoreImm8:
         return IsLoadStoreImmediate(value, LSByte);
       case kLoadStoreImm16:
@@ -74,6 +96,12 @@
         return IsLoadStoreImmediate(value, LSDoubleWord);
       case kNoImmediate:
         return false;
+      case kShift32Imm:  // Fall through.
+      case kShift64Imm:
+        // Shift operations only observe the bottom 5 or 6 bits of the value.
+        // All possible shifts can be encoded by discarding bits which have no
+        // effect.
+        return true;
     }
     return false;
   }
@@ -86,16 +114,16 @@
 };
 
 
-static void VisitRRFloat64(InstructionSelector* selector, ArchOpcode opcode,
-                           Node* node) {
+namespace {
+
+void VisitRR(InstructionSelector* selector, ArchOpcode opcode, Node* node) {
   Arm64OperandGenerator g(selector);
   selector->Emit(opcode, g.DefineAsRegister(node),
                  g.UseRegister(node->InputAt(0)));
 }
 
 
-static void VisitRRR(InstructionSelector* selector, ArchOpcode opcode,
-                     Node* node) {
+void VisitRRR(InstructionSelector* selector, ArchOpcode opcode, Node* node) {
   Arm64OperandGenerator g(selector);
   selector->Emit(opcode, g.DefineAsRegister(node),
                  g.UseRegister(node->InputAt(0)),
@@ -103,17 +131,8 @@
 }
 
 
-static void VisitRRRFloat64(InstructionSelector* selector, ArchOpcode opcode,
-                            Node* node) {
-  Arm64OperandGenerator g(selector);
-  selector->Emit(opcode, g.DefineAsRegister(node),
-                 g.UseRegister(node->InputAt(0)),
-                 g.UseRegister(node->InputAt(1)));
-}
-
-
-static void VisitRRO(InstructionSelector* selector, ArchOpcode opcode,
-                     Node* node, ImmediateMode operand_mode) {
+void VisitRRO(InstructionSelector* selector, ArchOpcode opcode, Node* node,
+              ImmediateMode operand_mode) {
   Arm64OperandGenerator g(selector);
   selector->Emit(opcode, g.DefineAsRegister(node),
                  g.UseRegister(node->InputAt(0)),
@@ -121,87 +140,135 @@
 }
 
 
-template <typename Matcher>
-static bool TryMatchShift(InstructionSelector* selector, Node* node,
-                          InstructionCode* opcode, IrOpcode::Value shift_opcode,
-                          ImmediateMode imm_mode,
-                          AddressingMode addressing_mode) {
-  if (node->opcode() != shift_opcode) return false;
+bool TryMatchAnyShift(InstructionSelector* selector, Node* node,
+                      Node* input_node, InstructionCode* opcode, bool try_ror) {
   Arm64OperandGenerator g(selector);
-  Matcher m(node);
-  if (g.CanBeImmediate(m.right().node(), imm_mode)) {
-    *opcode |= AddressingModeField::encode(addressing_mode);
-    return true;
+
+  if (!selector->CanCover(node, input_node)) return false;
+  if (input_node->InputCount() != 2) return false;
+  if (!g.IsIntegerConstant(input_node->InputAt(1))) return false;
+
+  switch (input_node->opcode()) {
+    case IrOpcode::kWord32Shl:
+    case IrOpcode::kWord64Shl:
+      *opcode |= AddressingModeField::encode(kMode_Operand2_R_LSL_I);
+      return true;
+    case IrOpcode::kWord32Shr:
+    case IrOpcode::kWord64Shr:
+      *opcode |= AddressingModeField::encode(kMode_Operand2_R_LSR_I);
+      return true;
+    case IrOpcode::kWord32Sar:
+    case IrOpcode::kWord64Sar:
+      *opcode |= AddressingModeField::encode(kMode_Operand2_R_ASR_I);
+      return true;
+    case IrOpcode::kWord32Ror:
+    case IrOpcode::kWord64Ror:
+      if (try_ror) {
+        *opcode |= AddressingModeField::encode(kMode_Operand2_R_ROR_I);
+        return true;
+      }
+      return false;
+    default:
+      return false;
+  }
+}
+
+
+bool TryMatchAnyExtend(Arm64OperandGenerator* g, InstructionSelector* selector,
+                       Node* node, Node* left_node, Node* right_node,
+                       InstructionOperand* left_op,
+                       InstructionOperand* right_op, InstructionCode* opcode) {
+  if (!selector->CanCover(node, right_node)) return false;
+
+  NodeMatcher nm(right_node);
+
+  if (nm.IsWord32And()) {
+    Int32BinopMatcher mright(right_node);
+    if (mright.right().Is(0xff) || mright.right().Is(0xffff)) {
+      int32_t mask = mright.right().Value();
+      *left_op = g->UseRegister(left_node);
+      *right_op = g->UseRegister(mright.left().node());
+      *opcode |= AddressingModeField::encode(
+          (mask == 0xff) ? kMode_Operand2_R_UXTB : kMode_Operand2_R_UXTH);
+      return true;
+    }
+  } else if (nm.IsWord32Sar()) {
+    Int32BinopMatcher mright(right_node);
+    if (selector->CanCover(mright.node(), mright.left().node()) &&
+        mright.left().IsWord32Shl()) {
+      Int32BinopMatcher mleft_of_right(mright.left().node());
+      if ((mright.right().Is(16) && mleft_of_right.right().Is(16)) ||
+          (mright.right().Is(24) && mleft_of_right.right().Is(24))) {
+        int32_t shift = mright.right().Value();
+        *left_op = g->UseRegister(left_node);
+        *right_op = g->UseRegister(mleft_of_right.left().node());
+        *opcode |= AddressingModeField::encode(
+            (shift == 24) ? kMode_Operand2_R_SXTB : kMode_Operand2_R_SXTH);
+        return true;
+      }
+    }
   }
   return false;
 }
 
 
-static bool TryMatchAnyShift(InstructionSelector* selector, Node* node,
-                             InstructionCode* opcode, bool try_ror) {
-  return TryMatchShift<Int32BinopMatcher>(selector, node, opcode,
-                                          IrOpcode::kWord32Shl, kShift32Imm,
-                                          kMode_Operand2_R_LSL_I) ||
-         TryMatchShift<Int32BinopMatcher>(selector, node, opcode,
-                                          IrOpcode::kWord32Shr, kShift32Imm,
-                                          kMode_Operand2_R_LSR_I) ||
-         TryMatchShift<Int32BinopMatcher>(selector, node, opcode,
-                                          IrOpcode::kWord32Sar, kShift32Imm,
-                                          kMode_Operand2_R_ASR_I) ||
-         (try_ror && TryMatchShift<Int32BinopMatcher>(
-                         selector, node, opcode, IrOpcode::kWord32Ror,
-                         kShift32Imm, kMode_Operand2_R_ROR_I)) ||
-         TryMatchShift<Int64BinopMatcher>(selector, node, opcode,
-                                          IrOpcode::kWord64Shl, kShift64Imm,
-                                          kMode_Operand2_R_LSL_I) ||
-         TryMatchShift<Int64BinopMatcher>(selector, node, opcode,
-                                          IrOpcode::kWord64Shr, kShift64Imm,
-                                          kMode_Operand2_R_LSR_I) ||
-         TryMatchShift<Int64BinopMatcher>(selector, node, opcode,
-                                          IrOpcode::kWord64Sar, kShift64Imm,
-                                          kMode_Operand2_R_ASR_I) ||
-         (try_ror && TryMatchShift<Int64BinopMatcher>(
-                         selector, node, opcode, IrOpcode::kWord64Ror,
-                         kShift64Imm, kMode_Operand2_R_ROR_I));
-}
-
-
 // Shared routine for multiple binary operations.
 template <typename Matcher>
-static void VisitBinop(InstructionSelector* selector, Node* node,
-                       InstructionCode opcode, ImmediateMode operand_mode,
-                       FlagsContinuation* cont) {
+void VisitBinop(InstructionSelector* selector, Node* node,
+                InstructionCode opcode, ImmediateMode operand_mode,
+                FlagsContinuation* cont) {
   Arm64OperandGenerator g(selector);
   Matcher m(node);
-  InstructionOperand* inputs[4];
+  InstructionOperand inputs[5];
   size_t input_count = 0;
-  InstructionOperand* outputs[2];
+  InstructionOperand outputs[2];
   size_t output_count = 0;
-  bool try_ror_operand = true;
+  bool is_cmp = (opcode == kArm64Cmp32) || (opcode == kArm64Cmn32);
 
-  if (m.IsInt32Add() || m.IsInt64Add() || m.IsInt32Sub() || m.IsInt64Sub()) {
-    try_ror_operand = false;
-  }
+  // We can commute cmp by switching the inputs and commuting the flags
+  // continuation.
+  bool can_commute = m.HasProperty(Operator::kCommutative) || is_cmp;
 
-  if (g.CanBeImmediate(m.right().node(), operand_mode)) {
-    inputs[input_count++] = g.UseRegister(m.left().node());
-    inputs[input_count++] = g.UseImmediate(m.right().node());
-  } else if (TryMatchAnyShift(selector, m.right().node(), &opcode,
-                              try_ror_operand)) {
-    Matcher m_shift(m.right().node());
-    inputs[input_count++] = g.UseRegister(m.left().node());
+  // The cmp and cmn instructions are encoded as sub or add with zero output
+  // register, and therefore support the same operand modes.
+  bool is_add_sub = m.IsInt32Add() || m.IsInt64Add() || m.IsInt32Sub() ||
+                    m.IsInt64Sub() || is_cmp;
+
+  Node* left_node = m.left().node();
+  Node* right_node = m.right().node();
+
+  if (g.CanBeImmediate(right_node, operand_mode)) {
+    inputs[input_count++] = g.UseRegister(left_node);
+    inputs[input_count++] = g.UseImmediate(right_node);
+  } else if (is_cmp && g.CanBeImmediate(left_node, operand_mode)) {
+    cont->Commute();
+    inputs[input_count++] = g.UseRegister(right_node);
+    inputs[input_count++] = g.UseImmediate(left_node);
+  } else if (is_add_sub &&
+             TryMatchAnyExtend(&g, selector, node, left_node, right_node,
+                               &inputs[0], &inputs[1], &opcode)) {
+    input_count += 2;
+  } else if (is_add_sub && can_commute &&
+             TryMatchAnyExtend(&g, selector, node, right_node, left_node,
+                               &inputs[0], &inputs[1], &opcode)) {
+    if (is_cmp) cont->Commute();
+    input_count += 2;
+  } else if (TryMatchAnyShift(selector, node, right_node, &opcode,
+                              !is_add_sub)) {
+    Matcher m_shift(right_node);
+    inputs[input_count++] = g.UseRegisterOrImmediateZero(left_node);
     inputs[input_count++] = g.UseRegister(m_shift.left().node());
     inputs[input_count++] = g.UseImmediate(m_shift.right().node());
-  } else if (m.HasProperty(Operator::kCommutative) &&
-             TryMatchAnyShift(selector, m.left().node(), &opcode,
-                              try_ror_operand)) {
-    Matcher m_shift(m.left().node());
-    inputs[input_count++] = g.UseRegister(m.right().node());
+  } else if (can_commute && TryMatchAnyShift(selector, node, left_node, &opcode,
+                                             !is_add_sub)) {
+    if (is_cmp) cont->Commute();
+    Matcher m_shift(left_node);
+    inputs[input_count++] = g.UseRegisterOrImmediateZero(right_node);
     inputs[input_count++] = g.UseRegister(m_shift.left().node());
     inputs[input_count++] = g.UseImmediate(m_shift.right().node());
   } else {
-    inputs[input_count++] = g.UseRegister(m.left().node());
-    inputs[input_count++] = g.UseRegister(m.right().node());
+    inputs[input_count++] = g.UseRegisterOrImmediateZero(left_node);
+    inputs[input_count++] = g.UseRegister(right_node);
   }
 
   if (cont->IsBranch()) {
@@ -209,83 +276,102 @@
     inputs[input_count++] = g.Label(cont->false_block());
   }
 
-  outputs[output_count++] = g.DefineAsRegister(node);
+  if (!is_cmp) {
+    outputs[output_count++] = g.DefineAsRegister(node);
+  }
+
   if (cont->IsSet()) {
     outputs[output_count++] = g.DefineAsRegister(cont->result());
   }
 
-  DCHECK_NE(0, input_count);
-  DCHECK_NE(0, output_count);
+  DCHECK_NE(0u, input_count);
+  DCHECK((output_count != 0) || is_cmp);
   DCHECK_GE(arraysize(inputs), input_count);
   DCHECK_GE(arraysize(outputs), output_count);
 
-  Instruction* instr = selector->Emit(cont->Encode(opcode), output_count,
-                                      outputs, input_count, inputs);
-  if (cont->IsBranch()) instr->MarkAsControl();
+  selector->Emit(cont->Encode(opcode), output_count, outputs, input_count,
+                 inputs);
 }
 
 
 // Shared routine for multiple binary operations.
 template <typename Matcher>
-static void VisitBinop(InstructionSelector* selector, Node* node,
-                       ArchOpcode opcode, ImmediateMode operand_mode) {
+void VisitBinop(InstructionSelector* selector, Node* node, ArchOpcode opcode,
+                ImmediateMode operand_mode) {
   FlagsContinuation cont;
   VisitBinop<Matcher>(selector, node, opcode, operand_mode, &cont);
 }
 
 
 template <typename Matcher>
-static void VisitAddSub(InstructionSelector* selector, Node* node,
-                        ArchOpcode opcode, ArchOpcode negate_opcode) {
+void VisitAddSub(InstructionSelector* selector, Node* node, ArchOpcode opcode,
+                 ArchOpcode negate_opcode) {
   Arm64OperandGenerator g(selector);
   Matcher m(node);
   if (m.right().HasValue() && (m.right().Value() < 0) &&
       g.CanBeImmediate(-m.right().Value(), kArithmeticImm)) {
     selector->Emit(negate_opcode, g.DefineAsRegister(node),
                    g.UseRegister(m.left().node()),
-                   g.TempImmediate(-m.right().Value()));
+                   g.TempImmediate(static_cast<int32_t>(-m.right().Value())));
   } else {
     VisitBinop<Matcher>(selector, node, opcode, kArithmeticImm);
   }
 }
 
 
+// For multiplications by immediate of the form x * (2^k + 1), where k > 0,
+// return the value of k, otherwise return zero. This is used to reduce the
+// multiplication to addition with left shift: x + (x << k).
+template <typename Matcher>
+int32_t LeftShiftForReducedMultiply(Matcher* m) {
+  DCHECK(m->IsInt32Mul() || m->IsInt64Mul());
+  if (m->right().HasValue() && m->right().Value() >= 3) {
+    uint64_t value_minus_one = m->right().Value() - 1;
+    if (base::bits::IsPowerOfTwo64(value_minus_one)) {
+      return WhichPowerOf2_64(value_minus_one);
+    }
+  }
+  return 0;
+}
+
+}  // namespace
+
+
 void InstructionSelector::VisitLoad(Node* node) {
-  MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node));
-  MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node));
+  LoadRepresentation load_rep = LoadRepresentationOf(node->op());
   Arm64OperandGenerator g(this);
   Node* base = node->InputAt(0);
   Node* index = node->InputAt(1);
-  ArchOpcode opcode;
+  ArchOpcode opcode = kArchNop;
   ImmediateMode immediate_mode = kNoImmediate;
-  switch (rep) {
-    case kRepFloat32:
+  switch (load_rep.representation()) {
+    case MachineRepresentation::kFloat32:
       opcode = kArm64LdrS;
       immediate_mode = kLoadStoreImm32;
       break;
-    case kRepFloat64:
+    case MachineRepresentation::kFloat64:
       opcode = kArm64LdrD;
       immediate_mode = kLoadStoreImm64;
       break;
-    case kRepBit:  // Fall through.
-    case kRepWord8:
-      opcode = typ == kTypeInt32 ? kArm64Ldrsb : kArm64Ldrb;
+    case MachineRepresentation::kBit:  // Fall through.
+    case MachineRepresentation::kWord8:
+      opcode = load_rep.IsSigned() ? kArm64Ldrsb : kArm64Ldrb;
       immediate_mode = kLoadStoreImm8;
       break;
-    case kRepWord16:
-      opcode = typ == kTypeInt32 ? kArm64Ldrsh : kArm64Ldrh;
+    case MachineRepresentation::kWord16:
+      opcode = load_rep.IsSigned() ? kArm64Ldrsh : kArm64Ldrh;
       immediate_mode = kLoadStoreImm16;
       break;
-    case kRepWord32:
+    case MachineRepresentation::kWord32:
       opcode = kArm64LdrW;
       immediate_mode = kLoadStoreImm32;
       break;
-    case kRepTagged:  // Fall through.
-    case kRepWord64:
+    case MachineRepresentation::kTagged:  // Fall through.
+    case MachineRepresentation::kWord64:
       opcode = kArm64Ldr;
       immediate_mode = kLoadStoreImm64;
       break;
-    default:
+    case MachineRepresentation::kNone:
       UNREACHABLE();
       return;
   }
@@ -305,88 +391,114 @@
   Node* index = node->InputAt(1);
   Node* value = node->InputAt(2);
 
-  StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node);
-  MachineType rep = RepresentationOf(store_rep.machine_type());
-  if (store_rep.write_barrier_kind() == kFullWriteBarrier) {
-    DCHECK(rep == kRepTagged);
-    // TODO(dcarney): refactor RecordWrite function to take temp registers
-    //                and pass them here instead of using fixed regs
-    // TODO(dcarney): handle immediate indices.
-    InstructionOperand* temps[] = {g.TempRegister(x11), g.TempRegister(x12)};
-    Emit(kArm64StoreWriteBarrier, NULL, g.UseFixed(base, x10),
-         g.UseFixed(index, x11), g.UseFixed(value, x12), arraysize(temps),
-         temps);
-    return;
-  }
-  DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind());
-  ArchOpcode opcode;
-  ImmediateMode immediate_mode = kNoImmediate;
-  switch (rep) {
-    case kRepFloat32:
-      opcode = kArm64StrS;
-      immediate_mode = kLoadStoreImm32;
-      break;
-    case kRepFloat64:
-      opcode = kArm64StrD;
-      immediate_mode = kLoadStoreImm64;
-      break;
-    case kRepBit:  // Fall through.
-    case kRepWord8:
-      opcode = kArm64Strb;
-      immediate_mode = kLoadStoreImm8;
-      break;
-    case kRepWord16:
-      opcode = kArm64Strh;
-      immediate_mode = kLoadStoreImm16;
-      break;
-    case kRepWord32:
-      opcode = kArm64StrW;
-      immediate_mode = kLoadStoreImm32;
-      break;
-    case kRepTagged:  // Fall through.
-    case kRepWord64:
-      opcode = kArm64Str;
-      immediate_mode = kLoadStoreImm64;
-      break;
-    default:
-      UNREACHABLE();
-      return;
-  }
-  if (g.CanBeImmediate(index, immediate_mode)) {
-    Emit(opcode | AddressingModeField::encode(kMode_MRI), NULL,
-         g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value));
+  StoreRepresentation store_rep = StoreRepresentationOf(node->op());
+  WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind();
+  MachineRepresentation rep = store_rep.representation();
+
+  // TODO(arm64): I guess this could be done in a better way.
+  if (write_barrier_kind != kNoWriteBarrier) {
+    DCHECK_EQ(MachineRepresentation::kTagged, rep);
+    InstructionOperand inputs[3];
+    size_t input_count = 0;
+    inputs[input_count++] = g.UseUniqueRegister(base);
+    inputs[input_count++] = g.UseUniqueRegister(index);
+    inputs[input_count++] = (write_barrier_kind == kMapWriteBarrier)
+                                ? g.UseRegister(value)
+                                : g.UseUniqueRegister(value);
+    RecordWriteMode record_write_mode = RecordWriteMode::kValueIsAny;
+    switch (write_barrier_kind) {
+      case kNoWriteBarrier:
+        UNREACHABLE();
+        break;
+      case kMapWriteBarrier:
+        record_write_mode = RecordWriteMode::kValueIsMap;
+        break;
+      case kPointerWriteBarrier:
+        record_write_mode = RecordWriteMode::kValueIsPointer;
+        break;
+      case kFullWriteBarrier:
+        record_write_mode = RecordWriteMode::kValueIsAny;
+        break;
+    }
+    InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()};
+    size_t const temp_count = arraysize(temps);
+    InstructionCode code = kArchStoreWithWriteBarrier;
+    code |= MiscField::encode(static_cast<int>(record_write_mode));
+    Emit(code, 0, nullptr, input_count, inputs, temp_count, temps);
   } else {
-    Emit(opcode | AddressingModeField::encode(kMode_MRR), NULL,
-         g.UseRegister(base), g.UseRegister(index), g.UseRegister(value));
+    ArchOpcode opcode = kArchNop;
+    ImmediateMode immediate_mode = kNoImmediate;
+    switch (rep) {
+      case MachineRepresentation::kFloat32:
+        opcode = kArm64StrS;
+        immediate_mode = kLoadStoreImm32;
+        break;
+      case MachineRepresentation::kFloat64:
+        opcode = kArm64StrD;
+        immediate_mode = kLoadStoreImm64;
+        break;
+      case MachineRepresentation::kBit:  // Fall through.
+      case MachineRepresentation::kWord8:
+        opcode = kArm64Strb;
+        immediate_mode = kLoadStoreImm8;
+        break;
+      case MachineRepresentation::kWord16:
+        opcode = kArm64Strh;
+        immediate_mode = kLoadStoreImm16;
+        break;
+      case MachineRepresentation::kWord32:
+        opcode = kArm64StrW;
+        immediate_mode = kLoadStoreImm32;
+        break;
+      case MachineRepresentation::kTagged:  // Fall through.
+      case MachineRepresentation::kWord64:
+        opcode = kArm64Str;
+        immediate_mode = kLoadStoreImm64;
+        break;
+      case MachineRepresentation::kNone:
+        UNREACHABLE();
+        return;
+    }
+    if (g.CanBeImmediate(index, immediate_mode)) {
+      Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
+           g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value));
+    } else {
+      Emit(opcode | AddressingModeField::encode(kMode_MRR), g.NoOutput(),
+           g.UseRegister(base), g.UseRegister(index), g.UseRegister(value));
+    }
   }
 }
 
 
 void InstructionSelector::VisitCheckedLoad(Node* node) {
-  MachineType rep = RepresentationOf(OpParameter<MachineType>(node));
-  MachineType typ = TypeOf(OpParameter<MachineType>(node));
+  CheckedLoadRepresentation load_rep = CheckedLoadRepresentationOf(node->op());
   Arm64OperandGenerator g(this);
   Node* const buffer = node->InputAt(0);
   Node* const offset = node->InputAt(1);
   Node* const length = node->InputAt(2);
-  ArchOpcode opcode;
-  switch (rep) {
-    case kRepWord8:
-      opcode = typ == kTypeInt32 ? kCheckedLoadInt8 : kCheckedLoadUint8;
+  ArchOpcode opcode = kArchNop;
+  switch (load_rep.representation()) {
+    case MachineRepresentation::kWord8:
+      opcode = load_rep.IsSigned() ? kCheckedLoadInt8 : kCheckedLoadUint8;
       break;
-    case kRepWord16:
-      opcode = typ == kTypeInt32 ? kCheckedLoadInt16 : kCheckedLoadUint16;
+    case MachineRepresentation::kWord16:
+      opcode = load_rep.IsSigned() ? kCheckedLoadInt16 : kCheckedLoadUint16;
       break;
-    case kRepWord32:
+    case MachineRepresentation::kWord32:
       opcode = kCheckedLoadWord32;
       break;
-    case kRepFloat32:
+    case MachineRepresentation::kWord64:
+      opcode = kCheckedLoadWord64;
+      break;
+    case MachineRepresentation::kFloat32:
       opcode = kCheckedLoadFloat32;
       break;
-    case kRepFloat64:
+    case MachineRepresentation::kFloat64:
       opcode = kCheckedLoadFloat64;
       break;
-    default:
+    case MachineRepresentation::kBit:     // Fall through.
+    case MachineRepresentation::kTagged:  // Fall through.
+    case MachineRepresentation::kNone:
       UNREACHABLE();
       return;
   }
@@ -396,34 +508,39 @@
 
 
 void InstructionSelector::VisitCheckedStore(Node* node) {
-  MachineType rep = RepresentationOf(OpParameter<MachineType>(node));
+  MachineRepresentation rep = CheckedStoreRepresentationOf(node->op());
   Arm64OperandGenerator g(this);
   Node* const buffer = node->InputAt(0);
   Node* const offset = node->InputAt(1);
   Node* const length = node->InputAt(2);
   Node* const value = node->InputAt(3);
-  ArchOpcode opcode;
+  ArchOpcode opcode = kArchNop;
   switch (rep) {
-    case kRepWord8:
+    case MachineRepresentation::kWord8:
       opcode = kCheckedStoreWord8;
       break;
-    case kRepWord16:
+    case MachineRepresentation::kWord16:
       opcode = kCheckedStoreWord16;
       break;
-    case kRepWord32:
+    case MachineRepresentation::kWord32:
       opcode = kCheckedStoreWord32;
       break;
-    case kRepFloat32:
+    case MachineRepresentation::kWord64:
+      opcode = kCheckedStoreWord64;
+      break;
+    case MachineRepresentation::kFloat32:
       opcode = kCheckedStoreFloat32;
       break;
-    case kRepFloat64:
+    case MachineRepresentation::kFloat64:
       opcode = kCheckedStoreFloat64;
       break;
-    default:
+    case MachineRepresentation::kBit:     // Fall through.
+    case MachineRepresentation::kTagged:  // Fall through.
+    case MachineRepresentation::kNone:
       UNREACHABLE();
       return;
   }
-  Emit(opcode, nullptr, g.UseRegister(buffer), g.UseRegister(offset),
+  Emit(opcode, g.NoOutput(), g.UseRegister(buffer), g.UseRegister(offset),
        g.UseOperand(length, kArithmeticImm), g.UseRegister(value));
 }
 
@@ -506,22 +623,25 @@
     uint32_t mask_msb = base::bits::CountLeadingZeros32(mask);
     if ((mask_width != 0) && (mask_msb + mask_width == 32)) {
       // The mask must be contiguous, and occupy the least-significant bits.
-      DCHECK_EQ(0, base::bits::CountTrailingZeros32(mask));
+      DCHECK_EQ(0u, base::bits::CountTrailingZeros32(mask));
 
       // Select Ubfx for And(Shr(x, imm), mask) where the mask is in the least
       // significant bits.
       Int32BinopMatcher mleft(m.left().node());
-      if (mleft.right().IsInRange(0, 31)) {
+      if (mleft.right().HasValue()) {
+        // Any shift value can match; int32 shifts use `value % 32`.
+        uint32_t lsb = mleft.right().Value() & 0x1f;
+
         // Ubfx cannot extract bits past the register size, however since
         // shifting the original value would have introduced some zeros we can
         // still use ubfx with a smaller mask and the remaining bits will be
         // zeros.
-        uint32_t lsb = mleft.right().Value();
         if (lsb + mask_width > 32) mask_width = 32 - lsb;
 
         Emit(kArm64Ubfx32, g.DefineAsRegister(node),
              g.UseRegister(mleft.left().node()),
-             g.UseImmediate(mleft.right().node()), g.TempImmediate(mask_width));
+             g.UseImmediateOrTemp(mleft.right().node(), lsb),
+             g.TempImmediate(mask_width));
         return;
       }
       // Other cases fall through to the normal And operation.
@@ -543,22 +663,25 @@
     uint64_t mask_msb = base::bits::CountLeadingZeros64(mask);
     if ((mask_width != 0) && (mask_msb + mask_width == 64)) {
       // The mask must be contiguous, and occupy the least-significant bits.
-      DCHECK_EQ(0, base::bits::CountTrailingZeros64(mask));
+      DCHECK_EQ(0u, base::bits::CountTrailingZeros64(mask));
 
       // Select Ubfx for And(Shr(x, imm), mask) where the mask is in the least
       // significant bits.
       Int64BinopMatcher mleft(m.left().node());
-      if (mleft.right().IsInRange(0, 63)) {
+      if (mleft.right().HasValue()) {
+        // Any shift value can match; int64 shifts use `value % 64`.
+        uint32_t lsb = static_cast<uint32_t>(mleft.right().Value() & 0x3f);
+
         // Ubfx cannot extract bits past the register size, however since
         // shifting the original value would have introduced some zeros we can
         // still use ubfx with a smaller mask and the remaining bits will be
         // zeros.
-        uint64_t lsb = mleft.right().Value();
         if (lsb + mask_width > 64) mask_width = 64 - lsb;
 
         Emit(kArm64Ubfx, g.DefineAsRegister(node),
              g.UseRegister(mleft.left().node()),
-             g.UseImmediate(mleft.right().node()), g.TempImmediate(mask_width));
+             g.UseImmediateOrTemp(mleft.right().node(), lsb),
+             g.TempImmediate(static_cast<int32_t>(mask_width)));
         return;
       }
       // Other cases fall through to the normal And operation.
@@ -603,6 +726,38 @@
 
 
 void InstructionSelector::VisitWord32Shl(Node* node) {
+  Int32BinopMatcher m(node);
+  if (m.left().IsWord32And() && CanCover(node, m.left().node()) &&
+      m.right().IsInRange(1, 31)) {
+    Arm64OperandGenerator g(this);
+    Int32BinopMatcher mleft(m.left().node());
+    if (mleft.right().HasValue()) {
+      uint32_t mask = mleft.right().Value();
+      uint32_t mask_width = base::bits::CountPopulation32(mask);
+      uint32_t mask_msb = base::bits::CountLeadingZeros32(mask);
+      if ((mask_width != 0) && (mask_msb + mask_width == 32)) {
+        uint32_t shift = m.right().Value();
+        DCHECK_EQ(0u, base::bits::CountTrailingZeros32(mask));
+        DCHECK_NE(0u, shift);
+
+        if ((shift + mask_width) >= 32) {
+          // If the mask is contiguous and reaches or extends beyond the top
+          // bit, only the shift is needed.
+          Emit(kArm64Lsl32, g.DefineAsRegister(node),
+               g.UseRegister(mleft.left().node()),
+               g.UseImmediate(m.right().node()));
+          return;
+        } else {
+          // Select Ubfiz for Shl(And(x, mask), imm) where the mask is
+          // contiguous, and the shift immediate non-zero.
+          Emit(kArm64Ubfiz32, g.DefineAsRegister(node),
+               g.UseRegister(mleft.left().node()),
+               g.UseImmediate(m.right().node()), g.TempImmediate(mask_width));
+          return;
+        }
+      }
+    }
+  }
   VisitRRO(this, kArm64Lsl32, node, kShift32Imm);
 }
 
@@ -623,47 +778,96 @@
 }
 
 
-void InstructionSelector::VisitWord32Shr(Node* node) {
-  Arm64OperandGenerator g(this);
+namespace {
+
+bool TryEmitBitfieldExtract32(InstructionSelector* selector, Node* node) {
+  Arm64OperandGenerator g(selector);
   Int32BinopMatcher m(node);
-  if (m.left().IsWord32And() && m.right().IsInRange(0, 31)) {
-    int32_t lsb = m.right().Value();
+  if (selector->CanCover(node, m.left().node()) && m.left().IsWord32Shl()) {
+    // Select Ubfx or Sbfx for (x << (K & 0x1f)) OP (K & 0x1f), where
+    // OP is >>> or >> and (K & 0x1f) != 0.
+    Int32BinopMatcher mleft(m.left().node());
+    if (mleft.right().HasValue() && m.right().HasValue() &&
+        (mleft.right().Value() & 0x1f) == (m.right().Value() & 0x1f)) {
+      DCHECK(m.IsWord32Shr() || m.IsWord32Sar());
+      ArchOpcode opcode = m.IsWord32Sar() ? kArm64Sbfx32 : kArm64Ubfx32;
+
+      int right_val = m.right().Value() & 0x1f;
+      DCHECK_NE(right_val, 0);
+
+      selector->Emit(opcode, g.DefineAsRegister(node),
+                     g.UseRegister(mleft.left().node()), g.TempImmediate(0),
+                     g.TempImmediate(32 - right_val));
+      return true;
+    }
+  }
+  return false;
+}
+
+}  // namespace
+
+
+void InstructionSelector::VisitWord32Shr(Node* node) {
+  Int32BinopMatcher m(node);
+  if (m.left().IsWord32And() && m.right().HasValue()) {
+    uint32_t lsb = m.right().Value() & 0x1f;
     Int32BinopMatcher mleft(m.left().node());
     if (mleft.right().HasValue()) {
-      uint32_t mask = (mleft.right().Value() >> lsb) << lsb;
-      uint32_t mask_width = base::bits::CountPopulation32(mask);
-      uint32_t mask_msb = base::bits::CountLeadingZeros32(mask);
       // Select Ubfx for Shr(And(x, mask), imm) where the result of the mask is
       // shifted into the least-significant bits.
+      uint32_t mask = (mleft.right().Value() >> lsb) << lsb;
+      unsigned mask_width = base::bits::CountPopulation32(mask);
+      unsigned mask_msb = base::bits::CountLeadingZeros32(mask);
       if ((mask_msb + mask_width + lsb) == 32) {
+        Arm64OperandGenerator g(this);
         DCHECK_EQ(lsb, base::bits::CountTrailingZeros32(mask));
         Emit(kArm64Ubfx32, g.DefineAsRegister(node),
-             g.UseRegister(mleft.left().node()), g.TempImmediate(lsb),
+             g.UseRegister(mleft.left().node()),
+             g.UseImmediateOrTemp(m.right().node(), lsb),
              g.TempImmediate(mask_width));
         return;
       }
     }
+  } else if (TryEmitBitfieldExtract32(this, node)) {
+    return;
   }
+
+  if (m.left().IsUint32MulHigh() && m.right().HasValue() &&
+      CanCover(node, node->InputAt(0))) {
+    // Combine this shift with the multiply and shift that would be generated
+    // by Uint32MulHigh.
+    Arm64OperandGenerator g(this);
+    Node* left = m.left().node();
+    int shift = m.right().Value() & 0x1f;
+    InstructionOperand const smull_operand = g.TempRegister();
+    Emit(kArm64Umull, smull_operand, g.UseRegister(left->InputAt(0)),
+         g.UseRegister(left->InputAt(1)));
+    Emit(kArm64Lsr, g.DefineAsRegister(node), smull_operand,
+         g.TempImmediate(32 + shift));
+    return;
+  }
+
   VisitRRO(this, kArm64Lsr32, node, kShift32Imm);
 }
 
 
 void InstructionSelector::VisitWord64Shr(Node* node) {
-  Arm64OperandGenerator g(this);
   Int64BinopMatcher m(node);
-  if (m.left().IsWord64And() && m.right().IsInRange(0, 63)) {
-    int64_t lsb = m.right().Value();
+  if (m.left().IsWord64And() && m.right().HasValue()) {
+    uint32_t lsb = m.right().Value() & 0x3f;
     Int64BinopMatcher mleft(m.left().node());
     if (mleft.right().HasValue()) {
       // Select Ubfx for Shr(And(x, mask), imm) where the result of the mask is
       // shifted into the least-significant bits.
       uint64_t mask = (mleft.right().Value() >> lsb) << lsb;
-      uint64_t mask_width = base::bits::CountPopulation64(mask);
-      uint64_t mask_msb = base::bits::CountLeadingZeros64(mask);
+      unsigned mask_width = base::bits::CountPopulation64(mask);
+      unsigned mask_msb = base::bits::CountLeadingZeros64(mask);
       if ((mask_msb + mask_width + lsb) == 64) {
+        Arm64OperandGenerator g(this);
         DCHECK_EQ(lsb, base::bits::CountTrailingZeros64(mask));
         Emit(kArm64Ubfx, g.DefineAsRegister(node),
-             g.UseRegister(mleft.left().node()), g.TempImmediate(lsb),
+             g.UseRegister(mleft.left().node()),
+             g.UseImmediateOrTemp(m.right().node(), lsb),
              g.TempImmediate(mask_width));
         return;
       }
@@ -674,21 +878,54 @@
 
 
 void InstructionSelector::VisitWord32Sar(Node* node) {
-  Arm64OperandGenerator g(this);
+  if (TryEmitBitfieldExtract32(this, node)) {
+    return;
+  }
+
   Int32BinopMatcher m(node);
-  // Select Sxth/Sxtb for (x << K) >> K where K is 16 or 24.
-  if (CanCover(node, m.left().node()) && m.left().IsWord32Shl()) {
-    Int32BinopMatcher mleft(m.left().node());
-    if (mleft.right().Is(16) && m.right().Is(16)) {
-      Emit(kArm64Sxth32, g.DefineAsRegister(node),
-           g.UseRegister(mleft.left().node()));
-      return;
-    } else if (mleft.right().Is(24) && m.right().Is(24)) {
-      Emit(kArm64Sxtb32, g.DefineAsRegister(node),
-           g.UseRegister(mleft.left().node()));
+  if (m.left().IsInt32MulHigh() && m.right().HasValue() &&
+      CanCover(node, node->InputAt(0))) {
+    // Combine this shift with the multiply and shift that would be generated
+    // by Int32MulHigh.
+    Arm64OperandGenerator g(this);
+    Node* left = m.left().node();
+    int shift = m.right().Value() & 0x1f;
+    InstructionOperand const smull_operand = g.TempRegister();
+    Emit(kArm64Smull, smull_operand, g.UseRegister(left->InputAt(0)),
+         g.UseRegister(left->InputAt(1)));
+    Emit(kArm64Asr, g.DefineAsRegister(node), smull_operand,
+         g.TempImmediate(32 + shift));
+    return;
+  }
+
+  if (m.left().IsInt32Add() && m.right().HasValue() &&
+      CanCover(node, node->InputAt(0))) {
+    Node* add_node = m.left().node();
+    Int32BinopMatcher madd_node(add_node);
+    if (madd_node.left().IsInt32MulHigh() &&
+        CanCover(add_node, madd_node.left().node())) {
+      // Combine the shift that would be generated by Int32MulHigh with the add
+      // on the left of this Sar operation. We do it here, as the result of the
+      // add potentially has 33 bits, so we have to ensure the result is
+      // truncated by being the input to this 32-bit Sar operation.
+      Arm64OperandGenerator g(this);
+      Node* mul_node = madd_node.left().node();
+
+      InstructionOperand const smull_operand = g.TempRegister();
+      Emit(kArm64Smull, smull_operand, g.UseRegister(mul_node->InputAt(0)),
+           g.UseRegister(mul_node->InputAt(1)));
+
+      InstructionOperand const add_operand = g.TempRegister();
+      Emit(kArm64Add | AddressingModeField::encode(kMode_Operand2_R_ASR_I),
+           add_operand, g.UseRegister(add_node->InputAt(1)), smull_operand,
+           g.TempImmediate(32));
+
+      Emit(kArm64Asr32, g.DefineAsRegister(node), add_operand,
+           g.UseImmediate(node->InputAt(1)));
       return;
     }
   }
+
   VisitRRO(this, kArm64Asr32, node, kShift32Imm);
 }
 
@@ -708,24 +945,56 @@
 }
 
 
+void InstructionSelector::VisitWord64Clz(Node* node) {
+  Arm64OperandGenerator g(this);
+  Emit(kArm64Clz, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitWord32Clz(Node* node) {
+  Arm64OperandGenerator g(this);
+  Emit(kArm64Clz32, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitWord32Ctz(Node* node) { UNREACHABLE(); }
+
+
+void InstructionSelector::VisitWord64Ctz(Node* node) { UNREACHABLE(); }
+
+
+void InstructionSelector::VisitWord32Popcnt(Node* node) { UNREACHABLE(); }
+
+
+void InstructionSelector::VisitWord64Popcnt(Node* node) { UNREACHABLE(); }
+
+
 void InstructionSelector::VisitInt32Add(Node* node) {
   Arm64OperandGenerator g(this);
   Int32BinopMatcher m(node);
   // Select Madd(x, y, z) for Add(Mul(x, y), z).
   if (m.left().IsInt32Mul() && CanCover(node, m.left().node())) {
     Int32BinopMatcher mleft(m.left().node());
-    Emit(kArm64Madd32, g.DefineAsRegister(node),
-         g.UseRegister(mleft.left().node()),
-         g.UseRegister(mleft.right().node()), g.UseRegister(m.right().node()));
-    return;
+    // Check multiply can't be later reduced to addition with shift.
+    if (LeftShiftForReducedMultiply(&mleft) == 0) {
+      Emit(kArm64Madd32, g.DefineAsRegister(node),
+           g.UseRegister(mleft.left().node()),
+           g.UseRegister(mleft.right().node()),
+           g.UseRegister(m.right().node()));
+      return;
+    }
   }
-  // Select Madd(x, y, z) for Add(x, Mul(x, y)).
+  // Select Madd(x, y, z) for Add(z, Mul(x, y)).
   if (m.right().IsInt32Mul() && CanCover(node, m.right().node())) {
     Int32BinopMatcher mright(m.right().node());
-    Emit(kArm64Madd32, g.DefineAsRegister(node),
-         g.UseRegister(mright.left().node()),
-         g.UseRegister(mright.right().node()), g.UseRegister(m.left().node()));
-    return;
+    // Check multiply can't be later reduced to addition with shift.
+    if (LeftShiftForReducedMultiply(&mright) == 0) {
+      Emit(kArm64Madd32, g.DefineAsRegister(node),
+           g.UseRegister(mright.left().node()),
+           g.UseRegister(mright.right().node()),
+           g.UseRegister(m.left().node()));
+      return;
+    }
   }
   VisitAddSub<Int32BinopMatcher>(this, node, kArm64Add32, kArm64Sub32);
 }
@@ -737,18 +1006,26 @@
   // Select Madd(x, y, z) for Add(Mul(x, y), z).
   if (m.left().IsInt64Mul() && CanCover(node, m.left().node())) {
     Int64BinopMatcher mleft(m.left().node());
-    Emit(kArm64Madd, g.DefineAsRegister(node),
-         g.UseRegister(mleft.left().node()),
-         g.UseRegister(mleft.right().node()), g.UseRegister(m.right().node()));
-    return;
+    // Check multiply can't be later reduced to addition with shift.
+    if (LeftShiftForReducedMultiply(&mleft) == 0) {
+      Emit(kArm64Madd, g.DefineAsRegister(node),
+           g.UseRegister(mleft.left().node()),
+           g.UseRegister(mleft.right().node()),
+           g.UseRegister(m.right().node()));
+      return;
+    }
   }
-  // Select Madd(x, y, z) for Add(x, Mul(x, y)).
+  // Select Madd(x, y, z) for Add(z, Mul(x, y)).
   if (m.right().IsInt64Mul() && CanCover(node, m.right().node())) {
     Int64BinopMatcher mright(m.right().node());
-    Emit(kArm64Madd, g.DefineAsRegister(node),
-         g.UseRegister(mright.left().node()),
-         g.UseRegister(mright.right().node()), g.UseRegister(m.left().node()));
-    return;
+    // Check multiply can't be later reduced to addition with shift.
+    if (LeftShiftForReducedMultiply(&mright) == 0) {
+      Emit(kArm64Madd, g.DefineAsRegister(node),
+           g.UseRegister(mright.left().node()),
+           g.UseRegister(mright.right().node()),
+           g.UseRegister(m.left().node()));
+      return;
+    }
   }
   VisitAddSub<Int64BinopMatcher>(this, node, kArm64Add, kArm64Sub);
 }
@@ -758,21 +1035,20 @@
   Arm64OperandGenerator g(this);
   Int32BinopMatcher m(node);
 
-  // Select Msub(a, x, y) for Sub(a, Mul(x, y)).
+  // Select Msub(x, y, a) for Sub(a, Mul(x, y)).
   if (m.right().IsInt32Mul() && CanCover(node, m.right().node())) {
     Int32BinopMatcher mright(m.right().node());
-    Emit(kArm64Msub32, g.DefineAsRegister(node),
-         g.UseRegister(mright.left().node()),
-         g.UseRegister(mright.right().node()), g.UseRegister(m.left().node()));
-    return;
+    // Check multiply can't be later reduced to addition with shift.
+    if (LeftShiftForReducedMultiply(&mright) == 0) {
+      Emit(kArm64Msub32, g.DefineAsRegister(node),
+           g.UseRegister(mright.left().node()),
+           g.UseRegister(mright.right().node()),
+           g.UseRegister(m.left().node()));
+      return;
+    }
   }
 
-  if (m.left().Is(0)) {
-    Emit(kArm64Neg32, g.DefineAsRegister(node),
-         g.UseRegister(m.right().node()));
-  } else {
-    VisitAddSub<Int32BinopMatcher>(this, node, kArm64Sub32, kArm64Add32);
-  }
+  VisitAddSub<Int32BinopMatcher>(this, node, kArm64Sub32, kArm64Add32);
 }
 
 
@@ -780,20 +1056,20 @@
   Arm64OperandGenerator g(this);
   Int64BinopMatcher m(node);
 
-  // Select Msub(a, x, y) for Sub(a, Mul(x, y)).
+  // Select Msub(x, y, a) for Sub(a, Mul(x, y)).
   if (m.right().IsInt64Mul() && CanCover(node, m.right().node())) {
     Int64BinopMatcher mright(m.right().node());
-    Emit(kArm64Msub, g.DefineAsRegister(node),
-         g.UseRegister(mright.left().node()),
-         g.UseRegister(mright.right().node()), g.UseRegister(m.left().node()));
-    return;
+    // Check multiply can't be later reduced to addition with shift.
+    if (LeftShiftForReducedMultiply(&mright) == 0) {
+      Emit(kArm64Msub, g.DefineAsRegister(node),
+           g.UseRegister(mright.left().node()),
+           g.UseRegister(mright.right().node()),
+           g.UseRegister(m.left().node()));
+      return;
+    }
   }
 
-  if (m.left().Is(0)) {
-    Emit(kArm64Neg, g.DefineAsRegister(node), g.UseRegister(m.right().node()));
-  } else {
-    VisitAddSub<Int64BinopMatcher>(this, node, kArm64Sub, kArm64Add);
-  }
+  VisitAddSub<Int64BinopMatcher>(this, node, kArm64Sub, kArm64Add);
 }
 
 
@@ -801,6 +1077,16 @@
   Arm64OperandGenerator g(this);
   Int32BinopMatcher m(node);
 
+  // First, try to reduce the multiplication to addition with left shift.
+  // x * (2^k + 1) -> x + (x << k)
+  int32_t shift = LeftShiftForReducedMultiply(&m);
+  if (shift > 0) {
+    Emit(kArm64Add32 | AddressingModeField::encode(kMode_Operand2_R_LSL_I),
+         g.DefineAsRegister(node), g.UseRegister(m.left().node()),
+         g.UseRegister(m.left().node()), g.TempImmediate(shift));
+    return;
+  }
+
   if (m.left().IsInt32Sub() && CanCover(node, m.left().node())) {
     Int32BinopMatcher mleft(m.left().node());
 
@@ -833,6 +1119,16 @@
   Arm64OperandGenerator g(this);
   Int64BinopMatcher m(node);
 
+  // First, try to reduce the multiplication to addition with left shift.
+  // x * (2^k + 1) -> x + (x << k)
+  int32_t shift = LeftShiftForReducedMultiply(&m);
+  if (shift > 0) {
+    Emit(kArm64Add | AddressingModeField::encode(kMode_Operand2_R_LSL_I),
+         g.DefineAsRegister(node), g.UseRegister(m.left().node()),
+         g.UseRegister(m.left().node()), g.TempImmediate(shift));
+    return;
+  }
+
   if (m.left().IsInt64Sub() && CanCover(node, m.left().node())) {
     Int64BinopMatcher mleft(m.left().node());
 
@@ -861,9 +1157,8 @@
 
 
 void InstructionSelector::VisitInt32MulHigh(Node* node) {
-  // TODO(arm64): Can we do better here?
   Arm64OperandGenerator g(this);
-  InstructionOperand* const smull_operand = g.TempRegister();
+  InstructionOperand const smull_operand = g.TempRegister();
   Emit(kArm64Smull, smull_operand, g.UseRegister(node->InputAt(0)),
        g.UseRegister(node->InputAt(1)));
   Emit(kArm64Asr, g.DefineAsRegister(node), smull_operand, g.TempImmediate(32));
@@ -871,9 +1166,8 @@
 
 
 void InstructionSelector::VisitUint32MulHigh(Node* node) {
-  // TODO(arm64): Can we do better here?
   Arm64OperandGenerator g(this);
-  InstructionOperand* const smull_operand = g.TempRegister();
+  InstructionOperand const smull_operand = g.TempRegister();
   Emit(kArm64Umull, smull_operand, g.UseRegister(node->InputAt(0)),
        g.UseRegister(node->InputAt(1)));
   Emit(kArm64Lsr, g.DefineAsRegister(node), smull_operand, g.TempImmediate(32));
@@ -921,43 +1215,100 @@
 
 
 void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) {
-  Arm64OperandGenerator g(this);
-  Emit(kArm64Float32ToFloat64, g.DefineAsRegister(node),
-       g.UseRegister(node->InputAt(0)));
+  VisitRR(this, kArm64Float32ToFloat64, node);
 }
 
 
 void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) {
-  Arm64OperandGenerator g(this);
-  Emit(kArm64Int32ToFloat64, g.DefineAsRegister(node),
-       g.UseRegister(node->InputAt(0)));
+  VisitRR(this, kArm64Int32ToFloat64, node);
 }
 
 
 void InstructionSelector::VisitChangeUint32ToFloat64(Node* node) {
-  Arm64OperandGenerator g(this);
-  Emit(kArm64Uint32ToFloat64, g.DefineAsRegister(node),
-       g.UseRegister(node->InputAt(0)));
+  VisitRR(this, kArm64Uint32ToFloat64, node);
 }
 
 
 void InstructionSelector::VisitChangeFloat64ToInt32(Node* node) {
-  Arm64OperandGenerator g(this);
-  Emit(kArm64Float64ToInt32, g.DefineAsRegister(node),
-       g.UseRegister(node->InputAt(0)));
+  VisitRR(this, kArm64Float64ToInt32, node);
 }
 
 
 void InstructionSelector::VisitChangeFloat64ToUint32(Node* node) {
+  VisitRR(this, kArm64Float64ToUint32, node);
+}
+
+
+void InstructionSelector::VisitTryTruncateFloat32ToInt64(Node* node) {
   Arm64OperandGenerator g(this);
-  Emit(kArm64Float64ToUint32, g.DefineAsRegister(node),
-       g.UseRegister(node->InputAt(0)));
+
+  InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0))};
+  InstructionOperand outputs[2];
+  size_t output_count = 0;
+  outputs[output_count++] = g.DefineAsRegister(node);
+
+  Node* success_output = NodeProperties::FindProjection(node, 1);
+  if (success_output) {
+    outputs[output_count++] = g.DefineAsRegister(success_output);
+  }
+
+  Emit(kArm64Float32ToInt64, output_count, outputs, 1, inputs);
+}
+
+
+void InstructionSelector::VisitTryTruncateFloat64ToInt64(Node* node) {
+  Arm64OperandGenerator g(this);
+
+  InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0))};
+  InstructionOperand outputs[2];
+  size_t output_count = 0;
+  outputs[output_count++] = g.DefineAsRegister(node);
+
+  Node* success_output = NodeProperties::FindProjection(node, 1);
+  if (success_output) {
+    outputs[output_count++] = g.DefineAsRegister(success_output);
+  }
+
+  Emit(kArm64Float64ToInt64, output_count, outputs, 1, inputs);
+}
+
+
+void InstructionSelector::VisitTryTruncateFloat32ToUint64(Node* node) {
+  Arm64OperandGenerator g(this);
+
+  InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0))};
+  InstructionOperand outputs[2];
+  size_t output_count = 0;
+  outputs[output_count++] = g.DefineAsRegister(node);
+
+  Node* success_output = NodeProperties::FindProjection(node, 1);
+  if (success_output) {
+    outputs[output_count++] = g.DefineAsRegister(success_output);
+  }
+
+  Emit(kArm64Float32ToUint64, output_count, outputs, 1, inputs);
+}
+
+
+void InstructionSelector::VisitTryTruncateFloat64ToUint64(Node* node) {
+  Arm64OperandGenerator g(this);
+
+  InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0))};
+  InstructionOperand outputs[2];
+  size_t output_count = 0;
+  outputs[output_count++] = g.DefineAsRegister(node);
+
+  Node* success_output = NodeProperties::FindProjection(node, 1);
+  if (success_output) {
+    outputs[output_count++] = g.DefineAsRegister(success_output);
+  }
+
+  Emit(kArm64Float64ToUint64, output_count, outputs, 1, inputs);
 }
 
 
 void InstructionSelector::VisitChangeInt32ToInt64(Node* node) {
-  Arm64OperandGenerator g(this);
-  Emit(kArm64Sxtw, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)));
+  VisitRR(this, kArm64Sxtw, node);
 }
 
 
@@ -1002,16 +1353,25 @@
 
 
 void InstructionSelector::VisitTruncateFloat64ToFloat32(Node* node) {
-  Arm64OperandGenerator g(this);
-  Emit(kArm64Float64ToFloat32, g.DefineAsRegister(node),
-       g.UseRegister(node->InputAt(0)));
+  VisitRR(this, kArm64Float64ToFloat32, node);
+}
+
+
+void InstructionSelector::VisitTruncateFloat64ToInt32(Node* node) {
+  switch (TruncationModeOf(node->op())) {
+    case TruncationMode::kJavaScript:
+      return VisitRR(this, kArchTruncateDoubleToI, node);
+    case TruncationMode::kRoundToZero:
+      return VisitRR(this, kArm64Float64ToInt32, node);
+  }
+  UNREACHABLE();
 }
 
 
 void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) {
   Arm64OperandGenerator g(this);
   Node* value = node->InputAt(0);
-  if (CanCover(node, value)) {
+  if (CanCover(node, value) && value->InputCount() >= 2) {
     Int64BinopMatcher m(value);
     if ((m.IsWord64Sar() && m.right().HasValue() &&
          (m.right().Value() == 32)) ||
@@ -1026,23 +1386,102 @@
 }
 
 
+void InstructionSelector::VisitRoundInt64ToFloat32(Node* node) {
+  VisitRR(this, kArm64Int64ToFloat32, node);
+}
+
+
+void InstructionSelector::VisitRoundInt64ToFloat64(Node* node) {
+  VisitRR(this, kArm64Int64ToFloat64, node);
+}
+
+
+void InstructionSelector::VisitRoundUint64ToFloat32(Node* node) {
+  VisitRR(this, kArm64Uint64ToFloat32, node);
+}
+
+
+void InstructionSelector::VisitRoundUint64ToFloat64(Node* node) {
+  VisitRR(this, kArm64Uint64ToFloat64, node);
+}
+
+
+void InstructionSelector::VisitBitcastFloat32ToInt32(Node* node) {
+  VisitRR(this, kArm64Float64ExtractLowWord32, node);
+}
+
+
+void InstructionSelector::VisitBitcastFloat64ToInt64(Node* node) {
+  VisitRR(this, kArm64U64MoveFloat64, node);
+}
+
+
+void InstructionSelector::VisitBitcastInt32ToFloat32(Node* node) {
+  VisitRR(this, kArm64Float64MoveU64, node);
+}
+
+
+void InstructionSelector::VisitBitcastInt64ToFloat64(Node* node) {
+  VisitRR(this, kArm64Float64MoveU64, node);
+}
+
+
+void InstructionSelector::VisitFloat32Add(Node* node) {
+  VisitRRR(this, kArm64Float32Add, node);
+}
+
+
 void InstructionSelector::VisitFloat64Add(Node* node) {
-  VisitRRRFloat64(this, kArm64Float64Add, node);
+  VisitRRR(this, kArm64Float64Add, node);
+}
+
+
+void InstructionSelector::VisitFloat32Sub(Node* node) {
+  VisitRRR(this, kArm64Float32Sub, node);
 }
 
 
 void InstructionSelector::VisitFloat64Sub(Node* node) {
-  VisitRRRFloat64(this, kArm64Float64Sub, node);
+  Arm64OperandGenerator g(this);
+  Float64BinopMatcher m(node);
+  if (m.left().IsMinusZero()) {
+    if (m.right().IsFloat64RoundDown() &&
+        CanCover(m.node(), m.right().node())) {
+      if (m.right().InputAt(0)->opcode() == IrOpcode::kFloat64Sub &&
+          CanCover(m.right().node(), m.right().InputAt(0))) {
+        Float64BinopMatcher mright0(m.right().InputAt(0));
+        if (mright0.left().IsMinusZero()) {
+          Emit(kArm64Float64RoundUp, g.DefineAsRegister(node),
+               g.UseRegister(mright0.right().node()));
+          return;
+        }
+      }
+    }
+    Emit(kArm64Float64Neg, g.DefineAsRegister(node),
+         g.UseRegister(m.right().node()));
+    return;
+  }
+  VisitRRR(this, kArm64Float64Sub, node);
+}
+
+
+void InstructionSelector::VisitFloat32Mul(Node* node) {
+  VisitRRR(this, kArm64Float32Mul, node);
 }
 
 
 void InstructionSelector::VisitFloat64Mul(Node* node) {
-  VisitRRRFloat64(this, kArm64Float64Mul, node);
+  VisitRRR(this, kArm64Float64Mul, node);
+}
+
+
+void InstructionSelector::VisitFloat32Div(Node* node) {
+  VisitRRR(this, kArm64Float32Div, node);
 }
 
 
 void InstructionSelector::VisitFloat64Div(Node* node) {
-  VisitRRRFloat64(this, kArm64Float64Div, node);
+  VisitRRR(this, kArm64Float64Div, node);
 }
 
 
@@ -1054,112 +1493,145 @@
 }
 
 
+void InstructionSelector::VisitFloat32Max(Node* node) {
+  VisitRRR(this, kArm64Float32Max, node);
+}
+
+
+void InstructionSelector::VisitFloat64Max(Node* node) {
+  VisitRRR(this, kArm64Float64Max, node);
+}
+
+
+void InstructionSelector::VisitFloat32Min(Node* node) {
+  VisitRRR(this, kArm64Float32Min, node);
+}
+
+
+void InstructionSelector::VisitFloat64Min(Node* node) {
+  VisitRRR(this, kArm64Float64Min, node);
+}
+
+
+void InstructionSelector::VisitFloat32Abs(Node* node) {
+  VisitRR(this, kArm64Float32Abs, node);
+}
+
+
+void InstructionSelector::VisitFloat64Abs(Node* node) {
+  VisitRR(this, kArm64Float64Abs, node);
+}
+
+
+void InstructionSelector::VisitFloat32Sqrt(Node* node) {
+  VisitRR(this, kArm64Float32Sqrt, node);
+}
+
+
 void InstructionSelector::VisitFloat64Sqrt(Node* node) {
-  VisitRRFloat64(this, kArm64Float64Sqrt, node);
+  VisitRR(this, kArm64Float64Sqrt, node);
 }
 
 
-void InstructionSelector::VisitFloat64Floor(Node* node) {
-  VisitRRFloat64(this, kArm64Float64Floor, node);
+void InstructionSelector::VisitFloat32RoundDown(Node* node) {
+  VisitRR(this, kArm64Float32RoundDown, node);
 }
 
 
-void InstructionSelector::VisitFloat64Ceil(Node* node) {
-  VisitRRFloat64(this, kArm64Float64Ceil, node);
+void InstructionSelector::VisitFloat64RoundDown(Node* node) {
+  VisitRR(this, kArm64Float64RoundDown, node);
+}
+
+
+void InstructionSelector::VisitFloat32RoundUp(Node* node) {
+  VisitRR(this, kArm64Float32RoundUp, node);
+}
+
+
+void InstructionSelector::VisitFloat64RoundUp(Node* node) {
+  VisitRR(this, kArm64Float64RoundUp, node);
+}
+
+
+void InstructionSelector::VisitFloat32RoundTruncate(Node* node) {
+  VisitRR(this, kArm64Float32RoundTruncate, node);
 }
 
 
 void InstructionSelector::VisitFloat64RoundTruncate(Node* node) {
-  VisitRRFloat64(this, kArm64Float64RoundTruncate, node);
+  VisitRR(this, kArm64Float64RoundTruncate, node);
 }
 
 
 void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) {
-  VisitRRFloat64(this, kArm64Float64RoundTiesAway, node);
+  VisitRR(this, kArm64Float64RoundTiesAway, node);
 }
 
 
-void InstructionSelector::VisitCall(Node* node) {
+void InstructionSelector::VisitFloat32RoundTiesEven(Node* node) {
+  VisitRR(this, kArm64Float32RoundTiesEven, node);
+}
+
+
+void InstructionSelector::VisitFloat64RoundTiesEven(Node* node) {
+  VisitRR(this, kArm64Float64RoundTiesEven, node);
+}
+
+
+void InstructionSelector::EmitPrepareArguments(
+    ZoneVector<PushParameter>* arguments, const CallDescriptor* descriptor,
+    Node* node) {
   Arm64OperandGenerator g(this);
-  const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(node);
-
-  FrameStateDescriptor* frame_state_descriptor = NULL;
-  if (descriptor->NeedsFrameState()) {
-    frame_state_descriptor =
-        GetFrameStateDescriptor(node->InputAt(descriptor->InputCount()));
-  }
-
-  CallBuffer buffer(zone(), descriptor, frame_state_descriptor);
-
-  // Compute InstructionOperands for inputs and outputs.
-  // TODO(turbofan): on ARM64 it's probably better to use the code object in a
-  // register if there are multiple uses of it. Improve constant pool and the
-  // heuristics in the register allocator for where to emit constants.
-  InitializeCallBuffer(node, &buffer, true, false);
 
   // Push the arguments to the stack.
-  bool pushed_count_uneven = buffer.pushed_nodes.size() & 1;
-  int aligned_push_count = buffer.pushed_nodes.size();
+  int aligned_push_count = static_cast<int>(arguments->size());
+
+  bool pushed_count_uneven = aligned_push_count & 1;
+  int claim_count = aligned_push_count;
+  if (pushed_count_uneven && descriptor->UseNativeStack()) {
+    // We can only claim for an even number of call arguments when we use the
+    // native stack.
+    claim_count++;
+  }
   // TODO(dcarney): claim and poke probably take small immediates,
   //                loop here or whatever.
   // Bump the stack pointer(s).
   if (aligned_push_count > 0) {
     // TODO(dcarney): it would be better to bump the csp here only
     //                and emit paired stores with increment for non c frames.
-    Emit(kArm64Claim | MiscField::encode(aligned_push_count), NULL);
+    Emit(kArm64ClaimForCallArguments, g.NoOutput(),
+         g.TempImmediate(claim_count));
   }
+
   // Move arguments to the stack.
-  {
-    int slot = buffer.pushed_nodes.size() - 1;
-    // Emit the uneven pushes.
-    if (pushed_count_uneven) {
-      Node* input = buffer.pushed_nodes[slot];
-      Emit(kArm64Poke | MiscField::encode(slot), NULL, g.UseRegister(input));
-      slot--;
-    }
-    // Now all pushes can be done in pairs.
-    for (; slot >= 0; slot -= 2) {
-      Emit(kArm64PokePair | MiscField::encode(slot), NULL,
-           g.UseRegister(buffer.pushed_nodes[slot]),
-           g.UseRegister(buffer.pushed_nodes[slot - 1]));
-    }
+  int slot = aligned_push_count - 1;
+  while (slot >= 0) {
+    Emit(kArm64Poke, g.NoOutput(), g.UseRegister((*arguments)[slot].node()),
+         g.TempImmediate(slot));
+    slot--;
+    // TODO(ahaas): Poke arguments in pairs if two subsequent arguments have the
+    //              same type.
+    // Emit(kArm64PokePair, g.NoOutput(), g.UseRegister((*arguments)[slot]),
+    //      g.UseRegister((*arguments)[slot - 1]), g.TempImmediate(slot));
+    // slot -= 2;
   }
-
-  // Select the appropriate opcode based on the call type.
-  InstructionCode opcode;
-  switch (descriptor->kind()) {
-    case CallDescriptor::kCallCodeObject: {
-      opcode = kArchCallCodeObject;
-      break;
-    }
-    case CallDescriptor::kCallJSFunction:
-      opcode = kArchCallJSFunction;
-      break;
-    default:
-      UNREACHABLE();
-      return;
-  }
-  opcode |= MiscField::encode(descriptor->flags());
-
-  // Emit the call instruction.
-  InstructionOperand** first_output =
-      buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL;
-  Instruction* call_instr =
-      Emit(opcode, buffer.outputs.size(), first_output,
-           buffer.instruction_args.size(), &buffer.instruction_args.front());
-  call_instr->MarkAsCall();
 }
 
 
+bool InstructionSelector::IsTailCallAddressImmediate() { return false; }
+
+
+namespace {
+
 // Shared routine for multiple compare operations.
-static void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
-                         InstructionOperand* left, InstructionOperand* right,
-                         FlagsContinuation* cont) {
+void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
+                  InstructionOperand left, InstructionOperand right,
+                  FlagsContinuation* cont) {
   Arm64OperandGenerator g(selector);
   opcode = cont->Encode(opcode);
   if (cont->IsBranch()) {
-    selector->Emit(opcode, NULL, left, right, g.Label(cont->true_block()),
-                   g.Label(cont->false_block()))->MarkAsControl();
+    selector->Emit(opcode, g.NoOutput(), left, right,
+                   g.Label(cont->true_block()), g.Label(cont->false_block()));
   } else {
     DCHECK(cont->IsSet());
     selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right);
@@ -1168,9 +1640,9 @@
 
 
 // Shared routine for multiple word compare operations.
-static void VisitWordCompare(InstructionSelector* selector, Node* node,
-                             InstructionCode opcode, FlagsContinuation* cont,
-                             bool commutative, ImmediateMode immediate_mode) {
+void VisitWordCompare(InstructionSelector* selector, Node* node,
+                      InstructionCode opcode, FlagsContinuation* cont,
+                      bool commutative, ImmediateMode immediate_mode) {
   Arm64OperandGenerator g(selector);
   Node* left = node->InputAt(0);
   Node* right = node->InputAt(1);
@@ -1190,43 +1662,94 @@
 }
 
 
-static void VisitWord32Compare(InstructionSelector* selector, Node* node,
-                               FlagsContinuation* cont) {
-  VisitWordCompare(selector, node, kArm64Cmp32, cont, false, kArithmeticImm);
+void VisitWord32Compare(InstructionSelector* selector, Node* node,
+                        FlagsContinuation* cont) {
+  Int32BinopMatcher m(node);
+  ArchOpcode opcode = kArm64Cmp32;
+
+  // Select negated compare for comparisons with negated right input.
+  if (m.right().IsInt32Sub()) {
+    Node* sub = m.right().node();
+    Int32BinopMatcher msub(sub);
+    if (msub.left().Is(0)) {
+      bool can_cover = selector->CanCover(node, sub);
+      node->ReplaceInput(1, msub.right().node());
+      // Even if the comparison node covers the subtraction, after the input
+      // replacement above, the node still won't cover the input to the
+      // subtraction; the subtraction still uses it.
+      // In order to get shifted operations to work, we must remove the rhs
+      // input to the subtraction, as TryMatchAnyShift requires this node to
+      // cover the input shift. We do this by setting it to the lhs input,
+      // as we know it's zero, and the result of the subtraction isn't used by
+      // any other node.
+      if (can_cover) sub->ReplaceInput(1, msub.left().node());
+      opcode = kArm64Cmn32;
+    }
+  }
+  VisitBinop<Int32BinopMatcher>(selector, node, opcode, kArithmeticImm, cont);
 }
 
 
-static void VisitWordTest(InstructionSelector* selector, Node* node,
-                          InstructionCode opcode, FlagsContinuation* cont) {
+void VisitWordTest(InstructionSelector* selector, Node* node,
+                   InstructionCode opcode, FlagsContinuation* cont) {
   Arm64OperandGenerator g(selector);
   VisitCompare(selector, opcode, g.UseRegister(node), g.UseRegister(node),
                cont);
 }
 
 
-static void VisitWord32Test(InstructionSelector* selector, Node* node,
-                            FlagsContinuation* cont) {
+void VisitWord32Test(InstructionSelector* selector, Node* node,
+                     FlagsContinuation* cont) {
   VisitWordTest(selector, node, kArm64Tst32, cont);
 }
 
 
-static void VisitWord64Test(InstructionSelector* selector, Node* node,
-                            FlagsContinuation* cont) {
+void VisitWord64Test(InstructionSelector* selector, Node* node,
+                     FlagsContinuation* cont) {
   VisitWordTest(selector, node, kArm64Tst, cont);
 }
 
 
-// Shared routine for multiple float compare operations.
-static void VisitFloat64Compare(InstructionSelector* selector, Node* node,
-                                FlagsContinuation* cont) {
+// Shared routine for multiple float32 compare operations.
+void VisitFloat32Compare(InstructionSelector* selector, Node* node,
+                         FlagsContinuation* cont) {
   Arm64OperandGenerator g(selector);
-  Node* left = node->InputAt(0);
-  Node* right = node->InputAt(1);
-  VisitCompare(selector, kArm64Float64Cmp, g.UseRegister(left),
-               g.UseRegister(right), cont);
+  Float32BinopMatcher m(node);
+  if (m.right().Is(0.0f)) {
+    VisitCompare(selector, kArm64Float32Cmp, g.UseRegister(m.left().node()),
+                 g.UseImmediate(m.right().node()), cont);
+  } else if (m.left().Is(0.0f)) {
+    cont->Commute();
+    VisitCompare(selector, kArm64Float32Cmp, g.UseRegister(m.right().node()),
+                 g.UseImmediate(m.left().node()), cont);
+  } else {
+    VisitCompare(selector, kArm64Float32Cmp, g.UseRegister(m.left().node()),
+                 g.UseRegister(m.right().node()), cont);
+  }
 }
 
 
+// Shared routine for multiple float64 compare operations.
+void VisitFloat64Compare(InstructionSelector* selector, Node* node,
+                         FlagsContinuation* cont) {
+  Arm64OperandGenerator g(selector);
+  Float64BinopMatcher m(node);
+  if (m.right().Is(0.0)) {
+    VisitCompare(selector, kArm64Float64Cmp, g.UseRegister(m.left().node()),
+                 g.UseImmediate(m.right().node()), cont);
+  } else if (m.left().Is(0.0)) {
+    cont->Commute();
+    VisitCompare(selector, kArm64Float64Cmp, g.UseRegister(m.right().node()),
+                 g.UseImmediate(m.left().node()), cont);
+  } else {
+    VisitCompare(selector, kArm64Float64Cmp, g.UseRegister(m.left().node()),
+                 g.UseRegister(m.right().node()), cont);
+  }
+}
+
+}  // namespace
+
+
 void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
                                       BasicBlock* fbranch) {
   OperandGenerator g(this);
@@ -1236,25 +1759,12 @@
   FlagsContinuation cont(kNotEqual, tbranch, fbranch);
 
   // Try to combine with comparisons against 0 by simply inverting the branch.
-  while (CanCover(user, value)) {
-    if (value->opcode() == IrOpcode::kWord32Equal) {
-      Int32BinopMatcher m(value);
-      if (m.right().Is(0)) {
-        user = value;
-        value = m.left().node();
-        cont.Negate();
-      } else {
-        break;
-      }
-    } else if (value->opcode() == IrOpcode::kWord64Equal) {
-      Int64BinopMatcher m(value);
-      if (m.right().Is(0)) {
-        user = value;
-        value = m.left().node();
-        cont.Negate();
-      } else {
-        break;
-      }
+  while (CanCover(user, value) && value->opcode() == IrOpcode::kWord32Equal) {
+    Int32BinopMatcher m(value);
+    if (m.right().Is(0)) {
+      user = value;
+      value = m.left().node();
+      cont.Negate();
     } else {
       break;
     }
@@ -1294,27 +1804,40 @@
         cont.OverwriteAndNegateIfEqual(kUnsignedLessThan);
         return VisitWordCompare(this, value, kArm64Cmp, &cont, false,
                                 kArithmeticImm);
+      case IrOpcode::kUint64LessThanOrEqual:
+        cont.OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
+        return VisitWordCompare(this, value, kArm64Cmp, &cont, false,
+                                kArithmeticImm);
+      case IrOpcode::kFloat32Equal:
+        cont.OverwriteAndNegateIfEqual(kEqual);
+        return VisitFloat32Compare(this, value, &cont);
+      case IrOpcode::kFloat32LessThan:
+        cont.OverwriteAndNegateIfEqual(kFloatLessThan);
+        return VisitFloat32Compare(this, value, &cont);
+      case IrOpcode::kFloat32LessThanOrEqual:
+        cont.OverwriteAndNegateIfEqual(kFloatLessThanOrEqual);
+        return VisitFloat32Compare(this, value, &cont);
       case IrOpcode::kFloat64Equal:
-        cont.OverwriteAndNegateIfEqual(kUnorderedEqual);
+        cont.OverwriteAndNegateIfEqual(kEqual);
         return VisitFloat64Compare(this, value, &cont);
       case IrOpcode::kFloat64LessThan:
-        cont.OverwriteAndNegateIfEqual(kUnorderedLessThan);
+        cont.OverwriteAndNegateIfEqual(kFloatLessThan);
         return VisitFloat64Compare(this, value, &cont);
       case IrOpcode::kFloat64LessThanOrEqual:
-        cont.OverwriteAndNegateIfEqual(kUnorderedLessThanOrEqual);
+        cont.OverwriteAndNegateIfEqual(kFloatLessThanOrEqual);
         return VisitFloat64Compare(this, value, &cont);
       case IrOpcode::kProjection:
         // Check if this is the overflow output projection of an
         // <Operation>WithOverflow node.
-        if (OpParameter<size_t>(value) == 1u) {
+        if (ProjectionIndexOf(value->op()) == 1u) {
           // We cannot combine the <Operation>WithOverflow with this branch
           // unless the 0th projection (the use of the actual value of the
-          // <Operation> is either NULL, which means there's no use of the
+          // <Operation> is either nullptr, which means there's no use of the
           // actual value, or was already defined, which means it is scheduled
           // *AFTER* this branch).
-          Node* node = value->InputAt(0);
-          Node* result = node->FindProjection(0);
-          if (result == NULL || IsDefined(result)) {
+          Node* const node = value->InputAt(0);
+          Node* const result = NodeProperties::FindProjection(node, 0);
+          if (result == nullptr || IsDefined(result)) {
             switch (node->opcode()) {
               case IrOpcode::kInt32AddWithOverflow:
                 cont.OverwriteAndNegateIfEqual(kOverflow);
@@ -1324,6 +1847,14 @@
                 cont.OverwriteAndNegateIfEqual(kOverflow);
                 return VisitBinop<Int32BinopMatcher>(this, node, kArm64Sub32,
                                                      kArithmeticImm, &cont);
+              case IrOpcode::kInt64AddWithOverflow:
+                cont.OverwriteAndNegateIfEqual(kOverflow);
+                return VisitBinop<Int64BinopMatcher>(this, node, kArm64Add,
+                                                     kArithmeticImm, &cont);
+              case IrOpcode::kInt64SubWithOverflow:
+                cont.OverwriteAndNegateIfEqual(kOverflow);
+                return VisitBinop<Int64BinopMatcher>(this, node, kArm64Sub,
+                                                     kArithmeticImm, &cont);
               default:
                 break;
             }
@@ -1334,8 +1865,7 @@
         return VisitWordCompare(this, value, kArm64Cmn32, &cont, true,
                                 kArithmeticImm);
       case IrOpcode::kInt32Sub:
-        return VisitWordCompare(this, value, kArm64Cmp32, &cont, false,
-                                kArithmeticImm);
+        return VisitWord32Compare(this, value, &cont);
       case IrOpcode::kWord32And: {
         Int32BinopMatcher m(value);
         if (m.right().HasValue() &&
@@ -1343,12 +1873,11 @@
           // If the mask has only one bit set, we can use tbz/tbnz.
           DCHECK((cont.condition() == kEqual) ||
                  (cont.condition() == kNotEqual));
-          Emit(cont.Encode(kArm64TestAndBranch32), NULL,
+          Emit(cont.Encode(kArm64TestAndBranch32), g.NoOutput(),
                g.UseRegister(m.left().node()),
                g.TempImmediate(
                    base::bits::CountTrailingZeros32(m.right().Value())),
-               g.Label(cont.true_block()),
-               g.Label(cont.false_block()))->MarkAsControl();
+               g.Label(cont.true_block()), g.Label(cont.false_block()));
           return;
         }
         return VisitWordCompare(this, value, kArm64Tst32, &cont, true,
@@ -1361,12 +1890,11 @@
           // If the mask has only one bit set, we can use tbz/tbnz.
           DCHECK((cont.condition() == kEqual) ||
                  (cont.condition() == kNotEqual));
-          Emit(cont.Encode(kArm64TestAndBranch), NULL,
+          Emit(cont.Encode(kArm64TestAndBranch), g.NoOutput(),
                g.UseRegister(m.left().node()),
                g.TempImmediate(
                    base::bits::CountTrailingZeros64(m.right().Value())),
-               g.Label(cont.true_block()),
-               g.Label(cont.false_block()))->MarkAsControl();
+               g.Label(cont.true_block()), g.Label(cont.false_block()));
           return;
         }
         return VisitWordCompare(this, value, kArm64Tst, &cont, true,
@@ -1378,9 +1906,37 @@
   }
 
   // Branch could not be combined with a compare, compare against 0 and branch.
-  Emit(cont.Encode(kArm64CompareAndBranch32), NULL, g.UseRegister(value),
-       g.Label(cont.true_block()),
-       g.Label(cont.false_block()))->MarkAsControl();
+  Emit(cont.Encode(kArm64CompareAndBranch32), g.NoOutput(),
+       g.UseRegister(value), g.Label(cont.true_block()),
+       g.Label(cont.false_block()));
+}
+
+
+void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) {
+  Arm64OperandGenerator g(this);
+  InstructionOperand value_operand = g.UseRegister(node->InputAt(0));
+
+  // Emit either ArchTableSwitch or ArchLookupSwitch.
+  size_t table_space_cost = 4 + sw.value_range;
+  size_t table_time_cost = 3;
+  size_t lookup_space_cost = 3 + 2 * sw.case_count;
+  size_t lookup_time_cost = sw.case_count;
+  if (sw.case_count > 0 &&
+      table_space_cost + 3 * table_time_cost <=
+          lookup_space_cost + 3 * lookup_time_cost &&
+      sw.min_value > std::numeric_limits<int32_t>::min()) {
+    InstructionOperand index_operand = value_operand;
+    if (sw.min_value) {
+      index_operand = g.TempRegister();
+      Emit(kArm64Sub32, index_operand, value_operand,
+           g.TempImmediate(sw.min_value));
+    }
+    // Generate a table lookup.
+    return EmitTableSwitch(sw, index_operand);
+  }
+
+  // Generate a sequence of conditional jumps.
+  return EmitLookupSwitch(sw, value_operand);
 }
 
 
@@ -1401,6 +1957,14 @@
         case IrOpcode::kWord32And:
           return VisitWordCompare(this, value, kArm64Tst32, &cont, true,
                                   kLogical32Imm);
+        case IrOpcode::kWord32Equal: {
+          // Word32Equal(Word32Equal(x, y), 0) => Word32Compare(x, y, ne).
+          Int32BinopMatcher mequal(value);
+          node->ReplaceInput(0, mequal.left().node());
+          node->ReplaceInput(1, mequal.right().node());
+          cont.Negate();
+          return VisitWord32Compare(this, node, &cont);
+        }
         default:
           break;
       }
@@ -1457,7 +2021,7 @@
 
 
 void InstructionSelector::VisitInt32AddWithOverflow(Node* node) {
-  if (Node* ovf = node->FindProjection(1)) {
+  if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
     FlagsContinuation cont(kOverflow, ovf);
     return VisitBinop<Int32BinopMatcher>(this, node, kArm64Add32,
                                          kArithmeticImm, &cont);
@@ -1468,7 +2032,7 @@
 
 
 void InstructionSelector::VisitInt32SubWithOverflow(Node* node) {
-  if (Node* ovf = node->FindProjection(1)) {
+  if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
     FlagsContinuation cont(kOverflow, ovf);
     return VisitBinop<Int32BinopMatcher>(this, node, kArm64Sub32,
                                          kArithmeticImm, &cont);
@@ -1478,6 +2042,28 @@
 }
 
 
+void InstructionSelector::VisitInt64AddWithOverflow(Node* node) {
+  if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
+    FlagsContinuation cont(kOverflow, ovf);
+    return VisitBinop<Int64BinopMatcher>(this, node, kArm64Add, kArithmeticImm,
+                                         &cont);
+  }
+  FlagsContinuation cont;
+  VisitBinop<Int64BinopMatcher>(this, node, kArm64Add, kArithmeticImm, &cont);
+}
+
+
+void InstructionSelector::VisitInt64SubWithOverflow(Node* node) {
+  if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
+    FlagsContinuation cont(kOverflow, ovf);
+    return VisitBinop<Int64BinopMatcher>(this, node, kArm64Sub, kArithmeticImm,
+                                         &cont);
+  }
+  FlagsContinuation cont;
+  VisitBinop<Int64BinopMatcher>(this, node, kArm64Sub, kArithmeticImm, &cont);
+}
+
+
 void InstructionSelector::VisitInt64LessThan(Node* node) {
   FlagsContinuation cont(kSignedLessThan, node);
   VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm);
@@ -1496,35 +2082,118 @@
 }
 
 
+void InstructionSelector::VisitUint64LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kUnsignedLessThanOrEqual, node);
+  VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm);
+}
+
+
+void InstructionSelector::VisitFloat32Equal(Node* node) {
+  FlagsContinuation cont(kEqual, node);
+  VisitFloat32Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitFloat32LessThan(Node* node) {
+  FlagsContinuation cont(kFloatLessThan, node);
+  VisitFloat32Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitFloat32LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kFloatLessThanOrEqual, node);
+  VisitFloat32Compare(this, node, &cont);
+}
+
+
 void InstructionSelector::VisitFloat64Equal(Node* node) {
-  FlagsContinuation cont(kUnorderedEqual, node);
+  FlagsContinuation cont(kEqual, node);
   VisitFloat64Compare(this, node, &cont);
 }
 
 
 void InstructionSelector::VisitFloat64LessThan(Node* node) {
-  FlagsContinuation cont(kUnorderedLessThan, node);
+  FlagsContinuation cont(kFloatLessThan, node);
   VisitFloat64Compare(this, node, &cont);
 }
 
 
 void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
-  FlagsContinuation cont(kUnorderedLessThanOrEqual, node);
+  FlagsContinuation cont(kFloatLessThanOrEqual, node);
   VisitFloat64Compare(this, node, &cont);
 }
 
 
+void InstructionSelector::VisitFloat64ExtractLowWord32(Node* node) {
+  Arm64OperandGenerator g(this);
+  Emit(kArm64Float64ExtractLowWord32, g.DefineAsRegister(node),
+       g.UseRegister(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitFloat64ExtractHighWord32(Node* node) {
+  Arm64OperandGenerator g(this);
+  Emit(kArm64Float64ExtractHighWord32, g.DefineAsRegister(node),
+       g.UseRegister(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitFloat64InsertLowWord32(Node* node) {
+  Arm64OperandGenerator g(this);
+  Node* left = node->InputAt(0);
+  Node* right = node->InputAt(1);
+  if (left->opcode() == IrOpcode::kFloat64InsertHighWord32 &&
+      CanCover(node, left)) {
+    Node* right_of_left = left->InputAt(1);
+    Emit(kArm64Bfi, g.DefineSameAsFirst(right), g.UseRegister(right),
+         g.UseRegister(right_of_left), g.TempImmediate(32),
+         g.TempImmediate(32));
+    Emit(kArm64Float64MoveU64, g.DefineAsRegister(node), g.UseRegister(right));
+    return;
+  }
+  Emit(kArm64Float64InsertLowWord32, g.DefineAsRegister(node),
+       g.UseRegister(left), g.UseRegister(right));
+}
+
+
+void InstructionSelector::VisitFloat64InsertHighWord32(Node* node) {
+  Arm64OperandGenerator g(this);
+  Node* left = node->InputAt(0);
+  Node* right = node->InputAt(1);
+  if (left->opcode() == IrOpcode::kFloat64InsertLowWord32 &&
+      CanCover(node, left)) {
+    Node* right_of_left = left->InputAt(1);
+    Emit(kArm64Bfi, g.DefineSameAsFirst(left), g.UseRegister(right_of_left),
+         g.UseRegister(right), g.TempImmediate(32), g.TempImmediate(32));
+    Emit(kArm64Float64MoveU64, g.DefineAsRegister(node), g.UseRegister(left));
+    return;
+  }
+  Emit(kArm64Float64InsertHighWord32, g.DefineAsRegister(node),
+       g.UseRegister(left), g.UseRegister(right));
+}
+
+
 // static
 MachineOperatorBuilder::Flags
 InstructionSelector::SupportedMachineOperatorFlags() {
-  return MachineOperatorBuilder::kFloat64Floor |
-         MachineOperatorBuilder::kFloat64Ceil |
+  return MachineOperatorBuilder::kFloat32Max |
+         MachineOperatorBuilder::kFloat32Min |
+         MachineOperatorBuilder::kFloat32RoundDown |
+         MachineOperatorBuilder::kFloat64Max |
+         MachineOperatorBuilder::kFloat64Min |
+         MachineOperatorBuilder::kFloat64RoundDown |
+         MachineOperatorBuilder::kFloat32RoundUp |
+         MachineOperatorBuilder::kFloat64RoundUp |
+         MachineOperatorBuilder::kFloat32RoundTruncate |
          MachineOperatorBuilder::kFloat64RoundTruncate |
          MachineOperatorBuilder::kFloat64RoundTiesAway |
+         MachineOperatorBuilder::kFloat32RoundTiesEven |
+         MachineOperatorBuilder::kFloat64RoundTiesEven |
          MachineOperatorBuilder::kWord32ShiftIsSafe |
          MachineOperatorBuilder::kInt32DivIsSafe |
          MachineOperatorBuilder::kUint32DivIsSafe;
 }
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/src/compiler/arm64/linkage-arm64.cc b/src/compiler/arm64/linkage-arm64.cc
deleted file mode 100644
index 291b552..0000000
--- a/src/compiler/arm64/linkage-arm64.cc
+++ /dev/null
@@ -1,67 +0,0 @@
-// 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/v8.h"
-
-#include "src/assembler.h"
-#include "src/code-stubs.h"
-#include "src/compiler/linkage.h"
-#include "src/compiler/linkage-impl.h"
-#include "src/zone.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-struct Arm64LinkageHelperTraits {
-  static Register ReturnValueReg() { return x0; }
-  static Register ReturnValue2Reg() { return x1; }
-  static Register JSCallFunctionReg() { return x1; }
-  static Register ContextReg() { return cp; }
-  static Register RuntimeCallFunctionReg() { return x1; }
-  static Register RuntimeCallArgCountReg() { return x0; }
-  static RegList CCalleeSaveRegisters() {
-    // TODO(dcarney): correct callee saved registers.
-    return 0;
-  }
-  static Register CRegisterParameter(int i) {
-    static Register register_parameters[] = {x0, x1, x2, x3, x4, x5, x6, x7};
-    return register_parameters[i];
-  }
-  static int CRegisterParametersLength() { return 8; }
-};
-
-
-typedef LinkageHelper<Arm64LinkageHelperTraits> LH;
-
-CallDescriptor* Linkage::GetJSCallDescriptor(int parameter_count, Zone* zone,
-                                             CallDescriptor::Flags flags) {
-  return LH::GetJSCallDescriptor(zone, parameter_count, flags);
-}
-
-
-CallDescriptor* Linkage::GetRuntimeCallDescriptor(
-    Runtime::FunctionId function, int parameter_count,
-    Operator::Properties properties, Zone* zone) {
-  return LH::GetRuntimeCallDescriptor(zone, function, parameter_count,
-                                      properties);
-}
-
-
-CallDescriptor* Linkage::GetStubCallDescriptor(
-    const CallInterfaceDescriptor& descriptor, int stack_parameter_count,
-    CallDescriptor::Flags flags, Operator::Properties properties, Zone* zone) {
-  return LH::GetStubCallDescriptor(zone, descriptor, stack_parameter_count,
-                                   flags, properties);
-}
-
-
-CallDescriptor* Linkage::GetSimplifiedCDescriptor(Zone* zone,
-                                                  MachineSignature* sig) {
-  return LH::GetSimplifiedCDescriptor(zone, sig);
-}
-
-}  // namespace compiler
-}  // namespace internal
-}  // namespace v8
diff --git a/src/compiler/ast-graph-builder.cc b/src/compiler/ast-graph-builder.cc
index cde5e71..c70dfbf 100644
--- a/src/compiler/ast-graph-builder.cc
+++ b/src/compiler/ast-graph-builder.cc
@@ -4,38 +4,481 @@
 
 #include "src/compiler/ast-graph-builder.h"
 
+#include "src/ast/scopes.h"
 #include "src/compiler.h"
 #include "src/compiler/ast-loop-assignment-analyzer.h"
 #include "src/compiler/control-builders.h"
+#include "src/compiler/linkage.h"
+#include "src/compiler/liveness-analyzer.h"
 #include "src/compiler/machine-operator.h"
 #include "src/compiler/node-matchers.h"
-#include "src/compiler/node-properties-inl.h"
 #include "src/compiler/node-properties.h"
-#include "src/full-codegen.h"
-#include "src/parser.h"
-#include "src/scopes.h"
+#include "src/compiler/operator-properties.h"
+#include "src/compiler/state-values-utils.h"
+#include "src/compiler/type-hint-analyzer.h"
+#include "src/parsing/parser.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
+
+// Each expression in the AST is evaluated in a specific context. This context
+// decides how the evaluation result is passed up the visitor.
+class AstGraphBuilder::AstContext BASE_EMBEDDED {
+ public:
+  bool IsEffect() const { return kind_ == Expression::kEffect; }
+  bool IsValue() const { return kind_ == Expression::kValue; }
+  bool IsTest() const { return kind_ == Expression::kTest; }
+
+  // Determines how to combine the frame state with the value
+  // that is about to be plugged into this AstContext.
+  OutputFrameStateCombine GetStateCombine() {
+    return IsEffect() ? OutputFrameStateCombine::Ignore()
+                      : OutputFrameStateCombine::Push();
+  }
+
+  // Plug a node into this expression context.  Call this function in tail
+  // position in the Visit functions for expressions.
+  virtual void ProduceValue(Node* value) = 0;
+
+  // Unplugs a node from this expression context.  Call this to retrieve the
+  // result of another Visit function that already plugged the context.
+  virtual Node* ConsumeValue() = 0;
+
+  // Shortcut for "context->ProduceValue(context->ConsumeValue())".
+  void ReplaceValue() { ProduceValue(ConsumeValue()); }
+
+ protected:
+  AstContext(AstGraphBuilder* owner, Expression::Context kind);
+  virtual ~AstContext();
+
+  AstGraphBuilder* owner() const { return owner_; }
+  Environment* environment() const { return owner_->environment(); }
+
+// We want to be able to assert, in a context-specific way, that the stack
+// height makes sense when the context is filled.
+#ifdef DEBUG
+  int original_height_;
+#endif
+
+ private:
+  Expression::Context kind_;
+  AstGraphBuilder* owner_;
+  AstContext* outer_;
+};
+
+
+// Context to evaluate expression for its side effects only.
+class AstGraphBuilder::AstEffectContext final : public AstContext {
+ public:
+  explicit AstEffectContext(AstGraphBuilder* owner)
+      : AstContext(owner, Expression::kEffect) {}
+  ~AstEffectContext() final;
+  void ProduceValue(Node* value) final;
+  Node* ConsumeValue() final;
+};
+
+
+// Context to evaluate expression for its value (and side effects).
+class AstGraphBuilder::AstValueContext final : public AstContext {
+ public:
+  explicit AstValueContext(AstGraphBuilder* owner)
+      : AstContext(owner, Expression::kValue) {}
+  ~AstValueContext() final;
+  void ProduceValue(Node* value) final;
+  Node* ConsumeValue() final;
+};
+
+
+// Context to evaluate expression for a condition value (and side effects).
+class AstGraphBuilder::AstTestContext final : public AstContext {
+ public:
+  AstTestContext(AstGraphBuilder* owner, TypeFeedbackId feedback_id)
+      : AstContext(owner, Expression::kTest), feedback_id_(feedback_id) {}
+  ~AstTestContext() final;
+  void ProduceValue(Node* value) final;
+  Node* ConsumeValue() final;
+
+ private:
+  TypeFeedbackId const feedback_id_;
+};
+
+
+// Scoped class tracking context objects created by the visitor. Represents
+// mutations of the context chain within the function body and allows to
+// change the current {scope} and {context} during visitation.
+class AstGraphBuilder::ContextScope BASE_EMBEDDED {
+ public:
+  ContextScope(AstGraphBuilder* builder, Scope* scope, Node* context)
+      : builder_(builder),
+        outer_(builder->execution_context()),
+        scope_(scope),
+        depth_(builder_->environment()->context_chain_length()) {
+    builder_->environment()->PushContext(context);  // Push.
+    builder_->set_execution_context(this);
+  }
+
+  ~ContextScope() {
+    builder_->set_execution_context(outer_);  // Pop.
+    builder_->environment()->PopContext();
+    CHECK_EQ(depth_, builder_->environment()->context_chain_length());
+  }
+
+  // Current scope during visitation.
+  Scope* scope() const { return scope_; }
+
+ private:
+  AstGraphBuilder* builder_;
+  ContextScope* outer_;
+  Scope* scope_;
+  int depth_;
+};
+
+
+// Scoped class tracking control statements entered by the visitor. There are
+// different types of statements participating in this stack to properly track
+// local as well as non-local control flow:
+//  - IterationStatement : Allows proper 'break' and 'continue' behavior.
+//  - BreakableStatement : Allows 'break' from block and switch statements.
+//  - TryCatchStatement  : Intercepts 'throw' and implicit exceptional edges.
+//  - TryFinallyStatement: Intercepts 'break', 'continue', 'throw' and 'return'.
+class AstGraphBuilder::ControlScope BASE_EMBEDDED {
+ public:
+  explicit ControlScope(AstGraphBuilder* builder)
+      : builder_(builder),
+        outer_(builder->execution_control()),
+        context_length_(builder->environment()->context_chain_length()),
+        stack_height_(builder->environment()->stack_height()) {
+    builder_->set_execution_control(this);  // Push.
+  }
+
+  virtual ~ControlScope() {
+    builder_->set_execution_control(outer_);  // Pop.
+  }
+
+  // Either 'break' or 'continue' to the target statement.
+  void BreakTo(BreakableStatement* target);
+  void ContinueTo(BreakableStatement* target);
+
+  // Either 'return' or 'throw' the given value.
+  void ReturnValue(Node* return_value);
+  void ThrowValue(Node* exception_value);
+
+  class DeferredCommands;
+
+ protected:
+  enum Command { CMD_BREAK, CMD_CONTINUE, CMD_RETURN, CMD_THROW };
+
+  // Performs one of the above commands on this stack of control scopes. This
+  // walks through the stack giving each scope a chance to execute or defer the
+  // given command by overriding the {Execute} method appropriately. Note that
+  // this also drops extra operands from the environment for each skipped scope.
+  void PerformCommand(Command cmd, Statement* target, Node* value);
+
+  // Interface to execute a given command in this scope. Returning {true} here
+  // indicates successful execution whereas {false} requests to skip scope.
+  virtual bool Execute(Command cmd, Statement* target, Node* value) {
+    // For function-level control.
+    switch (cmd) {
+      case CMD_THROW:
+        builder()->BuildThrow(value);
+        return true;
+      case CMD_RETURN:
+        builder()->BuildReturn(value);
+        return true;
+      case CMD_BREAK:
+      case CMD_CONTINUE:
+        break;
+    }
+    return false;
+  }
+
+  Environment* environment() { return builder_->environment(); }
+  AstGraphBuilder* builder() const { return builder_; }
+  int context_length() const { return context_length_; }
+  int stack_height() const { return stack_height_; }
+
+ private:
+  AstGraphBuilder* builder_;
+  ControlScope* outer_;
+  int context_length_;
+  int stack_height_;
+};
+
+
+// Helper class for a try-finally control scope. It can record intercepted
+// control-flow commands that cause entry into a finally-block, and re-apply
+// them after again leaving that block. Special tokens are used to identify
+// paths going through the finally-block to dispatch after leaving the block.
+class AstGraphBuilder::ControlScope::DeferredCommands : public ZoneObject {
+ public:
+  explicit DeferredCommands(AstGraphBuilder* owner)
+      : owner_(owner), deferred_(owner->local_zone()) {}
+
+  // One recorded control-flow command.
+  struct Entry {
+    Command command;       // The command type being applied on this path.
+    Statement* statement;  // The target statement for the command or {nullptr}.
+    Node* token;           // A token identifying this particular path.
+  };
+
+  // Records a control-flow command while entering the finally-block. This also
+  // generates a new dispatch token that identifies one particular path.
+  Node* RecordCommand(Command cmd, Statement* stmt, Node* value) {
+    Node* token = NewPathTokenForDeferredCommand();
+    deferred_.push_back({cmd, stmt, token});
+    return token;
+  }
+
+  // Returns the dispatch token to be used to identify the implicit fall-through
+  // path at the end of a try-block into the corresponding finally-block.
+  Node* GetFallThroughToken() { return NewPathTokenForImplicitFallThrough(); }
+
+  // Applies all recorded control-flow commands after the finally-block again.
+  // This generates a dynamic dispatch on the token from the entry point.
+  void ApplyDeferredCommands(Node* token, Node* value) {
+    SwitchBuilder dispatch(owner_, static_cast<int>(deferred_.size()));
+    dispatch.BeginSwitch();
+    for (size_t i = 0; i < deferred_.size(); ++i) {
+      Node* condition = NewPathDispatchCondition(token, deferred_[i].token);
+      dispatch.BeginLabel(static_cast<int>(i), condition);
+      dispatch.EndLabel();
+    }
+    for (size_t i = 0; i < deferred_.size(); ++i) {
+      dispatch.BeginCase(static_cast<int>(i));
+      owner_->execution_control()->PerformCommand(
+          deferred_[i].command, deferred_[i].statement, value);
+      dispatch.EndCase();
+    }
+    dispatch.EndSwitch();
+  }
+
+ protected:
+  Node* NewPathTokenForDeferredCommand() {
+    return owner_->jsgraph()->Constant(static_cast<int>(deferred_.size()));
+  }
+  Node* NewPathTokenForImplicitFallThrough() {
+    return owner_->jsgraph()->Constant(-1);
+  }
+  Node* NewPathDispatchCondition(Node* t1, Node* t2) {
+    // TODO(mstarzinger): This should be machine()->WordEqual(), but our Phi
+    // nodes all have kRepTagged|kTypeAny, which causes representation mismatch.
+    return owner_->NewNode(owner_->javascript()->StrictEqual(), t1, t2);
+  }
+
+ private:
+  AstGraphBuilder* owner_;
+  ZoneVector<Entry> deferred_;
+};
+
+
+// Control scope implementation for a BreakableStatement.
+class AstGraphBuilder::ControlScopeForBreakable : public ControlScope {
+ public:
+  ControlScopeForBreakable(AstGraphBuilder* owner, BreakableStatement* target,
+                           ControlBuilder* control)
+      : ControlScope(owner), target_(target), control_(control) {}
+
+ protected:
+  bool Execute(Command cmd, Statement* target, Node* value) override {
+    if (target != target_) return false;  // We are not the command target.
+    switch (cmd) {
+      case CMD_BREAK:
+        control_->Break();
+        return true;
+      case CMD_CONTINUE:
+      case CMD_THROW:
+      case CMD_RETURN:
+        break;
+    }
+    return false;
+  }
+
+ private:
+  BreakableStatement* target_;
+  ControlBuilder* control_;
+};
+
+
+// Control scope implementation for an IterationStatement.
+class AstGraphBuilder::ControlScopeForIteration : public ControlScope {
+ public:
+  ControlScopeForIteration(AstGraphBuilder* owner, IterationStatement* target,
+                           LoopBuilder* control)
+      : ControlScope(owner), target_(target), control_(control) {}
+
+ protected:
+  bool Execute(Command cmd, Statement* target, Node* value) override {
+    if (target != target_) return false;  // We are not the command target.
+    switch (cmd) {
+      case CMD_BREAK:
+        control_->Break();
+        return true;
+      case CMD_CONTINUE:
+        control_->Continue();
+        return true;
+      case CMD_THROW:
+      case CMD_RETURN:
+        break;
+    }
+    return false;
+  }
+
+ private:
+  BreakableStatement* target_;
+  LoopBuilder* control_;
+};
+
+
+// Control scope implementation for a TryCatchStatement.
+class AstGraphBuilder::ControlScopeForCatch : public ControlScope {
+ public:
+  ControlScopeForCatch(AstGraphBuilder* owner, TryCatchBuilder* control)
+      : ControlScope(owner), control_(control) {
+    builder()->try_nesting_level_++;  // Increment nesting.
+    builder()->try_catch_nesting_level_++;
+  }
+  ~ControlScopeForCatch() {
+    builder()->try_nesting_level_--;  // Decrement nesting.
+    builder()->try_catch_nesting_level_--;
+  }
+
+ protected:
+  bool Execute(Command cmd, Statement* target, Node* value) override {
+    switch (cmd) {
+      case CMD_THROW:
+        control_->Throw(value);
+        return true;
+      case CMD_BREAK:
+      case CMD_CONTINUE:
+      case CMD_RETURN:
+        break;
+    }
+    return false;
+  }
+
+ private:
+  TryCatchBuilder* control_;
+};
+
+
+// Control scope implementation for a TryFinallyStatement.
+class AstGraphBuilder::ControlScopeForFinally : public ControlScope {
+ public:
+  ControlScopeForFinally(AstGraphBuilder* owner, DeferredCommands* commands,
+                         TryFinallyBuilder* control)
+      : ControlScope(owner), commands_(commands), control_(control) {
+    builder()->try_nesting_level_++;  // Increment nesting.
+  }
+  ~ControlScopeForFinally() {
+    builder()->try_nesting_level_--;  // Decrement nesting.
+  }
+
+ protected:
+  bool Execute(Command cmd, Statement* target, Node* value) override {
+    Node* token = commands_->RecordCommand(cmd, target, value);
+    control_->LeaveTry(token, value);
+    return true;
+  }
+
+ private:
+  DeferredCommands* commands_;
+  TryFinallyBuilder* control_;
+};
+
+
+// Helper for generating before and after frame states.
+class AstGraphBuilder::FrameStateBeforeAndAfter {
+ public:
+  FrameStateBeforeAndAfter(AstGraphBuilder* builder, BailoutId id_before)
+      : builder_(builder), frame_state_before_(nullptr) {
+    frame_state_before_ = id_before == BailoutId::None()
+                              ? builder_->jsgraph()->EmptyFrameState()
+                              : builder_->environment()->Checkpoint(id_before);
+  }
+
+  void AddToNode(
+      Node* node, BailoutId id_after,
+      OutputFrameStateCombine combine = OutputFrameStateCombine::Ignore()) {
+    int count = OperatorProperties::GetFrameStateInputCount(node->op());
+    DCHECK_LE(count, 2);
+
+    if (count >= 1) {
+      // Add the frame state for after the operation.
+      DCHECK_EQ(IrOpcode::kDead,
+                NodeProperties::GetFrameStateInput(node, 0)->opcode());
+
+      Node* frame_state_after =
+          id_after == BailoutId::None()
+              ? builder_->jsgraph()->EmptyFrameState()
+              : builder_->environment()->Checkpoint(id_after, combine);
+
+      NodeProperties::ReplaceFrameStateInput(node, 0, frame_state_after);
+    }
+
+    if (count >= 2) {
+      // Add the frame state for before the operation.
+      DCHECK_EQ(IrOpcode::kDead,
+                NodeProperties::GetFrameStateInput(node, 1)->opcode());
+      NodeProperties::ReplaceFrameStateInput(node, 1, frame_state_before_);
+    }
+  }
+
+ private:
+  AstGraphBuilder* builder_;
+  Node* frame_state_before_;
+};
+
+
 AstGraphBuilder::AstGraphBuilder(Zone* local_zone, CompilationInfo* info,
-                                 JSGraph* jsgraph, LoopAssignmentAnalysis* loop)
-    : StructuredGraphBuilder(local_zone, jsgraph->graph(), jsgraph->common()),
+                                 JSGraph* jsgraph, LoopAssignmentAnalysis* loop,
+                                 TypeHintAnalysis* type_hint_analysis)
+    : isolate_(info->isolate()),
+      local_zone_(local_zone),
       info_(info),
       jsgraph_(jsgraph),
+      environment_(nullptr),
+      ast_context_(nullptr),
       globals_(0, local_zone),
-      breakable_(NULL),
-      execution_context_(NULL),
-      loop_assignment_analysis_(loop) {
-  InitializeAstVisitor(local_zone);
+      execution_control_(nullptr),
+      execution_context_(nullptr),
+      try_catch_nesting_level_(0),
+      try_nesting_level_(0),
+      input_buffer_size_(0),
+      input_buffer_(nullptr),
+      exit_controls_(local_zone),
+      loop_assignment_analysis_(loop),
+      type_hint_analysis_(type_hint_analysis),
+      state_values_cache_(jsgraph),
+      liveness_analyzer_(static_cast<size_t>(info->scope()->num_stack_slots()),
+                         local_zone),
+      frame_state_function_info_(common()->CreateFrameStateFunctionInfo(
+          FrameStateType::kJavaScriptFunction, info->num_parameters() + 1,
+          info->scope()->num_stack_slots(), info->shared_info(),
+          CALL_MAINTAINS_NATIVE_CONTEXT)) {
+  InitializeAstVisitor(info->isolate());
+}
+
+
+Node* AstGraphBuilder::GetFunctionClosureForContext() {
+  Scope* closure_scope = current_scope()->ClosureScope();
+  if (closure_scope->is_script_scope() ||
+      closure_scope->is_module_scope()) {
+    // Contexts nested in the native context have a canonical empty function as
+    // their closure, not the anonymous closure containing the global code.
+    return BuildLoadNativeContextField(Context::CLOSURE_INDEX);
+  } else {
+    DCHECK(closure_scope->is_function_scope());
+    return GetFunctionClosure();
+  }
 }
 
 
 Node* AstGraphBuilder::GetFunctionClosure() {
   if (!function_closure_.is_set()) {
-    // Parameter -1 is special for the function closure
-    const Operator* op = common()->Parameter(-1);
+    int index = Linkage::kJSCallClosureParamIndex;
+    const Operator* op = common()->Parameter(index, "%closure");
     Node* node = NewNode(op, graph()->start());
     function_closure_.set(node);
   }
@@ -45,8 +488,9 @@
 
 Node* AstGraphBuilder::GetFunctionContext() {
   if (!function_context_.is_set()) {
-    // Parameter (arity + 1) is special for the outer context of the function
-    const Operator* op = common()->Parameter(info()->num_parameters() + 1);
+    int params = info()->num_parameters_including_this();
+    int index = Linkage::GetJSCallContextParamIndex(params);
+    const Operator* op = common()->Parameter(index, "%context");
     Node* node = NewNode(op, graph()->start());
     function_context_.set(node);
   }
@@ -54,58 +498,117 @@
 }
 
 
-bool AstGraphBuilder::CreateGraph() {
-  Scope* scope = info()->scope();
-  DCHECK(graph() != NULL);
+Node* AstGraphBuilder::GetNewTarget() {
+  if (!new_target_.is_set()) {
+    int params = info()->num_parameters_including_this();
+    int index = Linkage::GetJSCallNewTargetParamIndex(params);
+    const Operator* op = common()->Parameter(index, "%new.target");
+    Node* node = NewNode(op, graph()->start());
+    new_target_.set(node);
+  }
+  return new_target_.get();
+}
 
-  // Set up the basic structure of the graph.
-  int parameter_count = info()->num_parameters();
-  graph()->SetStart(graph()->NewNode(common()->Start(parameter_count)));
+
+bool AstGraphBuilder::CreateGraph(bool stack_check) {
+  Scope* scope = info()->scope();
+  DCHECK_NOT_NULL(graph());
+
+  // Set up the basic structure of the graph. Outputs for {Start} are the formal
+  // parameters (including the receiver) plus new target, number of arguments,
+  // context and closure.
+  int actual_parameter_count = info()->num_parameters_including_this() + 4;
+  graph()->SetStart(graph()->NewNode(common()->Start(actual_parameter_count)));
 
   // Initialize the top-level environment.
   Environment env(this, scope, graph()->start());
   set_environment(&env);
 
+  if (info()->is_osr()) {
+    // Use OSR normal entry as the start of the top-level environment.
+    // It will be replaced with {Dead} after typing and optimizations.
+    NewNode(common()->OsrNormalEntry());
+  }
+
   // Initialize the incoming context.
-  Node* outer_context = GetFunctionContext();
-  set_current_context(outer_context);
+  ContextScope incoming(this, scope, GetFunctionContext());
 
-  // Build receiver check for sloppy mode if necessary.
-  // TODO(mstarzinger/verwaest): Should this be moved back into the CallIC?
-  Node* original_receiver = env.Lookup(scope->receiver());
-  Node* patched_receiver = BuildPatchReceiverToGlobalProxy(original_receiver);
-  env.Bind(scope->receiver(), patched_receiver);
+  // Initialize control scope.
+  ControlScope control(this);
 
-  // Build node to initialize local function context.
-  Node* closure = GetFunctionClosure();
-  Node* inner_context = BuildLocalFunctionContext(outer_context, closure);
+  // TODO(mstarzinger): For now we cannot assume that the {this} parameter is
+  // not {the_hole}, because for derived classes {this} has a TDZ and the
+  // JSConstructStubForDerived magically passes {the_hole} as a receiver.
+  if (scope->has_this_declaration() && scope->receiver()->is_const_mode()) {
+    env.RawParameterBind(0, jsgraph()->TheHoleConstant());
+  }
 
-  // Push top-level function scope for the function body.
-  ContextScope top_context(this, scope, inner_context);
+  // Build local context only if there are context allocated variables.
+  if (info()->num_heap_slots() > 0) {
+    // Push a new inner context scope for the current activation.
+    Node* inner_context = BuildLocalActivationContext(GetFunctionContext());
+    ContextScope top_context(this, scope, inner_context);
+    CreateGraphBody(stack_check);
+  } else {
+    // Simply use the outer function context in building the graph.
+    CreateGraphBody(stack_check);
+  }
+
+  // Finish the basic structure of the graph.
+  DCHECK_NE(0u, exit_controls_.size());
+  int const input_count = static_cast<int>(exit_controls_.size());
+  Node** const inputs = &exit_controls_.front();
+  Node* end = graph()->NewNode(common()->End(input_count), input_count, inputs);
+  graph()->SetEnd(end);
+
+  // Compute local variable liveness information and use it to relax
+  // frame states.
+  ClearNonLiveSlotsInFrameStates();
+
+  // Failures indicated by stack overflow.
+  return !HasStackOverflow();
+}
+
+
+void AstGraphBuilder::CreateGraphBody(bool stack_check) {
+  Scope* scope = info()->scope();
 
   // Build the arguments object if it is used.
   BuildArgumentsObject(scope->arguments());
 
+  // Build rest arguments array if it is used.
+  int rest_index;
+  Variable* rest_parameter = scope->rest_parameter(&rest_index);
+  BuildRestArgumentsArray(rest_parameter, rest_index);
+
+  // Build assignment to {.this_function} variable if it is used.
+  BuildThisFunctionVariable(scope->this_function_var());
+
+  // Build assignment to {new.target} variable if it is used.
+  BuildNewTargetVariable(scope->new_target_var());
+
   // Emit tracing call if requested to do so.
   if (FLAG_trace) {
     NewNode(javascript()->CallRuntime(Runtime::kTraceEnter, 0));
   }
 
-  // Visit implicit declaration of the function name.
-  if (scope->is_function_scope() && scope->function() != NULL) {
-    VisitVariableDeclaration(scope->function());
+  // Visit illegal re-declaration and bail out if it exists.
+  if (scope->HasIllegalRedeclaration()) {
+    VisitForEffect(scope->GetIllegalRedeclaration());
+    return;
   }
 
   // Visit declarations within the function scope.
   VisitDeclarations(scope->declarations());
 
   // Build a stack-check before the body.
-  Node* node = BuildStackCheck();
-  PrepareFrameState(node, BailoutId::FunctionEntry());
+  if (stack_check) {
+    Node* node = NewNode(javascript()->StackCheck());
+    PrepareFrameState(node, BailoutId::FunctionEntry());
+  }
 
   // Visit statements in the function body.
-  VisitStatements(info()->function()->body());
-  if (HasStackOverflow()) return false;
+  VisitStatements(info()->literal()->body());
 
   // Emit tracing call if requested to do so.
   if (FLAG_trace) {
@@ -115,60 +618,88 @@
   }
 
   // Return 'undefined' in case we can fall off the end.
-  Node* control = NewNode(common()->Return(), jsgraph()->UndefinedConstant());
-  UpdateControlDependencyToLeaveFunction(control);
-
-  // Finish the basic structure of the graph.
-  environment()->UpdateControlDependency(exit_control());
-  graph()->SetEnd(NewNode(common()->End()));
-
-  return true;
+  BuildReturn(jsgraph()->UndefinedConstant());
 }
 
 
-// Left-hand side can only be a property, a global or a variable slot.
-enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
+void AstGraphBuilder::ClearNonLiveSlotsInFrameStates() {
+  if (!FLAG_analyze_environment_liveness ||
+      !info()->is_deoptimization_enabled()) {
+    return;
+  }
 
-
-// Determine the left-hand side kind of an assignment.
-static LhsKind DetermineLhsKind(Expression* expr) {
-  Property* property = expr->AsProperty();
-  DCHECK(expr->IsValidReferenceExpression());
-  LhsKind lhs_kind =
-      (property == NULL) ? VARIABLE : (property->key()->IsPropertyName())
-                                          ? NAMED_PROPERTY
-                                          : KEYED_PROPERTY;
-  return lhs_kind;
+  NonLiveFrameStateSlotReplacer replacer(
+      &state_values_cache_, jsgraph()->UndefinedConstant(),
+      liveness_analyzer()->local_count(), local_zone());
+  Variable* arguments = info()->scope()->arguments();
+  if (arguments != nullptr && arguments->IsStackAllocated()) {
+    replacer.MarkPermanentlyLive(arguments->index());
+  }
+  liveness_analyzer()->Run(&replacer);
+  if (FLAG_trace_environment_liveness) {
+    OFStream os(stdout);
+    liveness_analyzer()->Print(os);
+  }
 }
 
 
-StructuredGraphBuilder::Environment* AstGraphBuilder::CopyEnvironment(
-    StructuredGraphBuilder::Environment* env) {
-  return new (zone()) Environment(*reinterpret_cast<Environment*>(env));
+// Gets the bailout id just before reading a variable proxy, but only for
+// unallocated variables.
+static BailoutId BeforeId(VariableProxy* proxy) {
+  return proxy->var()->IsUnallocatedOrGlobalSlot() ? proxy->BeforeId()
+                                                   : BailoutId::None();
+}
+
+
+static const char* GetDebugParameterName(Zone* zone, Scope* scope, int index) {
+#if DEBUG
+  const AstRawString* name = scope->parameter(index)->raw_name();
+  if (name && name->length() > 0) {
+    char* data = zone->NewArray<char>(name->length() + 1);
+    data[name->length()] = 0;
+    memcpy(data, name->raw_data(), name->length());
+    return data;
+  }
+#endif
+  return nullptr;
 }
 
 
 AstGraphBuilder::Environment::Environment(AstGraphBuilder* builder,
                                           Scope* scope,
                                           Node* control_dependency)
-    : StructuredGraphBuilder::Environment(builder, control_dependency),
+    : builder_(builder),
       parameters_count_(scope->num_parameters() + 1),
       locals_count_(scope->num_stack_slots()),
-      parameters_node_(NULL),
-      locals_node_(NULL),
-      stack_node_(NULL) {
+      liveness_block_(IsLivenessAnalysisEnabled()
+                          ? builder_->liveness_analyzer()->NewBlock()
+                          : nullptr),
+      values_(builder_->local_zone()),
+      contexts_(builder_->local_zone()),
+      control_dependency_(control_dependency),
+      effect_dependency_(control_dependency),
+      parameters_node_(nullptr),
+      locals_node_(nullptr),
+      stack_node_(nullptr) {
   DCHECK_EQ(scope->num_parameters() + 1, parameters_count());
 
   // Bind the receiver variable.
-  Node* receiver = builder->graph()->NewNode(common()->Parameter(0),
-                                             builder->graph()->start());
-  values()->push_back(receiver);
+  int param_num = 0;
+  if (builder->info()->is_this_defined()) {
+    const Operator* op = common()->Parameter(param_num++, "%this");
+    Node* receiver = builder->graph()->NewNode(op, builder->graph()->start());
+    values()->push_back(receiver);
+  } else {
+    values()->push_back(builder->jsgraph()->UndefinedConstant());
+  }
 
   // Bind all parameter variables. The parameter indices are shifted by 1
-  // (receiver is parameter index -1 but environment index 0).
+  // (receiver is variable index -1 but {Parameter} node index 0 and located at
+  // index 0 in the environment).
   for (int i = 0; i < scope->num_parameters(); ++i) {
-    Node* parameter = builder->graph()->NewNode(common()->Parameter(i + 1),
-                                                builder->graph()->start());
+    const char* debug_name = GetDebugParameterName(graph()->zone(), scope, i);
+    const Operator* op = common()->Parameter(param_num++, debug_name);
+    Node* parameter = builder->graph()->NewNode(op, builder->graph()->start());
     values()->push_back(parameter);
   }
 
@@ -178,21 +709,127 @@
 }
 
 
-AstGraphBuilder::Environment::Environment(const Environment& copy)
-    : StructuredGraphBuilder::Environment(
-          static_cast<StructuredGraphBuilder::Environment>(copy)),
-      parameters_count_(copy.parameters_count_),
-      locals_count_(copy.locals_count_),
-      parameters_node_(copy.parameters_node_),
-      locals_node_(copy.locals_node_),
-      stack_node_(copy.stack_node_) {}
+AstGraphBuilder::Environment::Environment(AstGraphBuilder::Environment* copy,
+                                          LivenessAnalyzerBlock* liveness_block)
+    : builder_(copy->builder_),
+      parameters_count_(copy->parameters_count_),
+      locals_count_(copy->locals_count_),
+      liveness_block_(liveness_block),
+      values_(copy->zone()),
+      contexts_(copy->zone()),
+      control_dependency_(copy->control_dependency_),
+      effect_dependency_(copy->effect_dependency_),
+      parameters_node_(copy->parameters_node_),
+      locals_node_(copy->locals_node_),
+      stack_node_(copy->stack_node_) {
+  const size_t kStackEstimate = 7;  // optimum from experimentation!
+  values_.reserve(copy->values_.size() + kStackEstimate);
+  values_.insert(values_.begin(), copy->values_.begin(), copy->values_.end());
+  contexts_.reserve(copy->contexts_.size());
+  contexts_.insert(contexts_.begin(), copy->contexts_.begin(),
+                   copy->contexts_.end());
+}
+
+
+void AstGraphBuilder::Environment::Bind(Variable* variable, Node* node) {
+  DCHECK(variable->IsStackAllocated());
+  if (variable->IsParameter()) {
+    // The parameter indices are shifted by 1 (receiver is variable
+    // index -1 but located at index 0 in the environment).
+    values()->at(variable->index() + 1) = node;
+  } else {
+    DCHECK(variable->IsStackLocal());
+    values()->at(variable->index() + parameters_count_) = node;
+    DCHECK(IsLivenessBlockConsistent());
+    if (liveness_block() != nullptr) {
+      liveness_block()->Bind(variable->index());
+    }
+  }
+}
+
+
+Node* AstGraphBuilder::Environment::Lookup(Variable* variable) {
+  DCHECK(variable->IsStackAllocated());
+  if (variable->IsParameter()) {
+    // The parameter indices are shifted by 1 (receiver is variable
+    // index -1 but located at index 0 in the environment).
+    return values()->at(variable->index() + 1);
+  } else {
+    DCHECK(variable->IsStackLocal());
+    DCHECK(IsLivenessBlockConsistent());
+    if (liveness_block() != nullptr) {
+      liveness_block()->Lookup(variable->index());
+    }
+    return values()->at(variable->index() + parameters_count_);
+  }
+}
+
+
+void AstGraphBuilder::Environment::MarkAllLocalsLive() {
+  DCHECK(IsLivenessBlockConsistent());
+  if (liveness_block() != nullptr) {
+    for (int i = 0; i < locals_count_; i++) {
+      liveness_block()->Lookup(i);
+    }
+  }
+}
+
+
+void AstGraphBuilder::Environment::RawParameterBind(int index, Node* node) {
+  DCHECK_LT(index, parameters_count());
+  values()->at(index) = node;
+}
+
+
+Node* AstGraphBuilder::Environment::RawParameterLookup(int index) {
+  DCHECK_LT(index, parameters_count());
+  return values()->at(index);
+}
+
+
+AstGraphBuilder::Environment*
+AstGraphBuilder::Environment::CopyForConditional() {
+  LivenessAnalyzerBlock* copy_liveness_block = nullptr;
+  if (liveness_block() != nullptr) {
+    copy_liveness_block =
+        builder_->liveness_analyzer()->NewBlock(liveness_block());
+    liveness_block_ = builder_->liveness_analyzer()->NewBlock(liveness_block());
+  }
+  return new (zone()) Environment(this, copy_liveness_block);
+}
+
+
+AstGraphBuilder::Environment*
+AstGraphBuilder::Environment::CopyAsUnreachable() {
+  Environment* env = new (zone()) Environment(this, nullptr);
+  env->MarkAsUnreachable();
+  return env;
+}
+
+
+AstGraphBuilder::Environment*
+AstGraphBuilder::Environment::CopyAndShareLiveness() {
+  if (liveness_block() != nullptr) {
+    // Finish the current liveness block before copying.
+    liveness_block_ = builder_->liveness_analyzer()->NewBlock(liveness_block());
+  }
+  Environment* env = new (zone()) Environment(this, liveness_block());
+  return env;
+}
+
+
+AstGraphBuilder::Environment* AstGraphBuilder::Environment::CopyForLoop(
+    BitVector* assigned, bool is_osr) {
+  PrepareForLoop(assigned, is_osr);
+  return CopyAndShareLiveness();
+}
 
 
 void AstGraphBuilder::Environment::UpdateStateValues(Node** state_values,
                                                      int offset, int count) {
   bool should_update = false;
-  Node** env_values = (count == 0) ? NULL : &values()->at(offset);
-  if (*state_values == NULL || (*state_values)->InputCount() != count) {
+  Node** env_values = (count == 0) ? nullptr : &values()->at(offset);
+  if (*state_values == nullptr || (*state_values)->InputCount() != count) {
     should_update = true;
   } else {
     DCHECK(static_cast<size_t>(offset + count) <= values()->size());
@@ -210,18 +847,50 @@
 }
 
 
+void AstGraphBuilder::Environment::UpdateStateValuesWithCache(
+    Node** state_values, int offset, int count) {
+  Node** env_values = (count == 0) ? nullptr : &values()->at(offset);
+  *state_values = builder_->state_values_cache_.GetNodeForValues(
+      env_values, static_cast<size_t>(count));
+}
+
+
 Node* AstGraphBuilder::Environment::Checkpoint(
     BailoutId ast_id, OutputFrameStateCombine combine) {
+  if (!builder()->info()->is_deoptimization_enabled()) {
+    return builder()->jsgraph()->EmptyFrameState();
+  }
+
   UpdateStateValues(&parameters_node_, 0, parameters_count());
-  UpdateStateValues(&locals_node_, parameters_count(), locals_count());
+  UpdateStateValuesWithCache(&locals_node_, parameters_count(), locals_count());
   UpdateStateValues(&stack_node_, parameters_count() + locals_count(),
                     stack_height());
 
-  const Operator* op = common()->FrameState(JS_FRAME, ast_id, combine);
+  const Operator* op = common()->FrameState(
+      ast_id, combine, builder()->frame_state_function_info());
 
-  return graph()->NewNode(op, parameters_node_, locals_node_, stack_node_,
-                          GetContext(),
-                          builder()->jsgraph()->UndefinedConstant());
+  Node* result = graph()->NewNode(op, parameters_node_, locals_node_,
+                                  stack_node_, builder()->current_context(),
+                                  builder()->GetFunctionClosure(),
+                                  builder()->graph()->start());
+
+  DCHECK(IsLivenessBlockConsistent());
+  if (liveness_block() != nullptr) {
+    liveness_block()->Checkpoint(result);
+  }
+  return result;
+}
+
+
+bool AstGraphBuilder::Environment::IsLivenessAnalysisEnabled() {
+  return FLAG_analyze_environment_liveness &&
+         builder()->info()->is_deoptimization_enabled();
+}
+
+
+bool AstGraphBuilder::Environment::IsLivenessBlockConsistent() {
+  return (!IsLivenessAnalysisEnabled() || IsMarkedAsUnreachable()) ==
+         (liveness_block() == nullptr);
 }
 
 
@@ -266,11 +935,11 @@
 
 
 void AstGraphBuilder::AstTestContext::ProduceValue(Node* value) {
-  environment()->Push(owner()->BuildToBoolean(value));
+  environment()->Push(owner()->BuildToBoolean(value, feedback_id_));
 }
 
 
-Node* AstGraphBuilder::AstEffectContext::ConsumeValue() { return NULL; }
+Node* AstGraphBuilder::AstEffectContext::ConsumeValue() { return nullptr; }
 
 
 Node* AstGraphBuilder::AstValueContext::ConsumeValue() {
@@ -283,36 +952,68 @@
 }
 
 
-AstGraphBuilder::BreakableScope* AstGraphBuilder::BreakableScope::FindBreakable(
-    BreakableStatement* target) {
-  BreakableScope* current = this;
-  while (current != NULL && current->target_ != target) {
-    owner_->environment()->Drop(current->drop_extra_);
-    current = current->next_;
+Scope* AstGraphBuilder::current_scope() const {
+  return execution_context_->scope();
+}
+
+
+Node* AstGraphBuilder::current_context() const {
+  return environment()->Context();
+}
+
+
+void AstGraphBuilder::ControlScope::PerformCommand(Command command,
+                                                   Statement* target,
+                                                   Node* value) {
+  Environment* env = environment()->CopyAsUnreachable();
+  ControlScope* current = this;
+  while (current != nullptr) {
+    environment()->TrimStack(current->stack_height());
+    environment()->TrimContextChain(current->context_length());
+    if (current->Execute(command, target, value)) break;
+    current = current->outer_;
   }
-  DCHECK(current != NULL);  // Always found (unless stack is malformed).
-  return current;
+  builder()->set_environment(env);
+  DCHECK_NOT_NULL(current);  // Always handled (unless stack is malformed).
 }
 
 
-void AstGraphBuilder::BreakableScope::BreakTarget(BreakableStatement* stmt) {
-  FindBreakable(stmt)->control_->Break();
+void AstGraphBuilder::ControlScope::BreakTo(BreakableStatement* stmt) {
+  PerformCommand(CMD_BREAK, stmt, builder()->jsgraph()->TheHoleConstant());
 }
 
 
-void AstGraphBuilder::BreakableScope::ContinueTarget(BreakableStatement* stmt) {
-  FindBreakable(stmt)->control_->Continue();
+void AstGraphBuilder::ControlScope::ContinueTo(BreakableStatement* stmt) {
+  PerformCommand(CMD_CONTINUE, stmt, builder()->jsgraph()->TheHoleConstant());
+}
+
+
+void AstGraphBuilder::ControlScope::ReturnValue(Node* return_value) {
+  PerformCommand(CMD_RETURN, nullptr, return_value);
+}
+
+
+void AstGraphBuilder::ControlScope::ThrowValue(Node* exception_value) {
+  PerformCommand(CMD_THROW, nullptr, exception_value);
 }
 
 
 void AstGraphBuilder::VisitForValueOrNull(Expression* expr) {
-  if (expr == NULL) {
+  if (expr == nullptr) {
     return environment()->Push(jsgraph()->NullConstant());
   }
   VisitForValue(expr);
 }
 
 
+void AstGraphBuilder::VisitForValueOrTheHole(Expression* expr) {
+  if (expr == nullptr) {
+    return environment()->Push(jsgraph()->TheHoleConstant());
+  }
+  VisitForValue(expr);
+}
+
+
 void AstGraphBuilder::VisitForValues(ZoneList<Expression*>* exprs) {
   for (int i = 0; i < exprs->length(); ++i) {
     VisitForValue(exprs->at(i));
@@ -341,7 +1042,7 @@
 
 
 void AstGraphBuilder::VisitForTest(Expression* expr) {
-  AstTestContext for_condition(this);
+  AstTestContext for_condition(this, expr->test_id());
   if (!CheckStackOverflow()) {
     expr->Accept(this);
   } else {
@@ -365,7 +1066,8 @@
   VariableMode mode = decl->mode();
   bool hole_init = mode == CONST || mode == CONST_LEGACY || mode == LET;
   switch (variable->location()) {
-    case Variable::UNALLOCATED: {
+    case VariableLocation::GLOBAL:
+    case VariableLocation::UNALLOCATED: {
       Handle<Oddball> value = variable->binding_needs_init()
                                   ? isolate()->factory()->the_hole_value()
                                   : isolate()->factory()->undefined_value();
@@ -373,21 +1075,21 @@
       globals()->push_back(value);
       break;
     }
-    case Variable::PARAMETER:
-    case Variable::LOCAL:
+    case VariableLocation::PARAMETER:
+    case VariableLocation::LOCAL:
       if (hole_init) {
         Node* value = jsgraph()->TheHoleConstant();
         environment()->Bind(variable, value);
       }
       break;
-    case Variable::CONTEXT:
+    case VariableLocation::CONTEXT:
       if (hole_init) {
         Node* value = jsgraph()->TheHoleConstant();
         const Operator* op = javascript()->StoreContext(0, variable->index());
         NewNode(op, current_context(), value);
       }
       break;
-    case Variable::LOOKUP:
+    case VariableLocation::LOOKUP:
       UNIMPLEMENTED();
   }
 }
@@ -396,40 +1098,36 @@
 void AstGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* decl) {
   Variable* variable = decl->proxy()->var();
   switch (variable->location()) {
-    case Variable::UNALLOCATED: {
-      Handle<SharedFunctionInfo> function =
-          Compiler::BuildFunctionInfo(decl->fun(), info()->script(), info());
+    case VariableLocation::GLOBAL:
+    case VariableLocation::UNALLOCATED: {
+      Handle<SharedFunctionInfo> function = Compiler::GetSharedFunctionInfo(
+          decl->fun(), info()->script(), info());
       // Check for stack-overflow exception.
       if (function.is_null()) return SetStackOverflow();
       globals()->push_back(variable->name());
       globals()->push_back(function);
       break;
     }
-    case Variable::PARAMETER:
-    case Variable::LOCAL: {
+    case VariableLocation::PARAMETER:
+    case VariableLocation::LOCAL: {
       VisitForValue(decl->fun());
       Node* value = environment()->Pop();
       environment()->Bind(variable, value);
       break;
     }
-    case Variable::CONTEXT: {
+    case VariableLocation::CONTEXT: {
       VisitForValue(decl->fun());
       Node* value = environment()->Pop();
       const Operator* op = javascript()->StoreContext(0, variable->index());
       NewNode(op, current_context(), value);
       break;
     }
-    case Variable::LOOKUP:
+    case VariableLocation::LOOKUP:
       UNIMPLEMENTED();
   }
 }
 
 
-void AstGraphBuilder::VisitModuleDeclaration(ModuleDeclaration* decl) {
-  UNREACHABLE();
-}
-
-
 void AstGraphBuilder::VisitImportDeclaration(ImportDeclaration* decl) {
   UNREACHABLE();
 }
@@ -440,43 +1138,26 @@
 }
 
 
-void AstGraphBuilder::VisitModuleLiteral(ModuleLiteral* modl) { UNREACHABLE(); }
-
-
-void AstGraphBuilder::VisitModuleVariable(ModuleVariable* modl) {
-  UNREACHABLE();
-}
-
-
-void AstGraphBuilder::VisitModulePath(ModulePath* modl) { UNREACHABLE(); }
-
-
-void AstGraphBuilder::VisitModuleUrl(ModuleUrl* modl) { UNREACHABLE(); }
-
-
 void AstGraphBuilder::VisitBlock(Block* stmt) {
   BlockBuilder block(this);
-  BreakableScope scope(this, stmt, &block, 0);
-  if (stmt->labels() != NULL) block.BeginBlock();
-  if (stmt->scope() == NULL) {
+  ControlScopeForBreakable scope(this, stmt, &block);
+  if (stmt->labels() != nullptr) block.BeginBlock();
+  if (stmt->scope() == nullptr) {
     // Visit statements in the same scope, no declarations.
     VisitStatements(stmt->statements());
   } else {
-    const Operator* op = javascript()->CreateBlockContext();
-    Node* scope_info = jsgraph()->Constant(stmt->scope()->GetScopeInfo());
-    Node* context = NewNode(op, scope_info, GetFunctionClosure());
-    ContextScope scope(this, stmt->scope(), context);
-
     // Visit declarations and statements in a block scope.
-    VisitDeclarations(stmt->scope()->declarations());
-    VisitStatements(stmt->statements());
+    if (stmt->scope()->NeedsContext()) {
+      Node* context = BuildLocalBlockContext(stmt->scope());
+      ContextScope scope(this, stmt->scope(), context);
+      VisitDeclarations(stmt->scope()->declarations());
+      VisitStatements(stmt->statements());
+    } else {
+      VisitDeclarations(stmt->scope()->declarations());
+      VisitStatements(stmt->statements());
+    }
   }
-  if (stmt->labels() != NULL) block.EndBlock();
-}
-
-
-void AstGraphBuilder::VisitModuleStatement(ModuleStatement* stmt) {
-  UNREACHABLE();
+  if (stmt->labels() != nullptr) block.EndBlock();
 }
 
 
@@ -490,6 +1171,12 @@
 }
 
 
+void AstGraphBuilder::VisitSloppyBlockFunctionStatement(
+    SloppyBlockFunctionStatement* stmt) {
+  Visit(stmt->statement());
+}
+
+
 void AstGraphBuilder::VisitIfStatement(IfStatement* stmt) {
   IfBuilder compare_if(this);
   VisitForTest(stmt->condition());
@@ -504,47 +1191,42 @@
 
 
 void AstGraphBuilder::VisitContinueStatement(ContinueStatement* stmt) {
-  StructuredGraphBuilder::Environment* env = environment()->CopyAsUnreachable();
-  breakable()->ContinueTarget(stmt->target());
-  set_environment(env);
+  execution_control()->ContinueTo(stmt->target());
 }
 
 
 void AstGraphBuilder::VisitBreakStatement(BreakStatement* stmt) {
-  StructuredGraphBuilder::Environment* env = environment()->CopyAsUnreachable();
-  breakable()->BreakTarget(stmt->target());
-  set_environment(env);
+  execution_control()->BreakTo(stmt->target());
 }
 
 
 void AstGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) {
   VisitForValue(stmt->expression());
   Node* result = environment()->Pop();
-  Node* control = NewNode(common()->Return(), result);
-  UpdateControlDependencyToLeaveFunction(control);
+  execution_control()->ReturnValue(result);
 }
 
 
 void AstGraphBuilder::VisitWithStatement(WithStatement* stmt) {
   VisitForValue(stmt->expression());
   Node* value = environment()->Pop();
+  Node* object = BuildToObject(value, stmt->ToObjectId());
   const Operator* op = javascript()->CreateWithContext();
-  Node* context = NewNode(op, value, GetFunctionClosure());
-  ContextScope scope(this, stmt->scope(), context);
-  Visit(stmt->statement());
+  Node* context = NewNode(op, object, GetFunctionClosureForContext());
+  PrepareFrameState(context, stmt->EntryId());
+  VisitInScope(stmt->statement(), stmt->scope(), context);
 }
 
 
 void AstGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
   ZoneList<CaseClause*>* clauses = stmt->cases();
   SwitchBuilder compare_switch(this, clauses->length());
-  BreakableScope scope(this, stmt, &compare_switch, 0);
+  ControlScopeForBreakable scope(this, stmt, &compare_switch);
   compare_switch.BeginSwitch();
   int default_index = -1;
 
   // Keep the switch value on the stack until a case matches.
   VisitForValue(stmt->tag());
-  Node* tag = environment()->Top();
 
   // Iterate over all cases and create nodes for label comparison.
   for (int i = 0; i < clauses->length(); i++) {
@@ -560,6 +1242,7 @@
     // value is still on the operand stack while the label is evaluated.
     VisitForValue(clause->label());
     Node* label = environment()->Pop();
+    Node* tag = environment()->Top();
     const Operator* op = javascript()->StrictEqual();
     Node* condition = NewNode(op, tag, label);
     compare_switch.BeginLabel(i, condition);
@@ -589,8 +1272,8 @@
 
 void AstGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
   LoopBuilder while_loop(this);
-  while_loop.BeginLoop(GetVariablesAssignedInLoop(stmt));
-  VisitIterationBody(stmt, &while_loop, 0);
+  while_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt));
+  VisitIterationBody(stmt, &while_loop);
   while_loop.EndBody();
   VisitForTest(stmt->cond());
   Node* condition = environment()->Pop();
@@ -601,11 +1284,11 @@
 
 void AstGraphBuilder::VisitWhileStatement(WhileStatement* stmt) {
   LoopBuilder while_loop(this);
-  while_loop.BeginLoop(GetVariablesAssignedInLoop(stmt));
+  while_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt));
   VisitForTest(stmt->cond());
   Node* condition = environment()->Pop();
   while_loop.BreakUnless(condition);
-  VisitIterationBody(stmt, &while_loop, 0);
+  VisitIterationBody(stmt, &while_loop);
   while_loop.EndBody();
   while_loop.EndLoop();
 }
@@ -614,219 +1297,368 @@
 void AstGraphBuilder::VisitForStatement(ForStatement* stmt) {
   LoopBuilder for_loop(this);
   VisitIfNotNull(stmt->init());
-  for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt));
-  if (stmt->cond() != NULL) {
+  for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt));
+  if (stmt->cond() != nullptr) {
     VisitForTest(stmt->cond());
     Node* condition = environment()->Pop();
     for_loop.BreakUnless(condition);
   } else {
     for_loop.BreakUnless(jsgraph()->TrueConstant());
   }
-  VisitIterationBody(stmt, &for_loop, 0);
+  VisitIterationBody(stmt, &for_loop);
   for_loop.EndBody();
   VisitIfNotNull(stmt->next());
   for_loop.EndLoop();
 }
 
 
-// TODO(dcarney): this is a big function.  Try to clean up some.
 void AstGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
   VisitForValue(stmt->subject());
-  Node* obj = environment()->Pop();
-  // Check for undefined or null before entering loop.
-  IfBuilder is_undefined(this);
-  Node* is_undefined_cond =
-      NewNode(javascript()->StrictEqual(), obj, jsgraph()->UndefinedConstant());
-  is_undefined.If(is_undefined_cond);
-  is_undefined.Then();
-  is_undefined.Else();
+  Node* object = environment()->Pop();
+  BlockBuilder for_block(this);
+  for_block.BeginBlock();
+  // Check for null or undefined before entering loop.
+  Node* is_null_cond =
+      NewNode(javascript()->StrictEqual(), object, jsgraph()->NullConstant());
+  for_block.BreakWhen(is_null_cond, BranchHint::kFalse);
+  Node* is_undefined_cond = NewNode(javascript()->StrictEqual(), object,
+                                    jsgraph()->UndefinedConstant());
+  for_block.BreakWhen(is_undefined_cond, BranchHint::kFalse);
   {
-    IfBuilder is_null(this);
-    Node* is_null_cond =
-        NewNode(javascript()->StrictEqual(), obj, jsgraph()->NullConstant());
-    is_null.If(is_null_cond);
-    is_null.Then();
-    is_null.Else();
     // Convert object to jsobject.
-    // PrepareForBailoutForId(stmt->PrepareId(), TOS_REG);
-    obj = NewNode(javascript()->ToObject(), obj);
-    PrepareFrameState(obj, stmt->ToObjectId(), OutputFrameStateCombine::Push());
-    environment()->Push(obj);
-    // TODO(dcarney): should do a fast enum cache check here to skip runtime.
-    environment()->Push(obj);
-    Node* cache_type = ProcessArguments(
-        javascript()->CallRuntime(Runtime::kGetPropertyNamesFast, 1), 1);
-    PrepareFrameState(cache_type, stmt->EnumId(),
-                      OutputFrameStateCombine::Push());
-    // TODO(dcarney): these next runtime calls should be removed in favour of
-    //                a few simplified instructions.
-    environment()->Push(obj);
-    environment()->Push(cache_type);
-    Node* cache_pair =
-        ProcessArguments(javascript()->CallRuntime(Runtime::kForInInit, 2), 2);
-    // cache_type may have been replaced.
-    Node* cache_array = NewNode(common()->Projection(0), cache_pair);
-    cache_type = NewNode(common()->Projection(1), cache_pair);
+    object = BuildToObject(object, stmt->ToObjectId());
+    environment()->Push(object);
+
+    // Prepare for-in cache.
+    Node* prepare = NewNode(javascript()->ForInPrepare(), object);
+    PrepareFrameState(prepare, stmt->EnumId(), OutputFrameStateCombine::Push());
+    Node* cache_type = NewNode(common()->Projection(0), prepare);
+    Node* cache_array = NewNode(common()->Projection(1), prepare);
+    Node* cache_length = NewNode(common()->Projection(2), prepare);
+
+    // Construct the rest of the environment.
     environment()->Push(cache_type);
     environment()->Push(cache_array);
-    Node* cache_length = ProcessArguments(
-        javascript()->CallRuntime(Runtime::kForInCacheArrayLength, 2), 2);
+    environment()->Push(cache_length);
+    environment()->Push(jsgraph()->ZeroConstant());
+
+    // Build the actual loop body.
+    LoopBuilder for_loop(this);
+    for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt));
     {
-      // TODO(dcarney): this check is actually supposed to be for the
-      //                empty enum case only.
-      IfBuilder have_no_properties(this);
-      Node* empty_array_cond = NewNode(javascript()->StrictEqual(),
-                                       cache_length, jsgraph()->ZeroConstant());
-      have_no_properties.If(empty_array_cond);
-      have_no_properties.Then();
-      // Pop obj and skip loop.
-      environment()->Pop();
-      have_no_properties.Else();
+      // These stack values are renamed in the case of OSR, so reload them
+      // from the environment.
+      Node* index = environment()->Peek(0);
+      Node* cache_length = environment()->Peek(1);
+      Node* cache_array = environment()->Peek(2);
+      Node* cache_type = environment()->Peek(3);
+      Node* object = environment()->Peek(4);
+
+      // Check loop termination condition.
+      Node* exit_cond = NewNode(javascript()->ForInDone(), index, cache_length);
+      for_loop.BreakWhen(exit_cond);
+
+      // Compute the next enumerated value.
+      Node* value = NewNode(javascript()->ForInNext(), object, cache_array,
+                            cache_type, index);
+      PrepareFrameState(value, stmt->FilterId(),
+                        OutputFrameStateCombine::Push());
+      IfBuilder test_value(this);
+      Node* test_value_cond = NewNode(javascript()->StrictEqual(), value,
+                                      jsgraph()->UndefinedConstant());
+      test_value.If(test_value_cond, BranchHint::kFalse);
+      test_value.Then();
+      test_value.Else();
       {
-        // Construct the rest of the environment.
-        environment()->Push(cache_type);
-        environment()->Push(cache_array);
-        environment()->Push(cache_length);
-        environment()->Push(jsgraph()->ZeroConstant());
-        // PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS);
-        LoopBuilder for_loop(this);
-        for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt));
-        // Check loop termination condition.
-        Node* index = environment()->Peek(0);
-        Node* exit_cond =
-            NewNode(javascript()->LessThan(), index, cache_length);
-        // TODO(jarin): provide real bailout id.
-        PrepareFrameState(exit_cond, BailoutId::None());
-        for_loop.BreakUnless(exit_cond);
-        // TODO(dcarney): this runtime call should be a handful of
-        //                simplified instructions that
-        //                basically produce
-        //                    value = array[index]
-        environment()->Push(obj);
-        environment()->Push(cache_array);
-        environment()->Push(cache_type);
-        environment()->Push(index);
-        Node* pair = ProcessArguments(
-            javascript()->CallRuntime(Runtime::kForInNext, 4), 4);
-        Node* value = NewNode(common()->Projection(0), pair);
-        Node* should_filter = NewNode(common()->Projection(1), pair);
-        environment()->Push(value);
-        {
-          // Test if FILTER_KEY needs to be called.
-          IfBuilder test_should_filter(this);
-          Node* should_filter_cond =
-              NewNode(javascript()->StrictEqual(), should_filter,
-                      jsgraph()->TrueConstant());
-          test_should_filter.If(should_filter_cond);
-          test_should_filter.Then();
-          value = environment()->Pop();
-          Node* builtins = BuildLoadBuiltinsObject();
-          Node* function = BuildLoadObjectField(
-              builtins,
-              JSBuiltinsObject::OffsetOfFunctionWithId(Builtins::FILTER_KEY));
-          // Callee.
-          environment()->Push(function);
-          // Receiver.
-          environment()->Push(obj);
-          // Args.
-          environment()->Push(value);
-          // result is either the string key or Smi(0) indicating the property
-          // is gone.
-          Node* res = ProcessArguments(
-              javascript()->CallFunction(3, NO_CALL_FUNCTION_FLAGS), 3);
-          // TODO(jarin): provide real bailout id.
-          PrepareFrameState(res, BailoutId::None());
-          Node* property_missing = NewNode(javascript()->StrictEqual(), res,
-                                           jsgraph()->ZeroConstant());
-          {
-            IfBuilder is_property_missing(this);
-            is_property_missing.If(property_missing);
-            is_property_missing.Then();
-            // Inc counter and continue.
-            Node* index_inc =
-                NewNode(javascript()->Add(), index, jsgraph()->OneConstant());
-            // TODO(jarin): provide real bailout id.
-            PrepareFrameState(index_inc, BailoutId::None());
-            environment()->Poke(0, index_inc);
-            for_loop.Continue();
-            is_property_missing.Else();
-            is_property_missing.End();
-          }
-          // Replace 'value' in environment.
-          environment()->Push(res);
-          test_should_filter.Else();
-          test_should_filter.End();
-        }
-        value = environment()->Pop();
         // Bind value and do loop body.
-        VisitForInAssignment(stmt->each(), value);
-        VisitIterationBody(stmt, &for_loop, 5);
-        for_loop.EndBody();
-        // Inc counter and continue.
-        Node* index_inc =
-            NewNode(javascript()->Add(), index, jsgraph()->OneConstant());
-        // TODO(jarin): provide real bailout id.
-        PrepareFrameState(index_inc, BailoutId::None());
-        environment()->Poke(0, index_inc);
-        for_loop.EndLoop();
-        environment()->Drop(5);
-        // PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
+        VectorSlotPair feedback =
+            CreateVectorSlotPair(stmt->EachFeedbackSlot());
+        VisitForInAssignment(stmt->each(), value, feedback, stmt->FilterId(),
+                             stmt->AssignmentId());
+        VisitIterationBody(stmt, &for_loop);
       }
-      have_no_properties.End();
+      test_value.End();
+      index = environment()->Peek(0);
+      for_loop.EndBody();
+
+      // Increment counter and continue.
+      index = NewNode(javascript()->ForInStep(), index);
+      environment()->Poke(0, index);
     }
-    is_null.End();
+    for_loop.EndLoop();
+    environment()->Drop(5);
   }
-  is_undefined.End();
+  for_block.EndBlock();
 }
 
 
 void AstGraphBuilder::VisitForOfStatement(ForOfStatement* stmt) {
-  VisitForValue(stmt->subject());
-  environment()->Pop();
-  // TODO(turbofan): create and use loop builder.
+  LoopBuilder for_loop(this);
+  VisitForEffect(stmt->assign_iterator());
+  for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt));
+  VisitForEffect(stmt->next_result());
+  VisitForTest(stmt->result_done());
+  Node* condition = environment()->Pop();
+  for_loop.BreakWhen(condition);
+  VisitForEffect(stmt->assign_each());
+  VisitIterationBody(stmt, &for_loop);
+  for_loop.EndBody();
+  for_loop.EndLoop();
 }
 
 
 void AstGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) {
-  UNREACHABLE();
+  TryCatchBuilder try_control(this);
+
+  // Evaluate the try-block inside a control scope. This simulates a handler
+  // that is intercepting 'throw' control commands.
+  try_control.BeginTry();
+  {
+    ControlScopeForCatch scope(this, &try_control);
+    STATIC_ASSERT(TryBlockConstant::kElementCount == 1);
+    environment()->Push(current_context());
+    Visit(stmt->try_block());
+    environment()->Pop();
+  }
+  try_control.EndTry();
+
+  // Insert lazy bailout point.
+  // TODO(mstarzinger): We are only using a 'call' to get a lazy bailout
+  // point. Ideally, we whould not re-enter optimized code when deoptimized
+  // lazily. Tracked by issue v8:4195.
+  NewNode(common()->LazyBailout(),
+          jsgraph()->ZeroConstant(),                      // dummy target.
+          environment()->Checkpoint(stmt->HandlerId()));  // frame state.
+
+  // Clear message object as we enter the catch block.
+  Node* the_hole = jsgraph()->TheHoleConstant();
+  NewNode(javascript()->StoreMessage(), the_hole);
+
+  // Create a catch scope that binds the exception.
+  Node* exception = try_control.GetExceptionNode();
+  Handle<String> name = stmt->variable()->name();
+  const Operator* op = javascript()->CreateCatchContext(name);
+  Node* context = NewNode(op, exception, GetFunctionClosureForContext());
+
+  // Evaluate the catch-block.
+  VisitInScope(stmt->catch_block(), stmt->scope(), context);
+  try_control.EndCatch();
 }
 
 
 void AstGraphBuilder::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
-  UNREACHABLE();
+  TryFinallyBuilder try_control(this);
+
+  // We keep a record of all paths that enter the finally-block to be able to
+  // dispatch to the correct continuation point after the statements in the
+  // finally-block have been evaluated.
+  //
+  // The try-finally construct can enter the finally-block in three ways:
+  // 1. By exiting the try-block normally, falling through at the end.
+  // 2. By exiting the try-block with a function-local control flow transfer
+  //    (i.e. through break/continue/return statements).
+  // 3. By exiting the try-block with a thrown exception.
+  Node* fallthrough_result = jsgraph()->TheHoleConstant();
+  ControlScope::DeferredCommands* commands =
+      new (local_zone()) ControlScope::DeferredCommands(this);
+
+  // Evaluate the try-block inside a control scope. This simulates a handler
+  // that is intercepting all control commands.
+  try_control.BeginTry();
+  {
+    ControlScopeForFinally scope(this, commands, &try_control);
+    STATIC_ASSERT(TryBlockConstant::kElementCount == 1);
+    environment()->Push(current_context());
+    Visit(stmt->try_block());
+    environment()->Pop();
+  }
+  try_control.EndTry(commands->GetFallThroughToken(), fallthrough_result);
+
+  // Insert lazy bailout point.
+  // TODO(mstarzinger): We are only using a 'call' to get a lazy bailout
+  // point. Ideally, we whould not re-enter optimized code when deoptimized
+  // lazily. Tracked by issue v8:4195.
+  NewNode(common()->LazyBailout(),
+          jsgraph()->ZeroConstant(),                      // dummy target.
+          environment()->Checkpoint(stmt->HandlerId()));  // frame state.
+
+  // The result value semantics depend on how the block was entered:
+  //  - ReturnStatement: It represents the return value being returned.
+  //  - ThrowStatement: It represents the exception being thrown.
+  //  - BreakStatement/ContinueStatement: Filled with the hole.
+  //  - Falling through into finally-block: Filled with the hole.
+  Node* result = try_control.GetResultValueNode();
+  Node* token = try_control.GetDispatchTokenNode();
+
+  // The result value, dispatch token and message is expected on the operand
+  // stack (this is in sync with FullCodeGenerator::EnterFinallyBlock).
+  Node* message = NewNode(javascript()->LoadMessage());
+  environment()->Push(token);  // TODO(mstarzinger): Cook token!
+  environment()->Push(result);
+  environment()->Push(message);
+
+  // Clear message object as we enter the finally block.
+  Node* the_hole = jsgraph()->TheHoleConstant();
+  NewNode(javascript()->StoreMessage(), the_hole);
+
+  // Evaluate the finally-block.
+  Visit(stmt->finally_block());
+  try_control.EndFinally();
+
+  // The result value, dispatch token and message is restored from the operand
+  // stack (this is in sync with FullCodeGenerator::ExitFinallyBlock).
+  message = environment()->Pop();
+  result = environment()->Pop();
+  token = environment()->Pop();  // TODO(mstarzinger): Uncook token!
+  NewNode(javascript()->StoreMessage(), message);
+
+  // Dynamic dispatch after the finally-block.
+  commands->ApplyDeferredCommands(token, result);
+
+  // TODO(mstarzinger): Remove bailout once everything works.
+  if (!FLAG_turbo_try_finally) SetStackOverflow();
 }
 
 
 void AstGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) {
-  // TODO(turbofan): Do we really need a separate reloc-info for this?
-  Node* node = NewNode(javascript()->CallRuntime(Runtime::kDebugBreak, 0));
+  Node* node =
+      NewNode(javascript()->CallRuntime(Runtime::kHandleDebuggerStatement, 0));
   PrepareFrameState(node, stmt->DebugBreakId());
+  environment()->MarkAllLocalsLive();
 }
 
 
 void AstGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) {
-  Node* context = current_context();
-
-  // Build a new shared function info if we cannot find one in the baseline
-  // code. We also have a stack overflow if the recursive compilation did.
-  expr->InitializeSharedInfo(handle(info()->shared_info()->code()));
-  Handle<SharedFunctionInfo> shared_info = expr->shared_info();
-  if (shared_info.is_null()) {
-    shared_info = Compiler::BuildFunctionInfo(expr, info()->script(), info());
-    CHECK(!shared_info.is_null());  // TODO(mstarzinger): Set stack overflow?
-  }
+  // Find or build a shared function info.
+  Handle<SharedFunctionInfo> shared_info =
+      Compiler::GetSharedFunctionInfo(expr, info()->script(), info());
+  CHECK(!shared_info.is_null());  // TODO(mstarzinger): Set stack overflow?
 
   // Create node to instantiate a new closure.
-  Node* info = jsgraph()->Constant(shared_info);
-  Node* pretenure = jsgraph()->BooleanConstant(expr->pretenure());
-  const Operator* op = javascript()->CallRuntime(Runtime::kNewClosure, 3);
-  Node* value = NewNode(op, context, info, pretenure);
+  PretenureFlag pretenure = expr->pretenure() ? TENURED : NOT_TENURED;
+  const Operator* op = javascript()->CreateClosure(shared_info, pretenure);
+  Node* value = NewNode(op);
   ast_context()->ProduceValue(value);
 }
 
 
 void AstGraphBuilder::VisitClassLiteral(ClassLiteral* expr) {
-  UNREACHABLE();
+  // Visit declarations and class literal in a block scope.
+  if (expr->scope()->ContextLocalCount() > 0) {
+    Node* context = BuildLocalBlockContext(expr->scope());
+    ContextScope scope(this, expr->scope(), context);
+    VisitDeclarations(expr->scope()->declarations());
+    VisitClassLiteralContents(expr);
+  } else {
+    VisitDeclarations(expr->scope()->declarations());
+    VisitClassLiteralContents(expr);
+  }
+}
+
+
+void AstGraphBuilder::VisitClassLiteralContents(ClassLiteral* expr) {
+  Node* class_name = expr->raw_name() ? jsgraph()->Constant(expr->name())
+                                      : jsgraph()->UndefinedConstant();
+
+  // The class name is expected on the operand stack.
+  environment()->Push(class_name);
+  VisitForValueOrTheHole(expr->extends());
+  VisitForValue(expr->constructor());
+
+  // Create node to instantiate a new class.
+  Node* constructor = environment()->Pop();
+  Node* extends = environment()->Pop();
+  Node* name = environment()->Pop();
+  Node* start = jsgraph()->Constant(expr->start_position());
+  Node* end = jsgraph()->Constant(expr->end_position());
+  const Operator* opc = javascript()->CallRuntime(Runtime::kDefineClass, 5);
+  Node* literal = NewNode(opc, name, extends, constructor, start, end);
+  PrepareFrameState(literal, expr->CreateLiteralId(),
+                    OutputFrameStateCombine::Push());
+
+  // The prototype is ensured to exist by Runtime_DefineClass. No access check
+  // is needed here since the constructor is created by the class literal.
+  Node* prototype =
+      BuildLoadObjectField(literal, JSFunction::kPrototypeOrInitialMapOffset);
+
+  // The class literal and the prototype are both expected on the operand stack
+  // during evaluation of the method values.
+  environment()->Push(literal);
+  environment()->Push(prototype);
+
+  // Create nodes to store method values into the literal.
+  for (int i = 0; i < expr->properties()->length(); i++) {
+    ObjectLiteral::Property* property = expr->properties()->at(i);
+    environment()->Push(environment()->Peek(property->is_static() ? 1 : 0));
+
+    VisitForValue(property->key());
+    Node* name = BuildToName(environment()->Pop(), expr->GetIdForProperty(i));
+    environment()->Push(name);
+
+    // The static prototype property is read only. We handle the non computed
+    // property name case in the parser. Since this is the only case where we
+    // need to check for an own read only property we special case this so we do
+    // not need to do this for every property.
+    if (property->is_static() && property->is_computed_name()) {
+      Node* check = BuildThrowIfStaticPrototype(environment()->Pop(),
+                                                expr->GetIdForProperty(i));
+      environment()->Push(check);
+    }
+
+    VisitForValue(property->value());
+    Node* value = environment()->Pop();
+    Node* key = environment()->Pop();
+    Node* receiver = environment()->Pop();
+
+    BuildSetHomeObject(value, receiver, property);
+
+    switch (property->kind()) {
+      case ObjectLiteral::Property::CONSTANT:
+      case ObjectLiteral::Property::MATERIALIZED_LITERAL:
+      case ObjectLiteral::Property::PROTOTYPE:
+        UNREACHABLE();
+      case ObjectLiteral::Property::COMPUTED: {
+        const Operator* op =
+            javascript()->CallRuntime(Runtime::kDefineClassMethod, 3);
+        NewNode(op, receiver, key, value);
+        break;
+      }
+      case ObjectLiteral::Property::GETTER: {
+        Node* attr = jsgraph()->Constant(DONT_ENUM);
+        const Operator* op = javascript()->CallRuntime(
+            Runtime::kDefineGetterPropertyUnchecked, 4);
+        NewNode(op, receiver, key, value, attr);
+        break;
+      }
+      case ObjectLiteral::Property::SETTER: {
+        Node* attr = jsgraph()->Constant(DONT_ENUM);
+        const Operator* op = javascript()->CallRuntime(
+            Runtime::kDefineSetterPropertyUnchecked, 4);
+        NewNode(op, receiver, key, value, attr);
+        break;
+      }
+    }
+  }
+
+  // Set both the prototype and constructor to have fast properties, and also
+  // freeze them in strong mode.
+  prototype = environment()->Pop();
+  literal = environment()->Pop();
+  const Operator* op =
+      javascript()->CallRuntime(Runtime::kFinalizeClassDefinition, 2);
+  literal = NewNode(op, literal, prototype);
+
+  // Assign to class variable.
+  if (expr->class_variable_proxy() != nullptr) {
+    Variable* var = expr->class_variable_proxy()->var();
+    FrameStateBeforeAndAfter states(this, BailoutId::None());
+    VectorSlotPair feedback = CreateVectorSlotPair(
+        expr->NeedsProxySlot() ? expr->ProxySlot()
+                               : FeedbackVectorSlot::Invalid());
+    BuildVariableAssignment(var, literal, Token::INIT, feedback,
+                            BailoutId::None(), states);
+  }
+  ast_context()->ProduceValue(literal);
 }
 
 
@@ -835,6 +1667,13 @@
 }
 
 
+void AstGraphBuilder::VisitDoExpression(DoExpression* expr) {
+  VisitBlock(expr->block());
+  VisitVariableProxy(expr->result());
+  ast_context()->ReplaceValue();
+}
+
+
 void AstGraphBuilder::VisitConditional(Conditional* expr) {
   IfBuilder compare_if(this);
   VisitForTest(expr->condition());
@@ -851,7 +1690,9 @@
 
 void AstGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
   VectorSlotPair pair = CreateVectorSlotPair(expr->VariableFeedbackSlot());
-  Node* value = BuildVariableLoad(expr->var(), expr->id(), pair);
+  FrameStateBeforeAndAfter states(this, BeforeId(expr));
+  Node* value = BuildVariableLoad(expr->var(), expr->id(), states, pair,
+                                  ast_context()->GetStateCombine());
   ast_context()->ProduceValue(value);
 }
 
@@ -866,14 +1707,9 @@
   Node* closure = GetFunctionClosure();
 
   // Create node to materialize a regular expression literal.
-  Node* literals_array =
-      BuildLoadObjectField(closure, JSFunction::kLiteralsOffset);
-  Node* literal_index = jsgraph()->Constant(expr->literal_index());
-  Node* pattern = jsgraph()->Constant(expr->pattern());
-  Node* flags = jsgraph()->Constant(expr->flags());
-  const Operator* op =
-      javascript()->CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
-  Node* literal = NewNode(op, literals_array, literal_index, pattern, flags);
+  const Operator* op = javascript()->CreateLiteralRegExp(
+      expr->pattern(), expr->flags(), expr->literal_index());
+  Node* literal = NewNode(op, closure);
   PrepareFrameState(literal, expr->id(), ast_context()->GetStateCombine());
   ast_context()->ProduceValue(literal);
 }
@@ -883,15 +1719,10 @@
   Node* closure = GetFunctionClosure();
 
   // Create node to deep-copy the literal boilerplate.
-  expr->BuildConstantProperties(isolate());
-  Node* literals_array =
-      BuildLoadObjectField(closure, JSFunction::kLiteralsOffset);
-  Node* literal_index = jsgraph()->Constant(expr->literal_index());
-  Node* constants = jsgraph()->Constant(expr->constant_properties());
-  Node* flags = jsgraph()->Constant(expr->ComputeFlags());
-  const Operator* op =
-      javascript()->CallRuntime(Runtime::kCreateObjectLiteral, 4);
-  Node* literal = NewNode(op, literals_array, literal_index, constants, flags);
+  const Operator* op = javascript()->CreateLiteralObject(
+      expr->constant_properties(), expr->ComputeFlags(true),
+      expr->literal_index());
+  Node* literal = NewNode(op, closure);
   PrepareFrameState(literal, expr->CreateLiteralId(),
                     OutputFrameStateCombine::Push());
 
@@ -899,18 +1730,15 @@
   // property values and is the value of the entire expression.
   environment()->Push(literal);
 
-  // Mark all computed expressions that are bound to a key that is shadowed by
-  // a later occurrence of the same key. For the marked expressions, no store
-  // code is emitted.
-  expr->CalculateEmitStore(zone());
-
   // Create nodes to store computed values into the literal.
-  AccessorTable accessor_table(zone());
-  for (int i = 0; i < expr->properties()->length(); i++) {
-    ObjectLiteral::Property* property = expr->properties()->at(i);
+  int property_index = 0;
+  AccessorTable accessor_table(local_zone());
+  for (; property_index < expr->properties()->length(); property_index++) {
+    ObjectLiteral::Property* property = expr->properties()->at(property_index);
+    if (property->is_computed_name()) break;
     if (property->IsCompileTimeValue()) continue;
 
-    Literal* key = property->key();
+    Literal* key = property->key()->AsLiteral();
     switch (property->kind()) {
       case ObjectLiteral::Property::CONSTANT:
         UNREACHABLE();
@@ -923,61 +1751,73 @@
         if (key->value()->IsInternalizedString()) {
           if (property->emit_store()) {
             VisitForValue(property->value());
+            FrameStateBeforeAndAfter states(this, property->value()->id());
             Node* value = environment()->Pop();
-            Unique<Name> name = MakeUnique(key->AsPropertyName());
-            Node* store = NewNode(javascript()->StoreNamed(strict_mode(), name),
-                                  literal, value);
-            PrepareFrameState(store, key->id());
+            Node* literal = environment()->Top();
+            Handle<Name> name = key->AsPropertyName();
+            VectorSlotPair feedback =
+                CreateVectorSlotPair(property->GetSlot(0));
+            Node* store = BuildNamedStore(literal, name, value, feedback);
+            states.AddToNode(store, key->id(),
+                             OutputFrameStateCombine::Ignore());
+            BuildSetHomeObject(value, literal, property, 1);
           } else {
             VisitForEffect(property->value());
           }
           break;
         }
-        environment()->Push(literal);  // Duplicate receiver.
+        environment()->Push(environment()->Top());  // Duplicate receiver.
         VisitForValue(property->key());
         VisitForValue(property->value());
         Node* value = environment()->Pop();
         Node* key = environment()->Pop();
         Node* receiver = environment()->Pop();
         if (property->emit_store()) {
-          Node* strict = jsgraph()->Constant(SLOPPY);
+          Node* language = jsgraph()->Constant(SLOPPY);
           const Operator* op =
               javascript()->CallRuntime(Runtime::kSetProperty, 4);
-          NewNode(op, receiver, key, value, strict);
+          Node* set_property = NewNode(op, receiver, key, value, language);
+          // SetProperty should not lazy deopt on an object literal.
+          PrepareFrameState(set_property, BailoutId::None());
+          BuildSetHomeObject(value, receiver, property);
         }
         break;
       }
       case ObjectLiteral::Property::PROTOTYPE: {
-        environment()->Push(literal);  // Duplicate receiver.
+        environment()->Push(environment()->Top());  // Duplicate receiver.
         VisitForValue(property->value());
         Node* value = environment()->Pop();
         Node* receiver = environment()->Pop();
-        if (property->emit_store()) {
-          const Operator* op =
-              javascript()->CallRuntime(Runtime::kInternalSetPrototype, 2);
-          Node* set_prototype = NewNode(op, receiver, value);
-          // SetPrototype should not lazy deopt on an object
-          // literal.
-          PrepareFrameState(set_prototype, BailoutId::None());
-        }
+        DCHECK(property->emit_store());
+        const Operator* op =
+            javascript()->CallRuntime(Runtime::kInternalSetPrototype, 2);
+        Node* set_prototype = NewNode(op, receiver, value);
+        // SetPrototype should not lazy deopt on an object literal.
+        PrepareFrameState(set_prototype,
+                          expr->GetIdForPropertySet(property_index));
         break;
       }
       case ObjectLiteral::Property::GETTER:
-        accessor_table.lookup(key)->second->getter = property->value();
+        if (property->emit_store()) {
+          accessor_table.lookup(key)->second->getter = property;
+        }
         break;
       case ObjectLiteral::Property::SETTER:
-        accessor_table.lookup(key)->second->setter = property->value();
+        if (property->emit_store()) {
+          accessor_table.lookup(key)->second->setter = property;
+        }
         break;
     }
   }
 
   // Create nodes to define accessors, using only a single call to the runtime
   // for each pair of corresponding getters and setters.
+  literal = environment()->Top();  // Reload from operand stack.
   for (AccessorTable::Iterator it = accessor_table.begin();
        it != accessor_table.end(); ++it) {
     VisitForValue(it->first);
-    VisitForValueOrNull(it->second->getter);
-    VisitForValueOrNull(it->second->setter);
+    VisitObjectLiteralAccessor(literal, it->second->getter);
+    VisitObjectLiteralAccessor(literal, it->second->setter);
     Node* setter = environment()->Pop();
     Node* getter = environment()->Pop();
     Node* name = environment()->Pop();
@@ -989,7 +1829,75 @@
     PrepareFrameState(call, BailoutId::None());
   }
 
+  // Object literals have two parts. The "static" part on the left contains no
+  // computed property names, and so we can compute its map ahead of time; see
+  // Runtime_CreateObjectLiteralBoilerplate. The second "dynamic" part starts
+  // with the first computed property name and continues with all properties to
+  // its right. All the code from above initializes the static component of the
+  // object literal, and arranges for the map of the result to reflect the
+  // static order in which the keys appear. For the dynamic properties, we
+  // compile them into a series of "SetOwnProperty" runtime calls. This will
+  // preserve insertion order.
+  for (; property_index < expr->properties()->length(); property_index++) {
+    ObjectLiteral::Property* property = expr->properties()->at(property_index);
+
+    if (property->kind() == ObjectLiteral::Property::PROTOTYPE) {
+      environment()->Push(environment()->Top());  // Duplicate receiver.
+      VisitForValue(property->value());
+      Node* value = environment()->Pop();
+      Node* receiver = environment()->Pop();
+      const Operator* op =
+          javascript()->CallRuntime(Runtime::kInternalSetPrototype, 2);
+      Node* call = NewNode(op, receiver, value);
+      PrepareFrameState(call, expr->GetIdForPropertySet(property_index));
+      continue;
+    }
+
+    environment()->Push(environment()->Top());  // Duplicate receiver.
+    VisitForValue(property->key());
+    Node* name = BuildToName(environment()->Pop(),
+                             expr->GetIdForPropertyName(property_index));
+    environment()->Push(name);
+    VisitForValue(property->value());
+    Node* value = environment()->Pop();
+    Node* key = environment()->Pop();
+    Node* receiver = environment()->Pop();
+    BuildSetHomeObject(value, receiver, property);
+    switch (property->kind()) {
+      case ObjectLiteral::Property::CONSTANT:
+      case ObjectLiteral::Property::COMPUTED:
+      case ObjectLiteral::Property::MATERIALIZED_LITERAL: {
+        Node* attr = jsgraph()->Constant(NONE);
+        const Operator* op =
+            javascript()->CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4);
+        Node* call = NewNode(op, receiver, key, value, attr);
+        PrepareFrameState(call, BailoutId::None());
+        break;
+      }
+      case ObjectLiteral::Property::PROTOTYPE:
+        UNREACHABLE();  // Handled specially above.
+        break;
+      case ObjectLiteral::Property::GETTER: {
+        Node* attr = jsgraph()->Constant(NONE);
+        const Operator* op = javascript()->CallRuntime(
+            Runtime::kDefineGetterPropertyUnchecked, 4);
+        Node* call = NewNode(op, receiver, key, value, attr);
+        PrepareFrameState(call, BailoutId::None());
+        break;
+      }
+      case ObjectLiteral::Property::SETTER: {
+        Node* attr = jsgraph()->Constant(NONE);
+        const Operator* op = javascript()->CallRuntime(
+            Runtime::kDefineSetterPropertyUnchecked, 4);
+        Node* call = NewNode(op, receiver, key, value, attr);
+        PrepareFrameState(call, BailoutId::None());
+        break;
+      }
+    }
+  }
+
   // Transform literals that contain functions to fast properties.
+  literal = environment()->Top();  // Reload from operand stack.
   if (expr->has_function()) {
     const Operator* op =
         javascript()->CallRuntime(Runtime::kToFastProperties, 1);
@@ -1000,83 +1908,163 @@
 }
 
 
+void AstGraphBuilder::VisitObjectLiteralAccessor(
+    Node* home_object, ObjectLiteralProperty* property) {
+  if (property == nullptr) {
+    VisitForValueOrNull(nullptr);
+  } else {
+    VisitForValue(property->value());
+    BuildSetHomeObject(environment()->Top(), home_object, property);
+  }
+}
+
+
 void AstGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
   Node* closure = GetFunctionClosure();
 
   // Create node to deep-copy the literal boilerplate.
-  expr->BuildConstantElements(isolate());
-  Node* literals_array =
-      BuildLoadObjectField(closure, JSFunction::kLiteralsOffset);
-  Node* literal_index = jsgraph()->Constant(expr->literal_index());
-  Node* constants = jsgraph()->Constant(expr->constant_elements());
-  Node* flags = jsgraph()->Constant(expr->ComputeFlags());
-  const Operator* op =
-      javascript()->CallRuntime(Runtime::kCreateArrayLiteral, 4);
-  Node* literal = NewNode(op, literals_array, literal_index, constants, flags);
+  const Operator* op = javascript()->CreateLiteralArray(
+      expr->constant_elements(), expr->ComputeFlags(true),
+      expr->literal_index());
+  Node* literal = NewNode(op, closure);
+  PrepareFrameState(literal, expr->CreateLiteralId(),
+                    OutputFrameStateCombine::Push());
 
-  // The array and the literal index are both expected on the operand stack
-  // during computation of the element values.
+  // The array is expected on the operand stack during computation of the
+  // element values.
   environment()->Push(literal);
-  environment()->Push(literal_index);
 
   // Create nodes to evaluate all the non-constant subexpressions and to store
   // them into the newly cloned array.
-  for (int i = 0; i < expr->values()->length(); i++) {
-    Expression* subexpr = expr->values()->at(i);
+  int array_index = 0;
+  for (; array_index < expr->values()->length(); array_index++) {
+    Expression* subexpr = expr->values()->at(array_index);
+    if (subexpr->IsSpread()) break;
     if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
 
     VisitForValue(subexpr);
-    Node* value = environment()->Pop();
-    Node* index = jsgraph()->Constant(i);
-    Node* store = NewNode(javascript()->StoreProperty(strict_mode()), literal,
-                          index, value);
-    PrepareFrameState(store, expr->GetIdForElement(i));
+    {
+      FrameStateBeforeAndAfter states(this, subexpr->id());
+      VectorSlotPair pair = CreateVectorSlotPair(expr->LiteralFeedbackSlot());
+      Node* value = environment()->Pop();
+      Node* index = jsgraph()->Constant(array_index);
+      Node* literal = environment()->Top();
+      Node* store = BuildKeyedStore(literal, index, value, pair);
+      states.AddToNode(store, expr->GetIdForElement(array_index),
+                       OutputFrameStateCombine::Ignore());
+    }
   }
 
-  environment()->Pop();  // Array literal index.
+  // In case the array literal contains spread expressions it has two parts. The
+  // first part is  the "static" array which has a literal index is handled
+  // above. The second part is the part after the first spread expression
+  // (inclusive) and these elements gets appended to the array. Note that the
+  // number elements an iterable produces is unknown ahead of time.
+  for (; array_index < expr->values()->length(); array_index++) {
+    Expression* subexpr = expr->values()->at(array_index);
+    Node* result;
+
+    if (subexpr->IsSpread()) {
+      VisitForValue(subexpr->AsSpread()->expression());
+      FrameStateBeforeAndAfter states(this,
+                                      subexpr->AsSpread()->expression()->id());
+      Node* iterable = environment()->Pop();
+      Node* array = environment()->Pop();
+      Node* function = BuildLoadNativeContextField(
+          Context::CONCAT_ITERABLE_TO_ARRAY_BUILTIN_INDEX);
+      result = NewNode(javascript()->CallFunction(3, language_mode()), function,
+                       array, iterable);
+      states.AddToNode(result, expr->GetIdForElement(array_index));
+    } else {
+      VisitForValue(subexpr);
+      Node* value = environment()->Pop();
+      Node* array = environment()->Pop();
+      const Operator* op =
+          javascript()->CallRuntime(Runtime::kAppendElement, 2);
+      result = NewNode(op, array, value);
+      PrepareFrameState(result, expr->GetIdForElement(array_index));
+    }
+
+    environment()->Push(result);
+  }
+
   ast_context()->ProduceValue(environment()->Pop());
 }
 
 
-void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value) {
-  DCHECK(expr->IsValidReferenceExpression());
+void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value,
+                                           const VectorSlotPair& feedback,
+                                           BailoutId bailout_id_before,
+                                           BailoutId bailout_id_after) {
+  DCHECK(expr->IsValidReferenceExpressionOrThis());
 
   // Left-hand side can only be a property, a global or a variable slot.
   Property* property = expr->AsProperty();
-  LhsKind assign_type = DetermineLhsKind(expr);
+  LhsKind assign_type = Property::GetAssignType(property);
 
   // Evaluate LHS expression and store the value.
   switch (assign_type) {
     case VARIABLE: {
       Variable* var = expr->AsVariableProxy()->var();
-      // TODO(jarin) Fill in the correct bailout id.
-      BuildVariableAssignment(var, value, Token::ASSIGN, BailoutId::None());
+      environment()->Push(value);
+      FrameStateBeforeAndAfter states(this, bailout_id_before);
+      value = environment()->Pop();
+      BuildVariableAssignment(var, value, Token::ASSIGN, feedback,
+                              bailout_id_after, states);
       break;
     }
     case NAMED_PROPERTY: {
       environment()->Push(value);
       VisitForValue(property->obj());
+      FrameStateBeforeAndAfter states(this, property->obj()->id());
       Node* object = environment()->Pop();
       value = environment()->Pop();
-      Unique<Name> name =
-          MakeUnique(property->key()->AsLiteral()->AsPropertyName());
-      Node* store =
-          NewNode(javascript()->StoreNamed(strict_mode(), name), object, value);
-      // TODO(jarin) Fill in the correct bailout id.
-      PrepareFrameState(store, BailoutId::None());
+      Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
+      Node* store = BuildNamedStore(object, name, value, feedback);
+      states.AddToNode(store, bailout_id_after,
+                       OutputFrameStateCombine::Ignore());
       break;
     }
     case KEYED_PROPERTY: {
       environment()->Push(value);
       VisitForValue(property->obj());
       VisitForValue(property->key());
+      FrameStateBeforeAndAfter states(this, property->key()->id());
       Node* key = environment()->Pop();
       Node* object = environment()->Pop();
       value = environment()->Pop();
-      Node* store = NewNode(javascript()->StoreProperty(strict_mode()), object,
-                            key, value);
-      // TODO(jarin) Fill in the correct bailout id.
-      PrepareFrameState(store, BailoutId::None());
+      Node* store = BuildKeyedStore(object, key, value, feedback);
+      states.AddToNode(store, bailout_id_after,
+                       OutputFrameStateCombine::Ignore());
+      break;
+    }
+    case NAMED_SUPER_PROPERTY: {
+      environment()->Push(value);
+      VisitForValue(property->obj()->AsSuperPropertyReference()->this_var());
+      VisitForValue(property->obj()->AsSuperPropertyReference()->home_object());
+      FrameStateBeforeAndAfter states(this, property->obj()->id());
+      Node* home_object = environment()->Pop();
+      Node* receiver = environment()->Pop();
+      value = environment()->Pop();
+      Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
+      Node* store = BuildNamedSuperStore(receiver, home_object, name, value);
+      states.AddToNode(store, bailout_id_after,
+                       OutputFrameStateCombine::Ignore());
+      break;
+    }
+    case KEYED_SUPER_PROPERTY: {
+      environment()->Push(value);
+      VisitForValue(property->obj()->AsSuperPropertyReference()->this_var());
+      VisitForValue(property->obj()->AsSuperPropertyReference()->home_object());
+      VisitForValue(property->key());
+      FrameStateBeforeAndAfter states(this, property->key()->id());
+      Node* key = environment()->Pop();
+      Node* home_object = environment()->Pop();
+      Node* receiver = environment()->Pop();
+      value = environment()->Pop();
+      Node* store = BuildKeyedSuperStore(receiver, home_object, key, value);
+      states.AddToNode(store, bailout_id_after,
+                       OutputFrameStateCombine::Ignore());
       break;
     }
   }
@@ -1084,48 +2072,67 @@
 
 
 void AstGraphBuilder::VisitAssignment(Assignment* expr) {
-  DCHECK(expr->target()->IsValidReferenceExpression());
+  DCHECK(expr->target()->IsValidReferenceExpressionOrThis());
 
   // Left-hand side can only be a property, a global or a variable slot.
   Property* property = expr->target()->AsProperty();
-  LhsKind assign_type = DetermineLhsKind(expr->target());
+  LhsKind assign_type = Property::GetAssignType(property);
+  bool needs_frame_state_before = true;
 
   // Evaluate LHS expression.
   switch (assign_type) {
-    case VARIABLE:
-      // Nothing to do here.
+    case VARIABLE: {
+      Variable* variable = expr->target()->AsVariableProxy()->var();
+      if (variable->location() == VariableLocation::PARAMETER ||
+          variable->location() == VariableLocation::LOCAL ||
+          variable->location() == VariableLocation::CONTEXT) {
+        needs_frame_state_before = false;
+      }
       break;
+    }
     case NAMED_PROPERTY:
       VisitForValue(property->obj());
       break;
-    case KEYED_PROPERTY: {
+    case KEYED_PROPERTY:
       VisitForValue(property->obj());
       VisitForValue(property->key());
       break;
-    }
+    case NAMED_SUPER_PROPERTY:
+      VisitForValue(property->obj()->AsSuperPropertyReference()->this_var());
+      VisitForValue(property->obj()->AsSuperPropertyReference()->home_object());
+      break;
+    case KEYED_SUPER_PROPERTY:
+      VisitForValue(property->obj()->AsSuperPropertyReference()->this_var());
+      VisitForValue(property->obj()->AsSuperPropertyReference()->home_object());
+      VisitForValue(property->key());
+      break;
   }
 
+  BailoutId before_store_id = BailoutId::None();
   // Evaluate the value and potentially handle compound assignments by loading
   // the left-hand side value and performing a binary operation.
   if (expr->is_compound()) {
-    Node* old_value = NULL;
+    Node* old_value = nullptr;
     switch (assign_type) {
       case VARIABLE: {
         VariableProxy* proxy = expr->target()->AsVariableProxy();
         VectorSlotPair pair =
             CreateVectorSlotPair(proxy->VariableFeedbackSlot());
-        old_value = BuildVariableLoad(proxy->var(), expr->target()->id(), pair);
+        FrameStateBeforeAndAfter states(this, BeforeId(proxy));
+        old_value =
+            BuildVariableLoad(proxy->var(), expr->target()->id(), states, pair,
+                              OutputFrameStateCombine::Push());
         break;
       }
       case NAMED_PROPERTY: {
         Node* object = environment()->Top();
-        Unique<Name> name =
-            MakeUnique(property->key()->AsLiteral()->AsPropertyName());
+        Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
         VectorSlotPair pair =
             CreateVectorSlotPair(property->PropertyFeedbackSlot());
-        old_value = NewNode(javascript()->LoadNamed(name, pair), object);
-        PrepareFrameState(old_value, property->LoadId(),
-                          OutputFrameStateCombine::Push());
+        FrameStateBeforeAndAfter states(this, property->obj()->id());
+        old_value = BuildNamedLoad(object, name, pair);
+        states.AddToNode(old_value, property->LoadId(),
+                         OutputFrameStateCombine::Push());
         break;
       }
       case KEYED_PROPERTY: {
@@ -1133,50 +2140,104 @@
         Node* object = environment()->Peek(1);
         VectorSlotPair pair =
             CreateVectorSlotPair(property->PropertyFeedbackSlot());
-        old_value = NewNode(javascript()->LoadProperty(pair), object, key);
-        PrepareFrameState(old_value, property->LoadId(),
-                          OutputFrameStateCombine::Push());
+        FrameStateBeforeAndAfter states(this, property->key()->id());
+        old_value = BuildKeyedLoad(object, key, pair);
+        states.AddToNode(old_value, property->LoadId(),
+                         OutputFrameStateCombine::Push());
+        break;
+      }
+      case NAMED_SUPER_PROPERTY: {
+        Node* home_object = environment()->Top();
+        Node* receiver = environment()->Peek(1);
+        Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
+        VectorSlotPair pair =
+            CreateVectorSlotPair(property->PropertyFeedbackSlot());
+        FrameStateBeforeAndAfter states(this, property->obj()->id());
+        old_value = BuildNamedSuperLoad(receiver, home_object, name, pair);
+        states.AddToNode(old_value, property->LoadId(),
+                         OutputFrameStateCombine::Push());
+        break;
+      }
+      case KEYED_SUPER_PROPERTY: {
+        Node* key = environment()->Top();
+        Node* home_object = environment()->Peek(1);
+        Node* receiver = environment()->Peek(2);
+        VectorSlotPair pair =
+            CreateVectorSlotPair(property->PropertyFeedbackSlot());
+        FrameStateBeforeAndAfter states(this, property->key()->id());
+        old_value = BuildKeyedSuperLoad(receiver, home_object, key, pair);
+        states.AddToNode(old_value, property->LoadId(),
+                         OutputFrameStateCombine::Push());
         break;
       }
     }
     environment()->Push(old_value);
     VisitForValue(expr->value());
-    Node* right = environment()->Pop();
-    Node* left = environment()->Pop();
-    Node* value = BuildBinaryOp(left, right, expr->binary_op());
-    PrepareFrameState(value, expr->binary_operation()->id(),
-                      OutputFrameStateCombine::Push());
+    Node* value;
+    {
+      FrameStateBeforeAndAfter states(this, expr->value()->id());
+      Node* right = environment()->Pop();
+      Node* left = environment()->Pop();
+      value =
+          BuildBinaryOp(left, right, expr->binary_op(),
+                        expr->binary_operation()->BinaryOperationFeedbackId());
+      states.AddToNode(value, expr->binary_operation()->id(),
+                       OutputFrameStateCombine::Push());
+    }
     environment()->Push(value);
+    if (needs_frame_state_before) {
+      before_store_id = expr->binary_operation()->id();
+    }
   } else {
     VisitForValue(expr->value());
+    if (needs_frame_state_before) {
+      before_store_id = expr->value()->id();
+    }
   }
 
+  FrameStateBeforeAndAfter store_states(this, before_store_id);
   // Store the value.
   Node* value = environment()->Pop();
+  VectorSlotPair feedback = CreateVectorSlotPair(expr->AssignmentSlot());
   switch (assign_type) {
     case VARIABLE: {
       Variable* variable = expr->target()->AsVariableProxy()->var();
-      BuildVariableAssignment(variable, value, expr->op(), expr->AssignmentId(),
-                              ast_context()->GetStateCombine());
+      BuildVariableAssignment(variable, value, expr->op(), feedback, expr->id(),
+                              store_states, ast_context()->GetStateCombine());
       break;
     }
     case NAMED_PROPERTY: {
       Node* object = environment()->Pop();
-      Unique<Name> name =
-          MakeUnique(property->key()->AsLiteral()->AsPropertyName());
-      Node* store =
-          NewNode(javascript()->StoreNamed(strict_mode(), name), object, value);
-      PrepareFrameState(store, expr->AssignmentId(),
-                        ast_context()->GetStateCombine());
+      Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
+      Node* store = BuildNamedStore(object, name, value, feedback);
+      store_states.AddToNode(store, expr->id(),
+                             ast_context()->GetStateCombine());
       break;
     }
     case KEYED_PROPERTY: {
       Node* key = environment()->Pop();
       Node* object = environment()->Pop();
-      Node* store = NewNode(javascript()->StoreProperty(strict_mode()), object,
-                            key, value);
-      PrepareFrameState(store, expr->AssignmentId(),
-                        ast_context()->GetStateCombine());
+      Node* store = BuildKeyedStore(object, key, value, feedback);
+      store_states.AddToNode(store, expr->id(),
+                             ast_context()->GetStateCombine());
+      break;
+    }
+    case NAMED_SUPER_PROPERTY: {
+      Node* home_object = environment()->Pop();
+      Node* receiver = environment()->Pop();
+      Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
+      Node* store = BuildNamedSuperStore(receiver, home_object, name, value);
+      store_states.AddToNode(store, expr->id(),
+                             ast_context()->GetStateCombine());
+      break;
+    }
+    case KEYED_SUPER_PROPERTY: {
+      Node* key = environment()->Pop();
+      Node* home_object = environment()->Pop();
+      Node* receiver = environment()->Pop();
+      Node* store = BuildKeyedSuperStore(receiver, home_object, key, value);
+      store_states.AddToNode(store, expr->id(),
+                             ast_context()->GetStateCombine());
       break;
     }
   }
@@ -1186,11 +2247,8 @@
 
 
 void AstGraphBuilder::VisitYield(Yield* expr) {
-  VisitForValue(expr->generator_object());
-  VisitForValue(expr->expression());
-  environment()->Pop();
-  environment()->Pop();
-  // TODO(turbofan): VisitYield
+  // TODO(turbofan): Implement yield here.
+  SetStackOverflow();
   ast_context()->ProduceValue(jsgraph()->UndefinedConstant());
 }
 
@@ -1198,29 +2256,62 @@
 void AstGraphBuilder::VisitThrow(Throw* expr) {
   VisitForValue(expr->exception());
   Node* exception = environment()->Pop();
-  const Operator* op = javascript()->CallRuntime(Runtime::kThrow, 1);
-  Node* value = NewNode(op, exception);
-  PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
+  Node* value = BuildThrowError(exception, expr->id());
   ast_context()->ProduceValue(value);
 }
 
 
 void AstGraphBuilder::VisitProperty(Property* expr) {
-  Node* value;
+  Node* value = nullptr;
+  LhsKind property_kind = Property::GetAssignType(expr);
   VectorSlotPair pair = CreateVectorSlotPair(expr->PropertyFeedbackSlot());
-  if (expr->key()->IsPropertyName()) {
-    VisitForValue(expr->obj());
-    Node* object = environment()->Pop();
-    Unique<Name> name = MakeUnique(expr->key()->AsLiteral()->AsPropertyName());
-    value = NewNode(javascript()->LoadNamed(name, pair), object);
-  } else {
-    VisitForValue(expr->obj());
-    VisitForValue(expr->key());
-    Node* key = environment()->Pop();
-    Node* object = environment()->Pop();
-    value = NewNode(javascript()->LoadProperty(pair), object, key);
+  switch (property_kind) {
+    case VARIABLE:
+      UNREACHABLE();
+      break;
+    case NAMED_PROPERTY: {
+      VisitForValue(expr->obj());
+      FrameStateBeforeAndAfter states(this, expr->obj()->id());
+      Node* object = environment()->Pop();
+      Handle<Name> name = expr->key()->AsLiteral()->AsPropertyName();
+      value = BuildNamedLoad(object, name, pair);
+      states.AddToNode(value, expr->id(), ast_context()->GetStateCombine());
+      break;
+    }
+    case KEYED_PROPERTY: {
+      VisitForValue(expr->obj());
+      VisitForValue(expr->key());
+      FrameStateBeforeAndAfter states(this, expr->key()->id());
+      Node* key = environment()->Pop();
+      Node* object = environment()->Pop();
+      value = BuildKeyedLoad(object, key, pair);
+      states.AddToNode(value, expr->id(), ast_context()->GetStateCombine());
+      break;
+    }
+    case NAMED_SUPER_PROPERTY: {
+      VisitForValue(expr->obj()->AsSuperPropertyReference()->this_var());
+      VisitForValue(expr->obj()->AsSuperPropertyReference()->home_object());
+      FrameStateBeforeAndAfter states(this, expr->obj()->id());
+      Node* home_object = environment()->Pop();
+      Node* receiver = environment()->Pop();
+      Handle<Name> name = expr->key()->AsLiteral()->AsPropertyName();
+      value = BuildNamedSuperLoad(receiver, home_object, name, pair);
+      states.AddToNode(value, expr->id(), ast_context()->GetStateCombine());
+      break;
+    }
+    case KEYED_SUPER_PROPERTY: {
+      VisitForValue(expr->obj()->AsSuperPropertyReference()->this_var());
+      VisitForValue(expr->obj()->AsSuperPropertyReference()->home_object());
+      VisitForValue(expr->key());
+      FrameStateBeforeAndAfter states(this, expr->key()->id());
+      Node* key = environment()->Pop();
+      Node* home_object = environment()->Pop();
+      Node* receiver = environment()->Pop();
+      value = BuildKeyedSuperLoad(receiver, home_object, key, pair);
+      states.AddToNode(value, expr->id(), ast_context()->GetStateCombine());
+      break;
+    }
   }
-  PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
   ast_context()->ProduceValue(value);
 }
 
@@ -1231,68 +2322,136 @@
 
   // Prepare the callee and the receiver to the function call. This depends on
   // the semantics of the underlying call type.
-  CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS;
-  Node* receiver_value = NULL;
-  Node* callee_value = NULL;
+  ConvertReceiverMode receiver_hint = ConvertReceiverMode::kAny;
+  Node* receiver_value = nullptr;
+  Node* callee_value = nullptr;
   bool possibly_eval = false;
   switch (call_type) {
     case Call::GLOBAL_CALL: {
       VariableProxy* proxy = callee->AsVariableProxy();
       VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot());
+      FrameStateBeforeAndAfter states(this, BeforeId(proxy));
       callee_value =
-          BuildVariableLoad(proxy->var(), expr->expression()->id(), pair);
+          BuildVariableLoad(proxy->var(), expr->expression()->id(), states,
+                            pair, OutputFrameStateCombine::Push());
+      receiver_hint = ConvertReceiverMode::kNullOrUndefined;
       receiver_value = jsgraph()->UndefinedConstant();
       break;
     }
     case Call::LOOKUP_SLOT_CALL: {
       Variable* variable = callee->AsVariableProxy()->var();
-      DCHECK(variable->location() == Variable::LOOKUP);
+      DCHECK(variable->location() == VariableLocation::LOOKUP);
       Node* name = jsgraph()->Constant(variable->name());
       const Operator* op =
           javascript()->CallRuntime(Runtime::kLoadLookupSlot, 2);
       Node* pair = NewNode(op, current_context(), name);
       callee_value = NewNode(common()->Projection(0), pair);
       receiver_value = NewNode(common()->Projection(1), pair);
-
-      PrepareFrameState(pair, expr->EvalOrLookupId(),
+      PrepareFrameState(pair, expr->LookupId(),
                         OutputFrameStateCombine::Push(2));
       break;
     }
-    case Call::PROPERTY_CALL: {
+    case Call::NAMED_PROPERTY_CALL: {
       Property* property = callee->AsProperty();
-      VisitForValue(property->obj());
-      Node* object = environment()->Top();
-      VectorSlotPair pair =
+      VectorSlotPair feedback =
           CreateVectorSlotPair(property->PropertyFeedbackSlot());
-      if (property->key()->IsPropertyName()) {
-        Unique<Name> name =
-            MakeUnique(property->key()->AsLiteral()->AsPropertyName());
-        callee_value = NewNode(javascript()->LoadNamed(name, pair), object);
-      } else {
-        VisitForValue(property->key());
-        Node* key = environment()->Pop();
-        callee_value = NewNode(javascript()->LoadProperty(pair), object, key);
-      }
-      PrepareFrameState(callee_value, property->LoadId(),
-                        OutputFrameStateCombine::Push());
+      VisitForValue(property->obj());
+      FrameStateBeforeAndAfter states(this, property->obj()->id());
+      Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
+      Node* object = environment()->Top();
+      callee_value = BuildNamedLoad(object, name, feedback);
+      states.AddToNode(callee_value, property->LoadId(),
+                       OutputFrameStateCombine::Push());
+      // Note that a property call requires the receiver to be wrapped into
+      // an object for sloppy callees. However the receiver is guaranteed
+      // not to be null or undefined at this point.
+      receiver_hint = ConvertReceiverMode::kNotNullOrUndefined;
       receiver_value = environment()->Pop();
-      // Note that a PROPERTY_CALL requires the receiver to be wrapped into an
-      // object for sloppy callees. This could also be modeled explicitly here,
-      // thereby obsoleting the need for a flag to the call operator.
-      flags = CALL_AS_METHOD;
       break;
     }
-    case Call::SUPER_CALL: {
-      // todo(dslomov): implement super calls in turbofan.
-      UNIMPLEMENTED();
+    case Call::KEYED_PROPERTY_CALL: {
+      Property* property = callee->AsProperty();
+      VectorSlotPair feedback =
+          CreateVectorSlotPair(property->PropertyFeedbackSlot());
+      VisitForValue(property->obj());
+      VisitForValue(property->key());
+      FrameStateBeforeAndAfter states(this, property->key()->id());
+      Node* key = environment()->Pop();
+      Node* object = environment()->Top();
+      callee_value = BuildKeyedLoad(object, key, feedback);
+      states.AddToNode(callee_value, property->LoadId(),
+                       OutputFrameStateCombine::Push());
+      // Note that a property call requires the receiver to be wrapped into
+      // an object for sloppy callees. However the receiver is guaranteed
+      // not to be null or undefined at this point.
+      receiver_hint = ConvertReceiverMode::kNotNullOrUndefined;
+      receiver_value = environment()->Pop();
       break;
     }
+    case Call::NAMED_SUPER_PROPERTY_CALL: {
+      Property* property = callee->AsProperty();
+      SuperPropertyReference* super_ref =
+          property->obj()->AsSuperPropertyReference();
+      VisitForValue(super_ref->home_object());
+      VisitForValue(super_ref->this_var());
+      Node* home = environment()->Peek(1);
+      Node* object = environment()->Top();
+      Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
+      FrameStateBeforeAndAfter states(this, property->obj()->id());
+      callee_value = BuildNamedSuperLoad(object, home, name, VectorSlotPair());
+      states.AddToNode(callee_value, property->LoadId(),
+                       OutputFrameStateCombine::Push());
+      // Note that a property call requires the receiver to be wrapped into
+      // an object for sloppy callees. Since the receiver is not the target of
+      // the load, it could very well be null or undefined at this point.
+      receiver_value = environment()->Pop();
+      environment()->Drop(1);
+      break;
+    }
+    case Call::KEYED_SUPER_PROPERTY_CALL: {
+      Property* property = callee->AsProperty();
+      SuperPropertyReference* super_ref =
+          property->obj()->AsSuperPropertyReference();
+      VisitForValue(super_ref->home_object());
+      VisitForValue(super_ref->this_var());
+      environment()->Push(environment()->Top());    // Duplicate this_var.
+      environment()->Push(environment()->Peek(2));  // Duplicate home_obj.
+      VisitForValue(property->key());
+      Node* key = environment()->Pop();
+      Node* home = environment()->Pop();
+      Node* object = environment()->Pop();
+      FrameStateBeforeAndAfter states(this, property->key()->id());
+      callee_value = BuildKeyedSuperLoad(object, home, key, VectorSlotPair());
+      states.AddToNode(callee_value, property->LoadId(),
+                       OutputFrameStateCombine::Push());
+      // Note that a property call requires the receiver to be wrapped into
+      // an object for sloppy callees. Since the receiver is not the target of
+      // the load, it could very well be null or undefined at this point.
+      receiver_value = environment()->Pop();
+      environment()->Drop(1);
+      break;
+    }
+    case Call::SUPER_CALL:
+      return VisitCallSuper(expr);
     case Call::POSSIBLY_EVAL_CALL:
       possibly_eval = true;
+      if (callee->AsVariableProxy()->var()->IsLookupSlot()) {
+        Variable* variable = callee->AsVariableProxy()->var();
+        Node* name = jsgraph()->Constant(variable->name());
+        const Operator* op =
+            javascript()->CallRuntime(Runtime::kLoadLookupSlot, 2);
+        Node* pair = NewNode(op, current_context(), name);
+        callee_value = NewNode(common()->Projection(0), pair);
+        receiver_value = NewNode(common()->Projection(1), pair);
+        PrepareFrameState(pair, expr->LookupId(),
+                          OutputFrameStateCombine::Push(2));
+        break;
+      }
     // Fall through.
     case Call::OTHER_CALL:
       VisitForValue(callee);
       callee_value = environment()->Pop();
+      receiver_hint = ConvertReceiverMode::kNullOrUndefined;
       receiver_value = jsgraph()->UndefinedConstant();
       break;
   }
@@ -1306,8 +2465,8 @@
   ZoneList<Expression*>* args = expr->arguments();
   VisitForValues(args);
 
-  // Resolve callee and receiver for a potential direct eval call. This block
-  // will mutate the callee and receiver values pushed onto the environment.
+  // Resolve callee for a potential direct eval call. This block will mutate the
+  // callee value pushed onto the environment.
   if (possibly_eval && args->length() > 0) {
     int arg_count = args->length();
 
@@ -1316,29 +2475,59 @@
     Node* source = environment()->Peek(arg_count - 1);
 
     // Create node to ask for help resolving potential eval call. This will
-    // provide a fully resolved callee and the corresponding receiver.
+    // provide a fully resolved callee to patch into the environment.
     Node* function = GetFunctionClosure();
-    Node* receiver = environment()->Lookup(info()->scope()->receiver());
-    Node* strict = jsgraph()->Constant(strict_mode());
-    Node* position = jsgraph()->Constant(info()->scope()->start_position());
+    Node* language = jsgraph()->Constant(language_mode());
+    Node* position = jsgraph()->Constant(current_scope()->start_position());
     const Operator* op =
-        javascript()->CallRuntime(Runtime::kResolvePossiblyDirectEval, 6);
-    Node* pair =
-        NewNode(op, callee, source, function, receiver, strict, position);
-    PrepareFrameState(pair, expr->EvalOrLookupId(),
+        javascript()->CallRuntime(Runtime::kResolvePossiblyDirectEval, 5);
+    Node* new_callee =
+        NewNode(op, callee, source, function, language, position);
+    PrepareFrameState(new_callee, expr->EvalId(),
                       OutputFrameStateCombine::PokeAt(arg_count + 1));
-    Node* new_callee = NewNode(common()->Projection(0), pair);
-    Node* new_receiver = NewNode(common()->Projection(1), pair);
 
-    // Patch callee and receiver on the environment.
+    // Patch callee on the environment.
     environment()->Poke(arg_count + 1, new_callee);
-    environment()->Poke(arg_count + 0, new_receiver);
   }
 
   // Create node to perform the function call.
-  const Operator* call = javascript()->CallFunction(args->length() + 2, flags);
+  VectorSlotPair feedback = CreateVectorSlotPair(expr->CallFeedbackICSlot());
+  const Operator* call = javascript()->CallFunction(
+      args->length() + 2, language_mode(), feedback, receiver_hint);
+  FrameStateBeforeAndAfter states(this, expr->CallId());
   Node* value = ProcessArguments(call, args->length() + 2);
-  PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
+  environment()->Push(value->InputAt(0));  // The callee passed to the call.
+  states.AddToNode(value, expr->ReturnId(), OutputFrameStateCombine::Push());
+  environment()->Drop(1);
+  ast_context()->ProduceValue(value);
+}
+
+
+void AstGraphBuilder::VisitCallSuper(Call* expr) {
+  SuperCallReference* super = expr->expression()->AsSuperCallReference();
+  DCHECK_NOT_NULL(super);
+
+  // Prepare the callee to the super call.
+  VisitForValue(super->this_function_var());
+  Node* this_function = environment()->Pop();
+  const Operator* op =
+      javascript()->CallRuntime(Runtime::kInlineGetSuperConstructor, 1);
+  Node* super_function = NewNode(op, this_function);
+  environment()->Push(super_function);
+
+  // Evaluate all arguments to the super call.
+  ZoneList<Expression*>* args = expr->arguments();
+  VisitForValues(args);
+
+  // The new target is loaded from the {new.target} variable.
+  VisitForValue(super->new_target_var());
+
+  // Create node to perform the super call.
+  const Operator* call =
+      javascript()->CallConstruct(args->length() + 2, VectorSlotPair());
+  FrameStateBeforeAndAfter states(this, super->new_target_var()->id());
+  Node* value = ProcessArguments(call, args->length() + 2);
+  states.AddToNode(value, expr->ReturnId(), OutputFrameStateCombine::Push());
   ast_context()->ProduceValue(value);
 }
 
@@ -1350,29 +2539,30 @@
   ZoneList<Expression*>* args = expr->arguments();
   VisitForValues(args);
 
+  // The baseline compiler doesn't push the new.target, so we need to record
+  // the frame state before the push.
+  FrameStateBeforeAndAfter states(
+      this, args->is_empty() ? expr->expression()->id() : args->last()->id());
+
+  // The new target is the same as the callee.
+  environment()->Push(environment()->Peek(args->length()));
+
   // Create node to perform the construct call.
-  const Operator* call = javascript()->CallConstruct(args->length() + 1);
-  Node* value = ProcessArguments(call, args->length() + 1);
-  PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
+  VectorSlotPair feedback = CreateVectorSlotPair(expr->CallNewFeedbackSlot());
+  const Operator* call =
+      javascript()->CallConstruct(args->length() + 2, feedback);
+  Node* value = ProcessArguments(call, args->length() + 2);
+  states.AddToNode(value, expr->ReturnId(), OutputFrameStateCombine::Push());
   ast_context()->ProduceValue(value);
 }
 
 
 void AstGraphBuilder::VisitCallJSRuntime(CallRuntime* expr) {
-  Handle<String> name = expr->name();
-
   // The callee and the receiver both have to be pushed onto the operand stack
   // before arguments are being evaluated.
-  CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS;
-  Node* receiver_value = BuildLoadBuiltinsObject();
-  Unique<String> unique = MakeUnique(name);
-  VectorSlotPair pair = CreateVectorSlotPair(expr->CallRuntimeFeedbackSlot());
-  Node* callee_value =
-      NewNode(javascript()->LoadNamed(unique, pair), receiver_value);
-  // TODO(jarin): Find/create a bailout id to deoptimize to (crankshaft
-  // refuses to optimize functions with jsruntime calls).
-  PrepareFrameState(callee_value, BailoutId::None(),
-                    OutputFrameStateCombine::Push());
+  Node* callee_value = BuildLoadNativeContextField(expr->context_index());
+  Node* receiver_value = jsgraph()->UndefinedConstant();
+
   environment()->Push(callee_value);
   environment()->Push(receiver_value);
 
@@ -1381,23 +2571,31 @@
   VisitForValues(args);
 
   // Create node to perform the JS runtime call.
-  const Operator* call = javascript()->CallFunction(args->length() + 2, flags);
+  const Operator* call =
+      javascript()->CallFunction(args->length() + 2, language_mode());
+  FrameStateBeforeAndAfter states(this, expr->CallId());
   Node* value = ProcessArguments(call, args->length() + 2);
-  PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
+  states.AddToNode(value, expr->id(), ast_context()->GetStateCombine());
   ast_context()->ProduceValue(value);
 }
 
 
 void AstGraphBuilder::VisitCallRuntime(CallRuntime* expr) {
-  const Runtime::Function* function = expr->function();
-
   // Handle calls to runtime functions implemented in JavaScript separately as
   // the call follows JavaScript ABI and the callee is statically unknown.
   if (expr->is_jsruntime()) {
-    DCHECK(function == NULL && expr->name()->length() > 0);
     return VisitCallJSRuntime(expr);
   }
 
+  const Runtime::Function* function = expr->function();
+
+  // TODO(mstarzinger): This bailout is a gigantic hack, the owner is ashamed.
+  if (function->function_id == Runtime::kInlineGeneratorNext ||
+      function->function_id == Runtime::kInlineGeneratorThrow) {
+    ast_context()->ProduceValue(jsgraph()->TheHoleConstant());
+    return SetStackOverflow();
+  }
+
   // Evaluate all arguments to the runtime call.
   ZoneList<Expression*>* args = expr->arguments();
   VisitForValues(args);
@@ -1405,8 +2603,9 @@
   // Create node to perform the runtime call.
   Runtime::FunctionId functionId = function->function_id;
   const Operator* call = javascript()->CallRuntime(functionId, args->length());
+  FrameStateBeforeAndAfter states(this, expr->CallId());
   Node* value = ProcessArguments(call, args->length());
-  PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
+  states.AddToNode(value, expr->id(), ast_context()->GetStateCombine());
   ast_context()->ProduceValue(value);
 }
 
@@ -1428,97 +2627,177 @@
 
 
 void AstGraphBuilder::VisitCountOperation(CountOperation* expr) {
-  DCHECK(expr->expression()->IsValidReferenceExpression());
+  DCHECK(expr->expression()->IsValidReferenceExpressionOrThis());
 
   // Left-hand side can only be a property, a global or a variable slot.
   Property* property = expr->expression()->AsProperty();
-  LhsKind assign_type = DetermineLhsKind(expr->expression());
+  LhsKind assign_type = Property::GetAssignType(property);
 
   // Reserve space for result of postfix operation.
   bool is_postfix = expr->is_postfix() && !ast_context()->IsEffect();
-  if (is_postfix) environment()->Push(jsgraph()->UndefinedConstant());
+  if (is_postfix && assign_type != VARIABLE) {
+    environment()->Push(jsgraph()->ZeroConstant());
+  }
 
   // Evaluate LHS expression and get old value.
-  Node* old_value = NULL;
+  Node* old_value = nullptr;
   int stack_depth = -1;
   switch (assign_type) {
     case VARIABLE: {
       VariableProxy* proxy = expr->expression()->AsVariableProxy();
       VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot());
+      FrameStateBeforeAndAfter states(this, BeforeId(proxy));
       old_value =
-          BuildVariableLoad(proxy->var(), expr->expression()->id(), pair);
+          BuildVariableLoad(proxy->var(), expr->expression()->id(), states,
+                            pair, OutputFrameStateCombine::Push());
       stack_depth = 0;
       break;
     }
     case NAMED_PROPERTY: {
       VisitForValue(property->obj());
+      FrameStateBeforeAndAfter states(this, property->obj()->id());
       Node* object = environment()->Top();
-      Unique<Name> name =
-          MakeUnique(property->key()->AsLiteral()->AsPropertyName());
+      Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
       VectorSlotPair pair =
           CreateVectorSlotPair(property->PropertyFeedbackSlot());
-      old_value = NewNode(javascript()->LoadNamed(name, pair), object);
-      PrepareFrameState(old_value, property->LoadId(),
-                        OutputFrameStateCombine::Push());
+      old_value = BuildNamedLoad(object, name, pair);
+      states.AddToNode(old_value, property->LoadId(),
+                       OutputFrameStateCombine::Push());
       stack_depth = 1;
       break;
     }
     case KEYED_PROPERTY: {
       VisitForValue(property->obj());
       VisitForValue(property->key());
+      FrameStateBeforeAndAfter states(this, property->key()->id());
       Node* key = environment()->Top();
       Node* object = environment()->Peek(1);
       VectorSlotPair pair =
           CreateVectorSlotPair(property->PropertyFeedbackSlot());
-      old_value = NewNode(javascript()->LoadProperty(pair), object, key);
-      PrepareFrameState(old_value, property->LoadId(),
-                        OutputFrameStateCombine::Push());
+      old_value = BuildKeyedLoad(object, key, pair);
+      states.AddToNode(old_value, property->LoadId(),
+                       OutputFrameStateCombine::Push());
       stack_depth = 2;
       break;
     }
+    case NAMED_SUPER_PROPERTY: {
+      VisitForValue(property->obj()->AsSuperPropertyReference()->this_var());
+      VisitForValue(property->obj()->AsSuperPropertyReference()->home_object());
+      FrameStateBeforeAndAfter states(this, property->obj()->id());
+      Node* home_object = environment()->Top();
+      Node* receiver = environment()->Peek(1);
+      Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
+      VectorSlotPair pair =
+          CreateVectorSlotPair(property->PropertyFeedbackSlot());
+      old_value = BuildNamedSuperLoad(receiver, home_object, name, pair);
+      states.AddToNode(old_value, property->LoadId(),
+                       OutputFrameStateCombine::Push());
+      stack_depth = 2;
+      break;
+    }
+    case KEYED_SUPER_PROPERTY: {
+      VisitForValue(property->obj()->AsSuperPropertyReference()->this_var());
+      VisitForValue(property->obj()->AsSuperPropertyReference()->home_object());
+      VisitForValue(property->key());
+      FrameStateBeforeAndAfter states(this, property->obj()->id());
+      Node* key = environment()->Top();
+      Node* home_object = environment()->Peek(1);
+      Node* receiver = environment()->Peek(2);
+      VectorSlotPair pair =
+          CreateVectorSlotPair(property->PropertyFeedbackSlot());
+      old_value = BuildKeyedSuperLoad(receiver, home_object, key, pair);
+      states.AddToNode(old_value, property->LoadId(),
+                       OutputFrameStateCombine::Push());
+      stack_depth = 3;
+      break;
+    }
   }
 
   // Convert old value into a number.
-  old_value = NewNode(javascript()->ToNumber(), old_value);
+  if (!is_strong(language_mode())) {
+    old_value = NewNode(javascript()->ToNumber(), old_value);
+    PrepareFrameState(old_value, expr->ToNumberId(),
+                      OutputFrameStateCombine::Push());
+  }
+
+  // Create a proper eager frame state for the stores.
+  environment()->Push(old_value);
+  FrameStateBeforeAndAfter store_states(this, expr->ToNumberId());
+  old_value = environment()->Pop();
 
   // Save result for postfix expressions at correct stack depth.
-  if (is_postfix) environment()->Poke(stack_depth, old_value);
+  if (is_postfix) {
+    if (assign_type != VARIABLE) {
+      environment()->Poke(stack_depth, old_value);
+    } else {
+      environment()->Push(old_value);
+    }
+  }
 
   // Create node to perform +1/-1 operation.
-  Node* value =
-      BuildBinaryOp(old_value, jsgraph()->OneConstant(), expr->binary_op());
-  // TODO(jarin) Insert proper bailout id here (will need to change
-  // full code generator).
-  PrepareFrameState(value, BailoutId::None());
+  Node* value;
+  {
+    // TODO(bmeurer): Cleanup this feedback/bailout mess!
+    FrameStateBeforeAndAfter states(this, BailoutId::None());
+    value = BuildBinaryOp(old_value, jsgraph()->OneConstant(),
+                          expr->binary_op(), TypeFeedbackId::None());
+    // This should never deoptimize outside strong mode because otherwise we
+    // have converted to number before.
+    states.AddToNode(value, is_strong(language_mode()) ? expr->ToNumberId()
+                                                       : BailoutId::None(),
+                     OutputFrameStateCombine::Ignore());
+  }
 
   // Store the value.
+  VectorSlotPair feedback = CreateVectorSlotPair(expr->CountSlot());
   switch (assign_type) {
     case VARIABLE: {
       Variable* variable = expr->expression()->AsVariableProxy()->var();
       environment()->Push(value);
-      BuildVariableAssignment(variable, value, expr->op(),
-                              expr->AssignmentId());
+      BuildVariableAssignment(variable, value, expr->op(), feedback,
+                              expr->AssignmentId(), store_states);
       environment()->Pop();
       break;
     }
     case NAMED_PROPERTY: {
       Node* object = environment()->Pop();
-      Unique<Name> name =
-          MakeUnique(property->key()->AsLiteral()->AsPropertyName());
-      Node* store =
-          NewNode(javascript()->StoreNamed(strict_mode(), name), object, value);
+      Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
+      Node* store = BuildNamedStore(object, name, value, feedback);
       environment()->Push(value);
-      PrepareFrameState(store, expr->AssignmentId());
+      store_states.AddToNode(store, expr->AssignmentId(),
+                             OutputFrameStateCombine::Ignore());
       environment()->Pop();
       break;
     }
     case KEYED_PROPERTY: {
       Node* key = environment()->Pop();
       Node* object = environment()->Pop();
-      Node* store = NewNode(javascript()->StoreProperty(strict_mode()), object,
-                            key, value);
+      Node* store = BuildKeyedStore(object, key, value, feedback);
       environment()->Push(value);
-      PrepareFrameState(store, expr->AssignmentId());
+      store_states.AddToNode(store, expr->AssignmentId(),
+                             OutputFrameStateCombine::Ignore());
+      environment()->Pop();
+      break;
+    }
+    case NAMED_SUPER_PROPERTY: {
+      Node* home_object = environment()->Pop();
+      Node* receiver = environment()->Pop();
+      Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
+      Node* store = BuildNamedSuperStore(receiver, home_object, name, value);
+      environment()->Push(value);
+      store_states.AddToNode(store, expr->AssignmentId(),
+                             OutputFrameStateCombine::Ignore());
+      environment()->Pop();
+      break;
+    }
+    case KEYED_SUPER_PROPERTY: {
+      Node* key = environment()->Pop();
+      Node* home_object = environment()->Pop();
+      Node* receiver = environment()->Pop();
+      Node* store = BuildKeyedSuperStore(receiver, home_object, key, value);
+      environment()->Push(value);
+      store_states.AddToNode(store, expr->AssignmentId(),
+                             OutputFrameStateCombine::Ignore());
       environment()->Pop();
       break;
     }
@@ -1541,10 +2820,12 @@
     default: {
       VisitForValue(expr->left());
       VisitForValue(expr->right());
+      FrameStateBeforeAndAfter states(this, expr->right()->id());
       Node* right = environment()->Pop();
       Node* left = environment()->Pop();
-      Node* value = BuildBinaryOp(left, right, expr->op());
-      PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
+      Node* value = BuildBinaryOp(left, right, expr->op(),
+                                  expr->BinaryOperationFeedbackId());
+      states.AddToNode(value, expr->id(), ast_context()->GetStateCombine());
       ast_context()->ProduceValue(value);
     }
   }
@@ -1567,16 +2848,16 @@
       op = javascript()->StrictNotEqual();
       break;
     case Token::LT:
-      op = javascript()->LessThan();
+      op = javascript()->LessThan(language_mode());
       break;
     case Token::GT:
-      op = javascript()->GreaterThan();
+      op = javascript()->GreaterThan(language_mode());
       break;
     case Token::LTE:
-      op = javascript()->LessThanOrEqual();
+      op = javascript()->LessThanOrEqual(language_mode());
       break;
     case Token::GTE:
-      op = javascript()->GreaterThanOrEqual();
+      op = javascript()->GreaterThanOrEqual(language_mode());
       break;
     case Token::INSTANCEOF:
       op = javascript()->InstanceOf();
@@ -1585,31 +2866,55 @@
       op = javascript()->HasProperty();
       break;
     default:
-      op = NULL;
+      op = nullptr;
       UNREACHABLE();
   }
   VisitForValue(expr->left());
   VisitForValue(expr->right());
+  FrameStateBeforeAndAfter states(this, expr->right()->id());
   Node* right = environment()->Pop();
   Node* left = environment()->Pop();
   Node* value = NewNode(op, left, right);
-  PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
+  states.AddToNode(value, expr->id(), ast_context()->GetStateCombine());
   ast_context()->ProduceValue(value);
 }
 
 
+void AstGraphBuilder::VisitSpread(Spread* expr) {
+  // Handled entirely by the parser itself.
+  UNREACHABLE();
+}
+
+
+void AstGraphBuilder::VisitEmptyParentheses(EmptyParentheses* expr) {
+  // Handled entirely by the parser itself.
+  UNREACHABLE();
+}
+
+
 void AstGraphBuilder::VisitThisFunction(ThisFunction* expr) {
   Node* value = GetFunctionClosure();
   ast_context()->ProduceValue(value);
 }
 
 
-void AstGraphBuilder::VisitSuperReference(SuperReference* expr) {
+void AstGraphBuilder::VisitSuperPropertyReference(
+    SuperPropertyReference* expr) {
+  Node* value = BuildThrowUnsupportedSuperError(expr->id());
+  ast_context()->ProduceValue(value);
+}
+
+
+void AstGraphBuilder::VisitSuperCallReference(SuperCallReference* expr) {
+  // Handled by VisitCall
   UNREACHABLE();
 }
 
 
-void AstGraphBuilder::VisitCaseClause(CaseClause* expr) { UNREACHABLE(); }
+void AstGraphBuilder::VisitCaseClause(CaseClause* expr) {
+  // Handled entirely in VisitSwitch.
+  UNREACHABLE();
+}
 
 
 void AstGraphBuilder::VisitDeclarations(ZoneList<Declaration*>* declarations) {
@@ -1622,24 +2927,36 @@
   for (Handle<Object> obj : *globals()) data->set(array_index++, *obj);
   int encoded_flags = DeclareGlobalsEvalFlag::encode(info()->is_eval()) |
                       DeclareGlobalsNativeFlag::encode(info()->is_native()) |
-                      DeclareGlobalsStrictMode::encode(strict_mode());
+                      DeclareGlobalsLanguageMode::encode(language_mode());
   Node* flags = jsgraph()->Constant(encoded_flags);
   Node* pairs = jsgraph()->Constant(data);
-  const Operator* op = javascript()->CallRuntime(Runtime::kDeclareGlobals, 3);
-  NewNode(op, current_context(), pairs, flags);
+  const Operator* op = javascript()->CallRuntime(Runtime::kDeclareGlobals, 2);
+  Node* call = NewNode(op, pairs, flags);
+  PrepareFrameState(call, BailoutId::Declarations());
   globals()->clear();
 }
 
 
 void AstGraphBuilder::VisitIfNotNull(Statement* stmt) {
-  if (stmt == NULL) return;
+  if (stmt == nullptr) return;
+  Visit(stmt);
+}
+
+
+void AstGraphBuilder::VisitInScope(Statement* stmt, Scope* s, Node* context) {
+  ContextScope scope(this, s, context);
+  DCHECK(s->declarations()->is_empty());
   Visit(stmt);
 }
 
 
 void AstGraphBuilder::VisitIterationBody(IterationStatement* stmt,
-                                         LoopBuilder* loop, int drop_extra) {
-  BreakableScope scope(this, stmt, loop, drop_extra);
+                                         LoopBuilder* loop) {
+  ControlScopeForIteration scope(this, stmt, loop);
+  if (FLAG_turbo_loop_stackcheck || !info()->shared_info()->asm_function()) {
+    Node* node = NewNode(javascript()->StackCheck());
+    PrepareFrameState(node, stmt->StackCheckId());
+  }
   Visit(stmt->body());
 }
 
@@ -1650,7 +2967,9 @@
     // Delete of an unqualified identifier is only allowed in classic mode but
     // deleting "this" is allowed in all language modes.
     Variable* variable = expr->expression()->AsVariableProxy()->var();
-    DCHECK(strict_mode() == SLOPPY || variable->is_this());
+    // Delete of an unqualified identifier is disallowed in strict mode but
+    // "delete this" is allowed.
+    DCHECK(is_sloppy(language_mode()) || variable->HasThisName(isolate()));
     value = BuildVariableDelete(variable, expr->id(),
                                 ast_context()->GetStateCombine());
   } else if (expr->expression()->IsProperty()) {
@@ -1659,7 +2978,7 @@
     VisitForValue(property->key());
     Node* key = environment()->Pop();
     Node* object = environment()->Pop();
-    value = NewNode(javascript()->DeleteProperty(strict_mode()), object, key);
+    value = NewNode(javascript()->DeleteProperty(language_mode()), object, key);
     PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
   } else {
     VisitForEffect(expr->expression());
@@ -1683,8 +3002,10 @@
     // perform a non-contextual load in case the operand is a variable proxy.
     VariableProxy* proxy = expr->expression()->AsVariableProxy();
     VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot());
-    operand = BuildVariableLoad(proxy->var(), expr->expression()->id(), pair,
-                                NOT_CONTEXTUAL);
+    FrameStateBeforeAndAfter states(this, BeforeId(proxy));
+    operand =
+        BuildVariableLoad(proxy->var(), expr->expression()->id(), states, pair,
+                          OutputFrameStateCombine::Push(), INSIDE_TYPEOF);
   } else {
     VisitForValue(expr->expression());
     operand = environment()->Pop();
@@ -1697,8 +3018,9 @@
 void AstGraphBuilder::VisitNot(UnaryOperation* expr) {
   VisitForValue(expr->expression());
   Node* operand = environment()->Pop();
-  // TODO(mstarzinger): Possible optimization when we are in effect context.
-  Node* value = NewNode(javascript()->UnaryNot(), operand);
+  Node* input = BuildToBoolean(operand, expr->expression()->test_id());
+  Node* value = NewNode(common()->Select(MachineRepresentation::kTagged), input,
+                        jsgraph()->FalseConstant(), jsgraph()->TrueConstant());
   ast_context()->ProduceValue(value);
 }
 
@@ -1715,13 +3037,15 @@
   IfBuilder compare_if(this);
   VisitForValue(expr->left());
   Node* condition = environment()->Top();
-  compare_if.If(BuildToBoolean(condition));
+  compare_if.If(BuildToBoolean(condition, expr->left()->test_id()));
   compare_if.Then();
   if (is_logical_and) {
     environment()->Pop();
     Visit(expr->right());
   } else if (ast_context()->IsEffect()) {
     environment()->Pop();
+  } else if (ast_context()->IsTest()) {
+    environment()->Poke(0, jsgraph()->TrueConstant());
   }
   compare_if.Else();
   if (!is_logical_and) {
@@ -1729,23 +3053,76 @@
     Visit(expr->right());
   } else if (ast_context()->IsEffect()) {
     environment()->Pop();
+  } else if (ast_context()->IsTest()) {
+    environment()->Poke(0, jsgraph()->FalseConstant());
   }
   compare_if.End();
   ast_context()->ReplaceValue();
 }
 
 
-StrictMode AstGraphBuilder::strict_mode() const {
-  return info()->strict_mode();
+LanguageMode AstGraphBuilder::language_mode() const {
+  return info()->language_mode();
 }
 
 
 VectorSlotPair AstGraphBuilder::CreateVectorSlotPair(
-    FeedbackVectorICSlot slot) const {
+    FeedbackVectorSlot slot) const {
   return VectorSlotPair(handle(info()->shared_info()->feedback_vector()), slot);
 }
 
 
+void AstGraphBuilder::VisitRewritableAssignmentExpression(
+    RewritableAssignmentExpression* node) {
+  Visit(node->expression());
+}
+
+
+namespace {
+
+// Limit of context chain length to which inline check is possible.
+const int kMaxCheckDepth = 30;
+
+// Sentinel for {TryLoadDynamicVariable} disabling inline checks.
+const uint32_t kFullCheckRequired = -1;
+
+}  // namespace
+
+
+uint32_t AstGraphBuilder::ComputeBitsetForDynamicGlobal(Variable* variable) {
+  DCHECK_EQ(DYNAMIC_GLOBAL, variable->mode());
+  bool found_eval_scope = false;
+  uint32_t check_depths = 0;
+  for (Scope* s = current_scope(); s != nullptr; s = s->outer_scope()) {
+    if (s->num_heap_slots() <= 0) continue;
+    // TODO(mstarzinger): If we have reached an eval scope, we check all
+    // extensions from this point. Replicated from full-codegen, figure out
+    // whether this is still needed. If not, drop {found_eval_scope} below.
+    if (s->is_eval_scope()) found_eval_scope = true;
+    if (!s->calls_sloppy_eval() && !found_eval_scope) continue;
+    int depth = current_scope()->ContextChainLength(s);
+    if (depth > kMaxCheckDepth) return kFullCheckRequired;
+    check_depths |= 1 << depth;
+  }
+  return check_depths;
+}
+
+
+uint32_t AstGraphBuilder::ComputeBitsetForDynamicContext(Variable* variable) {
+  DCHECK_EQ(DYNAMIC_LOCAL, variable->mode());
+  uint32_t check_depths = 0;
+  for (Scope* s = current_scope(); s != nullptr; s = s->outer_scope()) {
+    if (s->num_heap_slots() <= 0) continue;
+    if (!s->calls_sloppy_eval() && s != variable->scope()) continue;
+    int depth = current_scope()->ContextChainLength(s);
+    if (depth > kMaxCheckDepth) return kFullCheckRequired;
+    check_depths |= 1 << depth;
+    if (s == variable->scope()) break;
+  }
+  return check_depths;
+}
+
+
 Node* AstGraphBuilder::ProcessArguments(const Operator* op, int arity) {
   DCHECK(environment()->stack_height() >= arity);
   Node** all = info()->zone()->NewArray<Node*>(arity);
@@ -1757,52 +3134,31 @@
 }
 
 
-Node* AstGraphBuilder::BuildPatchReceiverToGlobalProxy(Node* receiver) {
-  // Sloppy mode functions and builtins need to replace the receiver with the
-  // global proxy when called as functions (without an explicit receiver
-  // object). Otherwise there is nothing left to do here.
-  if (info()->strict_mode() != SLOPPY || info()->is_native()) return receiver;
-
-  // There is no need to perform patching if the receiver is never used. Note
-  // that scope predicates are purely syntactical, a call to eval might still
-  // inspect the receiver value.
-  if (!info()->scope()->uses_this() && !info()->scope()->inner_uses_this() &&
-      !info()->scope()->calls_sloppy_eval()) {
-    return receiver;
-  }
-
-  IfBuilder receiver_check(this);
-  Node* undefined = jsgraph()->UndefinedConstant();
-  Node* check = NewNode(javascript()->StrictEqual(), receiver, undefined);
-  receiver_check.If(check);
-  receiver_check.Then();
-  environment()->Push(BuildLoadGlobalProxy());
-  receiver_check.Else();
-  environment()->Push(receiver);
-  receiver_check.End();
-  return environment()->Pop();
-}
-
-
-Node* AstGraphBuilder::BuildLocalFunctionContext(Node* context, Node* closure) {
-  int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
-  if (heap_slots <= 0) return context;
+Node* AstGraphBuilder::BuildLocalActivationContext(Node* context) {
+  Scope* scope = info()->scope();
 
   // Allocate a new local context.
-  const Operator* op = javascript()->CreateFunctionContext();
-  Node* local_context = NewNode(op, closure);
-  set_current_context(local_context);
+  Node* local_context = scope->is_script_scope()
+                            ? BuildLocalScriptContext(scope)
+                            : BuildLocalFunctionContext(scope);
+
+  if (scope->has_this_declaration() && scope->receiver()->IsContextSlot()) {
+    Node* receiver = environment()->RawParameterLookup(0);
+    // Context variable (at bottom of the context chain).
+    Variable* variable = scope->receiver();
+    DCHECK_EQ(0, scope->ContextChainLength(variable->scope()));
+    const Operator* op = javascript()->StoreContext(0, variable->index());
+    NewNode(op, local_context, receiver);
+  }
 
   // Copy parameters into context if necessary.
-  int num_parameters = info()->scope()->num_parameters();
+  int num_parameters = scope->num_parameters();
   for (int i = 0; i < num_parameters; i++) {
-    Variable* variable = info()->scope()->parameter(i);
+    Variable* variable = scope->parameter(i);
     if (!variable->IsContextSlot()) continue;
-    // Temporary parameter node. The parameter indices are shifted by 1
-    // (receiver is parameter index -1 but environment index 0).
-    Node* parameter = NewNode(common()->Parameter(i + 1), graph()->start());
+    Node* parameter = environment()->RawParameterLookup(i + 1);
     // Context variable (at bottom of the context chain).
-    DCHECK_EQ(0, info()->scope()->ContextChainLength(variable->scope()));
+    DCHECK_EQ(0, scope->ContextChainLength(variable->scope()));
     const Operator* op = javascript()->StoreContext(0, variable->index());
     NewNode(op, local_context, parameter);
   }
@@ -1811,25 +3167,145 @@
 }
 
 
+Node* AstGraphBuilder::BuildLocalFunctionContext(Scope* scope) {
+  DCHECK(scope->is_function_scope());
+
+  // Allocate a new local context.
+  int slot_count = scope->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
+  const Operator* op = javascript()->CreateFunctionContext(slot_count);
+  Node* local_context = NewNode(op, GetFunctionClosure());
+
+  return local_context;
+}
+
+
+Node* AstGraphBuilder::BuildLocalScriptContext(Scope* scope) {
+  DCHECK(scope->is_script_scope());
+
+  // Allocate a new local context.
+  Handle<ScopeInfo> scope_info = scope->GetScopeInfo(isolate());
+  const Operator* op = javascript()->CreateScriptContext(scope_info);
+  Node* local_context = NewNode(op, GetFunctionClosure());
+  PrepareFrameState(local_context, BailoutId::ScriptContext(),
+                    OutputFrameStateCombine::Push());
+
+  return local_context;
+}
+
+
+Node* AstGraphBuilder::BuildLocalBlockContext(Scope* scope) {
+  DCHECK(scope->is_block_scope());
+
+  // Allocate a new local context.
+  Handle<ScopeInfo> scope_info = scope->GetScopeInfo(isolate());
+  const Operator* op = javascript()->CreateBlockContext(scope_info);
+  Node* local_context = NewNode(op, GetFunctionClosureForContext());
+
+  return local_context;
+}
+
+
 Node* AstGraphBuilder::BuildArgumentsObject(Variable* arguments) {
-  if (arguments == NULL) return NULL;
+  if (arguments == nullptr) return nullptr;
 
   // Allocate and initialize a new arguments object.
-  Node* callee = GetFunctionClosure();
-  const Operator* op = javascript()->CallRuntime(Runtime::kNewArguments, 1);
-  Node* object = NewNode(op, callee);
+  CreateArgumentsParameters::Type type =
+      is_strict(language_mode()) || !info()->has_simple_parameters()
+          ? CreateArgumentsParameters::kUnmappedArguments
+          : CreateArgumentsParameters::kMappedArguments;
+  const Operator* op = javascript()->CreateArguments(type, 0);
+  Node* object = NewNode(op, GetFunctionClosure());
+  PrepareFrameState(object, BailoutId::None());
 
-  // Assign the object to the arguments variable.
+  // Assign the object to the {arguments} variable. This should never lazy
+  // deopt, so it is fine to send invalid bailout id.
   DCHECK(arguments->IsContextSlot() || arguments->IsStackAllocated());
-  // This should never lazy deopt, so it is fine to send invalid bailout id.
-  BuildVariableAssignment(arguments, object, Token::ASSIGN, BailoutId::None());
+  FrameStateBeforeAndAfter states(this, BailoutId::None());
+  BuildVariableAssignment(arguments, object, Token::ASSIGN, VectorSlotPair(),
+                          BailoutId::None(), states);
+  return object;
+}
 
+
+Node* AstGraphBuilder::BuildRestArgumentsArray(Variable* rest, int index) {
+  if (rest == nullptr) return nullptr;
+
+  // Allocate and initialize a new arguments object.
+  CreateArgumentsParameters::Type type = CreateArgumentsParameters::kRestArray;
+  const Operator* op = javascript()->CreateArguments(type, index);
+  Node* object = NewNode(op, GetFunctionClosure());
+  PrepareFrameState(object, BailoutId::None());
+
+  // Assign the object to the {rest} variable. This should never lazy
+  // deopt, so it is fine to send invalid bailout id.
+  DCHECK(rest->IsContextSlot() || rest->IsStackAllocated());
+  FrameStateBeforeAndAfter states(this, BailoutId::None());
+  BuildVariableAssignment(rest, object, Token::ASSIGN, VectorSlotPair(),
+                          BailoutId::None(), states);
+  return object;
+}
+
+
+Node* AstGraphBuilder::BuildThisFunctionVariable(Variable* this_function_var) {
+  if (this_function_var == nullptr) return nullptr;
+
+  // Retrieve the closure we were called with.
+  Node* this_function = GetFunctionClosure();
+
+  // Assign the object to the {.this_function} variable. This should never lazy
+  // deopt, so it is fine to send invalid bailout id.
+  FrameStateBeforeAndAfter states(this, BailoutId::None());
+  BuildVariableAssignment(this_function_var, this_function, Token::INIT,
+                          VectorSlotPair(), BailoutId::None(), states);
+  return this_function;
+}
+
+
+Node* AstGraphBuilder::BuildNewTargetVariable(Variable* new_target_var) {
+  if (new_target_var == nullptr) return nullptr;
+
+  // Retrieve the new target we were called with.
+  Node* object = GetNewTarget();
+
+  // Assign the object to the {new.target} variable. This should never lazy
+  // deopt, so it is fine to send invalid bailout id.
+  FrameStateBeforeAndAfter states(this, BailoutId::None());
+  BuildVariableAssignment(new_target_var, object, Token::INIT, VectorSlotPair(),
+                          BailoutId::None(), states);
   return object;
 }
 
 
 Node* AstGraphBuilder::BuildHoleCheckSilent(Node* value, Node* for_hole,
                                             Node* not_hole) {
+  Node* the_hole = jsgraph()->TheHoleConstant();
+  Node* check = NewNode(javascript()->StrictEqual(), value, the_hole);
+  return NewNode(
+      common()->Select(MachineRepresentation::kTagged, BranchHint::kFalse),
+      check, for_hole, not_hole);
+}
+
+
+Node* AstGraphBuilder::BuildHoleCheckThenThrow(Node* value, Variable* variable,
+                                               Node* not_hole,
+                                               BailoutId bailout_id) {
+  IfBuilder hole_check(this);
+  Node* the_hole = jsgraph()->TheHoleConstant();
+  Node* check = NewNode(javascript()->StrictEqual(), value, the_hole);
+  hole_check.If(check);
+  hole_check.Then();
+  Node* error = BuildThrowReferenceError(variable, bailout_id);
+  environment()->Push(error);
+  hole_check.Else();
+  environment()->Push(not_hole);
+  hole_check.End();
+  return environment()->Pop();
+}
+
+
+Node* AstGraphBuilder::BuildHoleCheckElseThrow(Node* value, Variable* variable,
+                                               Node* for_hole,
+                                               BailoutId bailout_id) {
   IfBuilder hole_check(this);
   Node* the_hole = jsgraph()->TheHoleConstant();
   Node* check = NewNode(javascript()->StrictEqual(), value, the_hole);
@@ -1837,47 +3313,50 @@
   hole_check.Then();
   environment()->Push(for_hole);
   hole_check.Else();
-  environment()->Push(not_hole);
+  Node* error = BuildThrowReferenceError(variable, bailout_id);
+  environment()->Push(error);
   hole_check.End();
   return environment()->Pop();
 }
 
 
-Node* AstGraphBuilder::BuildHoleCheckThrow(Node* value, Variable* variable,
-                                           Node* not_hole,
-                                           BailoutId bailout_id) {
-  IfBuilder hole_check(this);
-  Node* the_hole = jsgraph()->TheHoleConstant();
-  Node* check = NewNode(javascript()->StrictEqual(), value, the_hole);
-  hole_check.If(check);
-  hole_check.Then();
-  environment()->Push(BuildThrowReferenceError(variable, bailout_id));
-  hole_check.Else();
-  environment()->Push(not_hole);
-  hole_check.End();
+Node* AstGraphBuilder::BuildThrowIfStaticPrototype(Node* name,
+                                                   BailoutId bailout_id) {
+  IfBuilder prototype_check(this);
+  Node* prototype_string =
+      jsgraph()->Constant(isolate()->factory()->prototype_string());
+  Node* check = NewNode(javascript()->StrictEqual(), name, prototype_string);
+  prototype_check.If(check);
+  prototype_check.Then();
+  Node* error = BuildThrowStaticPrototypeError(bailout_id);
+  environment()->Push(error);
+  prototype_check.Else();
+  environment()->Push(name);
+  prototype_check.End();
   return environment()->Pop();
 }
 
 
 Node* AstGraphBuilder::BuildVariableLoad(Variable* variable,
                                          BailoutId bailout_id,
+                                         FrameStateBeforeAndAfter& states,
                                          const VectorSlotPair& feedback,
-                                         ContextualMode contextual_mode) {
+                                         OutputFrameStateCombine combine,
+                                         TypeofMode typeof_mode) {
   Node* the_hole = jsgraph()->TheHoleConstant();
   VariableMode mode = variable->mode();
   switch (variable->location()) {
-    case Variable::UNALLOCATED: {
+    case VariableLocation::GLOBAL:
+    case VariableLocation::UNALLOCATED: {
       // Global var, const, or let variable.
-      Node* global = BuildLoadGlobalObject();
-      Unique<Name> name = MakeUnique(variable->name());
-      const Operator* op =
-          javascript()->LoadNamed(name, feedback, contextual_mode);
-      Node* node = NewNode(op, global);
-      PrepareFrameState(node, bailout_id, OutputFrameStateCombine::Push());
-      return node;
+      Handle<Name> name = variable->name();
+      if (Node* node = TryLoadGlobalConstant(name)) return node;
+      Node* value = BuildGlobalLoad(name, feedback, typeof_mode);
+      states.AddToNode(value, bailout_id, combine);
+      return value;
     }
-    case Variable::PARAMETER:
-    case Variable::LOCAL: {
+    case VariableLocation::PARAMETER:
+    case VariableLocation::LOCAL: {
       // Local var, const, or let variable.
       Node* value = environment()->Lookup(variable);
       if (mode == CONST_LEGACY) {
@@ -1893,12 +3372,12 @@
         if (value->op() == the_hole->op()) {
           value = BuildThrowReferenceError(variable, bailout_id);
         } else if (value->opcode() == IrOpcode::kPhi) {
-          value = BuildHoleCheckThrow(value, variable, value, bailout_id);
+          value = BuildHoleCheckThenThrow(value, variable, value, bailout_id);
         }
       }
       return value;
     }
-    case Variable::CONTEXT: {
+    case VariableLocation::CONTEXT: {
       // Context variable (potentially up the context chain).
       int depth = current_scope()->ContextChainLength(variable->scope());
       bool immutable = variable->maybe_assigned() == kNotAssigned;
@@ -1914,318 +3393,974 @@
         value = BuildHoleCheckSilent(value, undefined, value);
       } else if (mode == LET || mode == CONST) {
         // Perform check for uninitialized let/const variables.
-        value = BuildHoleCheckThrow(value, variable, value, bailout_id);
+        value = BuildHoleCheckThenThrow(value, variable, value, bailout_id);
       }
       return value;
     }
-    case Variable::LOOKUP: {
+    case VariableLocation::LOOKUP: {
       // Dynamic lookup of context variable (anywhere in the chain).
-      Node* name = jsgraph()->Constant(variable->name());
-      Runtime::FunctionId function_id =
-          (contextual_mode == CONTEXTUAL)
-              ? Runtime::kLoadLookupSlot
-              : Runtime::kLoadLookupSlotNoReferenceError;
-      const Operator* op = javascript()->CallRuntime(function_id, 2);
-      Node* pair = NewNode(op, current_context(), name);
-      PrepareFrameState(pair, bailout_id, OutputFrameStateCombine::Push(1));
-      return NewNode(common()->Projection(0), pair);
+      Handle<String> name = variable->name();
+      if (Node* node =
+              TryLoadDynamicVariable(variable, name, bailout_id, states,
+                                     feedback, combine, typeof_mode)) {
+        return node;
+      }
+      const Operator* op = javascript()->LoadDynamic(name, typeof_mode);
+      Node* value = NewNode(op, BuildLoadFeedbackVector(), current_context());
+      states.AddToNode(value, bailout_id, combine);
+      return value;
     }
   }
   UNREACHABLE();
-  return NULL;
+  return nullptr;
 }
 
 
-Node* AstGraphBuilder::BuildVariableDelete(
-    Variable* variable, BailoutId bailout_id,
-    OutputFrameStateCombine state_combine) {
+Node* AstGraphBuilder::BuildVariableDelete(Variable* variable,
+                                           BailoutId bailout_id,
+                                           OutputFrameStateCombine combine) {
   switch (variable->location()) {
-    case Variable::UNALLOCATED: {
+    case VariableLocation::GLOBAL:
+    case VariableLocation::UNALLOCATED: {
       // Global var, const, or let variable.
       Node* global = BuildLoadGlobalObject();
       Node* name = jsgraph()->Constant(variable->name());
-      const Operator* op = javascript()->DeleteProperty(strict_mode());
+      const Operator* op = javascript()->DeleteProperty(language_mode());
       Node* result = NewNode(op, global, name);
-      PrepareFrameState(result, bailout_id, state_combine);
+      PrepareFrameState(result, bailout_id, combine);
       return result;
     }
-    case Variable::PARAMETER:
-    case Variable::LOCAL:
-    case Variable::CONTEXT:
+    case VariableLocation::PARAMETER:
+    case VariableLocation::LOCAL:
+    case VariableLocation::CONTEXT: {
       // Local var, const, or let variable or context variable.
-      return jsgraph()->BooleanConstant(variable->is_this());
-    case Variable::LOOKUP: {
+      return jsgraph()->BooleanConstant(variable->HasThisName(isolate()));
+    }
+    case VariableLocation::LOOKUP: {
       // Dynamic lookup of context variable (anywhere in the chain).
       Node* name = jsgraph()->Constant(variable->name());
       const Operator* op =
           javascript()->CallRuntime(Runtime::kDeleteLookupSlot, 2);
       Node* result = NewNode(op, current_context(), name);
-      PrepareFrameState(result, bailout_id, state_combine);
+      PrepareFrameState(result, bailout_id, combine);
       return result;
     }
   }
   UNREACHABLE();
-  return NULL;
+  return nullptr;
 }
 
 
 Node* AstGraphBuilder::BuildVariableAssignment(
-    Variable* variable, Node* value, Token::Value op, BailoutId bailout_id,
-    OutputFrameStateCombine combine) {
+    Variable* variable, Node* value, Token::Value op,
+    const VectorSlotPair& feedback, BailoutId bailout_id,
+    FrameStateBeforeAndAfter& states, OutputFrameStateCombine combine) {
   Node* the_hole = jsgraph()->TheHoleConstant();
   VariableMode mode = variable->mode();
   switch (variable->location()) {
-    case Variable::UNALLOCATED: {
+    case VariableLocation::GLOBAL:
+    case VariableLocation::UNALLOCATED: {
       // Global var, const, or let variable.
-      Node* global = BuildLoadGlobalObject();
-      Unique<Name> name = MakeUnique(variable->name());
-      const Operator* op = javascript()->StoreNamed(strict_mode(), name);
-      Node* store = NewNode(op, global, value);
-      PrepareFrameState(store, bailout_id, combine);
+      Handle<Name> name = variable->name();
+      Node* store = BuildGlobalStore(name, value, feedback);
+      states.AddToNode(store, bailout_id, combine);
       return store;
     }
-    case Variable::PARAMETER:
-    case Variable::LOCAL:
+    case VariableLocation::PARAMETER:
+    case VariableLocation::LOCAL:
       // Local var, const, or let variable.
-      if (mode == CONST_LEGACY && op == Token::INIT_CONST_LEGACY) {
+      if (mode == CONST_LEGACY && op == Token::INIT) {
         // Perform an initialization check for legacy const variables.
         Node* current = environment()->Lookup(variable);
         if (current->op() != the_hole->op()) {
           value = BuildHoleCheckSilent(current, value, current);
         }
-      } else if (mode == CONST_LEGACY && op != Token::INIT_CONST_LEGACY) {
-        // Non-initializing assignments to legacy const is
+      } else if (mode == CONST_LEGACY && op != Token::INIT) {
+        // Non-initializing assignment to legacy const is
         // - exception in strict mode.
         // - ignored in sloppy mode.
-        if (strict_mode() == STRICT) {
+        if (is_strict(language_mode())) {
           return BuildThrowConstAssignError(bailout_id);
         }
         return value;
-      } else if (mode == LET && op != Token::INIT_LET) {
+      } else if (mode == LET && op == Token::INIT) {
+        // No initialization check needed because scoping guarantees it. Note
+        // that we still perform a lookup to keep the variable live, because
+        // baseline code might contain debug code that inspects the variable.
+        Node* current = environment()->Lookup(variable);
+        CHECK_NOT_NULL(current);
+      } else if (mode == LET && op != Token::INIT) {
         // Perform an initialization check for let declared variables.
-        // Also note that the dynamic hole-check is only done to ensure that
-        // this does not break in the presence of do-expressions within the
-        // temporal dead zone of a let declared variable.
         Node* current = environment()->Lookup(variable);
         if (current->op() == the_hole->op()) {
-          value = BuildThrowReferenceError(variable, bailout_id);
-        } else if (value->opcode() == IrOpcode::kPhi) {
-          value = BuildHoleCheckThrow(current, variable, value, bailout_id);
+          return BuildThrowReferenceError(variable, bailout_id);
+        } else if (current->opcode() == IrOpcode::kPhi) {
+          BuildHoleCheckThenThrow(current, variable, value, bailout_id);
         }
-      } else if (mode == CONST && op != Token::INIT_CONST) {
-        // Non-initializing assignments to const is exception in all modes.
+      } else if (mode == CONST && op == Token::INIT) {
+        // Perform an initialization check for const {this} variables.
+        // Note that the {this} variable is the only const variable being able
+        // to trigger bind operations outside the TDZ, via {super} calls.
+        Node* current = environment()->Lookup(variable);
+        if (current->op() != the_hole->op() && variable->is_this()) {
+          value = BuildHoleCheckElseThrow(current, variable, value, bailout_id);
+        }
+      } else if (mode == CONST && op != Token::INIT) {
+        // Assignment to const is exception in all modes.
+        Node* current = environment()->Lookup(variable);
+        if (current->op() == the_hole->op()) {
+          return BuildThrowReferenceError(variable, bailout_id);
+        } else if (current->opcode() == IrOpcode::kPhi) {
+          BuildHoleCheckThenThrow(current, variable, value, bailout_id);
+        }
         return BuildThrowConstAssignError(bailout_id);
       }
       environment()->Bind(variable, value);
       return value;
-    case Variable::CONTEXT: {
+    case VariableLocation::CONTEXT: {
       // Context variable (potentially up the context chain).
       int depth = current_scope()->ContextChainLength(variable->scope());
-      if (mode == CONST_LEGACY && op == Token::INIT_CONST_LEGACY) {
+      if (mode == CONST_LEGACY && op == Token::INIT) {
         // Perform an initialization check for legacy const variables.
         const Operator* op =
             javascript()->LoadContext(depth, variable->index(), false);
         Node* current = NewNode(op, current_context());
         value = BuildHoleCheckSilent(current, value, current);
-      } else if (mode == CONST_LEGACY && op != Token::INIT_CONST_LEGACY) {
-        // Non-initializing assignments to legacy const is
+      } else if (mode == CONST_LEGACY && op != Token::INIT) {
+        // Non-initializing assignment to legacy const is
         // - exception in strict mode.
         // - ignored in sloppy mode.
-        if (strict_mode() == STRICT) {
+        if (is_strict(language_mode())) {
           return BuildThrowConstAssignError(bailout_id);
         }
         return value;
-      } else if (mode == LET && op != Token::INIT_LET) {
+      } else if (mode == LET && op != Token::INIT) {
         // Perform an initialization check for let declared variables.
         const Operator* op =
             javascript()->LoadContext(depth, variable->index(), false);
         Node* current = NewNode(op, current_context());
-        value = BuildHoleCheckThrow(current, variable, value, bailout_id);
-      } else if (mode == CONST && op != Token::INIT_CONST) {
-        // Non-initializing assignments to const is exception in all modes.
+        value = BuildHoleCheckThenThrow(current, variable, value, bailout_id);
+      } else if (mode == CONST && op == Token::INIT) {
+        // Perform an initialization check for const {this} variables.
+        // Note that the {this} variable is the only const variable being able
+        // to trigger bind operations outside the TDZ, via {super} calls.
+        if (variable->is_this()) {
+          const Operator* op =
+              javascript()->LoadContext(depth, variable->index(), false);
+          Node* current = NewNode(op, current_context());
+          value = BuildHoleCheckElseThrow(current, variable, value, bailout_id);
+        }
+      } else if (mode == CONST && op != Token::INIT) {
+        // Assignment to const is exception in all modes.
+        const Operator* op =
+            javascript()->LoadContext(depth, variable->index(), false);
+        Node* current = NewNode(op, current_context());
+        BuildHoleCheckThenThrow(current, variable, value, bailout_id);
         return BuildThrowConstAssignError(bailout_id);
       }
       const Operator* op = javascript()->StoreContext(depth, variable->index());
       return NewNode(op, current_context(), value);
     }
-    case Variable::LOOKUP: {
+    case VariableLocation::LOOKUP: {
       // Dynamic lookup of context variable (anywhere in the chain).
       Node* name = jsgraph()->Constant(variable->name());
-      Node* strict = jsgraph()->Constant(strict_mode());
+      Node* language = jsgraph()->Constant(language_mode());
       // TODO(mstarzinger): Use Runtime::kInitializeLegacyConstLookupSlot for
       // initializations of const declarations.
       const Operator* op =
           javascript()->CallRuntime(Runtime::kStoreLookupSlot, 4);
-      Node* store = NewNode(op, value, current_context(), name, strict);
+      Node* store = NewNode(op, value, current_context(), name, language);
       PrepareFrameState(store, bailout_id, combine);
       return store;
     }
   }
   UNREACHABLE();
-  return NULL;
+  return nullptr;
+}
+
+
+Node* AstGraphBuilder::BuildKeyedLoad(Node* object, Node* key,
+                                      const VectorSlotPair& feedback) {
+  const Operator* op = javascript()->LoadProperty(language_mode(), feedback);
+  Node* node = NewNode(op, object, key, BuildLoadFeedbackVector());
+  return node;
+}
+
+
+Node* AstGraphBuilder::BuildNamedLoad(Node* object, Handle<Name> name,
+                                      const VectorSlotPair& feedback) {
+  const Operator* op = javascript()->LoadNamed(language_mode(), name, feedback);
+  Node* node = NewNode(op, object, BuildLoadFeedbackVector());
+  return node;
+}
+
+
+Node* AstGraphBuilder::BuildKeyedStore(Node* object, Node* key, Node* value,
+                                       const VectorSlotPair& feedback) {
+  const Operator* op = javascript()->StoreProperty(language_mode(), feedback);
+  Node* node = NewNode(op, object, key, value, BuildLoadFeedbackVector());
+  return node;
+}
+
+
+Node* AstGraphBuilder::BuildNamedStore(Node* object, Handle<Name> name,
+                                       Node* value,
+                                       const VectorSlotPair& feedback) {
+  const Operator* op =
+      javascript()->StoreNamed(language_mode(), name, feedback);
+  Node* node = NewNode(op, object, value, BuildLoadFeedbackVector());
+  return node;
+}
+
+
+Node* AstGraphBuilder::BuildNamedSuperLoad(Node* receiver, Node* home_object,
+                                           Handle<Name> name,
+                                           const VectorSlotPair& feedback) {
+  Node* name_node = jsgraph()->Constant(name);
+  Node* language = jsgraph()->Constant(language_mode());
+  const Operator* op = javascript()->CallRuntime(Runtime::kLoadFromSuper, 4);
+  Node* node = NewNode(op, receiver, home_object, name_node, language);
+  return node;
+}
+
+
+Node* AstGraphBuilder::BuildKeyedSuperLoad(Node* receiver, Node* home_object,
+                                           Node* key,
+                                           const VectorSlotPair& feedback) {
+  Node* language = jsgraph()->Constant(language_mode());
+  const Operator* op =
+      javascript()->CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
+  Node* node = NewNode(op, receiver, home_object, key, language);
+  return node;
+}
+
+
+Node* AstGraphBuilder::BuildKeyedSuperStore(Node* receiver, Node* home_object,
+                                            Node* key, Node* value) {
+  Runtime::FunctionId function_id = is_strict(language_mode())
+                                        ? Runtime::kStoreKeyedToSuper_Strict
+                                        : Runtime::kStoreKeyedToSuper_Sloppy;
+  const Operator* op = javascript()->CallRuntime(function_id, 4);
+  Node* node = NewNode(op, receiver, home_object, key, value);
+  return node;
+}
+
+
+Node* AstGraphBuilder::BuildNamedSuperStore(Node* receiver, Node* home_object,
+                                            Handle<Name> name, Node* value) {
+  Node* name_node = jsgraph()->Constant(name);
+  Runtime::FunctionId function_id = is_strict(language_mode())
+                                        ? Runtime::kStoreToSuper_Strict
+                                        : Runtime::kStoreToSuper_Sloppy;
+  const Operator* op = javascript()->CallRuntime(function_id, 4);
+  Node* node = NewNode(op, receiver, home_object, name_node, value);
+  return node;
+}
+
+
+Node* AstGraphBuilder::BuildGlobalLoad(Handle<Name> name,
+                                       const VectorSlotPair& feedback,
+                                       TypeofMode typeof_mode) {
+  const Operator* op = javascript()->LoadGlobal(name, feedback, typeof_mode);
+  Node* node = NewNode(op, BuildLoadFeedbackVector());
+  return node;
+}
+
+
+Node* AstGraphBuilder::BuildGlobalStore(Handle<Name> name, Node* value,
+                                        const VectorSlotPair& feedback) {
+  const Operator* op =
+      javascript()->StoreGlobal(language_mode(), name, feedback);
+  Node* node = NewNode(op, value, BuildLoadFeedbackVector());
+  return node;
 }
 
 
 Node* AstGraphBuilder::BuildLoadObjectField(Node* object, int offset) {
-  Node* field_load = NewNode(jsgraph()->machine()->Load(kMachAnyTagged), object,
-                             jsgraph()->Int32Constant(offset - kHeapObjectTag));
-  return field_load;
+  return NewNode(jsgraph()->machine()->Load(MachineType::AnyTagged()), object,
+                 jsgraph()->IntPtrConstant(offset - kHeapObjectTag));
 }
 
 
-Node* AstGraphBuilder::BuildLoadBuiltinsObject() {
-  Node* global = BuildLoadGlobalObject();
-  Node* builtins =
-      BuildLoadObjectField(global, JSGlobalObject::kBuiltinsOffset);
-  return builtins;
+Node* AstGraphBuilder::BuildLoadImmutableObjectField(Node* object, int offset) {
+  return graph()->NewNode(jsgraph()->machine()->Load(MachineType::AnyTagged()),
+                          object,
+                          jsgraph()->IntPtrConstant(offset - kHeapObjectTag),
+                          graph()->start(), graph()->start());
 }
 
 
 Node* AstGraphBuilder::BuildLoadGlobalObject() {
-  Node* context = GetFunctionContext();
-  const Operator* load_op =
-      javascript()->LoadContext(0, Context::GLOBAL_OBJECT_INDEX, true);
-  return NewNode(load_op, context);
+  return BuildLoadNativeContextField(Context::EXTENSION_INDEX);
 }
 
 
-Node* AstGraphBuilder::BuildLoadGlobalProxy() {
-  Node* global = BuildLoadGlobalObject();
-  Node* proxy =
-      BuildLoadObjectField(global, JSGlobalObject::kGlobalProxyOffset);
-  return proxy;
+Node* AstGraphBuilder::BuildLoadNativeContextField(int index) {
+  const Operator* op =
+      javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true);
+  Node* native_context = NewNode(op, current_context());
+  return NewNode(javascript()->LoadContext(0, index, true), native_context);
 }
 
 
-Node* AstGraphBuilder::BuildToBoolean(Node* input) {
-  // TODO(titzer): this should be in a JSOperatorReducer.
-  switch (input->opcode()) {
-    case IrOpcode::kInt32Constant:
-      return jsgraph_->BooleanConstant(!Int32Matcher(input).Is(0));
-    case IrOpcode::kFloat64Constant:
-      return jsgraph_->BooleanConstant(!Float64Matcher(input).Is(0));
-    case IrOpcode::kNumberConstant:
-      return jsgraph_->BooleanConstant(!NumberMatcher(input).Is(0));
-    case IrOpcode::kHeapConstant: {
-      Handle<Object> object = HeapObjectMatcher<Object>(input).Value().handle();
-      if (object->IsTrue()) return jsgraph_->TrueConstant();
-      if (object->IsFalse()) return jsgraph_->FalseConstant();
-      // TODO(turbofan): other constants.
-      break;
-    }
-    default:
-      break;
+Node* AstGraphBuilder::BuildLoadFeedbackVector() {
+  if (!feedback_vector_.is_set()) {
+    Node* closure = GetFunctionClosure();
+    Node* shared = BuildLoadImmutableObjectField(
+        closure, JSFunction::kSharedFunctionInfoOffset);
+    Node* vector = BuildLoadImmutableObjectField(
+        shared, SharedFunctionInfo::kFeedbackVectorOffset);
+    feedback_vector_.set(vector);
   }
-  if (NodeProperties::IsTyped(input)) {
-    Type* upper = NodeProperties::GetBounds(input).upper;
-    if (upper->Is(Type::Boolean())) return input;
-  }
+  return feedback_vector_.get();
+}
 
-  return NewNode(javascript()->ToBoolean(), input);
+
+Node* AstGraphBuilder::BuildToBoolean(Node* input, TypeFeedbackId feedback_id) {
+  if (Node* node = TryFastToBoolean(input)) return node;
+  ToBooleanHints hints;
+  if (!type_hint_analysis_ ||
+      !type_hint_analysis_->GetToBooleanHints(feedback_id, &hints)) {
+    hints = ToBooleanHint::kAny;
+  }
+  return NewNode(javascript()->ToBoolean(hints), input);
+}
+
+
+Node* AstGraphBuilder::BuildToName(Node* input, BailoutId bailout_id) {
+  if (Node* node = TryFastToName(input)) return node;
+  Node* name = NewNode(javascript()->ToName(), input);
+  PrepareFrameState(name, bailout_id);
+  return name;
+}
+
+
+Node* AstGraphBuilder::BuildToObject(Node* input, BailoutId bailout_id) {
+  Node* object = NewNode(javascript()->ToObject(), input);
+  PrepareFrameState(object, bailout_id, OutputFrameStateCombine::Push());
+  return object;
+}
+
+
+Node* AstGraphBuilder::BuildSetHomeObject(Node* value, Node* home_object,
+                                          ObjectLiteralProperty* property,
+                                          int slot_number) {
+  Expression* expr = property->value();
+  if (!FunctionLiteral::NeedsHomeObject(expr)) return value;
+  Handle<Name> name = isolate()->factory()->home_object_symbol();
+  FrameStateBeforeAndAfter states(this, BailoutId::None());
+  VectorSlotPair feedback =
+      CreateVectorSlotPair(property->GetSlot(slot_number));
+  Node* store = BuildNamedStore(value, name, home_object, feedback);
+  states.AddToNode(store, BailoutId::None(), OutputFrameStateCombine::Ignore());
+  return store;
+}
+
+
+Node* AstGraphBuilder::BuildThrowError(Node* exception, BailoutId bailout_id) {
+  const Operator* op = javascript()->CallRuntime(Runtime::kThrow, 1);
+  Node* call = NewNode(op, exception);
+  PrepareFrameState(call, bailout_id);
+  Node* control = NewNode(common()->Throw(), call);
+  UpdateControlDependencyToLeaveFunction(control);
+  return call;
 }
 
 
 Node* AstGraphBuilder::BuildThrowReferenceError(Variable* variable,
                                                 BailoutId bailout_id) {
-  // TODO(mstarzinger): Should be unified with the VisitThrow implementation.
   Node* variable_name = jsgraph()->Constant(variable->name());
   const Operator* op =
       javascript()->CallRuntime(Runtime::kThrowReferenceError, 1);
   Node* call = NewNode(op, variable_name);
   PrepareFrameState(call, bailout_id);
+  Node* control = NewNode(common()->Throw(), call);
+  UpdateControlDependencyToLeaveFunction(control);
   return call;
 }
 
 
 Node* AstGraphBuilder::BuildThrowConstAssignError(BailoutId bailout_id) {
-  // TODO(mstarzinger): Should be unified with the VisitThrow implementation.
   const Operator* op =
       javascript()->CallRuntime(Runtime::kThrowConstAssignError, 0);
   Node* call = NewNode(op);
   PrepareFrameState(call, bailout_id);
+  Node* control = NewNode(common()->Throw(), call);
+  UpdateControlDependencyToLeaveFunction(control);
   return call;
 }
 
 
-Node* AstGraphBuilder::BuildBinaryOp(Node* left, Node* right, Token::Value op) {
+Node* AstGraphBuilder::BuildThrowStaticPrototypeError(BailoutId bailout_id) {
+  const Operator* op =
+      javascript()->CallRuntime(Runtime::kThrowStaticPrototypeError, 0);
+  Node* call = NewNode(op);
+  PrepareFrameState(call, bailout_id);
+  Node* control = NewNode(common()->Throw(), call);
+  UpdateControlDependencyToLeaveFunction(control);
+  return call;
+}
+
+
+Node* AstGraphBuilder::BuildThrowUnsupportedSuperError(BailoutId bailout_id) {
+  const Operator* op =
+      javascript()->CallRuntime(Runtime::kThrowUnsupportedSuperError, 0);
+  Node* call = NewNode(op);
+  PrepareFrameState(call, bailout_id);
+  Node* control = NewNode(common()->Throw(), call);
+  UpdateControlDependencyToLeaveFunction(control);
+  return call;
+}
+
+
+Node* AstGraphBuilder::BuildReturn(Node* return_value) {
+  Node* control = NewNode(common()->Return(), return_value);
+  UpdateControlDependencyToLeaveFunction(control);
+  return control;
+}
+
+
+Node* AstGraphBuilder::BuildThrow(Node* exception_value) {
+  NewNode(javascript()->CallRuntime(Runtime::kReThrow, 1), exception_value);
+  Node* control = NewNode(common()->Throw(), exception_value);
+  UpdateControlDependencyToLeaveFunction(control);
+  return control;
+}
+
+
+Node* AstGraphBuilder::BuildBinaryOp(Node* left, Node* right, Token::Value op,
+                                     TypeFeedbackId feedback_id) {
   const Operator* js_op;
+  BinaryOperationHints hints;
+  if (!type_hint_analysis_ ||
+      !type_hint_analysis_->GetBinaryOperationHints(feedback_id, &hints)) {
+    hints = BinaryOperationHints::Any();
+  }
   switch (op) {
     case Token::BIT_OR:
-      js_op = javascript()->BitwiseOr();
+      js_op = javascript()->BitwiseOr(language_mode(), hints);
       break;
     case Token::BIT_AND:
-      js_op = javascript()->BitwiseAnd();
+      js_op = javascript()->BitwiseAnd(language_mode(), hints);
       break;
     case Token::BIT_XOR:
-      js_op = javascript()->BitwiseXor();
+      js_op = javascript()->BitwiseXor(language_mode(), hints);
       break;
     case Token::SHL:
-      js_op = javascript()->ShiftLeft();
+      js_op = javascript()->ShiftLeft(language_mode(), hints);
       break;
     case Token::SAR:
-      js_op = javascript()->ShiftRight();
+      js_op = javascript()->ShiftRight(language_mode(), hints);
       break;
     case Token::SHR:
-      js_op = javascript()->ShiftRightLogical();
+      js_op = javascript()->ShiftRightLogical(language_mode(), hints);
       break;
     case Token::ADD:
-      js_op = javascript()->Add();
+      js_op = javascript()->Add(language_mode(), hints);
       break;
     case Token::SUB:
-      js_op = javascript()->Subtract();
+      js_op = javascript()->Subtract(language_mode(), hints);
       break;
     case Token::MUL:
-      js_op = javascript()->Multiply();
+      js_op = javascript()->Multiply(language_mode(), hints);
       break;
     case Token::DIV:
-      js_op = javascript()->Divide();
+      js_op = javascript()->Divide(language_mode(), hints);
       break;
     case Token::MOD:
-      js_op = javascript()->Modulus();
+      js_op = javascript()->Modulus(language_mode(), hints);
       break;
     default:
       UNREACHABLE();
-      js_op = NULL;
+      js_op = nullptr;
   }
   return NewNode(js_op, left, right);
 }
 
 
-Node* AstGraphBuilder::BuildStackCheck() {
-  IfBuilder stack_check(this);
-  Node* limit =
-      NewNode(jsgraph()->machine()->Load(kMachPtr),
-              jsgraph()->ExternalConstant(
-                  ExternalReference::address_of_stack_limit(isolate())),
-              jsgraph()->ZeroConstant());
-  Node* stack = NewNode(jsgraph()->machine()->LoadStackPointer());
-  Node* tag = NewNode(jsgraph()->machine()->UintLessThan(), limit, stack);
-  stack_check.If(tag, BranchHint::kTrue);
-  stack_check.Then();
-  stack_check.Else();
-  Node* guard = NewNode(javascript()->CallRuntime(Runtime::kStackGuard, 0));
-  stack_check.End();
-  return guard;
+Node* AstGraphBuilder::TryLoadGlobalConstant(Handle<Name> name) {
+  // Optimize global constants like "undefined", "Infinity", and "NaN".
+  Handle<Object> constant_value = isolate()->factory()->GlobalConstantFor(name);
+  if (!constant_value.is_null()) return jsgraph()->Constant(constant_value);
+  return nullptr;
+}
+
+
+Node* AstGraphBuilder::TryLoadDynamicVariable(
+    Variable* variable, Handle<String> name, BailoutId bailout_id,
+    FrameStateBeforeAndAfter& states, const VectorSlotPair& feedback,
+    OutputFrameStateCombine combine, TypeofMode typeof_mode) {
+  VariableMode mode = variable->mode();
+
+  if (mode == DYNAMIC_GLOBAL) {
+    uint32_t bitset = ComputeBitsetForDynamicGlobal(variable);
+    if (bitset == kFullCheckRequired) return nullptr;
+
+    // We are using two blocks to model fast and slow cases.
+    BlockBuilder fast_block(this);
+    BlockBuilder slow_block(this);
+    environment()->Push(jsgraph()->TheHoleConstant());
+    slow_block.BeginBlock();
+    environment()->Pop();
+    fast_block.BeginBlock();
+
+    // Perform checks whether the fast mode applies, by looking for any
+    // extension object which might shadow the optimistic declaration.
+    for (int depth = 0; bitset != 0; bitset >>= 1, depth++) {
+      if ((bitset & 1) == 0) continue;
+      Node* load = NewNode(
+          javascript()->LoadContext(depth, Context::EXTENSION_INDEX, false),
+          current_context());
+      Node* check = NewNode(javascript()->StrictEqual(), load,
+                            jsgraph()->TheHoleConstant());
+      fast_block.BreakUnless(check, BranchHint::kTrue);
+    }
+
+    // Fast case, because variable is not shadowed. Perform global slot load.
+    Node* fast = BuildGlobalLoad(name, feedback, typeof_mode);
+    states.AddToNode(fast, bailout_id, combine);
+    environment()->Push(fast);
+    slow_block.Break();
+    environment()->Pop();
+    fast_block.EndBlock();
+
+    // Slow case, because variable potentially shadowed. Perform dynamic lookup.
+    const Operator* op = javascript()->LoadDynamic(name, typeof_mode);
+    Node* slow = NewNode(op, BuildLoadFeedbackVector(), current_context());
+    states.AddToNode(slow, bailout_id, combine);
+    environment()->Push(slow);
+    slow_block.EndBlock();
+
+    return environment()->Pop();
+  }
+
+  if (mode == DYNAMIC_LOCAL) {
+    uint32_t bitset = ComputeBitsetForDynamicContext(variable);
+    if (bitset == kFullCheckRequired) return nullptr;
+
+    // We are using two blocks to model fast and slow cases.
+    BlockBuilder fast_block(this);
+    BlockBuilder slow_block(this);
+    environment()->Push(jsgraph()->TheHoleConstant());
+    slow_block.BeginBlock();
+    environment()->Pop();
+    fast_block.BeginBlock();
+
+    // Perform checks whether the fast mode applies, by looking for any
+    // extension object which might shadow the optimistic declaration.
+    for (int depth = 0; bitset != 0; bitset >>= 1, depth++) {
+      if ((bitset & 1) == 0) continue;
+      Node* load = NewNode(
+          javascript()->LoadContext(depth, Context::EXTENSION_INDEX, false),
+          current_context());
+      Node* check = NewNode(javascript()->StrictEqual(), load,
+                            jsgraph()->TheHoleConstant());
+      fast_block.BreakUnless(check, BranchHint::kTrue);
+    }
+
+    // Fast case, because variable is not shadowed. Perform context slot load.
+    Variable* local = variable->local_if_not_shadowed();
+    DCHECK(local->location() == VariableLocation::CONTEXT);  // Must be context.
+    Node* fast = BuildVariableLoad(local, bailout_id, states, feedback, combine,
+                                   typeof_mode);
+    environment()->Push(fast);
+    slow_block.Break();
+    environment()->Pop();
+    fast_block.EndBlock();
+
+    // Slow case, because variable potentially shadowed. Perform dynamic lookup.
+    const Operator* op = javascript()->LoadDynamic(name, typeof_mode);
+    Node* slow = NewNode(op, BuildLoadFeedbackVector(), current_context());
+    states.AddToNode(slow, bailout_id, combine);
+    environment()->Push(slow);
+    slow_block.EndBlock();
+
+    return environment()->Pop();
+  }
+
+  return nullptr;
+}
+
+
+Node* AstGraphBuilder::TryFastToBoolean(Node* input) {
+  switch (input->opcode()) {
+    case IrOpcode::kNumberConstant: {
+      NumberMatcher m(input);
+      return jsgraph_->BooleanConstant(!m.Is(0) && !m.IsNaN());
+    }
+    case IrOpcode::kHeapConstant: {
+      Handle<HeapObject> object = HeapObjectMatcher(input).Value();
+      return jsgraph_->BooleanConstant(object->BooleanValue());
+    }
+    case IrOpcode::kJSEqual:
+    case IrOpcode::kJSNotEqual:
+    case IrOpcode::kJSStrictEqual:
+    case IrOpcode::kJSStrictNotEqual:
+    case IrOpcode::kJSLessThan:
+    case IrOpcode::kJSLessThanOrEqual:
+    case IrOpcode::kJSGreaterThan:
+    case IrOpcode::kJSGreaterThanOrEqual:
+    case IrOpcode::kJSToBoolean:
+    case IrOpcode::kJSDeleteProperty:
+    case IrOpcode::kJSHasProperty:
+    case IrOpcode::kJSInstanceOf:
+      return input;
+    default:
+      break;
+  }
+  return nullptr;
+}
+
+
+Node* AstGraphBuilder::TryFastToName(Node* input) {
+  switch (input->opcode()) {
+    case IrOpcode::kHeapConstant: {
+      Handle<HeapObject> object = HeapObjectMatcher(input).Value();
+      if (object->IsName()) return input;
+      break;
+    }
+    case IrOpcode::kJSToString:
+    case IrOpcode::kJSToName:
+    case IrOpcode::kJSTypeOf:
+      return input;
+    default:
+      break;
+  }
+  return nullptr;
+}
+
+
+bool AstGraphBuilder::CheckOsrEntry(IterationStatement* stmt) {
+  if (info()->osr_ast_id() == stmt->OsrEntryId()) {
+    info()->set_osr_expr_stack_height(std::max(
+        environment()->stack_height(), info()->osr_expr_stack_height()));
+    return true;
+  }
+  return false;
 }
 
 
 void AstGraphBuilder::PrepareFrameState(Node* node, BailoutId ast_id,
                                         OutputFrameStateCombine combine) {
-  if (OperatorProperties::HasFrameStateInput(node->op())) {
-    DCHECK(NodeProperties::GetFrameStateInput(node)->opcode() ==
-           IrOpcode::kDead);
+  if (OperatorProperties::GetFrameStateInputCount(node->op()) > 0) {
+    DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
+
+    DCHECK_EQ(IrOpcode::kDead,
+              NodeProperties::GetFrameStateInput(node, 0)->opcode());
     NodeProperties::ReplaceFrameStateInput(
-        node, environment()->Checkpoint(ast_id, combine));
+        node, 0, environment()->Checkpoint(ast_id, combine));
   }
 }
 
 
 BitVector* AstGraphBuilder::GetVariablesAssignedInLoop(
     IterationStatement* stmt) {
-  if (loop_assignment_analysis_ == NULL) return NULL;
+  if (loop_assignment_analysis_ == nullptr) return nullptr;
   return loop_assignment_analysis_->GetVariablesAssignedInLoop(stmt);
 }
 
+
+Node** AstGraphBuilder::EnsureInputBufferSize(int size) {
+  if (size > input_buffer_size_) {
+    size = size + kInputBufferSizeIncrement + input_buffer_size_;
+    input_buffer_ = local_zone()->NewArray<Node*>(size);
+    input_buffer_size_ = size;
+  }
+  return input_buffer_;
+}
+
+
+Node* AstGraphBuilder::MakeNode(const Operator* op, int value_input_count,
+                                Node** value_inputs, bool incomplete) {
+  DCHECK_EQ(op->ValueInputCount(), value_input_count);
+
+  bool has_context = OperatorProperties::HasContextInput(op);
+  int frame_state_count = OperatorProperties::GetFrameStateInputCount(op);
+  bool has_control = op->ControlInputCount() == 1;
+  bool has_effect = op->EffectInputCount() == 1;
+
+  DCHECK(op->ControlInputCount() < 2);
+  DCHECK(op->EffectInputCount() < 2);
+
+  Node* result = nullptr;
+  if (!has_context && frame_state_count == 0 && !has_control && !has_effect) {
+    result = graph()->NewNode(op, value_input_count, value_inputs, incomplete);
+  } else {
+    bool inside_try_scope = try_nesting_level_ > 0;
+    int input_count_with_deps = value_input_count;
+    if (has_context) ++input_count_with_deps;
+    input_count_with_deps += frame_state_count;
+    if (has_control) ++input_count_with_deps;
+    if (has_effect) ++input_count_with_deps;
+    Node** buffer = EnsureInputBufferSize(input_count_with_deps);
+    memcpy(buffer, value_inputs, kPointerSize * value_input_count);
+    Node** current_input = buffer + value_input_count;
+    if (has_context) {
+      *current_input++ = current_context();
+    }
+    for (int i = 0; i < frame_state_count; i++) {
+      // The frame state will be inserted later. Here we misuse
+      // the {Dead} node as a sentinel to be later overwritten
+      // with the real frame state.
+      *current_input++ = jsgraph()->Dead();
+    }
+    if (has_effect) {
+      *current_input++ = environment_->GetEffectDependency();
+    }
+    if (has_control) {
+      *current_input++ = environment_->GetControlDependency();
+    }
+    result = graph()->NewNode(op, input_count_with_deps, buffer, incomplete);
+    if (!environment()->IsMarkedAsUnreachable()) {
+      // Update the current control dependency for control-producing nodes.
+      if (NodeProperties::IsControl(result)) {
+        environment_->UpdateControlDependency(result);
+      }
+      // Update the current effect dependency for effect-producing nodes.
+      if (result->op()->EffectOutputCount() > 0) {
+        environment_->UpdateEffectDependency(result);
+      }
+      // Add implicit exception continuation for throwing nodes.
+      if (!result->op()->HasProperty(Operator::kNoThrow) && inside_try_scope) {
+        // Conservative prediction whether caught locally.
+        IfExceptionHint hint = try_catch_nesting_level_ > 0
+                                   ? IfExceptionHint::kLocallyCaught
+                                   : IfExceptionHint::kLocallyUncaught;
+        // Copy the environment for the success continuation.
+        Environment* success_env = environment()->CopyForConditional();
+        const Operator* op = common()->IfException(hint);
+        Node* effect = environment()->GetEffectDependency();
+        Node* on_exception = graph()->NewNode(op, effect, result);
+        environment_->UpdateControlDependency(on_exception);
+        environment_->UpdateEffectDependency(on_exception);
+        execution_control()->ThrowValue(on_exception);
+        set_environment(success_env);
+      }
+      // Add implicit success continuation for throwing nodes.
+      if (!result->op()->HasProperty(Operator::kNoThrow)) {
+        const Operator* op = common()->IfSuccess();
+        Node* on_success = graph()->NewNode(op, result);
+        environment_->UpdateControlDependency(on_success);
+      }
+    }
+  }
+
+  return result;
+}
+
+
+void AstGraphBuilder::UpdateControlDependencyToLeaveFunction(Node* exit) {
+  if (environment()->IsMarkedAsUnreachable()) return;
+  environment()->MarkAsUnreachable();
+  exit_controls_.push_back(exit);
+}
+
+
+void AstGraphBuilder::Environment::Merge(Environment* other) {
+  DCHECK(values_.size() == other->values_.size());
+  DCHECK(contexts_.size() == other->contexts_.size());
+
+  // Nothing to do if the other environment is dead.
+  if (other->IsMarkedAsUnreachable()) return;
+
+  // Resurrect a dead environment by copying the contents of the other one and
+  // placing a singleton merge as the new control dependency.
+  if (this->IsMarkedAsUnreachable()) {
+    Node* other_control = other->control_dependency_;
+    Node* inputs[] = {other_control};
+    control_dependency_ =
+        graph()->NewNode(common()->Merge(1), arraysize(inputs), inputs, true);
+    effect_dependency_ = other->effect_dependency_;
+    values_ = other->values_;
+    contexts_ = other->contexts_;
+    if (IsLivenessAnalysisEnabled()) {
+      liveness_block_ =
+          builder_->liveness_analyzer()->NewBlock(other->liveness_block());
+    }
+    return;
+  }
+
+  // Record the merge for the local variable liveness calculation.
+  // For loops, we are connecting a back edge into the existing block;
+  // for merges, we create a new merged block.
+  if (IsLivenessAnalysisEnabled()) {
+    if (GetControlDependency()->opcode() != IrOpcode::kLoop) {
+      liveness_block_ =
+          builder_->liveness_analyzer()->NewBlock(liveness_block());
+    }
+    liveness_block()->AddPredecessor(other->liveness_block());
+  }
+
+  // Create a merge of the control dependencies of both environments and update
+  // the current environment's control dependency accordingly.
+  Node* control = builder_->MergeControl(this->GetControlDependency(),
+                                         other->GetControlDependency());
+  UpdateControlDependency(control);
+
+  // Create a merge of the effect dependencies of both environments and update
+  // the current environment's effect dependency accordingly.
+  Node* effect = builder_->MergeEffect(this->GetEffectDependency(),
+                                       other->GetEffectDependency(), control);
+  UpdateEffectDependency(effect);
+
+  // Introduce Phi nodes for values that have differing input at merge points,
+  // potentially extending an existing Phi node if possible.
+  for (int i = 0; i < static_cast<int>(values_.size()); ++i) {
+    values_[i] = builder_->MergeValue(values_[i], other->values_[i], control);
+  }
+  for (int i = 0; i < static_cast<int>(contexts_.size()); ++i) {
+    contexts_[i] =
+        builder_->MergeValue(contexts_[i], other->contexts_[i], control);
+  }
+}
+
+
+void AstGraphBuilder::Environment::PrepareForLoop(BitVector* assigned,
+                                                  bool is_osr) {
+  int size = static_cast<int>(values()->size());
+
+  Node* control = builder_->NewLoop();
+  if (assigned == nullptr) {
+    // Assume that everything is updated in the loop.
+    for (int i = 0; i < size; ++i) {
+      values()->at(i) = builder_->NewPhi(1, values()->at(i), control);
+    }
+  } else {
+    // Only build phis for those locals assigned in this loop.
+    for (int i = 0; i < size; ++i) {
+      if (i < assigned->length() && !assigned->Contains(i)) continue;
+      Node* phi = builder_->NewPhi(1, values()->at(i), control);
+      values()->at(i) = phi;
+    }
+  }
+  Node* effect = builder_->NewEffectPhi(1, GetEffectDependency(), control);
+  UpdateEffectDependency(effect);
+
+  // Connect the loop to end via Terminate if it's not marked as unreachable.
+  if (!IsMarkedAsUnreachable()) {
+    // Connect the Loop node to end via a Terminate node.
+    Node* terminate = builder_->graph()->NewNode(
+        builder_->common()->Terminate(), effect, control);
+    builder_->exit_controls_.push_back(terminate);
+  }
+
+  if (builder_->info()->is_osr()) {
+    // Introduce phis for all context values in the case of an OSR graph.
+    for (size_t i = 0; i < contexts()->size(); ++i) {
+      Node* context = contexts()->at(i);
+      contexts()->at(i) = builder_->NewPhi(1, context, control);
+    }
+  }
+
+  if (is_osr) {
+    // Merge OSR values as inputs to the phis of the loop.
+    Graph* graph = builder_->graph();
+    Node* osr_loop_entry = builder_->graph()->NewNode(
+        builder_->common()->OsrLoopEntry(), graph->start(), graph->start());
+
+    builder_->MergeControl(control, osr_loop_entry);
+    builder_->MergeEffect(effect, osr_loop_entry, control);
+
+    for (int i = 0; i < size; ++i) {
+      Node* value = values()->at(i);
+      Node* osr_value =
+          graph->NewNode(builder_->common()->OsrValue(i), osr_loop_entry);
+      values()->at(i) = builder_->MergeValue(value, osr_value, control);
+    }
+
+    // Rename all the contexts in the environment.
+    // The innermost context is the OSR value, and the outer contexts are
+    // reconstructed by dynamically walking up the context chain.
+    Node* osr_context = nullptr;
+    const Operator* op =
+        builder_->javascript()->LoadContext(0, Context::PREVIOUS_INDEX, true);
+    const Operator* op_inner =
+        builder_->common()->OsrValue(Linkage::kOsrContextSpillSlotIndex);
+    int last = static_cast<int>(contexts()->size() - 1);
+    for (int i = last; i >= 0; i--) {
+      Node* context = contexts()->at(i);
+      osr_context = (i == last) ? graph->NewNode(op_inner, osr_loop_entry)
+                                : graph->NewNode(op, osr_context, osr_context,
+                                                 osr_loop_entry);
+      contexts()->at(i) = builder_->MergeValue(context, osr_context, control);
+    }
+  }
+}
+
+
+Node* AstGraphBuilder::NewPhi(int count, Node* input, Node* control) {
+  const Operator* phi_op = common()->Phi(MachineRepresentation::kTagged, count);
+  Node** buffer = EnsureInputBufferSize(count + 1);
+  MemsetPointer(buffer, input, count);
+  buffer[count] = control;
+  return graph()->NewNode(phi_op, count + 1, buffer, true);
+}
+
+
+// TODO(mstarzinger): Revisit this once we have proper effect states.
+Node* AstGraphBuilder::NewEffectPhi(int count, Node* input, Node* control) {
+  const Operator* phi_op = common()->EffectPhi(count);
+  Node** buffer = EnsureInputBufferSize(count + 1);
+  MemsetPointer(buffer, input, count);
+  buffer[count] = control;
+  return graph()->NewNode(phi_op, count + 1, buffer, true);
+}
+
+
+Node* AstGraphBuilder::MergeControl(Node* control, Node* other) {
+  int inputs = control->op()->ControlInputCount() + 1;
+  if (control->opcode() == IrOpcode::kLoop) {
+    // Control node for loop exists, add input.
+    const Operator* op = common()->Loop(inputs);
+    control->AppendInput(graph_zone(), other);
+    NodeProperties::ChangeOp(control, op);
+  } else if (control->opcode() == IrOpcode::kMerge) {
+    // Control node for merge exists, add input.
+    const Operator* op = common()->Merge(inputs);
+    control->AppendInput(graph_zone(), other);
+    NodeProperties::ChangeOp(control, op);
+  } else {
+    // Control node is a singleton, introduce a merge.
+    const Operator* op = common()->Merge(inputs);
+    Node* inputs[] = {control, other};
+    control = graph()->NewNode(op, arraysize(inputs), inputs, true);
+  }
+  return control;
+}
+
+
+Node* AstGraphBuilder::MergeEffect(Node* value, Node* other, Node* control) {
+  int inputs = control->op()->ControlInputCount();
+  if (value->opcode() == IrOpcode::kEffectPhi &&
+      NodeProperties::GetControlInput(value) == control) {
+    // Phi already exists, add input.
+    value->InsertInput(graph_zone(), inputs - 1, other);
+    NodeProperties::ChangeOp(value, common()->EffectPhi(inputs));
+  } else if (value != other) {
+    // Phi does not exist yet, introduce one.
+    value = NewEffectPhi(inputs, value, control);
+    value->ReplaceInput(inputs - 1, other);
+  }
+  return value;
+}
+
+
+Node* AstGraphBuilder::MergeValue(Node* value, Node* other, Node* control) {
+  int inputs = control->op()->ControlInputCount();
+  if (value->opcode() == IrOpcode::kPhi &&
+      NodeProperties::GetControlInput(value) == control) {
+    // Phi already exists, add input.
+    value->InsertInput(graph_zone(), inputs - 1, other);
+    NodeProperties::ChangeOp(
+        value, common()->Phi(MachineRepresentation::kTagged, inputs));
+  } else if (value != other) {
+    // Phi does not exist yet, introduce one.
+    value = NewPhi(inputs, value, control);
+    value->ReplaceInput(inputs - 1, other);
+  }
+  return value;
+}
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/src/compiler/ast-graph-builder.h b/src/compiler/ast-graph-builder.h
index 0337c81..3b6302d 100644
--- a/src/compiler/ast-graph-builder.h
+++ b/src/compiler/ast-graph-builder.h
@@ -5,133 +5,87 @@
 #ifndef V8_COMPILER_AST_GRAPH_BUILDER_H_
 #define V8_COMPILER_AST_GRAPH_BUILDER_H_
 
-#include "src/v8.h"
-
-#include "src/ast.h"
-#include "src/compiler/graph-builder.h"
+#include "src/ast/ast.h"
 #include "src/compiler/js-graph.h"
+#include "src/compiler/liveness-analyzer.h"
+#include "src/compiler/state-values-utils.h"
 
 namespace v8 {
 namespace internal {
+
+// Forward declarations.
+class BitVector;
+
+
 namespace compiler {
 
+// Forward declarations.
 class ControlBuilder;
 class Graph;
 class LoopAssignmentAnalysis;
 class LoopBuilder;
+class Node;
+class TypeHintAnalysis;
+
 
 // The AstGraphBuilder produces a high-level IR graph, based on an
 // underlying AST. The produced graph can either be compiled into a
 // stand-alone function or be wired into another graph for the purposes
 // of function inlining.
-class AstGraphBuilder : public StructuredGraphBuilder, public AstVisitor {
+class AstGraphBuilder : public AstVisitor {
  public:
   AstGraphBuilder(Zone* local_zone, CompilationInfo* info, JSGraph* jsgraph,
-                  LoopAssignmentAnalysis* loop_assignment = NULL);
+                  LoopAssignmentAnalysis* loop_assignment = nullptr,
+                  TypeHintAnalysis* type_hint_analysis = nullptr);
 
   // Creates a graph by visiting the entire AST.
-  bool CreateGraph();
+  bool CreateGraph(bool stack_check = true);
 
- protected:
-  class AstContext;
-  class AstEffectContext;
-  class AstValueContext;
-  class AstTestContext;
-  class BreakableScope;
-  class ContextScope;
-  class Environment;
-
-  Environment* environment() {
-    return reinterpret_cast<Environment*>(
-        StructuredGraphBuilder::environment());
+  // Helpers to create new control nodes.
+  Node* NewIfTrue() { return NewNode(common()->IfTrue()); }
+  Node* NewIfFalse() { return NewNode(common()->IfFalse()); }
+  Node* NewMerge() { return NewNode(common()->Merge(1), true); }
+  Node* NewLoop() { return NewNode(common()->Loop(1), true); }
+  Node* NewBranch(Node* condition, BranchHint hint = BranchHint::kNone) {
+    return NewNode(common()->Branch(hint), condition);
   }
 
-  AstContext* ast_context() const { return ast_context_; }
-  BreakableScope* breakable() const { return breakable_; }
-  ContextScope* execution_context() const { return execution_context_; }
-
-  void set_ast_context(AstContext* ctx) { ast_context_ = ctx; }
-  void set_breakable(BreakableScope* brk) { breakable_ = brk; }
-  void set_execution_context(ContextScope* ctx) { execution_context_ = ctx; }
-
-  // Support for control flow builders. The concrete type of the environment
-  // depends on the graph builder, but environments themselves are not virtual.
-  typedef StructuredGraphBuilder::Environment BaseEnvironment;
-  BaseEnvironment* CopyEnvironment(BaseEnvironment* env) OVERRIDE;
-
-  // Getters for values in the activation record.
-  Node* GetFunctionClosure();
-  Node* GetFunctionContext();
-
-  //
-  // The following build methods all generate graph fragments and return one
-  // resulting node. The operand stack height remains the same, variables and
-  // other dependencies tracked by the environment might be mutated though.
-  //
-
-  // Builder to create a receiver check for sloppy mode.
-  Node* BuildPatchReceiverToGlobalProxy(Node* receiver);
-
-  // Builder to create a local function context.
-  Node* BuildLocalFunctionContext(Node* context, Node* closure);
-
-  // Builder to create an arguments object if it is used.
-  Node* BuildArgumentsObject(Variable* arguments);
-
-  // Builders for variable load and assignment.
-  Node* BuildVariableAssignment(Variable* var, Node* value, Token::Value op,
-                                BailoutId bailout_id,
-                                OutputFrameStateCombine state_combine =
-                                    OutputFrameStateCombine::Ignore());
-  Node* BuildVariableDelete(Variable* var, BailoutId bailout_id,
-                            OutputFrameStateCombine state_combine);
-  Node* BuildVariableLoad(Variable* var, BailoutId bailout_id,
-                          const VectorSlotPair& feedback,
-                          ContextualMode mode = CONTEXTUAL);
-
-  // Builders for accessing the function context.
-  Node* BuildLoadBuiltinsObject();
-  Node* BuildLoadGlobalObject();
-  Node* BuildLoadGlobalProxy();
-  Node* BuildLoadClosure();
-  Node* BuildLoadObjectField(Node* object, int offset);
-
-  // Builders for automatic type conversion.
-  Node* BuildToBoolean(Node* value);
-
-  // Builders for error reporting at runtime.
-  Node* BuildThrowReferenceError(Variable* var, BailoutId bailout_id);
-  Node* BuildThrowConstAssignError(BailoutId bailout_id);
-
-  // Builders for dynamic hole-checks at runtime.
-  Node* BuildHoleCheckSilent(Node* value, Node* for_hole, Node* not_hole);
-  Node* BuildHoleCheckThrow(Node* value, Variable* var, Node* not_hole,
-                            BailoutId bailout_id);
-
-  // Builders for binary operations.
-  Node* BuildBinaryOp(Node* left, Node* right, Token::Value op);
-
-  // Builder for stack-check guards.
-  Node* BuildStackCheck();
-
-#define DECLARE_VISIT(type) void Visit##type(type* node) OVERRIDE;
+ protected:
+#define DECLARE_VISIT(type) void Visit##type(type* node) override;
   // Visiting functions for AST nodes make this an AstVisitor.
   AST_NODE_LIST(DECLARE_VISIT)
 #undef DECLARE_VISIT
 
   // Visiting function for declarations list is overridden.
-  void VisitDeclarations(ZoneList<Declaration*>* declarations) OVERRIDE;
+  void VisitDeclarations(ZoneList<Declaration*>* declarations) override;
 
  private:
+  class AstContext;
+  class AstEffectContext;
+  class AstValueContext;
+  class AstTestContext;
+  class ContextScope;
+  class ControlScope;
+  class ControlScopeForBreakable;
+  class ControlScopeForIteration;
+  class ControlScopeForCatch;
+  class ControlScopeForFinally;
+  class Environment;
+  class FrameStateBeforeAndAfter;
+  friend class ControlBuilder;
+
+  Isolate* isolate_;
+  Zone* local_zone_;
   CompilationInfo* info_;
-  AstContext* ast_context_;
   JSGraph* jsgraph_;
+  Environment* environment_;
+  AstContext* ast_context_;
 
   // List of global declarations for functions and variables.
   ZoneVector<Handle<Object>> globals_;
 
-  // Stack of breakable statements entered by the visitor.
-  BreakableScope* breakable_;
+  // Stack of control scopes currently entered by the visitor.
+  ControlScope* execution_control_;
 
   // Stack of context objects pushed onto the chain by the visitor.
   ContextScope* execution_context_;
@@ -139,28 +93,308 @@
   // Nodes representing values in the activation record.
   SetOncePointer<Node> function_closure_;
   SetOncePointer<Node> function_context_;
+  SetOncePointer<Node> new_target_;
+
+  // Tracks how many try-blocks are currently entered.
+  int try_catch_nesting_level_;
+  int try_nesting_level_;
+
+  // Temporary storage for building node input lists.
+  int input_buffer_size_;
+  Node** input_buffer_;
+
+  // Optimization to cache loaded feedback vector.
+  SetOncePointer<Node> feedback_vector_;
+
+  // Control nodes that exit the function body.
+  ZoneVector<Node*> exit_controls_;
 
   // Result of loop assignment analysis performed before graph creation.
   LoopAssignmentAnalysis* loop_assignment_analysis_;
 
+  // Result of type hint analysis performed before graph creation.
+  TypeHintAnalysis* type_hint_analysis_;
+
+  // Cache for StateValues nodes for frame states.
+  StateValuesCache state_values_cache_;
+
+  // Analyzer of local variable liveness.
+  LivenessAnalyzer liveness_analyzer_;
+
+  // Function info for frame state construction.
+  const FrameStateFunctionInfo* const frame_state_function_info_;
+
+  // Growth increment for the temporary buffer used to construct input lists to
+  // new nodes.
+  static const int kInputBufferSizeIncrement = 64;
+
+  Zone* local_zone() const { return local_zone_; }
+  Environment* environment() const { return environment_; }
+  AstContext* ast_context() const { return ast_context_; }
+  ControlScope* execution_control() const { return execution_control_; }
+  ContextScope* execution_context() const { return execution_context_; }
+  CommonOperatorBuilder* common() const { return jsgraph_->common(); }
   CompilationInfo* info() const { return info_; }
-  inline StrictMode strict_mode() const;
+  Isolate* isolate() const { return isolate_; }
+  LanguageMode language_mode() const;
   JSGraph* jsgraph() { return jsgraph_; }
+  Graph* graph() { return jsgraph_->graph(); }
+  Zone* graph_zone() { return graph()->zone(); }
   JSOperatorBuilder* javascript() { return jsgraph_->javascript(); }
   ZoneVector<Handle<Object>>* globals() { return &globals_; }
+  Scope* current_scope() const;
+  Node* current_context() const;
+  LivenessAnalyzer* liveness_analyzer() { return &liveness_analyzer_; }
+  const FrameStateFunctionInfo* frame_state_function_info() const {
+    return frame_state_function_info_;
+  }
 
-  // Current scope during visitation.
-  inline Scope* current_scope() const;
+  void set_environment(Environment* env) { environment_ = env; }
+  void set_ast_context(AstContext* ctx) { ast_context_ = ctx; }
+  void set_execution_control(ControlScope* ctrl) { execution_control_ = ctrl; }
+  void set_execution_context(ContextScope* ctx) { execution_context_ = ctx; }
+
+  // Create the main graph body by visiting the AST.
+  void CreateGraphBody(bool stack_check);
+
+  // Get or create the node that represents the incoming function closure.
+  Node* GetFunctionClosureForContext();
+  Node* GetFunctionClosure();
+
+  // Get or create the node that represents the incoming function context.
+  Node* GetFunctionContext();
+
+  // Get or create the node that represents the incoming new target value.
+  Node* GetNewTarget();
+
+  // Node creation helpers.
+  Node* NewNode(const Operator* op, bool incomplete = false) {
+    return MakeNode(op, 0, static_cast<Node**>(nullptr), incomplete);
+  }
+
+  Node* NewNode(const Operator* op, Node* n1) {
+    return MakeNode(op, 1, &n1, false);
+  }
+
+  Node* NewNode(const Operator* op, Node* n1, Node* n2) {
+    Node* buffer[] = {n1, n2};
+    return MakeNode(op, arraysize(buffer), buffer, false);
+  }
+
+  Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3) {
+    Node* buffer[] = {n1, n2, n3};
+    return MakeNode(op, arraysize(buffer), buffer, false);
+  }
+
+  Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4) {
+    Node* buffer[] = {n1, n2, n3, n4};
+    return MakeNode(op, arraysize(buffer), buffer, false);
+  }
+
+  Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
+                Node* n5) {
+    Node* buffer[] = {n1, n2, n3, n4, n5};
+    return MakeNode(op, arraysize(buffer), buffer, false);
+  }
+
+  Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
+                Node* n5, Node* n6) {
+    Node* nodes[] = {n1, n2, n3, n4, n5, n6};
+    return MakeNode(op, arraysize(nodes), nodes, false);
+  }
+
+  Node* NewNode(const Operator* op, int value_input_count, Node** value_inputs,
+                bool incomplete = false) {
+    return MakeNode(op, value_input_count, value_inputs, incomplete);
+  }
+
+  // Creates a new Phi node having {count} input values.
+  Node* NewPhi(int count, Node* input, Node* control);
+  Node* NewEffectPhi(int count, Node* input, Node* control);
+
+  // Helpers for merging control, effect or value dependencies.
+  Node* MergeControl(Node* control, Node* other);
+  Node* MergeEffect(Node* value, Node* other, Node* control);
+  Node* MergeValue(Node* value, Node* other, Node* control);
+
+  // The main node creation chokepoint. Adds context, frame state, effect,
+  // and control dependencies depending on the operator.
+  Node* MakeNode(const Operator* op, int value_input_count, Node** value_inputs,
+                 bool incomplete);
+
+  // Helper to indicate a node exits the function body.
+  void UpdateControlDependencyToLeaveFunction(Node* exit);
+
+  // Builds deoptimization for a given node.
+  void PrepareFrameState(Node* node, BailoutId ast_id,
+                         OutputFrameStateCombine framestate_combine =
+                             OutputFrameStateCombine::Ignore());
+
+  BitVector* GetVariablesAssignedInLoop(IterationStatement* stmt);
+
+  // Check if the given statement is an OSR entry.
+  // If so, record the stack height into the compilation and return {true}.
+  bool CheckOsrEntry(IterationStatement* stmt);
+
+  // Computes local variable liveness and replaces dead variables in
+  // frame states with the undefined values.
+  void ClearNonLiveSlotsInFrameStates();
+
+  Node** EnsureInputBufferSize(int size);
 
   // Named and keyed loads require a VectorSlotPair for successful lowering.
-  VectorSlotPair CreateVectorSlotPair(FeedbackVectorICSlot slot) const;
+  VectorSlotPair CreateVectorSlotPair(FeedbackVectorSlot slot) const;
+
+  // Determine which contexts need to be checked for extension objects that
+  // might shadow the optimistic declaration of dynamic lookup variables.
+  uint32_t ComputeBitsetForDynamicGlobal(Variable* variable);
+  uint32_t ComputeBitsetForDynamicContext(Variable* variable);
+
+  // ===========================================================================
+  // The following build methods all generate graph fragments and return one
+  // resulting node. The operand stack height remains the same, variables and
+  // other dependencies tracked by the environment might be mutated though.
+
+  // Builders to create local function, script and block contexts.
+  Node* BuildLocalActivationContext(Node* context);
+  Node* BuildLocalFunctionContext(Scope* scope);
+  Node* BuildLocalScriptContext(Scope* scope);
+  Node* BuildLocalBlockContext(Scope* scope);
+
+  // Builder to create an arguments object if it is used.
+  Node* BuildArgumentsObject(Variable* arguments);
+
+  // Builder to create an array of rest parameters if used
+  Node* BuildRestArgumentsArray(Variable* rest, int index);
+
+  // Builder that assigns to the {.this_function} internal variable if needed.
+  Node* BuildThisFunctionVariable(Variable* this_function_var);
+
+  // Builder that assigns to the {new.target} internal variable if needed.
+  Node* BuildNewTargetVariable(Variable* new_target_var);
+
+  // Builders for variable load and assignment.
+  Node* BuildVariableAssignment(Variable* variable, Node* value,
+                                Token::Value op, const VectorSlotPair& slot,
+                                BailoutId bailout_id,
+                                FrameStateBeforeAndAfter& states,
+                                OutputFrameStateCombine framestate_combine =
+                                    OutputFrameStateCombine::Ignore());
+  Node* BuildVariableDelete(Variable* variable, BailoutId bailout_id,
+                            OutputFrameStateCombine framestate_combine);
+  Node* BuildVariableLoad(Variable* variable, BailoutId bailout_id,
+                          FrameStateBeforeAndAfter& states,
+                          const VectorSlotPair& feedback,
+                          OutputFrameStateCombine framestate_combine,
+                          TypeofMode typeof_mode = NOT_INSIDE_TYPEOF);
+
+  // Builders for property loads and stores.
+  Node* BuildKeyedLoad(Node* receiver, Node* key,
+                       const VectorSlotPair& feedback);
+  Node* BuildNamedLoad(Node* receiver, Handle<Name> name,
+                       const VectorSlotPair& feedback);
+  Node* BuildKeyedStore(Node* receiver, Node* key, Node* value,
+                        const VectorSlotPair& feedback);
+  Node* BuildNamedStore(Node* receiver, Handle<Name> name, Node* value,
+                        const VectorSlotPair& feedback);
+
+  // Builders for super property loads and stores.
+  Node* BuildKeyedSuperStore(Node* receiver, Node* home_object, Node* key,
+                             Node* value);
+  Node* BuildNamedSuperStore(Node* receiver, Node* home_object,
+                             Handle<Name> name, Node* value);
+  Node* BuildNamedSuperLoad(Node* receiver, Node* home_object,
+                            Handle<Name> name, const VectorSlotPair& feedback);
+  Node* BuildKeyedSuperLoad(Node* receiver, Node* home_object, Node* key,
+                            const VectorSlotPair& feedback);
+
+  // Builders for global variable loads and stores.
+  Node* BuildGlobalLoad(Handle<Name> name, const VectorSlotPair& feedback,
+                        TypeofMode typeof_mode);
+  Node* BuildGlobalStore(Handle<Name> name, Node* value,
+                         const VectorSlotPair& feedback);
+
+  // Builders for accessing the function context.
+  Node* BuildLoadGlobalObject();
+  Node* BuildLoadNativeContextField(int index);
+  Node* BuildLoadFeedbackVector();
+
+  // Builder for accessing a (potentially immutable) object field.
+  Node* BuildLoadObjectField(Node* object, int offset);
+  Node* BuildLoadImmutableObjectField(Node* object, int offset);
+
+  // Builders for automatic type conversion.
+  Node* BuildToBoolean(Node* input, TypeFeedbackId feedback_id);
+  Node* BuildToName(Node* input, BailoutId bailout_id);
+  Node* BuildToObject(Node* input, BailoutId bailout_id);
+
+  // Builder for adding the [[HomeObject]] to a value if the value came from a
+  // function literal and needs a home object. Do nothing otherwise.
+  Node* BuildSetHomeObject(Node* value, Node* home_object,
+                           ObjectLiteralProperty* property,
+                           int slot_number = 0);
+
+  // Builders for error reporting at runtime.
+  Node* BuildThrowError(Node* exception, BailoutId bailout_id);
+  Node* BuildThrowReferenceError(Variable* var, BailoutId bailout_id);
+  Node* BuildThrowConstAssignError(BailoutId bailout_id);
+  Node* BuildThrowStaticPrototypeError(BailoutId bailout_id);
+  Node* BuildThrowUnsupportedSuperError(BailoutId bailout_id);
+
+  // Builders for dynamic hole-checks at runtime.
+  Node* BuildHoleCheckSilent(Node* value, Node* for_hole, Node* not_hole);
+  Node* BuildHoleCheckThenThrow(Node* value, Variable* var, Node* not_hole,
+                                BailoutId bailout_id);
+  Node* BuildHoleCheckElseThrow(Node* value, Variable* var, Node* for_hole,
+                                BailoutId bailout_id);
+
+  // Builders for conditional errors.
+  Node* BuildThrowIfStaticPrototype(Node* name, BailoutId bailout_id);
+
+  // Builders for non-local control flow.
+  Node* BuildReturn(Node* return_value);
+  Node* BuildThrow(Node* exception_value);
+
+  // Builders for binary operations.
+  Node* BuildBinaryOp(Node* left, Node* right, Token::Value op,
+                      TypeFeedbackId feedback_id);
 
   // Process arguments to a call by popping {arity} elements off the operand
   // stack and build a call node using the given call operator.
   Node* ProcessArguments(const Operator* op, int arity);
 
+  // ===========================================================================
+  // The following build methods have the same contract as the above ones, but
+  // they can also return {nullptr} to indicate that no fragment was built. Note
+  // that these are optimizations, disabling any of them should still produce
+  // correct graphs.
+
+  // Optimization for variable load from global object.
+  Node* TryLoadGlobalConstant(Handle<Name> name);
+
+  // Optimization for variable load of dynamic lookup slot that is most likely
+  // to resolve to a global slot or context slot (inferred from scope chain).
+  Node* TryLoadDynamicVariable(Variable* variable, Handle<String> name,
+                               BailoutId bailout_id,
+                               FrameStateBeforeAndAfter& states,
+                               const VectorSlotPair& feedback,
+                               OutputFrameStateCombine combine,
+                               TypeofMode typeof_mode);
+
+  // Optimizations for automatic type conversion.
+  Node* TryFastToBoolean(Node* input);
+  Node* TryFastToName(Node* input);
+
+  // ===========================================================================
+  // The following visitation methods all recursively visit a subtree of the
+  // underlying AST and extent the graph. The operand stack is mutated in a way
+  // consistent with other compilers:
+  //  - Expressions pop operands and push result, depending on {AstContext}.
+  //  - Statements keep the operand stack balanced.
+
   // Visit statements.
   void VisitIfNotNull(Statement* stmt);
+  void VisitInScope(Statement* stmt, Scope* scope, Node* context);
 
   // Visit expressions.
   void Visit(Expression* expr);
@@ -168,10 +402,14 @@
   void VisitForEffect(Expression* expr);
   void VisitForValue(Expression* expr);
   void VisitForValueOrNull(Expression* expr);
+  void VisitForValueOrTheHole(Expression* expr);
   void VisitForValues(ZoneList<Expression*>* exprs);
 
   // Common for all IterationStatement bodies.
-  void VisitIterationBody(IterationStatement* stmt, LoopBuilder* loop, int);
+  void VisitIterationBody(IterationStatement* stmt, LoopBuilder* loop);
+
+  // Dispatched from VisitCall.
+  void VisitCallSuper(Call* expr);
 
   // Dispatched from VisitCallRuntime.
   void VisitCallJSRuntime(CallRuntime* expr);
@@ -188,14 +426,17 @@
   void VisitArithmeticExpression(BinaryOperation* expr);
 
   // Dispatched from VisitForInStatement.
-  void VisitForInAssignment(Expression* expr, Node* value);
+  void VisitForInAssignment(Expression* expr, Node* value,
+                            const VectorSlotPair& feedback,
+                            BailoutId bailout_id_before,
+                            BailoutId bailout_id_after);
 
-  // Builds deoptimization for a given node.
-  void PrepareFrameState(
-      Node* node, BailoutId ast_id,
-      OutputFrameStateCombine combine = OutputFrameStateCombine::Ignore());
+  // Dispatched from VisitObjectLiteral.
+  void VisitObjectLiteralAccessor(Node* home_object,
+                                  ObjectLiteralProperty* property);
 
-  BitVector* GetVariablesAssignedInLoop(IterationStatement* stmt);
+  // Dispatched from VisitClassLiteral.
+  void VisitClassLiteralContents(ClassLiteral* expr);
 
   DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
   DISALLOW_COPY_AND_ASSIGN(AstGraphBuilder);
@@ -210,38 +451,33 @@
 //
 //  [parameters (+receiver)] [locals] [operand stack]
 //
-class AstGraphBuilder::Environment
-    : public StructuredGraphBuilder::Environment {
+class AstGraphBuilder::Environment : public ZoneObject {
  public:
   Environment(AstGraphBuilder* builder, Scope* scope, Node* control_dependency);
-  Environment(const Environment& copy);
 
   int parameters_count() const { return parameters_count_; }
   int locals_count() const { return locals_count_; }
+  int context_chain_length() { return static_cast<int>(contexts_.size()); }
   int stack_height() {
     return static_cast<int>(values()->size()) - parameters_count_ -
            locals_count_;
   }
 
-  // Operations on parameter or local variables. The parameter indices are
-  // shifted by 1 (receiver is parameter index -1 but environment index 0).
-  void Bind(Variable* variable, Node* node) {
-    DCHECK(variable->IsStackAllocated());
-    if (variable->IsParameter()) {
-      values()->at(variable->index() + 1) = node;
-    } else {
-      DCHECK(variable->IsStackLocal());
-      values()->at(variable->index() + parameters_count_) = node;
-    }
-  }
-  Node* Lookup(Variable* variable) {
-    DCHECK(variable->IsStackAllocated());
-    if (variable->IsParameter()) {
-      return values()->at(variable->index() + 1);
-    } else {
-      DCHECK(variable->IsStackLocal());
-      return values()->at(variable->index() + parameters_count_);
-    }
+  // Operations on parameter or local variables.
+  void Bind(Variable* variable, Node* node);
+  Node* Lookup(Variable* variable);
+  void MarkAllLocalsLive();
+
+  // Raw operations on parameter variables.
+  void RawParameterBind(int index, Node* node);
+  Node* RawParameterLookup(int index);
+
+  // Operations on the context chain.
+  Node* Context() const { return contexts_.back(); }
+  void PushContext(Node* context) { contexts()->push_back(context); }
+  void PopContext() { contexts()->pop_back(); }
+  void TrimContextChain(int trim_to_length) {
+    contexts()->resize(trim_to_length);
   }
 
   // Operations on the operand stack.
@@ -274,176 +510,82 @@
     DCHECK(depth >= 0 && depth <= stack_height());
     values()->erase(values()->end() - depth, values()->end());
   }
+  void TrimStack(int trim_to_height) {
+    int depth = stack_height() - trim_to_height;
+    DCHECK(depth >= 0 && depth <= stack_height());
+    values()->erase(values()->end() - depth, values()->end());
+  }
 
   // Preserve a checkpoint of the environment for the IR graph. Any
   // further mutation of the environment will not affect checkpoints.
-  Node* Checkpoint(BailoutId ast_id, OutputFrameStateCombine combine);
+  Node* Checkpoint(BailoutId ast_id, OutputFrameStateCombine combine =
+                                         OutputFrameStateCombine::Ignore());
 
- protected:
-  AstGraphBuilder* builder() const {
-    return reinterpret_cast<AstGraphBuilder*>(
-        StructuredGraphBuilder::Environment::builder());
+  // Control dependency tracked by this environment.
+  Node* GetControlDependency() { return control_dependency_; }
+  void UpdateControlDependency(Node* dependency) {
+    control_dependency_ = dependency;
   }
 
- private:
-  void UpdateStateValues(Node** state_values, int offset, int count);
+  // Effect dependency tracked by this environment.
+  Node* GetEffectDependency() { return effect_dependency_; }
+  void UpdateEffectDependency(Node* dependency) {
+    effect_dependency_ = dependency;
+  }
 
+  // Mark this environment as being unreachable.
+  void MarkAsUnreachable() {
+    UpdateControlDependency(builder()->jsgraph()->Dead());
+    liveness_block_ = nullptr;
+  }
+  bool IsMarkedAsUnreachable() {
+    return GetControlDependency()->opcode() == IrOpcode::kDead;
+  }
+
+  // Merge another environment into this one.
+  void Merge(Environment* other);
+
+  // Copies this environment at a control-flow split point.
+  Environment* CopyForConditional();
+
+  // Copies this environment to a potentially unreachable control-flow point.
+  Environment* CopyAsUnreachable();
+
+  // Copies this environment at a loop header control-flow point.
+  Environment* CopyForLoop(BitVector* assigned, bool is_osr = false);
+
+ private:
+  AstGraphBuilder* builder_;
   int parameters_count_;
   int locals_count_;
+  LivenessAnalyzerBlock* liveness_block_;
+  NodeVector values_;
+  NodeVector contexts_;
+  Node* control_dependency_;
+  Node* effect_dependency_;
   Node* parameters_node_;
   Node* locals_node_;
   Node* stack_node_;
+
+  explicit Environment(Environment* copy,
+                       LivenessAnalyzerBlock* liveness_block);
+  Environment* CopyAndShareLiveness();
+  void UpdateStateValues(Node** state_values, int offset, int count);
+  void UpdateStateValuesWithCache(Node** state_values, int offset, int count);
+  Zone* zone() const { return builder_->local_zone(); }
+  Graph* graph() const { return builder_->graph(); }
+  AstGraphBuilder* builder() const { return builder_; }
+  CommonOperatorBuilder* common() { return builder_->common(); }
+  NodeVector* values() { return &values_; }
+  NodeVector* contexts() { return &contexts_; }
+  LivenessAnalyzerBlock* liveness_block() { return liveness_block_; }
+  bool IsLivenessAnalysisEnabled();
+  bool IsLivenessBlockConsistent();
+
+  // Prepare environment to be used as loop header.
+  void PrepareForLoop(BitVector* assigned, bool is_osr = false);
 };
 
-
-// Each expression in the AST is evaluated in a specific context. This context
-// decides how the evaluation result is passed up the visitor.
-class AstGraphBuilder::AstContext BASE_EMBEDDED {
- public:
-  bool IsEffect() const { return kind_ == Expression::kEffect; }
-  bool IsValue() const { return kind_ == Expression::kValue; }
-  bool IsTest() const { return kind_ == Expression::kTest; }
-
-  // Determines how to combine the frame state with the value
-  // that is about to be plugged into this AstContext.
-  OutputFrameStateCombine GetStateCombine() {
-    return IsEffect() ? OutputFrameStateCombine::Ignore()
-                      : OutputFrameStateCombine::Push();
-  }
-
-  // Plug a node into this expression context.  Call this function in tail
-  // position in the Visit functions for expressions.
-  virtual void ProduceValue(Node* value) = 0;
-
-  // Unplugs a node from this expression context.  Call this to retrieve the
-  // result of another Visit function that already plugged the context.
-  virtual Node* ConsumeValue() = 0;
-
-  // Shortcut for "context->ProduceValue(context->ConsumeValue())".
-  void ReplaceValue() { ProduceValue(ConsumeValue()); }
-
- protected:
-  AstContext(AstGraphBuilder* owner, Expression::Context kind);
-  virtual ~AstContext();
-
-  AstGraphBuilder* owner() const { return owner_; }
-  Environment* environment() const { return owner_->environment(); }
-
-// We want to be able to assert, in a context-specific way, that the stack
-// height makes sense when the context is filled.
-#ifdef DEBUG
-  int original_height_;
-#endif
-
- private:
-  Expression::Context kind_;
-  AstGraphBuilder* owner_;
-  AstContext* outer_;
-};
-
-
-// Context to evaluate expression for its side effects only.
-class AstGraphBuilder::AstEffectContext FINAL : public AstContext {
- public:
-  explicit AstEffectContext(AstGraphBuilder* owner)
-      : AstContext(owner, Expression::kEffect) {}
-  ~AstEffectContext() FINAL;
-  void ProduceValue(Node* value) FINAL;
-  Node* ConsumeValue() FINAL;
-};
-
-
-// Context to evaluate expression for its value (and side effects).
-class AstGraphBuilder::AstValueContext FINAL : public AstContext {
- public:
-  explicit AstValueContext(AstGraphBuilder* owner)
-      : AstContext(owner, Expression::kValue) {}
-  ~AstValueContext() FINAL;
-  void ProduceValue(Node* value) FINAL;
-  Node* ConsumeValue() FINAL;
-};
-
-
-// Context to evaluate expression for a condition value (and side effects).
-class AstGraphBuilder::AstTestContext FINAL : public AstContext {
- public:
-  explicit AstTestContext(AstGraphBuilder* owner)
-      : AstContext(owner, Expression::kTest) {}
-  ~AstTestContext() FINAL;
-  void ProduceValue(Node* value) FINAL;
-  Node* ConsumeValue() FINAL;
-};
-
-
-// Scoped class tracking breakable statements entered by the visitor. Allows to
-// properly 'break' and 'continue' iteration statements as well as to 'break'
-// from blocks within switch statements.
-class AstGraphBuilder::BreakableScope BASE_EMBEDDED {
- public:
-  BreakableScope(AstGraphBuilder* owner, BreakableStatement* target,
-                 ControlBuilder* control, int drop_extra)
-      : owner_(owner),
-        target_(target),
-        next_(owner->breakable()),
-        control_(control),
-        drop_extra_(drop_extra) {
-    owner_->set_breakable(this);  // Push.
-  }
-
-  ~BreakableScope() {
-    owner_->set_breakable(next_);  // Pop.
-  }
-
-  // Either 'break' or 'continue' the target statement.
-  void BreakTarget(BreakableStatement* target);
-  void ContinueTarget(BreakableStatement* target);
-
- private:
-  AstGraphBuilder* owner_;
-  BreakableStatement* target_;
-  BreakableScope* next_;
-  ControlBuilder* control_;
-  int drop_extra_;
-
-  // Find the correct scope for the target statement. Note that this also drops
-  // extra operands from the environment for each scope skipped along the way.
-  BreakableScope* FindBreakable(BreakableStatement* target);
-};
-
-
-// Scoped class tracking context objects created by the visitor. Represents
-// mutations of the context chain within the function body and allows to
-// change the current {scope} and {context} during visitation.
-class AstGraphBuilder::ContextScope BASE_EMBEDDED {
- public:
-  ContextScope(AstGraphBuilder* owner, Scope* scope, Node* context)
-      : owner_(owner),
-        next_(owner->execution_context()),
-        outer_(owner->current_context()),
-        scope_(scope) {
-    owner_->set_execution_context(this);  // Push.
-    owner_->set_current_context(context);
-  }
-
-  ~ContextScope() {
-    owner_->set_execution_context(next_);  // Pop.
-    owner_->set_current_context(outer_);
-  }
-
-  // Current scope during visitation.
-  Scope* scope() const { return scope_; }
-
- private:
-  AstGraphBuilder* owner_;
-  ContextScope* next_;
-  Node* outer_;
-  Scope* scope_;
-};
-
-Scope* AstGraphBuilder::current_scope() const {
-  return execution_context_->scope();
-}
-
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/src/compiler/ast-loop-assignment-analyzer.cc b/src/compiler/ast-loop-assignment-analyzer.cc
index 7adac56..2074c94 100644
--- a/src/compiler/ast-loop-assignment-analyzer.cc
+++ b/src/compiler/ast-loop-assignment-analyzer.cc
@@ -3,7 +3,8 @@
 // found in the LICENSE file.
 
 #include "src/compiler/ast-loop-assignment-analyzer.h"
-#include "src/parser.h"
+#include "src/compiler.h"
+#include "src/parsing/parser.h"
 
 namespace v8 {
 namespace internal {
@@ -12,16 +13,16 @@
 typedef class AstLoopAssignmentAnalyzer ALAA;  // for code shortitude.
 
 ALAA::AstLoopAssignmentAnalyzer(Zone* zone, CompilationInfo* info)
-    : info_(info), loop_stack_(zone) {
-  InitializeAstVisitor(zone);
+    : info_(info), zone_(zone), loop_stack_(zone) {
+  InitializeAstVisitor(info->isolate());
 }
 
 
 LoopAssignmentAnalysis* ALAA::Analyze() {
-  LoopAssignmentAnalysis* a = new (zone()) LoopAssignmentAnalysis(zone());
+  LoopAssignmentAnalysis* a = new (zone_) LoopAssignmentAnalysis(zone_);
   result_ = a;
-  VisitStatements(info()->function()->body());
-  result_ = NULL;
+  VisitStatements(info()->literal()->body());
+  result_ = nullptr;
   return a;
 }
 
@@ -29,7 +30,9 @@
 void ALAA::Enter(IterationStatement* loop) {
   int num_variables = 1 + info()->scope()->num_parameters() +
                       info()->scope()->num_stack_slots();
-  BitVector* bits = new (zone()) BitVector(num_variables, zone());
+  BitVector* bits = new (zone_) BitVector(num_variables, zone_);
+  if (info()->is_osr() && info()->osr_ast_id() == loop->OsrEntryId())
+    bits->AddAll();
   loop_stack_.push_back(bits);
 }
 
@@ -52,12 +55,8 @@
 
 void ALAA::VisitVariableDeclaration(VariableDeclaration* leaf) {}
 void ALAA::VisitFunctionDeclaration(FunctionDeclaration* leaf) {}
-void ALAA::VisitModuleDeclaration(ModuleDeclaration* leaf) {}
 void ALAA::VisitImportDeclaration(ImportDeclaration* leaf) {}
 void ALAA::VisitExportDeclaration(ExportDeclaration* leaf) {}
-void ALAA::VisitModuleVariable(ModuleVariable* leaf) {}
-void ALAA::VisitModulePath(ModulePath* leaf) {}
-void ALAA::VisitModuleUrl(ModuleUrl* leaf) {}
 void ALAA::VisitEmptyStatement(EmptyStatement* leaf) {}
 void ALAA::VisitContinueStatement(ContinueStatement* leaf) {}
 void ALAA::VisitBreakStatement(BreakStatement* leaf) {}
@@ -68,18 +67,22 @@
 void ALAA::VisitLiteral(Literal* leaf) {}
 void ALAA::VisitRegExpLiteral(RegExpLiteral* leaf) {}
 void ALAA::VisitThisFunction(ThisFunction* leaf) {}
-void ALAA::VisitSuperReference(SuperReference* leaf) {}
+void ALAA::VisitSuperPropertyReference(SuperPropertyReference* leaf) {}
+void ALAA::VisitSuperCallReference(SuperCallReference* leaf) {}
 
 
 // ---------------------------------------------------------------------------
 // -- Pass-through nodes------------------------------------------------------
 // ---------------------------------------------------------------------------
-void ALAA::VisitModuleLiteral(ModuleLiteral* e) { Visit(e->body()); }
-
-
 void ALAA::VisitBlock(Block* stmt) { VisitStatements(stmt->statements()); }
 
 
+void ALAA::VisitDoExpression(DoExpression* expr) {
+  Visit(expr->block());
+  Visit(expr->result());
+}
+
+
 void ALAA::VisitExpressionStatement(ExpressionStatement* stmt) {
   Visit(stmt->expression());
 }
@@ -123,6 +126,7 @@
   VisitIfNotNull(e->constructor());
   ZoneList<ObjectLiteralProperty*>* properties = e->properties();
   for (int i = 0; i < properties->length(); i++) {
+    Visit(properties->at(i)->key());
     Visit(properties->at(i)->value());
   }
 }
@@ -138,6 +142,7 @@
 void ALAA::VisitObjectLiteral(ObjectLiteral* e) {
   ZoneList<ObjectLiteralProperty*>* properties = e->properties();
   for (int i = 0; i < properties->length(); i++) {
+    Visit(properties->at(i)->key());
     Visit(properties->at(i)->value());
   }
 }
@@ -193,22 +198,27 @@
 }
 
 
+void ALAA::VisitSpread(Spread* e) { Visit(e->expression()); }
+
+
+void ALAA::VisitEmptyParentheses(EmptyParentheses* e) { UNREACHABLE(); }
+
+
 void ALAA::VisitCaseClause(CaseClause* cc) {
   if (!cc->is_default()) Visit(cc->label());
   VisitStatements(cc->statements());
 }
 
 
-// ---------------------------------------------------------------------------
-// -- Interesting nodes-------------------------------------------------------
-// ---------------------------------------------------------------------------
-void ALAA::VisitModuleStatement(ModuleStatement* stmt) {
-  Visit(stmt->body());
-  // TODO(turbofan): can a module appear in a loop?
-  AnalyzeAssignment(stmt->proxy()->var());
+void ALAA::VisitSloppyBlockFunctionStatement(
+    SloppyBlockFunctionStatement* stmt) {
+  Visit(stmt->statement());
 }
 
 
+// ---------------------------------------------------------------------------
+// -- Interesting nodes-------------------------------------------------------
+// ---------------------------------------------------------------------------
 void ALAA::VisitTryCatchStatement(TryCatchStatement* stmt) {
   Visit(stmt->try_block());
   Visit(stmt->catch_block());
@@ -253,7 +263,9 @@
 
 
 void ALAA::VisitForOfStatement(ForOfStatement* loop) {
+  Visit(loop->assign_iterator());
   Enter(loop);
+  Visit(loop->assign_each());
   Visit(loop->each());
   Visit(loop->subject());
   Visit(loop->body());
@@ -276,6 +288,12 @@
 }
 
 
+void ALAA::VisitRewritableAssignmentExpression(
+    RewritableAssignmentExpression* expr) {
+  Visit(expr->expression());
+}
+
+
 void ALAA::AnalyzeAssignment(Variable* var) {
   if (!loop_stack_.empty() && var->IsStackAllocated()) {
     loop_stack_.back()->Add(GetVariableIndex(info()->scope(), var));
@@ -300,6 +318,6 @@
   }
   return count;
 }
-}
-}
-}  // namespace v8::internal::compiler
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/ast-loop-assignment-analyzer.h b/src/compiler/ast-loop-assignment-analyzer.h
index 00a7f2d..1696911 100644
--- a/src/compiler/ast-loop-assignment-analyzer.h
+++ b/src/compiler/ast-loop-assignment-analyzer.h
@@ -5,9 +5,8 @@
 #ifndef V8_COMPILER_AST_LOOP_ASSIGNMENT_ANALYZER_H_
 #define V8_COMPILER_AST_LOOP_ASSIGNMENT_ANALYZER_H_
 
-#include "src/ast.h"
+#include "src/ast/ast.h"
 #include "src/bit-vector.h"
-#include "src/v8.h"
 #include "src/zone-containers.h"
 
 namespace v8 {
@@ -27,7 +26,7 @@
       if (list_[i].first == loop) return list_[i].second;
     }
     UNREACHABLE();  // should never ask for loops that aren't here!
-    return NULL;
+    return nullptr;
   }
 
   int GetAssignmentCountForTesting(Scope* scope, Variable* var);
@@ -46,7 +45,7 @@
 
   LoopAssignmentAnalysis* Analyze();
 
-#define DECLARE_VISIT(type) void Visit##type(type* node) OVERRIDE;
+#define DECLARE_VISIT(type) void Visit##type(type* node) override;
   AST_NODE_LIST(DECLARE_VISIT)
 #undef DECLARE_VISIT
 
@@ -54,6 +53,7 @@
 
  private:
   CompilationInfo* info_;
+  Zone* zone_;
   ZoneDeque<BitVector*> loop_stack_;
   LoopAssignmentAnalysis* result_;
 
@@ -63,7 +63,7 @@
   void Exit(IterationStatement* loop);
 
   void VisitIfNotNull(AstNode* node) {
-    if (node != NULL) Visit(node);
+    if (node != nullptr) Visit(node);
   }
 
   void AnalyzeAssignment(Variable* var);
@@ -71,8 +71,8 @@
   DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
   DISALLOW_COPY_AND_ASSIGN(AstLoopAssignmentAnalyzer);
 };
-}
-}
-}  // namespace v8::internal::compiler
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
 
 #endif  // V8_COMPILER_AST_LOOP_ASSIGNMENT_ANALYZER_H_
diff --git a/src/compiler/basic-block-instrumentor.cc b/src/compiler/basic-block-instrumentor.cc
index d7d3ade..a966a5b 100644
--- a/src/compiler/basic-block-instrumentor.cc
+++ b/src/compiler/basic-block-instrumentor.cc
@@ -10,6 +10,7 @@
 #include "src/compiler/common-operator.h"
 #include "src/compiler/graph.h"
 #include "src/compiler/machine-operator.h"
+#include "src/compiler/node.h"
 #include "src/compiler/operator-properties.h"
 #include "src/compiler/schedule.h"
 
@@ -54,8 +55,7 @@
   BasicBlockProfiler::Data* data =
       info->isolate()->GetOrCreateBasicBlockProfiler()->NewData(n_blocks);
   // Set the function name.
-  if (!info->shared_info().is_null() &&
-      info->shared_info()->name()->IsString()) {
+  if (info->has_shared_info() && info->shared_info()->name()->IsString()) {
     std::ostringstream os;
     String::cast(info->shared_info()->name())->PrintUC16(os);
     data->SetFunctionName(&os);
@@ -81,11 +81,13 @@
     // Construct increment operation.
     Node* base = graph->NewNode(
         PointerConstant(&common, data->GetCounterAddress(block_number)));
-    Node* load = graph->NewNode(machine.Load(kMachUint32), base, zero);
+    Node* load = graph->NewNode(machine.Load(MachineType::Uint32()), base, zero,
+                                graph->start(), graph->start());
     Node* inc = graph->NewNode(machine.Int32Add(), load, one);
-    Node* store = graph->NewNode(
-        machine.Store(StoreRepresentation(kMachUint32, kNoWriteBarrier)), base,
-        zero, inc);
+    Node* store =
+        graph->NewNode(machine.Store(StoreRepresentation(
+                           MachineRepresentation::kWord32, kNoWriteBarrier)),
+                       base, zero, inc, graph->start(), graph->start());
     // Insert the new nodes.
     static const int kArraySize = 6;
     Node* to_insert[kArraySize] = {zero, one, base, load, inc, store};
diff --git a/src/compiler/basic-block-instrumentor.h b/src/compiler/basic-block-instrumentor.h
index 7edac0d..32dd82a 100644
--- a/src/compiler/basic-block-instrumentor.h
+++ b/src/compiler/basic-block-instrumentor.h
@@ -5,8 +5,7 @@
 #ifndef V8_COMPILER_BASIC_BLOCK_INSTRUMENTOR_H_
 #define V8_COMPILER_BASIC_BLOCK_INSTRUMENTOR_H_
 
-#include "src/v8.h"
-
+#include "src/allocation.h"
 #include "src/basic-block-profiler.h"
 
 namespace v8 {
diff --git a/src/compiler/branch-elimination.cc b/src/compiler/branch-elimination.cc
new file mode 100644
index 0000000..bc56e73
--- /dev/null
+++ b/src/compiler/branch-elimination.cc
@@ -0,0 +1,269 @@
+// Copyright 2015 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/branch-elimination.h"
+
+#include "src/compiler/js-graph.h"
+#include "src/compiler/node-properties.h"
+#include "src/compiler/simplified-operator.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+BranchElimination::BranchElimination(Editor* editor, JSGraph* js_graph,
+                                     Zone* zone)
+    : AdvancedReducer(editor),
+      node_conditions_(zone, js_graph->graph()->NodeCount()),
+      zone_(zone),
+      dead_(js_graph->graph()->NewNode(js_graph->common()->Dead())) {}
+
+
+BranchElimination::~BranchElimination() {}
+
+
+Reduction BranchElimination::Reduce(Node* node) {
+  switch (node->opcode()) {
+    case IrOpcode::kDead:
+      return NoChange();
+    case IrOpcode::kMerge:
+      return ReduceMerge(node);
+    case IrOpcode::kLoop:
+      return ReduceLoop(node);
+    case IrOpcode::kBranch:
+      return ReduceBranch(node);
+    case IrOpcode::kIfFalse:
+      return ReduceIf(node, false);
+    case IrOpcode::kIfTrue:
+      return ReduceIf(node, true);
+    case IrOpcode::kStart:
+      return ReduceStart(node);
+    default:
+      if (node->op()->ControlOutputCount() > 0) {
+        return ReduceOtherControl(node);
+      }
+      break;
+  }
+  return NoChange();
+}
+
+
+Reduction BranchElimination::ReduceBranch(Node* node) {
+  Node* condition = node->InputAt(0);
+  Node* control_input = NodeProperties::GetControlInput(node, 0);
+  const ControlPathConditions* from_input = node_conditions_.Get(control_input);
+  if (from_input != nullptr) {
+    Maybe<bool> condition_value = from_input->LookupCondition(condition);
+    // If we know the condition we can discard the branch.
+    if (condition_value.IsJust()) {
+      bool known_value = condition_value.FromJust();
+      for (Node* const use : node->uses()) {
+        switch (use->opcode()) {
+          case IrOpcode::kIfTrue:
+            Replace(use, known_value ? control_input : dead());
+            break;
+          case IrOpcode::kIfFalse:
+            Replace(use, known_value ? dead() : control_input);
+            break;
+          default:
+            UNREACHABLE();
+        }
+      }
+      return Replace(dead());
+    }
+  }
+  return TakeConditionsFromFirstControl(node);
+}
+
+
+Reduction BranchElimination::ReduceIf(Node* node, bool is_true_branch) {
+  // Add the condition to the list arriving from the input branch.
+  Node* branch = NodeProperties::GetControlInput(node, 0);
+  const ControlPathConditions* from_branch = node_conditions_.Get(branch);
+  // If we do not know anything about the predecessor, do not propagate just
+  // yet because we will have to recompute anyway once we compute the
+  // predecessor.
+  if (from_branch == nullptr) {
+    DCHECK(node_conditions_.Get(node) == nullptr);
+    return NoChange();
+  }
+  Node* condition = branch->InputAt(0);
+  return UpdateConditions(
+      node, from_branch->AddCondition(zone_, condition, is_true_branch));
+}
+
+
+Reduction BranchElimination::ReduceLoop(Node* node) {
+  // Here we rely on having only reducible loops:
+  // The loop entry edge always dominates the header, so we can just use
+  // the information from the loop entry edge.
+  return TakeConditionsFromFirstControl(node);
+}
+
+
+Reduction BranchElimination::ReduceMerge(Node* node) {
+  // Shortcut for the case when we do not know anything about some
+  // input.
+  for (int i = 0; i < node->InputCount(); i++) {
+    if (node_conditions_.Get(node->InputAt(i)) == nullptr) {
+      DCHECK(node_conditions_.Get(node) == nullptr);
+      return NoChange();
+    }
+  }
+
+  const ControlPathConditions* first = node_conditions_.Get(node->InputAt(0));
+  // Make a copy of the first input's conditions and merge with the conditions
+  // from other inputs.
+  ControlPathConditions* conditions =
+      new (zone_->New(sizeof(ControlPathConditions)))
+          ControlPathConditions(*first);
+  for (int i = 1; i < node->InputCount(); i++) {
+    conditions->Merge(*(node_conditions_.Get(node->InputAt(i))));
+  }
+
+  return UpdateConditions(node, conditions);
+}
+
+
+Reduction BranchElimination::ReduceStart(Node* node) {
+  return UpdateConditions(node, ControlPathConditions::Empty(zone_));
+}
+
+
+const BranchElimination::ControlPathConditions*
+BranchElimination::PathConditionsForControlNodes::Get(Node* node) {
+  if (static_cast<size_t>(node->id()) < info_for_node_.size()) {
+    return info_for_node_[node->id()];
+  }
+  return nullptr;
+}
+
+
+void BranchElimination::PathConditionsForControlNodes::Set(
+    Node* node, const ControlPathConditions* conditions) {
+  size_t index = static_cast<size_t>(node->id());
+  if (index >= info_for_node_.size()) {
+    info_for_node_.resize(index + 1, nullptr);
+  }
+  info_for_node_[index] = conditions;
+}
+
+
+Reduction BranchElimination::ReduceOtherControl(Node* node) {
+  DCHECK_EQ(1, node->op()->ControlInputCount());
+  return TakeConditionsFromFirstControl(node);
+}
+
+
+Reduction BranchElimination::TakeConditionsFromFirstControl(Node* node) {
+  // We just propagate the information from the control input (ideally,
+  // we would only revisit control uses if there is change).
+  const ControlPathConditions* from_input =
+      node_conditions_.Get(NodeProperties::GetControlInput(node, 0));
+  return UpdateConditions(node, from_input);
+}
+
+
+Reduction BranchElimination::UpdateConditions(
+    Node* node, const ControlPathConditions* conditions) {
+  const ControlPathConditions* original = node_conditions_.Get(node);
+  // Only signal that the node has Changed if the condition information has
+  // changed.
+  if (conditions != original) {
+    if (original == nullptr || *conditions != *original) {
+      node_conditions_.Set(node, conditions);
+      return Changed(node);
+    }
+  }
+  return NoChange();
+}
+
+
+// static
+const BranchElimination::ControlPathConditions*
+BranchElimination::ControlPathConditions::Empty(Zone* zone) {
+  return new (zone->New(sizeof(ControlPathConditions)))
+      ControlPathConditions(nullptr, 0);
+}
+
+
+void BranchElimination::ControlPathConditions::Merge(
+    const ControlPathConditions& other) {
+  // Change the current condition list to a longest common tail
+  // of this condition list and the other list. (The common tail
+  // should correspond to the list from the common dominator.)
+
+  // First, we throw away the prefix of the longer list, so that
+  // we have lists of the same length.
+  size_t other_size = other.condition_count_;
+  BranchCondition* other_condition = other.head_;
+  while (other_size > condition_count_) {
+    other_condition = other_condition->next;
+    other_size--;
+  }
+  while (condition_count_ > other_size) {
+    head_ = head_->next;
+    condition_count_--;
+  }
+
+  // Then we go through both lists in lock-step until we find
+  // the common tail.
+  while (head_ != other_condition) {
+    DCHECK(condition_count_ > 0);
+    condition_count_--;
+    other_condition = other_condition->next;
+    head_ = head_->next;
+  }
+}
+
+
+const BranchElimination::ControlPathConditions*
+BranchElimination::ControlPathConditions::AddCondition(Zone* zone,
+                                                       Node* condition,
+                                                       bool is_true) const {
+  DCHECK(LookupCondition(condition).IsNothing());
+
+  BranchCondition* new_head = new (zone->New(sizeof(BranchCondition)))
+      BranchCondition(condition, is_true, head_);
+
+  ControlPathConditions* conditions =
+      new (zone->New(sizeof(ControlPathConditions)))
+          ControlPathConditions(new_head, condition_count_ + 1);
+  return conditions;
+}
+
+
+Maybe<bool> BranchElimination::ControlPathConditions::LookupCondition(
+    Node* condition) const {
+  for (BranchCondition* current = head_; current != nullptr;
+       current = current->next) {
+    if (current->condition == condition) {
+      return Just<bool>(current->is_true);
+    }
+  }
+  return Nothing<bool>();
+}
+
+
+bool BranchElimination::ControlPathConditions::operator==(
+    const ControlPathConditions& other) const {
+  if (condition_count_ != other.condition_count_) return false;
+  BranchCondition* this_condition = head_;
+  BranchCondition* other_condition = other.head_;
+  while (true) {
+    if (this_condition == other_condition) return true;
+    if (this_condition->condition != other_condition->condition ||
+        this_condition->is_true != other_condition->is_true) {
+      return false;
+    }
+    this_condition = this_condition->next;
+    other_condition = other_condition->next;
+  }
+  UNREACHABLE();
+  return false;
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/branch-elimination.h b/src/compiler/branch-elimination.h
new file mode 100644
index 0000000..a7ac926
--- /dev/null
+++ b/src/compiler/branch-elimination.h
@@ -0,0 +1,97 @@
+// Copyright 2015 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.
+
+#ifndef V8_COMPILER_BRANCH_CONDITION_ELIMINATION_H_
+#define V8_COMPILER_BRANCH_CONDITION_ELIMINATION_H_
+
+#include "src/compiler/graph-reducer.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+class JSGraph;
+
+
+class BranchElimination final : public AdvancedReducer {
+ public:
+  BranchElimination(Editor* editor, JSGraph* js_graph, Zone* zone);
+  ~BranchElimination() final;
+
+  Reduction Reduce(Node* node) final;
+
+ private:
+  struct BranchCondition {
+    Node* condition;
+    bool is_true;
+    BranchCondition* next;
+
+    BranchCondition(Node* condition, bool is_true, BranchCondition* next)
+        : condition(condition), is_true(is_true), next(next) {}
+  };
+
+  // Class for tracking information about branch conditions.
+  // At the moment it is a linked list of conditions and their values
+  // (true or false).
+  class ControlPathConditions {
+   public:
+    Maybe<bool> LookupCondition(Node* condition) const;
+
+    const ControlPathConditions* AddCondition(Zone* zone, Node* condition,
+                                              bool is_true) const;
+    static const ControlPathConditions* Empty(Zone* zone);
+    void Merge(const ControlPathConditions& other);
+
+    bool operator==(const ControlPathConditions& other) const;
+    bool operator!=(const ControlPathConditions& other) const {
+      return !(*this == other);
+    }
+
+   private:
+    ControlPathConditions(BranchCondition* head, size_t condition_count)
+        : head_(head), condition_count_(condition_count) {}
+
+    BranchCondition* head_;
+    // We keep track of the list length so that we can find the longest
+    // common tail easily.
+    size_t condition_count_;
+  };
+
+  // Maps each control node to the condition information known about the node.
+  // If the information is nullptr, then we have not calculated the information
+  // yet.
+  class PathConditionsForControlNodes {
+   public:
+    PathConditionsForControlNodes(Zone* zone, size_t size_hint)
+        : info_for_node_(size_hint, nullptr, zone) {}
+    const ControlPathConditions* Get(Node* node);
+    void Set(Node* node, const ControlPathConditions* conditions);
+
+   private:
+    ZoneVector<const ControlPathConditions*> info_for_node_;
+  };
+
+  Reduction ReduceBranch(Node* node);
+  Reduction ReduceIf(Node* node, bool is_true_branch);
+  Reduction ReduceLoop(Node* node);
+  Reduction ReduceMerge(Node* node);
+  Reduction ReduceStart(Node* node);
+  Reduction ReduceOtherControl(Node* node);
+
+  Reduction TakeConditionsFromFirstControl(Node* node);
+  Reduction UpdateConditions(Node* node,
+                             const ControlPathConditions* conditions);
+
+  Node* dead() const { return dead_; }
+
+  PathConditionsForControlNodes node_conditions_;
+  Zone* zone_;
+  Node* dead_;
+};
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_BRANCH_CONDITION_ELIMINATION_H_
diff --git a/src/compiler/bytecode-branch-analysis.cc b/src/compiler/bytecode-branch-analysis.cc
new file mode 100644
index 0000000..27699a1
--- /dev/null
+++ b/src/compiler/bytecode-branch-analysis.cc
@@ -0,0 +1,125 @@
+// Copyright 2015 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/bytecode-branch-analysis.h"
+
+#include "src/interpreter/bytecode-array-iterator.h"
+#include "src/objects-inl.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+// The class contains all of the sites that contain
+// branches to a particular target (bytecode offset).
+class BytecodeBranchInfo final : public ZoneObject {
+ public:
+  explicit BytecodeBranchInfo(Zone* zone)
+      : back_edge_offsets_(zone), fore_edge_offsets_(zone) {}
+
+  void AddBranch(int source_offset, int target_offset);
+
+  // The offsets of bytecodes that refer to this bytecode as
+  // a back-edge predecessor.
+  const ZoneVector<int>* back_edge_offsets() { return &back_edge_offsets_; }
+
+  // The offsets of bytecodes that refer to this bytecode as
+  // a forwards-edge predecessor.
+  const ZoneVector<int>* fore_edge_offsets() { return &fore_edge_offsets_; }
+
+ private:
+  ZoneVector<int> back_edge_offsets_;
+  ZoneVector<int> fore_edge_offsets_;
+
+  DISALLOW_COPY_AND_ASSIGN(BytecodeBranchInfo);
+};
+
+
+void BytecodeBranchInfo::AddBranch(int source_offset, int target_offset) {
+  if (source_offset < target_offset) {
+    fore_edge_offsets_.push_back(source_offset);
+  } else {
+    back_edge_offsets_.push_back(source_offset);
+  }
+}
+
+
+BytecodeBranchAnalysis::BytecodeBranchAnalysis(
+    Handle<BytecodeArray> bytecode_array, Zone* zone)
+    : branch_infos_(zone),
+      bytecode_array_(bytecode_array),
+      reachable_(bytecode_array->length(), zone),
+      zone_(zone) {}
+
+
+void BytecodeBranchAnalysis::Analyze() {
+  interpreter::BytecodeArrayIterator iterator(bytecode_array());
+  bool reachable = true;
+  while (!iterator.done()) {
+    interpreter::Bytecode bytecode = iterator.current_bytecode();
+    int current_offset = iterator.current_offset();
+    // All bytecode basic blocks are generated to be forward reachable
+    // and may also be backward reachable. Hence if there's a forward
+    // branch targetting here the code becomes reachable.
+    reachable = reachable || forward_branches_target(current_offset);
+    if (reachable) {
+      reachable_.Add(current_offset);
+      if (interpreter::Bytecodes::IsConditionalJump(bytecode)) {
+        // Only the branch is recorded, the forward path falls through
+        // and is handled as normal bytecode data flow.
+        AddBranch(current_offset, iterator.GetJumpTargetOffset());
+      } else if (interpreter::Bytecodes::IsJump(bytecode)) {
+        // Unless the branch targets the next bytecode it's not
+        // reachable. If it targets the next bytecode the check at the
+        // start of the loop will set the reachable flag.
+        AddBranch(current_offset, iterator.GetJumpTargetOffset());
+        reachable = false;
+      } else if (interpreter::Bytecodes::IsJumpOrReturn(bytecode)) {
+        DCHECK_EQ(bytecode, interpreter::Bytecode::kReturn);
+        reachable = false;
+      }
+    }
+    iterator.Advance();
+  }
+}
+
+
+const ZoneVector<int>* BytecodeBranchAnalysis::BackwardBranchesTargetting(
+    int offset) const {
+  auto iterator = branch_infos_.find(offset);
+  if (branch_infos_.end() != iterator) {
+    return iterator->second->back_edge_offsets();
+  } else {
+    return nullptr;
+  }
+}
+
+
+const ZoneVector<int>* BytecodeBranchAnalysis::ForwardBranchesTargetting(
+    int offset) const {
+  auto iterator = branch_infos_.find(offset);
+  if (branch_infos_.end() != iterator) {
+    return iterator->second->fore_edge_offsets();
+  } else {
+    return nullptr;
+  }
+}
+
+
+void BytecodeBranchAnalysis::AddBranch(int source_offset, int target_offset) {
+  BytecodeBranchInfo* branch_info = nullptr;
+  auto iterator = branch_infos_.find(target_offset);
+  if (branch_infos_.end() == iterator) {
+    branch_info = new (zone()) BytecodeBranchInfo(zone());
+    branch_infos_.insert(std::make_pair(target_offset, branch_info));
+  } else {
+    branch_info = iterator->second;
+  }
+  branch_info->AddBranch(source_offset, target_offset);
+}
+
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/bytecode-branch-analysis.h b/src/compiler/bytecode-branch-analysis.h
new file mode 100644
index 0000000..0ef33b6
--- /dev/null
+++ b/src/compiler/bytecode-branch-analysis.h
@@ -0,0 +1,79 @@
+// Copyright 2015 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.
+
+#ifndef V8_COMPILER_BYTECODE_BRANCH_ANALYSIS_H_
+#define V8_COMPILER_BYTECODE_BRANCH_ANALYSIS_H_
+
+#include "src/bit-vector.h"
+#include "src/handles.h"
+#include "src/zone-containers.h"
+
+namespace v8 {
+namespace internal {
+
+class BytecodeArray;
+
+namespace compiler {
+
+class BytecodeBranchInfo;
+
+// A class for identifying the branch targets and their branch sites
+// within a bytecode array and also identifying which bytecodes are
+// reachable. This information can be used to construct the local
+// control flow logic for high-level IR graphs built from bytecode.
+//
+// NB This class relies on the only backwards branches in bytecode
+// being jumps back to loop headers.
+class BytecodeBranchAnalysis BASE_EMBEDDED {
+ public:
+  BytecodeBranchAnalysis(Handle<BytecodeArray> bytecode_array, Zone* zone);
+
+  // Analyze the bytecodes to find the branch sites and their
+  // targets. No other methods in this class return valid information
+  // until this has been called.
+  void Analyze();
+
+  // Offsets of bytecodes having a backward branch to the bytecode at |offset|.
+  const ZoneVector<int>* BackwardBranchesTargetting(int offset) const;
+
+  // Offsets of bytecodes having a forward branch to the bytecode at |offset|.
+  const ZoneVector<int>* ForwardBranchesTargetting(int offset) const;
+
+  // Returns true if the bytecode at |offset| is reachable.
+  bool is_reachable(int offset) const { return reachable_.Contains(offset); }
+
+  // Returns true if there are any forward branches to the bytecode at
+  // |offset|.
+  bool forward_branches_target(int offset) const {
+    const ZoneVector<int>* sites = ForwardBranchesTargetting(offset);
+    return sites != nullptr && sites->size() > 0;
+  }
+
+  // Returns true if there are any backward branches to the bytecode
+  // at |offset|.
+  bool backward_branches_target(int offset) const {
+    const ZoneVector<int>* sites = BackwardBranchesTargetting(offset);
+    return sites != nullptr && sites->size() > 0;
+  }
+
+ private:
+  void AddBranch(int origin_offset, int target_offset);
+
+  Zone* zone() const { return zone_; }
+  Handle<BytecodeArray> bytecode_array() const { return bytecode_array_; }
+
+  ZoneMap<int, BytecodeBranchInfo*> branch_infos_;
+  Handle<BytecodeArray> bytecode_array_;
+  BitVector reachable_;
+  Zone* zone_;
+
+  DISALLOW_COPY_AND_ASSIGN(BytecodeBranchAnalysis);
+};
+
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_BYTECODE_BRANCH_ANALYSIS_H_
diff --git a/src/compiler/bytecode-graph-builder.cc b/src/compiler/bytecode-graph-builder.cc
new file mode 100644
index 0000000..cf0b6ab
--- /dev/null
+++ b/src/compiler/bytecode-graph-builder.cc
@@ -0,0 +1,2040 @@
+// Copyright 2015 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/bytecode-graph-builder.h"
+
+#include "src/compiler/bytecode-branch-analysis.h"
+#include "src/compiler/linkage.h"
+#include "src/compiler/operator-properties.h"
+#include "src/interpreter/bytecodes.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+// Helper for generating frame states for before and after a bytecode.
+class BytecodeGraphBuilder::FrameStateBeforeAndAfter {
+ public:
+  FrameStateBeforeAndAfter(BytecodeGraphBuilder* builder,
+                           const interpreter::BytecodeArrayIterator& iterator)
+      : builder_(builder),
+        id_after_(BailoutId::None()),
+        added_to_node_(false),
+        output_poke_offset_(0),
+        output_poke_count_(0) {
+    BailoutId id_before(iterator.current_offset());
+    frame_state_before_ = builder_->environment()->Checkpoint(
+        id_before, OutputFrameStateCombine::Ignore());
+    id_after_ = BailoutId(id_before.ToInt() + iterator.current_bytecode_size());
+  }
+
+  ~FrameStateBeforeAndAfter() {
+    DCHECK(added_to_node_);
+    DCHECK(builder_->environment()->StateValuesAreUpToDate(output_poke_offset_,
+                                                           output_poke_count_));
+  }
+
+ private:
+  friend class Environment;
+
+  void AddToNode(Node* node, OutputFrameStateCombine combine) {
+    DCHECK(!added_to_node_);
+    int count = OperatorProperties::GetFrameStateInputCount(node->op());
+    DCHECK_LE(count, 2);
+    if (count >= 1) {
+      // Add the frame state for after the operation.
+      DCHECK_EQ(IrOpcode::kDead,
+                NodeProperties::GetFrameStateInput(node, 0)->opcode());
+      Node* frame_state_after =
+          builder_->environment()->Checkpoint(id_after_, combine);
+      NodeProperties::ReplaceFrameStateInput(node, 0, frame_state_after);
+    }
+
+    if (count >= 2) {
+      // Add the frame state for before the operation.
+      DCHECK_EQ(IrOpcode::kDead,
+                NodeProperties::GetFrameStateInput(node, 1)->opcode());
+      NodeProperties::ReplaceFrameStateInput(node, 1, frame_state_before_);
+    }
+
+    if (!combine.IsOutputIgnored()) {
+      output_poke_offset_ = static_cast<int>(combine.GetOffsetToPokeAt());
+      output_poke_count_ = node->op()->ValueOutputCount();
+    }
+    added_to_node_ = true;
+  }
+
+  BytecodeGraphBuilder* builder_;
+  Node* frame_state_before_;
+  BailoutId id_after_;
+
+  bool added_to_node_;
+  int output_poke_offset_;
+  int output_poke_count_;
+};
+
+
+// Issues:
+// - Scopes - intimately tied to AST. Need to eval what is needed.
+// - Need to resolve closure parameter treatment.
+BytecodeGraphBuilder::Environment::Environment(BytecodeGraphBuilder* builder,
+                                               int register_count,
+                                               int parameter_count,
+                                               Node* control_dependency,
+                                               Node* context)
+    : builder_(builder),
+      register_count_(register_count),
+      parameter_count_(parameter_count),
+      context_(context),
+      control_dependency_(control_dependency),
+      effect_dependency_(control_dependency),
+      values_(builder->local_zone()),
+      parameters_state_values_(nullptr),
+      registers_state_values_(nullptr),
+      accumulator_state_values_(nullptr) {
+  // The layout of values_ is:
+  //
+  // [receiver] [parameters] [registers] [accumulator]
+  //
+  // parameter[0] is the receiver (this), parameters 1..N are the
+  // parameters supplied to the method (arg0..argN-1). The accumulator
+  // is stored separately.
+
+  // Parameters including the receiver
+  for (int i = 0; i < parameter_count; i++) {
+    const char* debug_name = (i == 0) ? "%this" : nullptr;
+    const Operator* op = common()->Parameter(i, debug_name);
+    Node* parameter = builder->graph()->NewNode(op, graph()->start());
+    values()->push_back(parameter);
+  }
+
+  // Registers
+  register_base_ = static_cast<int>(values()->size());
+  Node* undefined_constant = builder->jsgraph()->UndefinedConstant();
+  values()->insert(values()->end(), register_count, undefined_constant);
+
+  // Accumulator
+  accumulator_base_ = static_cast<int>(values()->size());
+  values()->push_back(undefined_constant);
+}
+
+
+BytecodeGraphBuilder::Environment::Environment(
+    const BytecodeGraphBuilder::Environment* other)
+    : builder_(other->builder_),
+      register_count_(other->register_count_),
+      parameter_count_(other->parameter_count_),
+      context_(other->context_),
+      control_dependency_(other->control_dependency_),
+      effect_dependency_(other->effect_dependency_),
+      values_(other->zone()),
+      parameters_state_values_(nullptr),
+      registers_state_values_(nullptr),
+      accumulator_state_values_(nullptr),
+      register_base_(other->register_base_),
+      accumulator_base_(other->accumulator_base_) {
+  values_ = other->values_;
+}
+
+
+int BytecodeGraphBuilder::Environment::RegisterToValuesIndex(
+    interpreter::Register the_register) const {
+  if (the_register.is_parameter()) {
+    return the_register.ToParameterIndex(parameter_count());
+  } else {
+    return the_register.index() + register_base();
+  }
+}
+
+
+Node* BytecodeGraphBuilder::Environment::LookupAccumulator() const {
+  return values()->at(accumulator_base_);
+}
+
+
+Node* BytecodeGraphBuilder::Environment::LookupRegister(
+    interpreter::Register the_register) const {
+  if (the_register.is_function_context()) {
+    return builder()->GetFunctionContext();
+  } else if (the_register.is_function_closure()) {
+    return builder()->GetFunctionClosure();
+  } else if (the_register.is_new_target()) {
+    return builder()->GetNewTarget();
+  } else {
+    int values_index = RegisterToValuesIndex(the_register);
+    return values()->at(values_index);
+  }
+}
+
+
+void BytecodeGraphBuilder::Environment::ExchangeRegisters(
+    interpreter::Register reg0, interpreter::Register reg1) {
+  int reg0_index = RegisterToValuesIndex(reg0);
+  int reg1_index = RegisterToValuesIndex(reg1);
+  Node* saved_reg0_value = values()->at(reg0_index);
+  values()->at(reg0_index) = values()->at(reg1_index);
+  values()->at(reg1_index) = saved_reg0_value;
+}
+
+
+void BytecodeGraphBuilder::Environment::BindAccumulator(
+    Node* node, FrameStateBeforeAndAfter* states) {
+  if (states) {
+    states->AddToNode(node, OutputFrameStateCombine::PokeAt(0));
+  }
+  values()->at(accumulator_base_) = node;
+}
+
+
+void BytecodeGraphBuilder::Environment::BindRegister(
+    interpreter::Register the_register, Node* node,
+    FrameStateBeforeAndAfter* states) {
+  int values_index = RegisterToValuesIndex(the_register);
+  if (states) {
+    states->AddToNode(node, OutputFrameStateCombine::PokeAt(accumulator_base_ -
+                                                            values_index));
+  }
+  values()->at(values_index) = node;
+}
+
+
+void BytecodeGraphBuilder::Environment::BindRegistersToProjections(
+    interpreter::Register first_reg, Node* node,
+    FrameStateBeforeAndAfter* states) {
+  int values_index = RegisterToValuesIndex(first_reg);
+  if (states) {
+    states->AddToNode(node, OutputFrameStateCombine::PokeAt(accumulator_base_ -
+                                                            values_index));
+  }
+  for (int i = 0; i < node->op()->ValueOutputCount(); i++) {
+    values()->at(values_index + i) =
+        builder()->NewNode(common()->Projection(i), node);
+  }
+}
+
+
+void BytecodeGraphBuilder::Environment::RecordAfterState(
+    Node* node, FrameStateBeforeAndAfter* states) {
+  states->AddToNode(node, OutputFrameStateCombine::Ignore());
+}
+
+
+bool BytecodeGraphBuilder::Environment::IsMarkedAsUnreachable() const {
+  return GetControlDependency()->opcode() == IrOpcode::kDead;
+}
+
+
+void BytecodeGraphBuilder::Environment::MarkAsUnreachable() {
+  UpdateControlDependency(builder()->jsgraph()->Dead());
+}
+
+
+BytecodeGraphBuilder::Environment*
+BytecodeGraphBuilder::Environment::CopyForLoop() {
+  PrepareForLoop();
+  return new (zone()) Environment(this);
+}
+
+
+BytecodeGraphBuilder::Environment*
+BytecodeGraphBuilder::Environment::CopyForConditional() const {
+  return new (zone()) Environment(this);
+}
+
+
+void BytecodeGraphBuilder::Environment::Merge(
+    BytecodeGraphBuilder::Environment* other) {
+  // Nothing to do if the other environment is dead.
+  if (other->IsMarkedAsUnreachable()) {
+    return;
+  }
+
+  // Create a merge of the control dependencies of both environments and update
+  // the current environment's control dependency accordingly.
+  Node* control = builder()->MergeControl(GetControlDependency(),
+                                          other->GetControlDependency());
+  UpdateControlDependency(control);
+
+  // Create a merge of the effect dependencies of both environments and update
+  // the current environment's effect dependency accordingly.
+  Node* effect = builder()->MergeEffect(GetEffectDependency(),
+                                        other->GetEffectDependency(), control);
+  UpdateEffectDependency(effect);
+
+  // Introduce Phi nodes for values that have differing input at merge points,
+  // potentially extending an existing Phi node if possible.
+  context_ = builder()->MergeValue(context_, other->context_, control);
+  for (size_t i = 0; i < values_.size(); i++) {
+    values_[i] = builder()->MergeValue(values_[i], other->values_[i], control);
+  }
+}
+
+
+void BytecodeGraphBuilder::Environment::PrepareForLoop() {
+  // Create a control node for the loop header.
+  Node* control = builder()->NewLoop();
+
+  // Create a Phi for external effects.
+  Node* effect = builder()->NewEffectPhi(1, GetEffectDependency(), control);
+  UpdateEffectDependency(effect);
+
+  // Assume everything in the loop is updated.
+  context_ = builder()->NewPhi(1, context_, control);
+  int size = static_cast<int>(values()->size());
+  for (int i = 0; i < size; i++) {
+    values()->at(i) = builder()->NewPhi(1, values()->at(i), control);
+  }
+
+  // Connect to the loop end.
+  Node* terminate = builder()->graph()->NewNode(
+      builder()->common()->Terminate(), effect, control);
+  builder()->exit_controls_.push_back(terminate);
+}
+
+
+bool BytecodeGraphBuilder::Environment::StateValuesRequireUpdate(
+    Node** state_values, int offset, int count) {
+  if (!builder()->info()->is_deoptimization_enabled()) {
+    return false;
+  }
+  if (*state_values == nullptr) {
+    return true;
+  }
+  DCHECK_EQ((*state_values)->InputCount(), count);
+  DCHECK_LE(static_cast<size_t>(offset + count), values()->size());
+  Node** env_values = (count == 0) ? nullptr : &values()->at(offset);
+  for (int i = 0; i < count; i++) {
+    if ((*state_values)->InputAt(i) != env_values[i]) {
+      return true;
+    }
+  }
+  return false;
+}
+
+
+void BytecodeGraphBuilder::Environment::UpdateStateValues(Node** state_values,
+                                                          int offset,
+                                                          int count) {
+  if (StateValuesRequireUpdate(state_values, offset, count)) {
+    const Operator* op = common()->StateValues(count);
+    (*state_values) = graph()->NewNode(op, count, &values()->at(offset));
+  }
+}
+
+
+Node* BytecodeGraphBuilder::Environment::Checkpoint(
+    BailoutId bailout_id, OutputFrameStateCombine combine) {
+  if (!builder()->info()->is_deoptimization_enabled()) {
+    return builder()->jsgraph()->EmptyFrameState();
+  }
+
+  // TODO(rmcilroy): Consider using StateValuesCache for some state values.
+  UpdateStateValues(&parameters_state_values_, 0, parameter_count());
+  UpdateStateValues(&registers_state_values_, register_base(),
+                    register_count());
+  UpdateStateValues(&accumulator_state_values_, accumulator_base(), 1);
+
+  const Operator* op = common()->FrameState(
+      bailout_id, combine, builder()->frame_state_function_info());
+  Node* result = graph()->NewNode(
+      op, parameters_state_values_, registers_state_values_,
+      accumulator_state_values_, Context(), builder()->GetFunctionClosure(),
+      builder()->graph()->start());
+
+  return result;
+}
+
+
+bool BytecodeGraphBuilder::Environment::StateValuesAreUpToDate(
+    Node** state_values, int offset, int count, int output_poke_start,
+    int output_poke_end) {
+  DCHECK_LE(static_cast<size_t>(offset + count), values()->size());
+  for (int i = 0; i < count; i++, offset++) {
+    if (offset < output_poke_start || offset >= output_poke_end) {
+      if ((*state_values)->InputAt(i) != values()->at(offset)) {
+        return false;
+      }
+    }
+  }
+  return true;
+}
+
+
+bool BytecodeGraphBuilder::Environment::StateValuesAreUpToDate(
+    int output_poke_offset, int output_poke_count) {
+  // Poke offset is relative to the top of the stack (i.e., the accumulator).
+  int output_poke_start = accumulator_base() - output_poke_offset;
+  int output_poke_end = output_poke_start + output_poke_count;
+  return StateValuesAreUpToDate(&parameters_state_values_, 0, parameter_count(),
+                                output_poke_start, output_poke_end) &&
+         StateValuesAreUpToDate(&registers_state_values_, register_base(),
+                                register_count(), output_poke_start,
+                                output_poke_end) &&
+         StateValuesAreUpToDate(&accumulator_state_values_, accumulator_base(),
+                                1, output_poke_start, output_poke_end);
+}
+
+
+BytecodeGraphBuilder::BytecodeGraphBuilder(Zone* local_zone,
+                                           CompilationInfo* compilation_info,
+                                           JSGraph* jsgraph)
+    : local_zone_(local_zone),
+      info_(compilation_info),
+      jsgraph_(jsgraph),
+      bytecode_array_(handle(info()->shared_info()->bytecode_array())),
+      frame_state_function_info_(common()->CreateFrameStateFunctionInfo(
+          FrameStateType::kInterpretedFunction,
+          bytecode_array()->parameter_count(),
+          bytecode_array()->register_count(), info()->shared_info(),
+          CALL_MAINTAINS_NATIVE_CONTEXT)),
+      merge_environments_(local_zone),
+      loop_header_environments_(local_zone),
+      input_buffer_size_(0),
+      input_buffer_(nullptr),
+      exit_controls_(local_zone) {}
+
+
+Node* BytecodeGraphBuilder::GetNewTarget() {
+  if (!new_target_.is_set()) {
+    int params = bytecode_array()->parameter_count();
+    int index = Linkage::GetJSCallNewTargetParamIndex(params);
+    const Operator* op = common()->Parameter(index, "%new.target");
+    Node* node = NewNode(op, graph()->start());
+    new_target_.set(node);
+  }
+  return new_target_.get();
+}
+
+
+Node* BytecodeGraphBuilder::GetFunctionContext() {
+  if (!function_context_.is_set()) {
+    int params = bytecode_array()->parameter_count();
+    int index = Linkage::GetJSCallContextParamIndex(params);
+    const Operator* op = common()->Parameter(index, "%context");
+    Node* node = NewNode(op, graph()->start());
+    function_context_.set(node);
+  }
+  return function_context_.get();
+}
+
+
+Node* BytecodeGraphBuilder::GetFunctionClosure() {
+  if (!function_closure_.is_set()) {
+    int index = Linkage::kJSCallClosureParamIndex;
+    const Operator* op = common()->Parameter(index, "%closure");
+    Node* node = NewNode(op, graph()->start());
+    function_closure_.set(node);
+  }
+  return function_closure_.get();
+}
+
+
+Node* BytecodeGraphBuilder::BuildLoadObjectField(Node* object, int offset) {
+  return NewNode(jsgraph()->machine()->Load(MachineType::AnyTagged()), object,
+                 jsgraph()->IntPtrConstant(offset - kHeapObjectTag));
+}
+
+
+Node* BytecodeGraphBuilder::BuildLoadImmutableObjectField(Node* object,
+                                                          int offset) {
+  return graph()->NewNode(jsgraph()->machine()->Load(MachineType::AnyTagged()),
+                          object,
+                          jsgraph()->IntPtrConstant(offset - kHeapObjectTag),
+                          graph()->start(), graph()->start());
+}
+
+
+Node* BytecodeGraphBuilder::BuildLoadNativeContextField(int index) {
+  const Operator* op =
+      javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true);
+  Node* native_context = NewNode(op, environment()->Context());
+  return NewNode(javascript()->LoadContext(0, index, true), native_context);
+}
+
+
+Node* BytecodeGraphBuilder::BuildLoadFeedbackVector() {
+  if (!feedback_vector_.is_set()) {
+    Node* closure = GetFunctionClosure();
+    Node* shared = BuildLoadImmutableObjectField(
+        closure, JSFunction::kSharedFunctionInfoOffset);
+    Node* vector = BuildLoadImmutableObjectField(
+        shared, SharedFunctionInfo::kFeedbackVectorOffset);
+    feedback_vector_.set(vector);
+  }
+  return feedback_vector_.get();
+}
+
+
+VectorSlotPair BytecodeGraphBuilder::CreateVectorSlotPair(int slot_id) {
+  Handle<TypeFeedbackVector> feedback_vector = info()->feedback_vector();
+  FeedbackVectorSlot slot;
+  if (slot_id >= TypeFeedbackVector::kReservedIndexCount) {
+    slot = feedback_vector->ToSlot(slot_id);
+  }
+  return VectorSlotPair(feedback_vector, slot);
+}
+
+
+bool BytecodeGraphBuilder::CreateGraph(bool stack_check) {
+  // Set up the basic structure of the graph. Outputs for {Start} are
+  // the formal parameters (including the receiver) plus context and
+  // closure.
+
+  // Set up the basic structure of the graph. Outputs for {Start} are the formal
+  // parameters (including the receiver) plus new target, number of arguments,
+  // context and closure.
+  int actual_parameter_count = bytecode_array()->parameter_count() + 4;
+  graph()->SetStart(graph()->NewNode(common()->Start(actual_parameter_count)));
+
+  Environment env(this, bytecode_array()->register_count(),
+                  bytecode_array()->parameter_count(), graph()->start(),
+                  GetFunctionContext());
+  set_environment(&env);
+
+  CreateGraphBody(stack_check);
+
+  // Finish the basic structure of the graph.
+  DCHECK_NE(0u, exit_controls_.size());
+  int const input_count = static_cast<int>(exit_controls_.size());
+  Node** const inputs = &exit_controls_.front();
+  Node* end = graph()->NewNode(common()->End(input_count), input_count, inputs);
+  graph()->SetEnd(end);
+
+  return true;
+}
+
+
+void BytecodeGraphBuilder::CreateGraphBody(bool stack_check) {
+  // TODO(oth): Review ast-graph-builder equivalent, i.e. arguments
+  // object setup, this function variable if used, tracing hooks.
+
+  if (stack_check) {
+    Node* node = NewNode(javascript()->StackCheck());
+    PrepareEntryFrameState(node);
+  }
+
+  VisitBytecodes();
+}
+
+
+void BytecodeGraphBuilder::VisitBytecodes() {
+  BytecodeBranchAnalysis analysis(bytecode_array(), local_zone());
+  analysis.Analyze();
+  set_branch_analysis(&analysis);
+  interpreter::BytecodeArrayIterator iterator(bytecode_array());
+  set_bytecode_iterator(&iterator);
+  while (!iterator.done()) {
+    int current_offset = iterator.current_offset();
+    if (analysis.is_reachable(current_offset)) {
+      MergeEnvironmentsOfForwardBranches(current_offset);
+      BuildLoopHeaderForBackwardBranches(current_offset);
+
+      switch (iterator.current_bytecode()) {
+#define BYTECODE_CASE(name, ...)       \
+  case interpreter::Bytecode::k##name: \
+    Visit##name(iterator);             \
+    break;
+        BYTECODE_LIST(BYTECODE_CASE)
+#undef BYTECODE_CODE
+      }
+    }
+    iterator.Advance();
+  }
+  set_branch_analysis(nullptr);
+  set_bytecode_iterator(nullptr);
+}
+
+
+void BytecodeGraphBuilder::VisitLdaZero(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  Node* node = jsgraph()->ZeroConstant();
+  environment()->BindAccumulator(node);
+}
+
+
+void BytecodeGraphBuilder::VisitLdaSmi8(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  Node* node = jsgraph()->Constant(iterator.GetImmediateOperand(0));
+  environment()->BindAccumulator(node);
+}
+
+
+void BytecodeGraphBuilder::VisitLdaConstantWide(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  Node* node = jsgraph()->Constant(iterator.GetConstantForIndexOperand(0));
+  environment()->BindAccumulator(node);
+}
+
+
+void BytecodeGraphBuilder::VisitLdaConstant(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  Node* node = jsgraph()->Constant(iterator.GetConstantForIndexOperand(0));
+  environment()->BindAccumulator(node);
+}
+
+
+void BytecodeGraphBuilder::VisitLdaUndefined(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  Node* node = jsgraph()->UndefinedConstant();
+  environment()->BindAccumulator(node);
+}
+
+
+void BytecodeGraphBuilder::VisitLdaNull(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  Node* node = jsgraph()->NullConstant();
+  environment()->BindAccumulator(node);
+}
+
+
+void BytecodeGraphBuilder::VisitLdaTheHole(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  Node* node = jsgraph()->TheHoleConstant();
+  environment()->BindAccumulator(node);
+}
+
+
+void BytecodeGraphBuilder::VisitLdaTrue(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  Node* node = jsgraph()->TrueConstant();
+  environment()->BindAccumulator(node);
+}
+
+
+void BytecodeGraphBuilder::VisitLdaFalse(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  Node* node = jsgraph()->FalseConstant();
+  environment()->BindAccumulator(node);
+}
+
+
+void BytecodeGraphBuilder::VisitLdar(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  Node* value = environment()->LookupRegister(iterator.GetRegisterOperand(0));
+  environment()->BindAccumulator(value);
+}
+
+
+void BytecodeGraphBuilder::VisitStar(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  Node* value = environment()->LookupAccumulator();
+  environment()->BindRegister(iterator.GetRegisterOperand(0), value);
+}
+
+
+void BytecodeGraphBuilder::VisitMov(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  Node* value = environment()->LookupRegister(iterator.GetRegisterOperand(0));
+  environment()->BindRegister(iterator.GetRegisterOperand(1), value);
+}
+
+
+void BytecodeGraphBuilder::VisitExchange(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  environment()->ExchangeRegisters(iterator.GetRegisterOperand(0),
+                                   iterator.GetRegisterOperand(1));
+}
+
+
+void BytecodeGraphBuilder::VisitExchangeWide(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  environment()->ExchangeRegisters(iterator.GetRegisterOperand(0),
+                                   iterator.GetRegisterOperand(1));
+}
+
+
+void BytecodeGraphBuilder::BuildLoadGlobal(
+    const interpreter::BytecodeArrayIterator& iterator,
+    TypeofMode typeof_mode) {
+  FrameStateBeforeAndAfter states(this, iterator);
+  Handle<Name> name =
+      Handle<Name>::cast(iterator.GetConstantForIndexOperand(0));
+  VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(1));
+
+  const Operator* op = javascript()->LoadGlobal(name, feedback, typeof_mode);
+  Node* node = NewNode(op, BuildLoadFeedbackVector());
+  environment()->BindAccumulator(node, &states);
+}
+
+
+void BytecodeGraphBuilder::VisitLdaGlobalSloppy(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  DCHECK(is_sloppy(language_mode()));
+  BuildLoadGlobal(iterator, TypeofMode::NOT_INSIDE_TYPEOF);
+}
+
+
+void BytecodeGraphBuilder::VisitLdaGlobalStrict(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  DCHECK(is_strict(language_mode()));
+  BuildLoadGlobal(iterator, TypeofMode::NOT_INSIDE_TYPEOF);
+}
+
+
+void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeofSloppy(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  DCHECK(is_sloppy(language_mode()));
+  BuildLoadGlobal(iterator, TypeofMode::INSIDE_TYPEOF);
+}
+
+
+void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeofStrict(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  DCHECK(is_strict(language_mode()));
+  BuildLoadGlobal(iterator, TypeofMode::INSIDE_TYPEOF);
+}
+
+
+void BytecodeGraphBuilder::VisitLdaGlobalSloppyWide(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  DCHECK(is_sloppy(language_mode()));
+  BuildLoadGlobal(iterator, TypeofMode::NOT_INSIDE_TYPEOF);
+}
+
+
+void BytecodeGraphBuilder::VisitLdaGlobalStrictWide(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  DCHECK(is_strict(language_mode()));
+  BuildLoadGlobal(iterator, TypeofMode::NOT_INSIDE_TYPEOF);
+}
+
+
+void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeofSloppyWide(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  DCHECK(is_sloppy(language_mode()));
+  BuildLoadGlobal(iterator, TypeofMode::INSIDE_TYPEOF);
+}
+
+
+void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeofStrictWide(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  DCHECK(is_strict(language_mode()));
+  BuildLoadGlobal(iterator, TypeofMode::INSIDE_TYPEOF);
+}
+
+
+void BytecodeGraphBuilder::BuildStoreGlobal(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  FrameStateBeforeAndAfter states(this, iterator);
+  Handle<Name> name =
+      Handle<Name>::cast(iterator.GetConstantForIndexOperand(0));
+  VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(1));
+  Node* value = environment()->LookupAccumulator();
+
+  const Operator* op =
+      javascript()->StoreGlobal(language_mode(), name, feedback);
+  Node* node = NewNode(op, value, BuildLoadFeedbackVector());
+  environment()->RecordAfterState(node, &states);
+}
+
+
+void BytecodeGraphBuilder::VisitStaGlobalSloppy(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  DCHECK(is_sloppy(language_mode()));
+  BuildStoreGlobal(iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitStaGlobalStrict(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  DCHECK(is_strict(language_mode()));
+  BuildStoreGlobal(iterator);
+}
+
+void BytecodeGraphBuilder::VisitStaGlobalSloppyWide(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  DCHECK(is_sloppy(language_mode()));
+  BuildStoreGlobal(iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitStaGlobalStrictWide(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  DCHECK(is_strict(language_mode()));
+  BuildStoreGlobal(iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitLdaContextSlot(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  // TODO(mythria): LoadContextSlots are unrolled by the required depth when
+  // generating bytecode. Hence the value of depth is always 0. Update this
+  // code, when the implementation changes.
+  // TODO(mythria): immutable flag is also set to false. This information is not
+  // available in bytecode array. update this code when the implementation
+  // changes.
+  const Operator* op =
+      javascript()->LoadContext(0, iterator.GetIndexOperand(1), false);
+  Node* context = environment()->LookupRegister(iterator.GetRegisterOperand(0));
+  Node* node = NewNode(op, context);
+  environment()->BindAccumulator(node);
+}
+
+
+void BytecodeGraphBuilder::VisitLdaContextSlotWide(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  VisitLdaContextSlot(iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitStaContextSlot(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  // TODO(mythria): LoadContextSlots are unrolled by the required depth when
+  // generating bytecode. Hence the value of depth is always 0. Update this
+  // code, when the implementation changes.
+  const Operator* op =
+      javascript()->StoreContext(0, iterator.GetIndexOperand(1));
+  Node* context = environment()->LookupRegister(iterator.GetRegisterOperand(0));
+  Node* value = environment()->LookupAccumulator();
+  NewNode(op, context, value);
+}
+
+
+void BytecodeGraphBuilder::VisitStaContextSlotWide(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  VisitStaContextSlot(iterator);
+}
+
+
+void BytecodeGraphBuilder::BuildLdaLookupSlot(
+    TypeofMode typeof_mode,
+    const interpreter::BytecodeArrayIterator& iterator) {
+  FrameStateBeforeAndAfter states(this, iterator);
+  Handle<String> name =
+      Handle<String>::cast(iterator.GetConstantForIndexOperand(0));
+  const Operator* op = javascript()->LoadDynamic(name, typeof_mode);
+  Node* value =
+      NewNode(op, BuildLoadFeedbackVector(), environment()->Context());
+  environment()->BindAccumulator(value, &states);
+}
+
+
+void BytecodeGraphBuilder::VisitLdaLookupSlot(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildLdaLookupSlot(TypeofMode::NOT_INSIDE_TYPEOF, iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitLdaLookupSlotInsideTypeof(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildLdaLookupSlot(TypeofMode::INSIDE_TYPEOF, iterator);
+}
+
+
+void BytecodeGraphBuilder::BuildStaLookupSlot(
+    LanguageMode language_mode,
+    const interpreter::BytecodeArrayIterator& iterator) {
+  FrameStateBeforeAndAfter states(this, iterator);
+  Node* value = environment()->LookupAccumulator();
+  Node* name = jsgraph()->Constant(iterator.GetConstantForIndexOperand(0));
+  Node* language = jsgraph()->Constant(language_mode);
+  const Operator* op = javascript()->CallRuntime(Runtime::kStoreLookupSlot, 4);
+  Node* store = NewNode(op, value, environment()->Context(), name, language);
+  environment()->BindAccumulator(store, &states);
+}
+
+
+void BytecodeGraphBuilder::VisitLdaLookupSlotWide(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  VisitLdaLookupSlot(iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitLdaLookupSlotInsideTypeofWide(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  VisitLdaLookupSlotInsideTypeof(iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitStaLookupSlotSloppy(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildStaLookupSlot(LanguageMode::SLOPPY, iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitStaLookupSlotStrict(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildStaLookupSlot(LanguageMode::STRICT, iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitStaLookupSlotSloppyWide(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  VisitStaLookupSlotSloppy(iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitStaLookupSlotStrictWide(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  VisitStaLookupSlotStrict(iterator);
+}
+
+
+void BytecodeGraphBuilder::BuildNamedLoad(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  FrameStateBeforeAndAfter states(this, iterator);
+  Node* object = environment()->LookupRegister(iterator.GetRegisterOperand(0));
+  Handle<Name> name =
+      Handle<Name>::cast(iterator.GetConstantForIndexOperand(1));
+  VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(2));
+
+  const Operator* op = javascript()->LoadNamed(language_mode(), name, feedback);
+  Node* node = NewNode(op, object, BuildLoadFeedbackVector());
+  environment()->BindAccumulator(node, &states);
+}
+
+
+void BytecodeGraphBuilder::VisitLoadICSloppy(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  DCHECK(is_sloppy(language_mode()));
+  BuildNamedLoad(iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitLoadICStrict(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  DCHECK(is_strict(language_mode()));
+  BuildNamedLoad(iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitLoadICSloppyWide(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  DCHECK(is_sloppy(language_mode()));
+  BuildNamedLoad(iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitLoadICStrictWide(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  DCHECK(is_strict(language_mode()));
+  BuildNamedLoad(iterator);
+}
+
+
+void BytecodeGraphBuilder::BuildKeyedLoad(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  FrameStateBeforeAndAfter states(this, iterator);
+  Node* key = environment()->LookupAccumulator();
+  Node* object = environment()->LookupRegister(iterator.GetRegisterOperand(0));
+  VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(1));
+
+  const Operator* op = javascript()->LoadProperty(language_mode(), feedback);
+  Node* node = NewNode(op, object, key, BuildLoadFeedbackVector());
+  environment()->BindAccumulator(node, &states);
+}
+
+
+void BytecodeGraphBuilder::VisitKeyedLoadICSloppy(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  DCHECK(is_sloppy(language_mode()));
+  BuildKeyedLoad(iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitKeyedLoadICStrict(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  DCHECK(is_strict(language_mode()));
+  BuildKeyedLoad(iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitKeyedLoadICSloppyWide(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  DCHECK(is_sloppy(language_mode()));
+  BuildKeyedLoad(iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitKeyedLoadICStrictWide(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  DCHECK(is_strict(language_mode()));
+  BuildKeyedLoad(iterator);
+}
+
+
+void BytecodeGraphBuilder::BuildNamedStore(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  FrameStateBeforeAndAfter states(this, iterator);
+  Node* value = environment()->LookupAccumulator();
+  Node* object = environment()->LookupRegister(iterator.GetRegisterOperand(0));
+  Handle<Name> name =
+      Handle<Name>::cast(iterator.GetConstantForIndexOperand(1));
+  VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(2));
+
+  const Operator* op =
+      javascript()->StoreNamed(language_mode(), name, feedback);
+  Node* node = NewNode(op, object, value, BuildLoadFeedbackVector());
+  environment()->RecordAfterState(node, &states);
+}
+
+
+void BytecodeGraphBuilder::VisitStoreICSloppy(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  DCHECK(is_sloppy(language_mode()));
+  BuildNamedStore(iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitStoreICStrict(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  DCHECK(is_strict(language_mode()));
+  BuildNamedStore(iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitStoreICSloppyWide(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  DCHECK(is_sloppy(language_mode()));
+  BuildNamedStore(iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitStoreICStrictWide(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  DCHECK(is_strict(language_mode()));
+  BuildNamedStore(iterator);
+}
+
+
+void BytecodeGraphBuilder::BuildKeyedStore(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  FrameStateBeforeAndAfter states(this, iterator);
+  Node* value = environment()->LookupAccumulator();
+  Node* object = environment()->LookupRegister(iterator.GetRegisterOperand(0));
+  Node* key = environment()->LookupRegister(iterator.GetRegisterOperand(1));
+  VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(2));
+
+  const Operator* op = javascript()->StoreProperty(language_mode(), feedback);
+  Node* node = NewNode(op, object, key, value, BuildLoadFeedbackVector());
+  environment()->RecordAfterState(node, &states);
+}
+
+
+void BytecodeGraphBuilder::VisitKeyedStoreICSloppy(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  DCHECK(is_sloppy(language_mode()));
+  BuildKeyedStore(iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitKeyedStoreICStrict(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  DCHECK(is_strict(language_mode()));
+  BuildKeyedStore(iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitKeyedStoreICSloppyWide(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  DCHECK(is_sloppy(language_mode()));
+  BuildKeyedStore(iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitKeyedStoreICStrictWide(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  DCHECK(is_strict(language_mode()));
+  BuildKeyedStore(iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitPushContext(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  Node* context = environment()->LookupAccumulator();
+  environment()->BindRegister(iterator.GetRegisterOperand(0), context);
+  environment()->SetContext(context);
+}
+
+
+void BytecodeGraphBuilder::VisitPopContext(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  Node* context = environment()->LookupRegister(iterator.GetRegisterOperand(0));
+  environment()->SetContext(context);
+}
+
+
+void BytecodeGraphBuilder::VisitCreateClosure(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  Handle<SharedFunctionInfo> shared_info =
+      Handle<SharedFunctionInfo>::cast(iterator.GetConstantForIndexOperand(0));
+  PretenureFlag tenured =
+      iterator.GetImmediateOperand(1) ? TENURED : NOT_TENURED;
+  const Operator* op = javascript()->CreateClosure(shared_info, tenured);
+  Node* closure = NewNode(op);
+  environment()->BindAccumulator(closure);
+}
+
+
+void BytecodeGraphBuilder::VisitCreateClosureWide(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  VisitCreateClosure(iterator);
+}
+
+
+void BytecodeGraphBuilder::BuildCreateArguments(
+    CreateArgumentsParameters::Type type,
+    const interpreter::BytecodeArrayIterator& iterator) {
+  FrameStateBeforeAndAfter states(this, iterator);
+  const Operator* op = javascript()->CreateArguments(type, 0);
+  Node* object = NewNode(op, GetFunctionClosure());
+  environment()->BindAccumulator(object, &states);
+}
+
+
+void BytecodeGraphBuilder::VisitCreateMappedArguments(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildCreateArguments(CreateArgumentsParameters::kMappedArguments, iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitCreateUnmappedArguments(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildCreateArguments(CreateArgumentsParameters::kUnmappedArguments, iterator);
+}
+
+
+void BytecodeGraphBuilder::BuildCreateLiteral(
+    const Operator* op, const interpreter::BytecodeArrayIterator& iterator) {
+  FrameStateBeforeAndAfter states(this, iterator);
+  Node* literal = NewNode(op, GetFunctionClosure());
+  environment()->BindAccumulator(literal, &states);
+}
+
+
+void BytecodeGraphBuilder::BuildCreateRegExpLiteral(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  Handle<String> constant_pattern =
+      Handle<String>::cast(iterator.GetConstantForIndexOperand(0));
+  int literal_index = iterator.GetIndexOperand(1);
+  int literal_flags = iterator.GetImmediateOperand(2);
+  const Operator* op = javascript()->CreateLiteralRegExp(
+      constant_pattern, literal_flags, literal_index);
+  BuildCreateLiteral(op, iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitCreateRegExpLiteral(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildCreateRegExpLiteral(iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitCreateRegExpLiteralWide(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildCreateRegExpLiteral(iterator);
+}
+
+
+void BytecodeGraphBuilder::BuildCreateArrayLiteral(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  Handle<FixedArray> constant_elements =
+      Handle<FixedArray>::cast(iterator.GetConstantForIndexOperand(0));
+  int literal_index = iterator.GetIndexOperand(1);
+  int literal_flags = iterator.GetImmediateOperand(2);
+  const Operator* op = javascript()->CreateLiteralArray(
+      constant_elements, literal_flags, literal_index);
+  BuildCreateLiteral(op, iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitCreateArrayLiteral(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildCreateArrayLiteral(iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitCreateArrayLiteralWide(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildCreateArrayLiteral(iterator);
+}
+
+
+void BytecodeGraphBuilder::BuildCreateObjectLiteral(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  Handle<FixedArray> constant_properties =
+      Handle<FixedArray>::cast(iterator.GetConstantForIndexOperand(0));
+  int literal_index = iterator.GetIndexOperand(1);
+  int literal_flags = iterator.GetImmediateOperand(2);
+  const Operator* op = javascript()->CreateLiteralObject(
+      constant_properties, literal_flags, literal_index);
+  BuildCreateLiteral(op, iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitCreateObjectLiteral(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildCreateObjectLiteral(iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitCreateObjectLiteralWide(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildCreateObjectLiteral(iterator);
+}
+
+
+Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op,
+                                                 Node* callee,
+                                                 interpreter::Register receiver,
+                                                 size_t arity) {
+  Node** all = info()->zone()->NewArray<Node*>(static_cast<int>(arity));
+  all[0] = callee;
+  all[1] = environment()->LookupRegister(receiver);
+  int receiver_index = receiver.index();
+  for (int i = 2; i < static_cast<int>(arity); ++i) {
+    all[i] = environment()->LookupRegister(
+        interpreter::Register(receiver_index + i - 1));
+  }
+  Node* value = MakeNode(call_op, static_cast<int>(arity), all, false);
+  return value;
+}
+
+
+void BytecodeGraphBuilder::BuildCall(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  FrameStateBeforeAndAfter states(this, iterator);
+  // TODO(rmcilroy): Set receiver_hint correctly based on whether the receiver
+  // register has been loaded with null / undefined explicitly or we are sure it
+  // is not null / undefined.
+  ConvertReceiverMode receiver_hint = ConvertReceiverMode::kAny;
+  Node* callee = environment()->LookupRegister(iterator.GetRegisterOperand(0));
+  interpreter::Register receiver = iterator.GetRegisterOperand(1);
+  size_t arg_count = iterator.GetCountOperand(2);
+  VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(3));
+
+  const Operator* call = javascript()->CallFunction(
+      arg_count + 2, language_mode(), feedback, receiver_hint);
+  Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 2);
+  environment()->BindAccumulator(value, &states);
+}
+
+
+void BytecodeGraphBuilder::VisitCall(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildCall(iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitCallWide(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildCall(iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitCallJSRuntime(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  FrameStateBeforeAndAfter states(this, iterator);
+  Node* callee = BuildLoadNativeContextField(iterator.GetIndexOperand(0));
+  interpreter::Register receiver = iterator.GetRegisterOperand(1);
+  size_t arg_count = iterator.GetCountOperand(2);
+
+  // Create node to perform the JS runtime call.
+  const Operator* call =
+      javascript()->CallFunction(arg_count + 2, language_mode());
+  Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 2);
+  environment()->BindAccumulator(value, &states);
+}
+
+
+Node* BytecodeGraphBuilder::ProcessCallRuntimeArguments(
+    const Operator* call_runtime_op, interpreter::Register first_arg,
+    size_t arity) {
+  Node** all = info()->zone()->NewArray<Node*>(arity);
+  int first_arg_index = first_arg.index();
+  for (int i = 0; i < static_cast<int>(arity); ++i) {
+    all[i] = environment()->LookupRegister(
+        interpreter::Register(first_arg_index + i));
+  }
+  Node* value = MakeNode(call_runtime_op, static_cast<int>(arity), all, false);
+  return value;
+}
+
+
+void BytecodeGraphBuilder::VisitCallRuntime(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  FrameStateBeforeAndAfter states(this, iterator);
+  Runtime::FunctionId functionId =
+      static_cast<Runtime::FunctionId>(iterator.GetIndexOperand(0));
+  interpreter::Register first_arg = iterator.GetRegisterOperand(1);
+  size_t arg_count = iterator.GetCountOperand(2);
+
+  // Create node to perform the runtime call.
+  const Operator* call = javascript()->CallRuntime(functionId, arg_count);
+  Node* value = ProcessCallRuntimeArguments(call, first_arg, arg_count);
+  environment()->BindAccumulator(value, &states);
+}
+
+
+void BytecodeGraphBuilder::VisitCallRuntimeForPair(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  FrameStateBeforeAndAfter states(this, iterator);
+  Runtime::FunctionId functionId =
+      static_cast<Runtime::FunctionId>(iterator.GetIndexOperand(0));
+  interpreter::Register first_arg = iterator.GetRegisterOperand(1);
+  size_t arg_count = iterator.GetCountOperand(2);
+  interpreter::Register first_return = iterator.GetRegisterOperand(3);
+
+  // Create node to perform the runtime call.
+  const Operator* call = javascript()->CallRuntime(functionId, arg_count);
+  Node* return_pair = ProcessCallRuntimeArguments(call, first_arg, arg_count);
+  environment()->BindRegistersToProjections(first_return, return_pair, &states);
+}
+
+
+Node* BytecodeGraphBuilder::ProcessCallNewArguments(
+    const Operator* call_new_op, interpreter::Register callee,
+    interpreter::Register first_arg, size_t arity) {
+  Node** all = info()->zone()->NewArray<Node*>(arity);
+  all[0] = environment()->LookupRegister(callee);
+  int first_arg_index = first_arg.index();
+  for (int i = 1; i < static_cast<int>(arity) - 1; ++i) {
+    all[i] = environment()->LookupRegister(
+        interpreter::Register(first_arg_index + i - 1));
+  }
+  // Original constructor is the same as the callee.
+  all[arity - 1] = environment()->LookupRegister(callee);
+  Node* value = MakeNode(call_new_op, static_cast<int>(arity), all, false);
+  return value;
+}
+
+
+void BytecodeGraphBuilder::VisitNew(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  FrameStateBeforeAndAfter states(this, iterator);
+  interpreter::Register callee = iterator.GetRegisterOperand(0);
+  interpreter::Register first_arg = iterator.GetRegisterOperand(1);
+  size_t arg_count = iterator.GetCountOperand(2);
+
+  // TODO(turbofan): Pass the feedback here.
+  const Operator* call = javascript()->CallConstruct(
+      static_cast<int>(arg_count) + 2, VectorSlotPair());
+  Node* value = ProcessCallNewArguments(call, callee, first_arg, arg_count + 2);
+  environment()->BindAccumulator(value, &states);
+}
+
+
+void BytecodeGraphBuilder::VisitThrow(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  FrameStateBeforeAndAfter states(this, iterator);
+  Node* value = environment()->LookupAccumulator();
+  // TODO(mythria): Change to Runtime::kThrow when we have deoptimization
+  // information support in the interpreter.
+  NewNode(javascript()->CallRuntime(Runtime::kReThrow, 1), value);
+  Node* control = NewNode(common()->Throw(), value);
+  environment()->RecordAfterState(control, &states);
+  UpdateControlDependencyToLeaveFunction(control);
+}
+
+
+void BytecodeGraphBuilder::BuildBinaryOp(
+    const Operator* js_op, const interpreter::BytecodeArrayIterator& iterator) {
+  FrameStateBeforeAndAfter states(this, iterator);
+  Node* left = environment()->LookupRegister(iterator.GetRegisterOperand(0));
+  Node* right = environment()->LookupAccumulator();
+  Node* node = NewNode(js_op, left, right);
+  environment()->BindAccumulator(node, &states);
+}
+
+
+void BytecodeGraphBuilder::VisitAdd(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BinaryOperationHints hints = BinaryOperationHints::Any();
+  BuildBinaryOp(javascript()->Add(language_mode(), hints), iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitSub(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BinaryOperationHints hints = BinaryOperationHints::Any();
+  BuildBinaryOp(javascript()->Subtract(language_mode(), hints), iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitMul(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BinaryOperationHints hints = BinaryOperationHints::Any();
+  BuildBinaryOp(javascript()->Multiply(language_mode(), hints), iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitDiv(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BinaryOperationHints hints = BinaryOperationHints::Any();
+  BuildBinaryOp(javascript()->Divide(language_mode(), hints), iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitMod(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BinaryOperationHints hints = BinaryOperationHints::Any();
+  BuildBinaryOp(javascript()->Modulus(language_mode(), hints), iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitBitwiseOr(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BinaryOperationHints hints = BinaryOperationHints::Any();
+  BuildBinaryOp(javascript()->BitwiseOr(language_mode(), hints), iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitBitwiseXor(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BinaryOperationHints hints = BinaryOperationHints::Any();
+  BuildBinaryOp(javascript()->BitwiseXor(language_mode(), hints), iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitBitwiseAnd(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BinaryOperationHints hints = BinaryOperationHints::Any();
+  BuildBinaryOp(javascript()->BitwiseAnd(language_mode(), hints), iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitShiftLeft(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BinaryOperationHints hints = BinaryOperationHints::Any();
+  BuildBinaryOp(javascript()->ShiftLeft(language_mode(), hints), iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitShiftRight(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BinaryOperationHints hints = BinaryOperationHints::Any();
+  BuildBinaryOp(javascript()->ShiftRight(language_mode(), hints), iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitShiftRightLogical(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BinaryOperationHints hints = BinaryOperationHints::Any();
+  BuildBinaryOp(javascript()->ShiftRightLogical(language_mode(), hints),
+                iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitInc(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  FrameStateBeforeAndAfter states(this, iterator);
+  const Operator* js_op =
+      javascript()->Add(language_mode(), BinaryOperationHints::Any());
+  Node* node = NewNode(js_op, environment()->LookupAccumulator(),
+                       jsgraph()->OneConstant());
+  environment()->BindAccumulator(node, &states);
+}
+
+
+void BytecodeGraphBuilder::VisitDec(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  FrameStateBeforeAndAfter states(this, iterator);
+  const Operator* js_op =
+      javascript()->Subtract(language_mode(), BinaryOperationHints::Any());
+  Node* node = NewNode(js_op, environment()->LookupAccumulator(),
+                       jsgraph()->OneConstant());
+  environment()->BindAccumulator(node, &states);
+}
+
+
+void BytecodeGraphBuilder::VisitLogicalNot(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  Node* value = NewNode(javascript()->ToBoolean(ToBooleanHint::kAny),
+                        environment()->LookupAccumulator());
+  Node* node = NewNode(common()->Select(MachineRepresentation::kTagged), value,
+                       jsgraph()->FalseConstant(), jsgraph()->TrueConstant());
+  environment()->BindAccumulator(node);
+}
+
+
+void BytecodeGraphBuilder::VisitTypeOf(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  Node* node =
+      NewNode(javascript()->TypeOf(), environment()->LookupAccumulator());
+  environment()->BindAccumulator(node);
+}
+
+
+void BytecodeGraphBuilder::BuildDelete(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  FrameStateBeforeAndAfter states(this, iterator);
+  Node* key = environment()->LookupAccumulator();
+  Node* object = environment()->LookupRegister(iterator.GetRegisterOperand(0));
+  Node* node =
+      NewNode(javascript()->DeleteProperty(language_mode()), object, key);
+  environment()->BindAccumulator(node, &states);
+}
+
+
+void BytecodeGraphBuilder::VisitDeletePropertyStrict(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  DCHECK(is_strict(language_mode()));
+  BuildDelete(iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitDeletePropertySloppy(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  DCHECK(is_sloppy(language_mode()));
+  BuildDelete(iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitDeleteLookupSlot(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  FrameStateBeforeAndAfter states(this, iterator);
+  Node* name = environment()->LookupAccumulator();
+  const Operator* op = javascript()->CallRuntime(Runtime::kDeleteLookupSlot, 2);
+  Node* result = NewNode(op, environment()->Context(), name);
+  environment()->BindAccumulator(result, &states);
+}
+
+
+void BytecodeGraphBuilder::BuildCompareOp(
+    const Operator* js_op, const interpreter::BytecodeArrayIterator& iterator) {
+  FrameStateBeforeAndAfter states(this, iterator);
+  Node* left = environment()->LookupRegister(iterator.GetRegisterOperand(0));
+  Node* right = environment()->LookupAccumulator();
+  Node* node = NewNode(js_op, left, right);
+  environment()->BindAccumulator(node, &states);
+}
+
+
+void BytecodeGraphBuilder::VisitTestEqual(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildCompareOp(javascript()->Equal(), iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitTestNotEqual(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildCompareOp(javascript()->NotEqual(), iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitTestEqualStrict(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildCompareOp(javascript()->StrictEqual(), iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitTestNotEqualStrict(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildCompareOp(javascript()->StrictNotEqual(), iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitTestLessThan(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildCompareOp(javascript()->LessThan(language_mode()), iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitTestGreaterThan(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildCompareOp(javascript()->GreaterThan(language_mode()), iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitTestLessThanOrEqual(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildCompareOp(javascript()->LessThanOrEqual(language_mode()), iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitTestGreaterThanOrEqual(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildCompareOp(javascript()->GreaterThanOrEqual(language_mode()), iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitTestIn(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildCompareOp(javascript()->HasProperty(), iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitTestInstanceOf(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildCompareOp(javascript()->InstanceOf(), iterator);
+}
+
+
+void BytecodeGraphBuilder::BuildCastOperator(
+    const Operator* js_op, const interpreter::BytecodeArrayIterator& iterator) {
+  FrameStateBeforeAndAfter states(this, iterator);
+  Node* node = NewNode(js_op, environment()->LookupAccumulator());
+  environment()->BindAccumulator(node, &states);
+}
+
+
+void BytecodeGraphBuilder::VisitToName(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildCastOperator(javascript()->ToName(), iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitToObject(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildCastOperator(javascript()->ToObject(), iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitToNumber(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildCastOperator(javascript()->ToNumber(), iterator);
+}
+
+
+void BytecodeGraphBuilder::VisitJump(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildJump();
+}
+
+
+void BytecodeGraphBuilder::VisitJumpConstant(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildJump();
+}
+
+
+void BytecodeGraphBuilder::VisitJumpConstantWide(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildJump();
+}
+
+
+void BytecodeGraphBuilder::VisitJumpIfTrue(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildJumpIfEqual(jsgraph()->TrueConstant());
+}
+
+
+void BytecodeGraphBuilder::VisitJumpIfTrueConstant(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildJumpIfEqual(jsgraph()->TrueConstant());
+}
+
+
+void BytecodeGraphBuilder::VisitJumpIfTrueConstantWide(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildJumpIfEqual(jsgraph()->TrueConstant());
+}
+
+
+void BytecodeGraphBuilder::VisitJumpIfFalse(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildJumpIfEqual(jsgraph()->FalseConstant());
+}
+
+
+void BytecodeGraphBuilder::VisitJumpIfFalseConstant(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildJumpIfEqual(jsgraph()->FalseConstant());
+}
+
+
+void BytecodeGraphBuilder::VisitJumpIfFalseConstantWide(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildJumpIfEqual(jsgraph()->FalseConstant());
+}
+
+
+void BytecodeGraphBuilder::VisitJumpIfToBooleanTrue(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildJumpIfToBooleanEqual(jsgraph()->TrueConstant());
+}
+
+
+void BytecodeGraphBuilder::VisitJumpIfToBooleanTrueConstant(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildJumpIfToBooleanEqual(jsgraph()->TrueConstant());
+}
+
+
+void BytecodeGraphBuilder::VisitJumpIfToBooleanTrueConstantWide(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildJumpIfToBooleanEqual(jsgraph()->TrueConstant());
+}
+
+
+void BytecodeGraphBuilder::VisitJumpIfToBooleanFalse(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildJumpIfToBooleanEqual(jsgraph()->FalseConstant());
+}
+
+
+void BytecodeGraphBuilder::VisitJumpIfToBooleanFalseConstant(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildJumpIfToBooleanEqual(jsgraph()->FalseConstant());
+}
+
+
+void BytecodeGraphBuilder::VisitJumpIfToBooleanFalseConstantWide(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildJumpIfToBooleanEqual(jsgraph()->FalseConstant());
+}
+
+
+void BytecodeGraphBuilder::VisitJumpIfNull(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildJumpIfEqual(jsgraph()->NullConstant());
+}
+
+
+void BytecodeGraphBuilder::VisitJumpIfNullConstant(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildJumpIfEqual(jsgraph()->NullConstant());
+}
+
+
+void BytecodeGraphBuilder::VisitJumpIfNullConstantWide(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildJumpIfEqual(jsgraph()->NullConstant());
+}
+
+
+void BytecodeGraphBuilder::VisitJumpIfUndefined(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildJumpIfEqual(jsgraph()->UndefinedConstant());
+}
+
+
+void BytecodeGraphBuilder::VisitJumpIfUndefinedConstant(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildJumpIfEqual(jsgraph()->UndefinedConstant());
+}
+
+
+void BytecodeGraphBuilder::VisitJumpIfUndefinedConstantWide(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  BuildJumpIfEqual(jsgraph()->UndefinedConstant());
+}
+
+
+void BytecodeGraphBuilder::VisitReturn(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  Node* control =
+      NewNode(common()->Return(), environment()->LookupAccumulator());
+  UpdateControlDependencyToLeaveFunction(control);
+  set_environment(nullptr);
+}
+
+
+void BytecodeGraphBuilder::VisitForInPrepare(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  Node* prepare = nullptr;
+  {
+    FrameStateBeforeAndAfter states(this, iterator);
+    Node* receiver = environment()->LookupAccumulator();
+    prepare = NewNode(javascript()->ForInPrepare(), receiver);
+    environment()->RecordAfterState(prepare, &states);
+  }
+  // Project cache_type, cache_array, cache_length into register
+  // operands 1, 2, 3.
+  for (int i = 0; i < 3; i++) {
+    environment()->BindRegister(iterator.GetRegisterOperand(i),
+                                NewNode(common()->Projection(i), prepare));
+  }
+}
+
+
+void BytecodeGraphBuilder::VisitForInDone(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  FrameStateBeforeAndAfter states(this, iterator);
+  Node* index = environment()->LookupRegister(iterator.GetRegisterOperand(0));
+  Node* cache_length =
+      environment()->LookupRegister(iterator.GetRegisterOperand(1));
+  Node* exit_cond = NewNode(javascript()->ForInDone(), index, cache_length);
+  environment()->BindAccumulator(exit_cond, &states);
+}
+
+
+void BytecodeGraphBuilder::VisitForInNext(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  FrameStateBeforeAndAfter states(this, iterator);
+  Node* receiver =
+      environment()->LookupRegister(iterator.GetRegisterOperand(0));
+  Node* cache_type =
+      environment()->LookupRegister(iterator.GetRegisterOperand(1));
+  Node* cache_array =
+      environment()->LookupRegister(iterator.GetRegisterOperand(2));
+  Node* index = environment()->LookupRegister(iterator.GetRegisterOperand(3));
+  Node* value = NewNode(javascript()->ForInNext(), receiver, cache_array,
+                        cache_type, index);
+  environment()->BindAccumulator(value, &states);
+}
+
+
+void BytecodeGraphBuilder::VisitForInStep(
+    const interpreter::BytecodeArrayIterator& iterator) {
+  FrameStateBeforeAndAfter states(this, iterator);
+  Node* index = environment()->LookupRegister(iterator.GetRegisterOperand(0));
+  index = NewNode(javascript()->ForInStep(), index);
+  environment()->BindAccumulator(index, &states);
+}
+
+
+void BytecodeGraphBuilder::MergeEnvironmentsOfBackwardBranches(
+    int source_offset, int target_offset) {
+  DCHECK_GE(source_offset, target_offset);
+  const ZoneVector<int>* branch_sites =
+      branch_analysis()->BackwardBranchesTargetting(target_offset);
+  if (branch_sites->back() == source_offset) {
+    // The set of back branches is complete, merge them.
+    DCHECK_GE(branch_sites->at(0), target_offset);
+    Environment* merged = merge_environments_[branch_sites->at(0)];
+    for (size_t i = 1; i < branch_sites->size(); i++) {
+      DCHECK_GE(branch_sites->at(i), target_offset);
+      merged->Merge(merge_environments_[branch_sites->at(i)]);
+    }
+    // And now merge with loop header environment created when loop
+    // header was visited.
+    loop_header_environments_[target_offset]->Merge(merged);
+  }
+}
+
+
+void BytecodeGraphBuilder::MergeEnvironmentsOfForwardBranches(
+    int source_offset) {
+  if (branch_analysis()->forward_branches_target(source_offset)) {
+    // Merge environments of branches that reach this bytecode.
+    auto branch_sites =
+        branch_analysis()->ForwardBranchesTargetting(source_offset);
+    DCHECK_LT(branch_sites->at(0), source_offset);
+    Environment* merged = merge_environments_[branch_sites->at(0)];
+    for (size_t i = 1; i < branch_sites->size(); i++) {
+      DCHECK_LT(branch_sites->at(i), source_offset);
+      merged->Merge(merge_environments_[branch_sites->at(i)]);
+    }
+    if (environment()) {
+      merged->Merge(environment());
+    }
+    set_environment(merged);
+  }
+}
+
+
+void BytecodeGraphBuilder::BuildLoopHeaderForBackwardBranches(
+    int source_offset) {
+  if (branch_analysis()->backward_branches_target(source_offset)) {
+    // Add loop header and store a copy so we can connect merged back
+    // edge inputs to the loop header.
+    loop_header_environments_[source_offset] = environment()->CopyForLoop();
+  }
+}
+
+
+void BytecodeGraphBuilder::BuildJump(int source_offset, int target_offset) {
+  DCHECK_NULL(merge_environments_[source_offset]);
+  merge_environments_[source_offset] = environment();
+  if (source_offset >= target_offset) {
+    MergeEnvironmentsOfBackwardBranches(source_offset, target_offset);
+  }
+  set_environment(nullptr);
+}
+
+
+void BytecodeGraphBuilder::BuildJump() {
+  int source_offset = bytecode_iterator()->current_offset();
+  int target_offset = bytecode_iterator()->GetJumpTargetOffset();
+  BuildJump(source_offset, target_offset);
+}
+
+
+void BytecodeGraphBuilder::BuildConditionalJump(Node* condition) {
+  int source_offset = bytecode_iterator()->current_offset();
+  NewBranch(condition);
+  Environment* if_false_environment = environment()->CopyForConditional();
+  NewIfTrue();
+  BuildJump(source_offset, bytecode_iterator()->GetJumpTargetOffset());
+  set_environment(if_false_environment);
+  NewIfFalse();
+}
+
+
+void BytecodeGraphBuilder::BuildJumpIfEqual(Node* comperand) {
+  Node* accumulator = environment()->LookupAccumulator();
+  Node* condition =
+      NewNode(javascript()->StrictEqual(), accumulator, comperand);
+  BuildConditionalJump(condition);
+}
+
+
+void BytecodeGraphBuilder::BuildJumpIfToBooleanEqual(Node* comperand) {
+  Node* accumulator = environment()->LookupAccumulator();
+  Node* to_boolean =
+      NewNode(javascript()->ToBoolean(ToBooleanHint::kAny), accumulator);
+  Node* condition = NewNode(javascript()->StrictEqual(), to_boolean, comperand);
+  BuildConditionalJump(condition);
+}
+
+
+Node** BytecodeGraphBuilder::EnsureInputBufferSize(int size) {
+  if (size > input_buffer_size_) {
+    size = size + kInputBufferSizeIncrement + input_buffer_size_;
+    input_buffer_ = local_zone()->NewArray<Node*>(size);
+    input_buffer_size_ = size;
+  }
+  return input_buffer_;
+}
+
+
+void BytecodeGraphBuilder::PrepareEntryFrameState(Node* node) {
+  DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
+  DCHECK_EQ(IrOpcode::kDead,
+            NodeProperties::GetFrameStateInput(node, 0)->opcode());
+  NodeProperties::ReplaceFrameStateInput(
+      node, 0, environment()->Checkpoint(BailoutId(0),
+                                         OutputFrameStateCombine::Ignore()));
+}
+
+
+Node* BytecodeGraphBuilder::MakeNode(const Operator* op, int value_input_count,
+                                     Node** value_inputs, bool incomplete) {
+  DCHECK_EQ(op->ValueInputCount(), value_input_count);
+
+  bool has_context = OperatorProperties::HasContextInput(op);
+  int frame_state_count = OperatorProperties::GetFrameStateInputCount(op);
+  bool has_control = op->ControlInputCount() == 1;
+  bool has_effect = op->EffectInputCount() == 1;
+
+  DCHECK_LT(op->ControlInputCount(), 2);
+  DCHECK_LT(op->EffectInputCount(), 2);
+
+  Node* result = nullptr;
+  if (!has_context && frame_state_count == 0 && !has_control && !has_effect) {
+    result = graph()->NewNode(op, value_input_count, value_inputs, incomplete);
+  } else {
+    int input_count_with_deps = value_input_count;
+    if (has_context) ++input_count_with_deps;
+    input_count_with_deps += frame_state_count;
+    if (has_control) ++input_count_with_deps;
+    if (has_effect) ++input_count_with_deps;
+    Node** buffer = EnsureInputBufferSize(input_count_with_deps);
+    memcpy(buffer, value_inputs, kPointerSize * value_input_count);
+    Node** current_input = buffer + value_input_count;
+    if (has_context) {
+      *current_input++ = environment()->Context();
+    }
+    for (int i = 0; i < frame_state_count; i++) {
+      // The frame state will be inserted later. Here we misuse
+      // the {Dead} node as a sentinel to be later overwritten
+      // with the real frame state.
+      *current_input++ = jsgraph()->Dead();
+    }
+    if (has_effect) {
+      *current_input++ = environment()->GetEffectDependency();
+    }
+    if (has_control) {
+      *current_input++ = environment()->GetControlDependency();
+    }
+    result = graph()->NewNode(op, input_count_with_deps, buffer, incomplete);
+    if (!environment()->IsMarkedAsUnreachable()) {
+      // Update the current control dependency for control-producing nodes.
+      if (NodeProperties::IsControl(result)) {
+        environment()->UpdateControlDependency(result);
+      }
+      // Update the current effect dependency for effect-producing nodes.
+      if (result->op()->EffectOutputCount() > 0) {
+        environment()->UpdateEffectDependency(result);
+      }
+      // Add implicit success continuation for throwing nodes.
+      if (!result->op()->HasProperty(Operator::kNoThrow)) {
+        const Operator* if_success = common()->IfSuccess();
+        Node* on_success = graph()->NewNode(if_success, result);
+        environment_->UpdateControlDependency(on_success);
+      }
+    }
+  }
+
+  return result;
+}
+
+
+Node* BytecodeGraphBuilder::NewPhi(int count, Node* input, Node* control) {
+  const Operator* phi_op = common()->Phi(MachineRepresentation::kTagged, count);
+  Node** buffer = EnsureInputBufferSize(count + 1);
+  MemsetPointer(buffer, input, count);
+  buffer[count] = control;
+  return graph()->NewNode(phi_op, count + 1, buffer, true);
+}
+
+
+Node* BytecodeGraphBuilder::NewEffectPhi(int count, Node* input,
+                                         Node* control) {
+  const Operator* phi_op = common()->EffectPhi(count);
+  Node** buffer = EnsureInputBufferSize(count + 1);
+  MemsetPointer(buffer, input, count);
+  buffer[count] = control;
+  return graph()->NewNode(phi_op, count + 1, buffer, true);
+}
+
+
+Node* BytecodeGraphBuilder::MergeControl(Node* control, Node* other) {
+  int inputs = control->op()->ControlInputCount() + 1;
+  if (control->opcode() == IrOpcode::kLoop) {
+    // Control node for loop exists, add input.
+    const Operator* op = common()->Loop(inputs);
+    control->AppendInput(graph_zone(), other);
+    NodeProperties::ChangeOp(control, op);
+  } else if (control->opcode() == IrOpcode::kMerge) {
+    // Control node for merge exists, add input.
+    const Operator* op = common()->Merge(inputs);
+    control->AppendInput(graph_zone(), other);
+    NodeProperties::ChangeOp(control, op);
+  } else {
+    // Control node is a singleton, introduce a merge.
+    const Operator* op = common()->Merge(inputs);
+    Node* merge_inputs[] = {control, other};
+    control = graph()->NewNode(op, arraysize(merge_inputs), merge_inputs, true);
+  }
+  return control;
+}
+
+
+Node* BytecodeGraphBuilder::MergeEffect(Node* value, Node* other,
+                                        Node* control) {
+  int inputs = control->op()->ControlInputCount();
+  if (value->opcode() == IrOpcode::kEffectPhi &&
+      NodeProperties::GetControlInput(value) == control) {
+    // Phi already exists, add input.
+    value->InsertInput(graph_zone(), inputs - 1, other);
+    NodeProperties::ChangeOp(value, common()->EffectPhi(inputs));
+  } else if (value != other) {
+    // Phi does not exist yet, introduce one.
+    value = NewEffectPhi(inputs, value, control);
+    value->ReplaceInput(inputs - 1, other);
+  }
+  return value;
+}
+
+
+Node* BytecodeGraphBuilder::MergeValue(Node* value, Node* other,
+                                       Node* control) {
+  int inputs = control->op()->ControlInputCount();
+  if (value->opcode() == IrOpcode::kPhi &&
+      NodeProperties::GetControlInput(value) == control) {
+    // Phi already exists, add input.
+    value->InsertInput(graph_zone(), inputs - 1, other);
+    NodeProperties::ChangeOp(
+        value, common()->Phi(MachineRepresentation::kTagged, inputs));
+  } else if (value != other) {
+    // Phi does not exist yet, introduce one.
+    value = NewPhi(inputs, value, control);
+    value->ReplaceInput(inputs - 1, other);
+  }
+  return value;
+}
+
+
+void BytecodeGraphBuilder::UpdateControlDependencyToLeaveFunction(Node* exit) {
+  if (environment()->IsMarkedAsUnreachable()) return;
+  environment()->MarkAsUnreachable();
+  exit_controls_.push_back(exit);
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/bytecode-graph-builder.h b/src/compiler/bytecode-graph-builder.h
new file mode 100644
index 0000000..94a278c
--- /dev/null
+++ b/src/compiler/bytecode-graph-builder.h
@@ -0,0 +1,344 @@
+// Copyright 2015 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.
+
+#ifndef V8_COMPILER_BYTECODE_GRAPH_BUILDER_H_
+#define V8_COMPILER_BYTECODE_GRAPH_BUILDER_H_
+
+#include "src/compiler.h"
+#include "src/compiler/bytecode-branch-analysis.h"
+#include "src/compiler/js-graph.h"
+#include "src/interpreter/bytecode-array-iterator.h"
+#include "src/interpreter/bytecodes.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+// The BytecodeGraphBuilder produces a high-level IR graph based on
+// interpreter bytecodes.
+class BytecodeGraphBuilder {
+ public:
+  BytecodeGraphBuilder(Zone* local_zone, CompilationInfo* info,
+                       JSGraph* jsgraph);
+
+  // Creates a graph by visiting bytecodes.
+  bool CreateGraph(bool stack_check = true);
+
+  Graph* graph() const { return jsgraph_->graph(); }
+
+ private:
+  class Environment;
+  class FrameStateBeforeAndAfter;
+
+  void CreateGraphBody(bool stack_check);
+  void VisitBytecodes();
+
+  Node* LoadAccumulator(Node* value);
+
+  // Get or create the node that represents the outer function closure.
+  Node* GetFunctionClosure();
+
+  // Get or create the node that represents the outer function context.
+  Node* GetFunctionContext();
+
+  // Get or create the node that represents the incoming new target value.
+  Node* GetNewTarget();
+
+  // Builder for accessing a (potentially immutable) object field.
+  Node* BuildLoadObjectField(Node* object, int offset);
+  Node* BuildLoadImmutableObjectField(Node* object, int offset);
+
+  // Builder for accessing type feedback vector.
+  Node* BuildLoadFeedbackVector();
+
+  // Builder for loading the a native context field.
+  Node* BuildLoadNativeContextField(int index);
+
+  // Helper function for creating a pair containing type feedback vector and
+  // a feedback slot.
+  VectorSlotPair CreateVectorSlotPair(int slot_id);
+
+  void set_environment(Environment* env) { environment_ = env; }
+  const Environment* environment() const { return environment_; }
+  Environment* environment() { return environment_; }
+
+  // Node creation helpers
+  Node* NewNode(const Operator* op, bool incomplete = false) {
+    return MakeNode(op, 0, static_cast<Node**>(nullptr), incomplete);
+  }
+
+  Node* NewNode(const Operator* op, Node* n1) {
+    Node* buffer[] = {n1};
+    return MakeNode(op, arraysize(buffer), buffer, false);
+  }
+
+  Node* NewNode(const Operator* op, Node* n1, Node* n2) {
+    Node* buffer[] = {n1, n2};
+    return MakeNode(op, arraysize(buffer), buffer, false);
+  }
+
+  Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3) {
+    Node* buffer[] = {n1, n2, n3};
+    return MakeNode(op, arraysize(buffer), buffer, false);
+  }
+
+  Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4) {
+    Node* buffer[] = {n1, n2, n3, n4};
+    return MakeNode(op, arraysize(buffer), buffer, false);
+  }
+
+  // Helpers to create new control nodes.
+  Node* NewIfTrue() { return NewNode(common()->IfTrue()); }
+  Node* NewIfFalse() { return NewNode(common()->IfFalse()); }
+  Node* NewMerge() { return NewNode(common()->Merge(1), true); }
+  Node* NewLoop() { return NewNode(common()->Loop(1), true); }
+  Node* NewBranch(Node* condition, BranchHint hint = BranchHint::kNone) {
+    return NewNode(common()->Branch(hint), condition);
+  }
+
+  // Creates a new Phi node having {count} input values.
+  Node* NewPhi(int count, Node* input, Node* control);
+  Node* NewEffectPhi(int count, Node* input, Node* control);
+
+  // Helpers for merging control, effect or value dependencies.
+  Node* MergeControl(Node* control, Node* other);
+  Node* MergeEffect(Node* effect, Node* other_effect, Node* control);
+  Node* MergeValue(Node* value, Node* other_value, Node* control);
+
+  // The main node creation chokepoint. Adds context, frame state, effect,
+  // and control dependencies depending on the operator.
+  Node* MakeNode(const Operator* op, int value_input_count, Node** value_inputs,
+                 bool incomplete);
+
+  // Helper to indicate a node exits the function body.
+  void UpdateControlDependencyToLeaveFunction(Node* exit);
+
+  Node** EnsureInputBufferSize(int size);
+
+  Node* ProcessCallArguments(const Operator* call_op, Node* callee,
+                             interpreter::Register receiver, size_t arity);
+  Node* ProcessCallNewArguments(const Operator* call_new_op,
+                                interpreter::Register callee,
+                                interpreter::Register first_arg, size_t arity);
+  Node* ProcessCallRuntimeArguments(const Operator* call_runtime_op,
+                                    interpreter::Register first_arg,
+                                    size_t arity);
+
+  void BuildCreateLiteral(const Operator* op,
+                          const interpreter::BytecodeArrayIterator& iterator);
+  void BuildCreateRegExpLiteral(
+      const interpreter::BytecodeArrayIterator& iterator);
+  void BuildCreateArrayLiteral(
+      const interpreter::BytecodeArrayIterator& iterator);
+  void BuildCreateObjectLiteral(
+      const interpreter::BytecodeArrayIterator& iterator);
+  void BuildCreateArguments(CreateArgumentsParameters::Type type,
+                            const interpreter::BytecodeArrayIterator& iterator);
+  void BuildLoadGlobal(const interpreter::BytecodeArrayIterator& iterator,
+                       TypeofMode typeof_mode);
+  void BuildStoreGlobal(const interpreter::BytecodeArrayIterator& iterator);
+  void BuildNamedLoad(const interpreter::BytecodeArrayIterator& iterator);
+  void BuildKeyedLoad(const interpreter::BytecodeArrayIterator& iterator);
+  void BuildNamedStore(const interpreter::BytecodeArrayIterator& iterator);
+  void BuildKeyedStore(const interpreter::BytecodeArrayIterator& iterator);
+  void BuildLdaLookupSlot(TypeofMode typeof_mode,
+                          const interpreter::BytecodeArrayIterator& iterator);
+  void BuildStaLookupSlot(LanguageMode language_mode,
+                          const interpreter::BytecodeArrayIterator& iterator);
+  void BuildCall(const interpreter::BytecodeArrayIterator& iterator);
+  void BuildBinaryOp(const Operator* op,
+                     const interpreter::BytecodeArrayIterator& iterator);
+  void BuildCompareOp(const Operator* op,
+                      const interpreter::BytecodeArrayIterator& iterator);
+  void BuildDelete(const interpreter::BytecodeArrayIterator& iterator);
+  void BuildCastOperator(const Operator* js_op,
+                         const interpreter::BytecodeArrayIterator& iterator);
+
+  // Control flow plumbing.
+  void BuildJump(int source_offset, int target_offset);
+  void BuildJump();
+  void BuildConditionalJump(Node* condition);
+  void BuildJumpIfEqual(Node* comperand);
+  void BuildJumpIfToBooleanEqual(Node* boolean_comperand);
+
+  // Constructing merge and loop headers.
+  void MergeEnvironmentsOfBackwardBranches(int source_offset,
+                                           int target_offset);
+  void MergeEnvironmentsOfForwardBranches(int source_offset);
+  void BuildLoopHeaderForBackwardBranches(int source_offset);
+
+  // Attaches a frame state to |node| for the entry to the function.
+  void PrepareEntryFrameState(Node* node);
+
+  // Growth increment for the temporary buffer used to construct input lists to
+  // new nodes.
+  static const int kInputBufferSizeIncrement = 64;
+
+  // Field accessors
+  CommonOperatorBuilder* common() const { return jsgraph_->common(); }
+  Zone* graph_zone() const { return graph()->zone(); }
+  CompilationInfo* info() const { return info_; }
+  JSGraph* jsgraph() const { return jsgraph_; }
+  JSOperatorBuilder* javascript() const { return jsgraph_->javascript(); }
+  Zone* local_zone() const { return local_zone_; }
+  const Handle<BytecodeArray>& bytecode_array() const {
+    return bytecode_array_;
+  }
+  const FrameStateFunctionInfo* frame_state_function_info() const {
+    return frame_state_function_info_;
+  }
+
+  LanguageMode language_mode() const {
+    // TODO(mythria): Don't rely on parse information to get language mode.
+    return info()->language_mode();
+  }
+
+  const interpreter::BytecodeArrayIterator* bytecode_iterator() const {
+    return bytecode_iterator_;
+  }
+
+  void set_bytecode_iterator(
+      const interpreter::BytecodeArrayIterator* bytecode_iterator) {
+    bytecode_iterator_ = bytecode_iterator;
+  }
+
+  const BytecodeBranchAnalysis* branch_analysis() const {
+    return branch_analysis_;
+  }
+
+  void set_branch_analysis(const BytecodeBranchAnalysis* branch_analysis) {
+    branch_analysis_ = branch_analysis;
+  }
+
+#define DECLARE_VISIT_BYTECODE(name, ...) \
+  void Visit##name(const interpreter::BytecodeArrayIterator& iterator);
+  BYTECODE_LIST(DECLARE_VISIT_BYTECODE)
+#undef DECLARE_VISIT_BYTECODE
+
+  Zone* local_zone_;
+  CompilationInfo* info_;
+  JSGraph* jsgraph_;
+  Handle<BytecodeArray> bytecode_array_;
+  const FrameStateFunctionInfo* frame_state_function_info_;
+  const interpreter::BytecodeArrayIterator* bytecode_iterator_;
+  const BytecodeBranchAnalysis* branch_analysis_;
+  Environment* environment_;
+
+
+  // Merge environments are snapshots of the environment at a particular
+  // bytecode offset to be merged into a later environment.
+  ZoneMap<int, Environment*> merge_environments_;
+
+  // Loop header environments are environments created for bytecodes
+  // where it is known there are back branches, ie a loop header.
+  ZoneMap<int, Environment*> loop_header_environments_;
+
+  // Temporary storage for building node input lists.
+  int input_buffer_size_;
+  Node** input_buffer_;
+
+  // Nodes representing values in the activation record.
+  SetOncePointer<Node> function_context_;
+  SetOncePointer<Node> function_closure_;
+  SetOncePointer<Node> new_target_;
+
+  // Optimization to cache loaded feedback vector.
+  SetOncePointer<Node> feedback_vector_;
+
+  // Control nodes that exit the function body.
+  ZoneVector<Node*> exit_controls_;
+
+  DISALLOW_COPY_AND_ASSIGN(BytecodeGraphBuilder);
+};
+
+
+class BytecodeGraphBuilder::Environment : public ZoneObject {
+ public:
+  Environment(BytecodeGraphBuilder* builder, int register_count,
+              int parameter_count, Node* control_dependency, Node* context);
+
+  int parameter_count() const { return parameter_count_; }
+  int register_count() const { return register_count_; }
+
+  Node* LookupAccumulator() const;
+  Node* LookupRegister(interpreter::Register the_register) const;
+
+  void ExchangeRegisters(interpreter::Register reg0,
+                         interpreter::Register reg1);
+
+  void BindAccumulator(Node* node, FrameStateBeforeAndAfter* states = nullptr);
+  void BindRegister(interpreter::Register the_register, Node* node,
+                    FrameStateBeforeAndAfter* states = nullptr);
+  void BindRegistersToProjections(interpreter::Register first_reg, Node* node,
+                                  FrameStateBeforeAndAfter* states = nullptr);
+  void RecordAfterState(Node* node, FrameStateBeforeAndAfter* states);
+
+  bool IsMarkedAsUnreachable() const;
+  void MarkAsUnreachable();
+
+  // Effect dependency tracked by this environment.
+  Node* GetEffectDependency() { return effect_dependency_; }
+  void UpdateEffectDependency(Node* dependency) {
+    effect_dependency_ = dependency;
+  }
+
+  // Preserve a checkpoint of the environment for the IR graph. Any
+  // further mutation of the environment will not affect checkpoints.
+  Node* Checkpoint(BailoutId bytecode_offset, OutputFrameStateCombine combine);
+
+  // Returns true if the state values are up to date with the current
+  // environment.
+  bool StateValuesAreUpToDate(int output_poke_offset, int output_poke_count);
+
+  // Control dependency tracked by this environment.
+  Node* GetControlDependency() const { return control_dependency_; }
+  void UpdateControlDependency(Node* dependency) {
+    control_dependency_ = dependency;
+  }
+
+  Node* Context() const { return context_; }
+  void SetContext(Node* new_context) { context_ = new_context; }
+
+  Environment* CopyForConditional() const;
+  Environment* CopyForLoop();
+  void Merge(Environment* other);
+
+ private:
+  explicit Environment(const Environment* copy);
+  void PrepareForLoop();
+  bool StateValuesAreUpToDate(Node** state_values, int offset, int count,
+                              int output_poke_start, int output_poke_end);
+  bool StateValuesRequireUpdate(Node** state_values, int offset, int count);
+  void UpdateStateValues(Node** state_values, int offset, int count);
+
+  int RegisterToValuesIndex(interpreter::Register the_register) const;
+
+  Zone* zone() const { return builder_->local_zone(); }
+  Graph* graph() const { return builder_->graph(); }
+  CommonOperatorBuilder* common() const { return builder_->common(); }
+  BytecodeGraphBuilder* builder() const { return builder_; }
+  const NodeVector* values() const { return &values_; }
+  NodeVector* values() { return &values_; }
+  int register_base() const { return register_base_; }
+  int accumulator_base() const { return accumulator_base_; }
+
+  BytecodeGraphBuilder* builder_;
+  int register_count_;
+  int parameter_count_;
+  Node* context_;
+  Node* control_dependency_;
+  Node* effect_dependency_;
+  NodeVector values_;
+  Node* parameters_state_values_;
+  Node* registers_state_values_;
+  Node* accumulator_state_values_;
+  int register_base_;
+  int accumulator_base_;
+};
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_BYTECODE_GRAPH_BUILDER_H_
diff --git a/src/compiler/c-linkage.cc b/src/compiler/c-linkage.cc
new file mode 100644
index 0000000..44e0bf1
--- /dev/null
+++ b/src/compiler/c-linkage.cc
@@ -0,0 +1,229 @@
+// Copyright 2015 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/assembler.h"
+#include "src/macro-assembler.h"
+
+#include "src/compiler/linkage.h"
+
+#include "src/zone.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+namespace {
+LinkageLocation regloc(Register reg) {
+  return LinkageLocation::ForRegister(reg.code());
+}
+
+
+// Platform-specific configuration for C calling convention.
+#if V8_TARGET_ARCH_IA32
+// ===========================================================================
+// == ia32 ===================================================================
+// ===========================================================================
+#define CALLEE_SAVE_REGISTERS esi.bit() | edi.bit() | ebx.bit()
+
+#elif V8_TARGET_ARCH_X64
+// ===========================================================================
+// == x64 ====================================================================
+// ===========================================================================
+
+#ifdef _WIN64
+// == x64 windows ============================================================
+#define STACK_SHADOW_WORDS 4
+#define PARAM_REGISTERS rcx, rdx, r8, r9
+#define CALLEE_SAVE_REGISTERS                                             \
+  rbx.bit() | rdi.bit() | rsi.bit() | r12.bit() | r13.bit() | r14.bit() | \
+      r15.bit()
+#define CALLEE_SAVE_FP_REGISTERS                                        \
+  (1 << xmm6.code()) | (1 << xmm7.code()) | (1 << xmm8.code()) |        \
+      (1 << xmm9.code()) | (1 << xmm10.code()) | (1 << xmm11.code()) |  \
+      (1 << xmm12.code()) | (1 << xmm13.code()) | (1 << xmm14.code()) | \
+      (1 << xmm15.code())
+#else
+// == x64 other ==============================================================
+#define PARAM_REGISTERS rdi, rsi, rdx, rcx, r8, r9
+#define CALLEE_SAVE_REGISTERS \
+  rbx.bit() | r12.bit() | r13.bit() | r14.bit() | r15.bit()
+#endif
+
+#elif V8_TARGET_ARCH_X87
+// ===========================================================================
+// == x87 ====================================================================
+// ===========================================================================
+#define CALLEE_SAVE_REGISTERS esi.bit() | edi.bit() | ebx.bit()
+
+#elif V8_TARGET_ARCH_ARM
+// ===========================================================================
+// == arm ====================================================================
+// ===========================================================================
+#define PARAM_REGISTERS r0, r1, r2, r3
+#define CALLEE_SAVE_REGISTERS \
+  r4.bit() | r5.bit() | r6.bit() | r7.bit() | r8.bit() | r9.bit() | r10.bit()
+#define CALLEE_SAVE_FP_REGISTERS                                  \
+  (1 << d8.code()) | (1 << d9.code()) | (1 << d10.code()) |       \
+      (1 << d11.code()) | (1 << d12.code()) | (1 << d13.code()) | \
+      (1 << d14.code()) | (1 << d15.code())
+
+
+#elif V8_TARGET_ARCH_ARM64
+// ===========================================================================
+// == arm64 ====================================================================
+// ===========================================================================
+#define PARAM_REGISTERS x0, x1, x2, x3, x4, x5, x6, x7
+#define CALLEE_SAVE_REGISTERS                                     \
+  (1 << x19.code()) | (1 << x20.code()) | (1 << x21.code()) |     \
+      (1 << x22.code()) | (1 << x23.code()) | (1 << x24.code()) | \
+      (1 << x25.code()) | (1 << x26.code()) | (1 << x27.code()) | \
+      (1 << x28.code()) | (1 << x29.code()) | (1 << x30.code())
+
+
+#define CALLEE_SAVE_FP_REGISTERS                                  \
+  (1 << d8.code()) | (1 << d9.code()) | (1 << d10.code()) |       \
+      (1 << d11.code()) | (1 << d12.code()) | (1 << d13.code()) | \
+      (1 << d14.code()) | (1 << d15.code())
+
+#elif V8_TARGET_ARCH_MIPS
+// ===========================================================================
+// == mips ===================================================================
+// ===========================================================================
+#define PARAM_REGISTERS a0, a1, a2, a3
+#define CALLEE_SAVE_REGISTERS                                                  \
+  s0.bit() | s1.bit() | s2.bit() | s3.bit() | s4.bit() | s5.bit() | s6.bit() | \
+      s7.bit()
+#define CALLEE_SAVE_FP_REGISTERS \
+  f20.bit() | f22.bit() | f24.bit() | f26.bit() | f28.bit() | f30.bit()
+
+#elif V8_TARGET_ARCH_MIPS64
+// ===========================================================================
+// == mips64 =================================================================
+// ===========================================================================
+#define PARAM_REGISTERS a0, a1, a2, a3, a4, a5, a6, a7
+#define CALLEE_SAVE_REGISTERS                                                  \
+  s0.bit() | s1.bit() | s2.bit() | s3.bit() | s4.bit() | s5.bit() | s6.bit() | \
+      s7.bit()
+#define CALLEE_SAVE_FP_REGISTERS \
+  f20.bit() | f22.bit() | f24.bit() | f26.bit() | f28.bit() | f30.bit()
+
+#elif V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_PPC64
+// ===========================================================================
+// == ppc & ppc64 ============================================================
+// ===========================================================================
+#define PARAM_REGISTERS r3, r4, r5, r6, r7, r8, r9, r10
+#define CALLEE_SAVE_REGISTERS                                                 \
+  r14.bit() | r15.bit() | r16.bit() | r17.bit() | r18.bit() | r19.bit() |     \
+      r20.bit() | r21.bit() | r22.bit() | r23.bit() | r24.bit() | r25.bit() | \
+      r26.bit() | r27.bit() | r28.bit() | r29.bit() | r30.bit()
+#define CALLEE_SAVE_FP_REGISTERS                                              \
+  d14.bit() | d15.bit() | d16.bit() | d17.bit() | d18.bit() | d19.bit() |     \
+      d20.bit() | d21.bit() | d22.bit() | d23.bit() | d24.bit() | d25.bit() | \
+      d26.bit() | d27.bit() | d28.bit() | d29.bit() | d30.bit() | d31.bit()
+
+#else
+// ===========================================================================
+// == unknown ================================================================
+// ===========================================================================
+#define UNSUPPORTED_C_LINKAGE 1
+#endif
+}  // namespace
+
+
+// General code uses the above configuration data.
+CallDescriptor* Linkage::GetSimplifiedCDescriptor(
+    Zone* zone, const MachineSignature* msig) {
+  LocationSignature::Builder locations(zone, msig->return_count(),
+                                       msig->parameter_count());
+#if 0  // TODO(titzer): instruction selector tests break here.
+  // Check the types of the signature.
+  // Currently no floating point parameters or returns are allowed because
+  // on x87 and ia32, the FP top of stack is involved.
+
+  for (size_t i = 0; i < msig->return_count(); i++) {
+    MachineType type = RepresentationOf(msig->GetReturn(i));
+    CHECK(type != kRepFloat32 && type != kRepFloat64);
+  }
+  for (size_t i = 0; i < msig->parameter_count(); i++) {
+    MachineType type = RepresentationOf(msig->GetParam(i));
+    CHECK(type != kRepFloat32 && type != kRepFloat64);
+  }
+#endif
+
+#ifdef UNSUPPORTED_C_LINKAGE
+  // This method should not be called on unknown architectures.
+  V8_Fatal(__FILE__, __LINE__,
+           "requested C call descriptor on unsupported architecture");
+  return nullptr;
+#endif
+
+  // Add return location(s).
+  CHECK(locations.return_count_ <= 2);
+
+  if (locations.return_count_ > 0) {
+    locations.AddReturn(regloc(kReturnRegister0));
+  }
+  if (locations.return_count_ > 1) {
+    locations.AddReturn(regloc(kReturnRegister1));
+  }
+
+  const int parameter_count = static_cast<int>(msig->parameter_count());
+
+#ifdef PARAM_REGISTERS
+  static const Register kParamRegisters[] = {PARAM_REGISTERS};
+  static const int kParamRegisterCount =
+      static_cast<int>(arraysize(kParamRegisters));
+#else
+  static const Register* kParamRegisters = nullptr;
+  static const int kParamRegisterCount = 0;
+#endif
+
+#ifdef STACK_SHADOW_WORDS
+  int stack_offset = STACK_SHADOW_WORDS;
+#else
+  int stack_offset = 0;
+#endif
+  // Add register and/or stack parameter(s).
+  for (int i = 0; i < parameter_count; i++) {
+    if (i < kParamRegisterCount) {
+      locations.AddParam(regloc(kParamRegisters[i]));
+    } else {
+      locations.AddParam(
+          LinkageLocation::ForCallerFrameSlot(-1 - stack_offset));
+      stack_offset++;
+    }
+  }
+
+#ifdef CALLEE_SAVE_REGISTERS
+  const RegList kCalleeSaveRegisters = CALLEE_SAVE_REGISTERS;
+#else
+  const RegList kCalleeSaveRegisters = 0;
+#endif
+
+#ifdef CALLEE_SAVE_FP_REGISTERS
+  const RegList kCalleeSaveFPRegisters = CALLEE_SAVE_FP_REGISTERS;
+#else
+  const RegList kCalleeSaveFPRegisters = 0;
+#endif
+
+  // The target for C calls is always an address (i.e. machine pointer).
+  MachineType target_type = MachineType::Pointer();
+  LinkageLocation target_loc = LinkageLocation::ForAnyRegister();
+  return new (zone) CallDescriptor(  // --
+      CallDescriptor::kCallAddress,  // kind
+      target_type,                   // target MachineType
+      target_loc,                    // target location
+      msig,                          // machine_sig
+      locations.Build(),             // location_sig
+      0,                             // stack_parameter_count
+      Operator::kNoProperties,       // properties
+      kCalleeSaveRegisters,          // callee-saved registers
+      kCalleeSaveFPRegisters,        // callee-saved fp regs
+      CallDescriptor::kNoFlags,      // flags
+      "c-call");
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/change-lowering.cc b/src/compiler/change-lowering.cc
index 7ddc751..f791db1 100644
--- a/src/compiler/change-lowering.cc
+++ b/src/compiler/change-lowering.cc
@@ -4,12 +4,14 @@
 
 #include "src/compiler/change-lowering.h"
 
+#include "src/address-map.h"
 #include "src/code-factory.h"
-#include "src/compiler/diamond.h"
 #include "src/compiler/js-graph.h"
 #include "src/compiler/linkage.h"
 #include "src/compiler/machine-operator.h"
-#include "src/compiler/node-properties-inl.h"
+#include "src/compiler/node-properties.h"
+#include "src/compiler/operator-properties.h"
+#include "src/compiler/simplified-operator.h"
 
 namespace v8 {
 namespace internal {
@@ -37,6 +39,16 @@
       return ChangeTaggedToUI32(node->InputAt(0), control, kUnsigned);
     case IrOpcode::kChangeUint32ToTagged:
       return ChangeUint32ToTagged(node->InputAt(0), control);
+    case IrOpcode::kLoadField:
+      return LoadField(node);
+    case IrOpcode::kStoreField:
+      return StoreField(node);
+    case IrOpcode::kLoadElement:
+      return LoadElement(node);
+    case IrOpcode::kStoreElement:
+      return StoreElement(node);
+    case IrOpcode::kAllocate:
+      return Allocate(node);
     default:
       return NoChange();
   }
@@ -46,25 +58,17 @@
 
 
 Node* ChangeLowering::HeapNumberValueIndexConstant() {
-  STATIC_ASSERT(HeapNumber::kValueOffset % kPointerSize == 0);
-  const int heap_number_value_offset =
-      ((HeapNumber::kValueOffset / kPointerSize) * (machine()->Is64() ? 8 : 4));
-  return jsgraph()->IntPtrConstant(heap_number_value_offset - kHeapObjectTag);
+  return jsgraph()->IntPtrConstant(HeapNumber::kValueOffset - kHeapObjectTag);
 }
 
 
 Node* ChangeLowering::SmiMaxValueConstant() {
-  const int smi_value_size = machine()->Is32() ? SmiTagging<4>::SmiValueSize()
-                                               : SmiTagging<8>::SmiValueSize();
-  return jsgraph()->Int32Constant(
-      -(static_cast<int>(0xffffffffu << (smi_value_size - 1)) + 1));
+  return jsgraph()->Int32Constant(Smi::kMaxValue);
 }
 
 
 Node* ChangeLowering::SmiShiftBitsConstant() {
-  const int smi_shift_size = machine()->Is32() ? SmiTagging<4>::SmiShiftSize()
-                                               : SmiTagging<8>::SmiShiftSize();
-  return jsgraph()->IntPtrConstant(smi_shift_size + kSmiTagSize);
+  return jsgraph()->IntPtrConstant(kSmiShiftSize + kSmiTagSize);
 }
 
 
@@ -72,17 +76,22 @@
   // The AllocateHeapNumberStub does not use the context, so we can safely pass
   // in Smi zero here.
   Callable callable = CodeFactory::AllocateHeapNumber(isolate());
-  CallDescriptor* descriptor = linkage()->GetStubCallDescriptor(
-      callable.descriptor(), 0, CallDescriptor::kNoFlags);
   Node* target = jsgraph()->HeapConstant(callable.code());
   Node* context = jsgraph()->NoContextConstant();
-  Node* effect = graph()->NewNode(common()->ValueEffect(1), value);
-  Node* heap_number = graph()->NewNode(common()->Call(descriptor), target,
-                                       context, effect, control);
+  Node* effect = graph()->NewNode(common()->BeginRegion(), graph()->start());
+  if (!allocate_heap_number_operator_.is_set()) {
+    CallDescriptor* descriptor = Linkage::GetStubCallDescriptor(
+        isolate(), jsgraph()->zone(), callable.descriptor(), 0,
+        CallDescriptor::kNoFlags, Operator::kNoThrow);
+    allocate_heap_number_operator_.set(common()->Call(descriptor));
+  }
+  Node* heap_number = graph()->NewNode(allocate_heap_number_operator_.get(),
+                                       target, context, effect, control);
   Node* store = graph()->NewNode(
-      machine()->Store(StoreRepresentation(kMachFloat64, kNoWriteBarrier)),
+      machine()->Store(StoreRepresentation(MachineRepresentation::kFloat64,
+                                           kNoWriteBarrier)),
       heap_number, HeapNumberValueIndexConstant(), value, heap_number, control);
-  return graph()->NewNode(common()->Finish(1), heap_number, store);
+  return graph()->NewNode(common()->FinishRegion(), heap_number, store);
 }
 
 
@@ -91,6 +100,14 @@
 }
 
 
+Node* ChangeLowering::ChangeInt32ToSmi(Node* value) {
+  if (machine()->Is64()) {
+    value = graph()->NewNode(machine()->ChangeInt32ToInt64(), value);
+  }
+  return graph()->NewNode(machine()->WordShl(), value, SmiShiftBitsConstant());
+}
+
+
 Node* ChangeLowering::ChangeSmiToFloat64(Node* value) {
   return ChangeInt32ToFloat64(ChangeSmiToInt32(value));
 }
@@ -119,7 +136,7 @@
 
 
 Node* ChangeLowering::LoadHeapNumberValue(Node* value, Node* control) {
-  return graph()->NewNode(machine()->Load(kMachFloat64), value,
+  return graph()->NewNode(machine()->Load(MachineType::Float64()), value,
                           HeapNumberValueIndexConstant(), graph()->start(),
                           control);
 }
@@ -133,64 +150,151 @@
 }
 
 
-Node* ChangeLowering::Uint32LessThanOrEqual(Node* lhs, Node* rhs) {
-  return graph()->NewNode(machine()->Uint32LessThanOrEqual(), lhs, rhs);
-}
-
-
-Reduction ChangeLowering::ChangeBitToBool(Node* val, Node* control) {
-  MachineType const type = static_cast<MachineType>(kTypeBool | kRepTagged);
-  return Replace(graph()->NewNode(common()->Select(type), val,
-                                  jsgraph()->TrueConstant(),
-                                  jsgraph()->FalseConstant()));
-}
-
-
-Reduction ChangeLowering::ChangeBoolToBit(Node* val) {
+Reduction ChangeLowering::ChangeBitToBool(Node* value, Node* control) {
   return Replace(
-      graph()->NewNode(machine()->WordEqual(), val, jsgraph()->TrueConstant()));
+      graph()->NewNode(common()->Select(MachineRepresentation::kTagged), value,
+                       jsgraph()->TrueConstant(), jsgraph()->FalseConstant()));
 }
 
 
-Reduction ChangeLowering::ChangeFloat64ToTagged(Node* val, Node* control) {
-  return Replace(AllocateHeapNumberWithValue(val, control));
+Reduction ChangeLowering::ChangeBoolToBit(Node* value) {
+  return Replace(graph()->NewNode(machine()->WordEqual(), value,
+                                  jsgraph()->TrueConstant()));
+}
+
+
+Reduction ChangeLowering::ChangeFloat64ToTagged(Node* value, Node* control) {
+  Type* const value_type = NodeProperties::GetType(value);
+  Node* const value32 = graph()->NewNode(
+      machine()->TruncateFloat64ToInt32(TruncationMode::kRoundToZero), value);
+  // TODO(bmeurer): This fast case must be disabled until we kill the asm.js
+  // support in the generic JavaScript pipeline, because LoadBuffer is lying
+  // about its result.
+  // if (value_type->Is(Type::Signed32())) {
+  //   return ChangeInt32ToTagged(value32, control);
+  // }
+  Node* check_same = graph()->NewNode(
+      machine()->Float64Equal(), value,
+      graph()->NewNode(machine()->ChangeInt32ToFloat64(), value32));
+  Node* branch_same = graph()->NewNode(common()->Branch(), check_same, control);
+
+  Node* if_smi = graph()->NewNode(common()->IfTrue(), branch_same);
+  Node* vsmi;
+  Node* if_box = graph()->NewNode(common()->IfFalse(), branch_same);
+  Node* vbox;
+
+  // We only need to check for -0 if the {value} can potentially contain -0.
+  if (value_type->Maybe(Type::MinusZero())) {
+    Node* check_zero = graph()->NewNode(machine()->Word32Equal(), value32,
+                                        jsgraph()->Int32Constant(0));
+    Node* branch_zero = graph()->NewNode(common()->Branch(BranchHint::kFalse),
+                                         check_zero, if_smi);
+
+    Node* if_zero = graph()->NewNode(common()->IfTrue(), branch_zero);
+    Node* if_notzero = graph()->NewNode(common()->IfFalse(), branch_zero);
+
+    // In case of 0, we need to check the high bits for the IEEE -0 pattern.
+    Node* check_negative = graph()->NewNode(
+        machine()->Int32LessThan(),
+        graph()->NewNode(machine()->Float64ExtractHighWord32(), value),
+        jsgraph()->Int32Constant(0));
+    Node* branch_negative = graph()->NewNode(
+        common()->Branch(BranchHint::kFalse), check_negative, if_zero);
+
+    Node* if_negative = graph()->NewNode(common()->IfTrue(), branch_negative);
+    Node* if_notnegative =
+        graph()->NewNode(common()->IfFalse(), branch_negative);
+
+    // We need to create a box for negative 0.
+    if_smi = graph()->NewNode(common()->Merge(2), if_notzero, if_notnegative);
+    if_box = graph()->NewNode(common()->Merge(2), if_box, if_negative);
+  }
+
+  // On 64-bit machines we can just wrap the 32-bit integer in a smi, for 32-bit
+  // machines we need to deal with potential overflow and fallback to boxing.
+  if (machine()->Is64() || value_type->Is(Type::SignedSmall())) {
+    vsmi = ChangeInt32ToSmi(value32);
+  } else {
+    Node* smi_tag =
+        graph()->NewNode(machine()->Int32AddWithOverflow(), value32, value32);
+
+    Node* check_ovf = graph()->NewNode(common()->Projection(1), smi_tag);
+    Node* branch_ovf = graph()->NewNode(common()->Branch(BranchHint::kFalse),
+                                        check_ovf, if_smi);
+
+    Node* if_ovf = graph()->NewNode(common()->IfTrue(), branch_ovf);
+    if_box = graph()->NewNode(common()->Merge(2), if_ovf, if_box);
+
+    if_smi = graph()->NewNode(common()->IfFalse(), branch_ovf);
+    vsmi = graph()->NewNode(common()->Projection(0), smi_tag);
+  }
+
+  // Allocate the box for the {value}.
+  vbox = AllocateHeapNumberWithValue(value, if_box);
+
+  control = graph()->NewNode(common()->Merge(2), if_smi, if_box);
+  value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
+                           vsmi, vbox, control);
+  return Replace(value);
 }
 
 
 Reduction ChangeLowering::ChangeInt32ToTagged(Node* value, Node* control) {
-  if (machine()->Is64()) {
-    return Replace(graph()->NewNode(
-        machine()->Word64Shl(),
-        graph()->NewNode(machine()->ChangeInt32ToInt64(), value),
-        SmiShiftBitsConstant()));
-  } else if (NodeProperties::GetBounds(value).upper->Is(Type::SignedSmall())) {
-    return Replace(
-        graph()->NewNode(machine()->WordShl(), value, SmiShiftBitsConstant()));
+  if (machine()->Is64() ||
+      NodeProperties::GetType(value)->Is(Type::SignedSmall())) {
+    return Replace(ChangeInt32ToSmi(value));
   }
 
   Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(), value, value);
-  Node* ovf = graph()->NewNode(common()->Projection(1), add);
 
-  Diamond d(graph(), common(), ovf, BranchHint::kFalse);
-  d.Chain(control);
-  return Replace(
-      d.Phi(kMachAnyTagged,
-            AllocateHeapNumberWithValue(ChangeInt32ToFloat64(value), d.if_true),
-            graph()->NewNode(common()->Projection(0), add)));
+  Node* ovf = graph()->NewNode(common()->Projection(1), add);
+  Node* branch =
+      graph()->NewNode(common()->Branch(BranchHint::kFalse), ovf, control);
+
+  Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
+  Node* vtrue =
+      AllocateHeapNumberWithValue(ChangeInt32ToFloat64(value), if_true);
+
+  Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+  Node* vfalse = graph()->NewNode(common()->Projection(0), add);
+
+  Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
+  Node* phi = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
+                               vtrue, vfalse, merge);
+
+  return Replace(phi);
 }
 
 
 Reduction ChangeLowering::ChangeTaggedToUI32(Node* value, Node* control,
                                              Signedness signedness) {
-  const MachineType type = (signedness == kSigned) ? kMachInt32 : kMachUint32;
+  if (NodeProperties::GetType(value)->Is(Type::TaggedSigned())) {
+    return Replace(ChangeSmiToInt32(value));
+  }
+
   const Operator* op = (signedness == kSigned)
                            ? machine()->ChangeFloat64ToInt32()
                            : machine()->ChangeFloat64ToUint32();
-  Diamond d(graph(), common(), TestNotSmi(value), BranchHint::kFalse);
-  d.Chain(control);
-  return Replace(
-      d.Phi(type, graph()->NewNode(op, LoadHeapNumberValue(value, d.if_true)),
-            ChangeSmiToInt32(value)));
+
+  if (NodeProperties::GetType(value)->Is(Type::TaggedPointer())) {
+    return Replace(graph()->NewNode(op, LoadHeapNumberValue(value, control)));
+  }
+
+  Node* check = TestNotSmi(value);
+  Node* branch =
+      graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control);
+
+  Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
+  Node* vtrue = graph()->NewNode(op, LoadHeapNumberValue(value, if_true));
+
+  Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+  Node* vfalse = ChangeSmiToInt32(value);
+
+  Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
+  Node* phi = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
+                               vtrue, vfalse, merge);
+
+  return Replace(phi);
 }
 
 
@@ -200,6 +304,7 @@
   if (value->opcode() != opcode) return false;
   bool first = true;
   for (Edge const edge : value->use_edges()) {
+    if (NodeProperties::IsControlEdge(edge)) continue;
     if (NodeProperties::IsEffectEdge(edge)) continue;
     DCHECK(NodeProperties::IsValueEdge(edge));
     if (!first) return false;
@@ -220,46 +325,261 @@
     //     else LoadHeapNumberValue(y)
     Node* const object = NodeProperties::GetValueInput(value, 0);
     Node* const context = NodeProperties::GetContextInput(value);
+    Node* const frame_state = NodeProperties::GetFrameStateInput(value, 0);
     Node* const effect = NodeProperties::GetEffectInput(value);
     Node* const control = NodeProperties::GetControlInput(value);
 
-    Diamond d1(graph(), common(), TestNotSmi(object), BranchHint::kFalse);
-    d1.Chain(control);
+    const Operator* merge_op = common()->Merge(2);
+    const Operator* ephi_op = common()->EffectPhi(2);
+    const Operator* phi_op = common()->Phi(MachineRepresentation::kFloat64, 2);
 
-    Node* number =
-        graph()->NewNode(value->op(), object, context, effect, d1.if_true);
-    Diamond d2(graph(), common(), TestNotSmi(number));
-    d2.Nest(d1, true);
-    Node* phi2 = d2.Phi(kMachFloat64, LoadHeapNumberValue(number, d2.if_true),
-                        ChangeSmiToFloat64(number));
+    Node* check1 = TestNotSmi(object);
+    Node* branch1 =
+        graph()->NewNode(common()->Branch(BranchHint::kFalse), check1, control);
 
-    Node* phi1 = d1.Phi(kMachFloat64, phi2, ChangeSmiToFloat64(object));
-    Node* ephi1 = d1.EffectPhi(number, effect);
+    Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
+    Node* vtrue1 = graph()->NewNode(value->op(), object, context, frame_state,
+                                    effect, if_true1);
+    Node* etrue1 = vtrue1;
 
-    for (Edge edge : value->use_edges()) {
-      if (NodeProperties::IsEffectEdge(edge)) {
-        edge.UpdateTo(ephi1);
+    Node* check2 = TestNotSmi(vtrue1);
+    Node* branch2 = graph()->NewNode(common()->Branch(), check2, if_true1);
+
+    Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
+    Node* vtrue2 = LoadHeapNumberValue(vtrue1, if_true2);
+
+    Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
+    Node* vfalse2 = ChangeSmiToFloat64(vtrue1);
+
+    if_true1 = graph()->NewNode(merge_op, if_true2, if_false2);
+    vtrue1 = graph()->NewNode(phi_op, vtrue2, vfalse2, if_true1);
+
+    Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
+    Node* vfalse1 = ChangeSmiToFloat64(object);
+    Node* efalse1 = effect;
+
+    Node* merge1 = graph()->NewNode(merge_op, if_true1, if_false1);
+    Node* ephi1 = graph()->NewNode(ephi_op, etrue1, efalse1, merge1);
+    Node* phi1 = graph()->NewNode(phi_op, vtrue1, vfalse1, merge1);
+
+    // Wire the new diamond into the graph, {JSToNumber} can still throw.
+    NodeProperties::ReplaceUses(value, phi1, ephi1, etrue1, etrue1);
+
+    // TODO(mstarzinger): This iteration cuts out the IfSuccess projection from
+    // the node and places it inside the diamond. Come up with a helper method!
+    for (Node* use : etrue1->uses()) {
+      if (use->opcode() == IrOpcode::kIfSuccess) {
+        use->ReplaceUses(merge1);
+        NodeProperties::ReplaceControlInput(branch2, use);
       }
     }
+
     return Replace(phi1);
   }
 
-  Diamond d(graph(), common(), TestNotSmi(value), BranchHint::kFalse);
-  d.Chain(control);
-  Node* load = LoadHeapNumberValue(value, d.if_true);
-  Node* number = ChangeSmiToFloat64(value);
-  return Replace(d.Phi(kMachFloat64, load, number));
+  Node* check = TestNotSmi(value);
+  Node* branch =
+      graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control);
+
+  Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
+  Node* vtrue = LoadHeapNumberValue(value, if_true);
+
+  Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+  Node* vfalse = ChangeSmiToFloat64(value);
+
+  Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
+  Node* phi = graph()->NewNode(
+      common()->Phi(MachineRepresentation::kFloat64, 2), vtrue, vfalse, merge);
+
+  return Replace(phi);
 }
 
 
 Reduction ChangeLowering::ChangeUint32ToTagged(Node* value, Node* control) {
-  Diamond d(graph(), common(),
-            Uint32LessThanOrEqual(value, SmiMaxValueConstant()),
-            BranchHint::kTrue);
-  d.Chain(control);
-  return Replace(d.Phi(
-      kMachAnyTagged, ChangeUint32ToSmi(value),
-      AllocateHeapNumberWithValue(ChangeUint32ToFloat64(value), d.if_false)));
+  if (NodeProperties::GetType(value)->Is(Type::UnsignedSmall())) {
+    return Replace(ChangeUint32ToSmi(value));
+  }
+
+  Node* check = graph()->NewNode(machine()->Uint32LessThanOrEqual(), value,
+                                 SmiMaxValueConstant());
+  Node* branch =
+      graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
+
+  Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
+  Node* vtrue = ChangeUint32ToSmi(value);
+
+  Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+  Node* vfalse =
+      AllocateHeapNumberWithValue(ChangeUint32ToFloat64(value), if_false);
+
+  Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
+  Node* phi = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
+                               vtrue, vfalse, merge);
+
+  return Replace(phi);
+}
+
+
+namespace {
+
+WriteBarrierKind ComputeWriteBarrierKind(BaseTaggedness base_is_tagged,
+                                         MachineRepresentation representation,
+                                         Type* field_type, Type* input_type) {
+  if (field_type->Is(Type::TaggedSigned()) ||
+      input_type->Is(Type::TaggedSigned())) {
+    // Write barriers are only for writes of heap objects.
+    return kNoWriteBarrier;
+  }
+  if (input_type->Is(Type::BooleanOrNullOrUndefined())) {
+    // Write barriers are not necessary when storing true, false, null or
+    // undefined, because these special oddballs are always in the root set.
+    return kNoWriteBarrier;
+  }
+  if (base_is_tagged == kTaggedBase &&
+      representation == MachineRepresentation::kTagged) {
+    if (input_type->IsConstant() &&
+        input_type->AsConstant()->Value()->IsHeapObject()) {
+      Handle<HeapObject> input =
+          Handle<HeapObject>::cast(input_type->AsConstant()->Value());
+      if (input->IsMap()) {
+        // Write barriers for storing maps are cheaper.
+        return kMapWriteBarrier;
+      }
+      Isolate* const isolate = input->GetIsolate();
+      RootIndexMap root_index_map(isolate);
+      int root_index = root_index_map.Lookup(*input);
+      if (root_index != RootIndexMap::kInvalidRootIndex &&
+          isolate->heap()->RootIsImmortalImmovable(root_index)) {
+        // Write barriers are unnecessary for immortal immovable roots.
+        return kNoWriteBarrier;
+      }
+    }
+    if (field_type->Is(Type::TaggedPointer()) ||
+        input_type->Is(Type::TaggedPointer())) {
+      // Write barriers for heap objects don't need a Smi check.
+      return kPointerWriteBarrier;
+    }
+    // Write barriers are only for writes into heap objects (i.e. tagged base).
+    return kFullWriteBarrier;
+  }
+  return kNoWriteBarrier;
+}
+
+
+WriteBarrierKind ComputeWriteBarrierKind(BaseTaggedness base_is_tagged,
+                                         MachineRepresentation representation,
+                                         int field_offset, Type* field_type,
+                                         Type* input_type) {
+  if (base_is_tagged == kTaggedBase && field_offset == HeapObject::kMapOffset) {
+    // Write barriers for storing maps are cheaper.
+    return kMapWriteBarrier;
+  }
+  return ComputeWriteBarrierKind(base_is_tagged, representation, field_type,
+                                 input_type);
+}
+
+}  // namespace
+
+
+Reduction ChangeLowering::LoadField(Node* node) {
+  const FieldAccess& access = FieldAccessOf(node->op());
+  Node* offset = jsgraph()->IntPtrConstant(access.offset - access.tag());
+  node->InsertInput(graph()->zone(), 1, offset);
+  NodeProperties::ChangeOp(node, machine()->Load(access.machine_type));
+  return Changed(node);
+}
+
+
+Reduction ChangeLowering::StoreField(Node* node) {
+  const FieldAccess& access = FieldAccessOf(node->op());
+  Type* type = NodeProperties::GetType(node->InputAt(1));
+  WriteBarrierKind kind = ComputeWriteBarrierKind(
+      access.base_is_tagged, access.machine_type.representation(),
+      access.offset, access.type, type);
+  Node* offset = jsgraph()->IntPtrConstant(access.offset - access.tag());
+  node->InsertInput(graph()->zone(), 1, offset);
+  NodeProperties::ChangeOp(node,
+                           machine()->Store(StoreRepresentation(
+                               access.machine_type.representation(), kind)));
+  return Changed(node);
+}
+
+
+Node* ChangeLowering::ComputeIndex(const ElementAccess& access,
+                                   Node* const key) {
+  Node* index = key;
+  const int element_size_shift =
+      ElementSizeLog2Of(access.machine_type.representation());
+  if (element_size_shift) {
+    index = graph()->NewNode(machine()->Word32Shl(), index,
+                             jsgraph()->Int32Constant(element_size_shift));
+  }
+  const int fixed_offset = access.header_size - access.tag();
+  if (fixed_offset) {
+    index = graph()->NewNode(machine()->Int32Add(), index,
+                             jsgraph()->Int32Constant(fixed_offset));
+  }
+  if (machine()->Is64()) {
+    // TODO(turbofan): This is probably only correct for typed arrays, and only
+    // if the typed arrays are at most 2GiB in size, which happens to match
+    // exactly our current situation.
+    index = graph()->NewNode(machine()->ChangeUint32ToUint64(), index);
+  }
+  return index;
+}
+
+
+Reduction ChangeLowering::LoadElement(Node* node) {
+  const ElementAccess& access = ElementAccessOf(node->op());
+  node->ReplaceInput(1, ComputeIndex(access, node->InputAt(1)));
+  NodeProperties::ChangeOp(node, machine()->Load(access.machine_type));
+  return Changed(node);
+}
+
+
+Reduction ChangeLowering::StoreElement(Node* node) {
+  const ElementAccess& access = ElementAccessOf(node->op());
+  Type* type = NodeProperties::GetType(node->InputAt(2));
+  node->ReplaceInput(1, ComputeIndex(access, node->InputAt(1)));
+  NodeProperties::ChangeOp(
+      node, machine()->Store(StoreRepresentation(
+                access.machine_type.representation(),
+                ComputeWriteBarrierKind(access.base_is_tagged,
+                                        access.machine_type.representation(),
+                                        access.type, type))));
+  return Changed(node);
+}
+
+
+Reduction ChangeLowering::Allocate(Node* node) {
+  PretenureFlag pretenure = OpParameter<PretenureFlag>(node->op());
+  if (pretenure == NOT_TENURED) {
+    Callable callable = CodeFactory::AllocateInNewSpace(isolate());
+    Node* target = jsgraph()->HeapConstant(callable.code());
+    CallDescriptor* descriptor = Linkage::GetStubCallDescriptor(
+        isolate(), jsgraph()->zone(), callable.descriptor(), 0,
+        CallDescriptor::kNoFlags, Operator::kNoThrow);
+    const Operator* op = common()->Call(descriptor);
+    node->InsertInput(graph()->zone(), 0, target);
+    node->InsertInput(graph()->zone(), 2, jsgraph()->NoContextConstant());
+    NodeProperties::ChangeOp(node, op);
+  } else {
+    DCHECK_EQ(TENURED, pretenure);
+    AllocationSpace space = OLD_SPACE;
+    Runtime::FunctionId f = Runtime::kAllocateInTargetSpace;
+    Operator::Properties props = node->op()->properties();
+    CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor(
+        jsgraph()->zone(), f, 2, props, CallDescriptor::kNeedsFrameState);
+    ExternalReference ref(f, jsgraph()->isolate());
+    int32_t flags = AllocateTargetSpace::encode(space);
+    node->InsertInput(graph()->zone(), 0, jsgraph()->CEntryStubConstant(1));
+    node->InsertInput(graph()->zone(), 2, jsgraph()->SmiConstant(flags));
+    node->InsertInput(graph()->zone(), 3, jsgraph()->ExternalConstant(ref));
+    node->InsertInput(graph()->zone(), 4, jsgraph()->Int32Constant(2));
+    node->InsertInput(graph()->zone(), 5, jsgraph()->NoContextConstant());
+    NodeProperties::ChangeOp(node, common()->Call(desc));
+  }
+  return Changed(node);
 }
 
 
diff --git a/src/compiler/change-lowering.h b/src/compiler/change-lowering.h
index 773fd08..6d60776 100644
--- a/src/compiler/change-lowering.h
+++ b/src/compiler/change-lowering.h
@@ -13,17 +13,18 @@
 
 // Forward declarations.
 class CommonOperatorBuilder;
+struct ElementAccess;
 class JSGraph;
 class Linkage;
 class MachineOperatorBuilder;
+class Operator;
 
-class ChangeLowering FINAL : public Reducer {
+class ChangeLowering final : public Reducer {
  public:
-  ChangeLowering(JSGraph* jsgraph, Linkage* linkage)
-      : jsgraph_(jsgraph), linkage_(linkage) {}
-  ~ChangeLowering() FINAL;
+  explicit ChangeLowering(JSGraph* jsgraph) : jsgraph_(jsgraph) {}
+  ~ChangeLowering() final;
 
-  Reduction Reduce(Node* node) FINAL;
+  Reduction Reduce(Node* node) final;
 
  private:
   Node* HeapNumberValueIndexConstant();
@@ -32,13 +33,13 @@
 
   Node* AllocateHeapNumberWithValue(Node* value, Node* control);
   Node* ChangeInt32ToFloat64(Node* value);
+  Node* ChangeInt32ToSmi(Node* value);
   Node* ChangeSmiToFloat64(Node* value);
   Node* ChangeSmiToInt32(Node* value);
   Node* ChangeUint32ToFloat64(Node* value);
   Node* ChangeUint32ToSmi(Node* value);
   Node* LoadHeapNumberValue(Node* value, Node* control);
   Node* TestNotSmi(Node* value);
-  Node* Uint32LessThanOrEqual(Node* lhs, Node* rhs);
 
   Reduction ChangeBitToBool(Node* value, Node* control);
   Reduction ChangeBoolToBit(Node* value);
@@ -49,15 +50,21 @@
                                Signedness signedness);
   Reduction ChangeUint32ToTagged(Node* value, Node* control);
 
+  Reduction LoadField(Node* node);
+  Reduction StoreField(Node* node);
+  Reduction LoadElement(Node* node);
+  Reduction StoreElement(Node* node);
+  Reduction Allocate(Node* node);
+
+  Node* ComputeIndex(const ElementAccess& access, Node* const key);
   Graph* graph() const;
   Isolate* isolate() const;
   JSGraph* jsgraph() const { return jsgraph_; }
-  Linkage* linkage() const { return linkage_; }
   CommonOperatorBuilder* common() const;
   MachineOperatorBuilder* machine() const;
 
-  JSGraph* jsgraph_;
-  Linkage* linkage_;
+  JSGraph* const jsgraph_;
+  SetOncePointer<const Operator> allocate_heap_number_operator_;
 };
 
 }  // namespace compiler
diff --git a/src/compiler/coalesced-live-ranges.cc b/src/compiler/coalesced-live-ranges.cc
new file mode 100644
index 0000000..4ac3e21
--- /dev/null
+++ b/src/compiler/coalesced-live-ranges.cc
@@ -0,0 +1,143 @@
+// Copyright 2015 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/coalesced-live-ranges.h"
+#include "src/compiler/greedy-allocator.h"
+#include "src/compiler/register-allocator.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+
+LiveRangeConflictIterator::LiveRangeConflictIterator(const LiveRange* range,
+                                                     IntervalStore* storage)
+    : query_(range->first_interval()),
+      pos_(storage->end()),
+      intervals_(storage) {
+  MovePosAndQueryToFirstConflict();
+}
+
+
+LiveRange* LiveRangeConflictIterator::Current() const {
+  if (IsFinished()) return nullptr;
+  return pos_->range_;
+}
+
+
+void LiveRangeConflictIterator::MovePosToFirstConflictForQuery() {
+  DCHECK_NOT_NULL(query_);
+  auto end = intervals_->end();
+  LifetimePosition q_start = query_->start();
+  LifetimePosition q_end = query_->end();
+
+  if (intervals_->empty() || intervals_->rbegin()->end_ <= q_start ||
+      intervals_->begin()->start_ >= q_end) {
+    pos_ = end;
+    return;
+  }
+
+  pos_ = intervals_->upper_bound(AsAllocatedInterval(q_start));
+  // pos is either at the end (no start strictly greater than q_start) or
+  // at some position with the aforementioned property. In either case, the
+  // allocated interval before this one may intersect our query:
+  // either because, although it starts before this query's start, it ends
+  // after; or because it starts exactly at the query start. So unless we're
+  // right at the beginning of the storage - meaning the first allocated
+  // interval is also starting after this query's start - see what's behind.
+  if (pos_ != intervals_->begin()) {
+    --pos_;
+    if (!QueryIntersectsAllocatedInterval()) {
+      // The interval behind wasn't intersecting, so move back.
+      ++pos_;
+    }
+  }
+  if (pos_ == end || !QueryIntersectsAllocatedInterval()) {
+    pos_ = end;
+  }
+}
+
+
+void LiveRangeConflictIterator::MovePosAndQueryToFirstConflict() {
+  auto end = intervals_->end();
+  for (; query_ != nullptr; query_ = query_->next()) {
+    MovePosToFirstConflictForQuery();
+    if (pos_ != end) {
+      DCHECK(QueryIntersectsAllocatedInterval());
+      return;
+    }
+  }
+
+  Invalidate();
+}
+
+
+void LiveRangeConflictIterator::IncrementPosAndSkipOverRepetitions() {
+  auto end = intervals_->end();
+  DCHECK(pos_ != end);
+  LiveRange* current_conflict = Current();
+  while (pos_ != end && pos_->range_ == current_conflict) {
+    ++pos_;
+  }
+}
+
+
+LiveRange* LiveRangeConflictIterator::InternalGetNext(bool clean_behind) {
+  if (IsFinished()) return nullptr;
+
+  LiveRange* to_clear = Current();
+  IncrementPosAndSkipOverRepetitions();
+  // At this point, pos_ is either at the end, or on an interval that doesn't
+  // correspond to the same range as to_clear. This interval may not even be
+  // a conflict.
+  if (clean_behind) {
+    // Since we parked pos_ on an iterator that won't be affected by removal,
+    // we can safely delete to_clear's intervals.
+    for (auto interval = to_clear->first_interval(); interval != nullptr;
+         interval = interval->next()) {
+      AllocatedInterval erase_key(interval->start(), interval->end(), nullptr);
+      intervals_->erase(erase_key);
+    }
+  }
+  // We may have parked pos_ at the end, or on a non-conflict. In that case,
+  // move to the next query and reinitialize pos and query. This may invalidate
+  // the iterator, if no more conflicts are available.
+  if (!QueryIntersectsAllocatedInterval()) {
+    query_ = query_->next();
+    MovePosAndQueryToFirstConflict();
+  }
+  return Current();
+}
+
+
+LiveRangeConflictIterator CoalescedLiveRanges::GetConflicts(
+    const LiveRange* range) {
+  return LiveRangeConflictIterator(range, &intervals());
+}
+
+
+void CoalescedLiveRanges::AllocateRange(LiveRange* range) {
+  for (auto interval = range->first_interval(); interval != nullptr;
+       interval = interval->next()) {
+    AllocatedInterval to_insert(interval->start(), interval->end(), range);
+    intervals().insert(to_insert);
+  }
+}
+
+
+bool CoalescedLiveRanges::VerifyAllocationsAreValidForTesting() const {
+  LifetimePosition last_end = LifetimePosition::GapFromInstructionIndex(0);
+  for (auto i : intervals_) {
+    if (i.start_ < last_end) {
+      return false;
+    }
+    last_end = i.end_;
+  }
+  return true;
+}
+
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/coalesced-live-ranges.h b/src/compiler/coalesced-live-ranges.h
new file mode 100644
index 0000000..54bbce2
--- /dev/null
+++ b/src/compiler/coalesced-live-ranges.h
@@ -0,0 +1,158 @@
+// Copyright 2015 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.
+
+#ifndef V8_COALESCED_LIVE_RANGES_H_
+#define V8_COALESCED_LIVE_RANGES_H_
+
+#include "src/compiler/register-allocator.h"
+#include "src/zone-containers.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+
+// Implementation detail for CoalescedLiveRanges.
+struct AllocatedInterval {
+  AllocatedInterval(LifetimePosition start, LifetimePosition end,
+                    LiveRange* range)
+      : start_(start), end_(end), range_(range) {}
+
+  LifetimePosition start_;
+  LifetimePosition end_;
+  LiveRange* range_;
+  bool operator<(const AllocatedInterval& other) const {
+    return start_ < other.start_;
+  }
+  bool operator>(const AllocatedInterval& other) const {
+    return start_ > other.start_;
+  }
+};
+typedef ZoneSet<AllocatedInterval> IntervalStore;
+
+
+// An iterator over conflicts of a live range, obtained from CoalescedLiveRanges
+// The design supports two main scenarios (see GreedyAllocator):
+// (1) observing each conflicting range, without mutating the allocations, and
+// (2) observing each conflicting range, and then moving to the next, after
+// removing the current conflict.
+class LiveRangeConflictIterator {
+ public:
+  // Current conflict. nullptr if no conflicts, or if we reached the end of
+  // conflicts.
+  LiveRange* Current() const;
+
+  // Get the next conflict. Caller should handle non-consecutive repetitions of
+  // the same range.
+  LiveRange* GetNext() { return InternalGetNext(false); }
+
+  // Get the next conflict, after evicting the current one. Caller may expect
+  // to never observe the same live range more than once.
+  LiveRange* RemoveCurrentAndGetNext() { return InternalGetNext(true); }
+
+ private:
+  friend class CoalescedLiveRanges;
+
+  typedef IntervalStore::const_iterator interval_iterator;
+  LiveRangeConflictIterator(const LiveRange* range, IntervalStore* store);
+
+  // Move the store iterator to  first interval intersecting query. Since the
+  // intervals are sorted, subsequent intervals intersecting query follow. May
+  // leave the store iterator at "end", meaning that the current query does not
+  // have an intersection.
+  void MovePosToFirstConflictForQuery();
+
+  // Move both query and store iterator to the first intersection, if any. If
+  // none, then it invalidates the iterator (IsFinished() == true)
+  void MovePosAndQueryToFirstConflict();
+
+  // Increment pos and skip over intervals belonging to the same range we
+  // started with (i.e. Current() before the call). It is possible that range
+  // will be seen again, but not consecutively.
+  void IncrementPosAndSkipOverRepetitions();
+
+  // Common implementation used by both GetNext as well as
+  // ClearCurrentAndGetNext.
+  LiveRange* InternalGetNext(bool clean_behind);
+
+  bool IsFinished() const { return query_ == nullptr; }
+
+  static AllocatedInterval AsAllocatedInterval(LifetimePosition pos) {
+    return AllocatedInterval(pos, LifetimePosition::Invalid(), nullptr);
+  }
+
+  // Intersection utilities.
+  static bool Intersects(LifetimePosition a_start, LifetimePosition a_end,
+                         LifetimePosition b_start, LifetimePosition b_end) {
+    return a_start < b_end && b_start < a_end;
+  }
+
+  bool QueryIntersectsAllocatedInterval() const {
+    DCHECK_NOT_NULL(query_);
+    return pos_ != intervals_->end() &&
+           Intersects(query_->start(), query_->end(), pos_->start_, pos_->end_);
+  }
+
+  void Invalidate() {
+    query_ = nullptr;
+    pos_ = intervals_->end();
+  }
+
+  const UseInterval* query_;
+  interval_iterator pos_;
+  IntervalStore* intervals_;
+};
+
+// Collection of live ranges allocated to the same register.
+// It supports efficiently finding all conflicts for a given, non-allocated
+// range. See AllocatedInterval.
+// Allocated live ranges do not intersect. At most, individual use intervals
+// touch. We store, for a live range, an AllocatedInterval corresponding to each
+// of that range's UseIntervals. We keep the list of AllocatedIntervals sorted
+// by starts. Then, given the non-intersecting property, we know that
+// consecutive AllocatedIntervals have the property that the "smaller"'s end is
+// less or equal to the "larger"'s start.
+// This allows for quick (logarithmic complexity) identification of the first
+// AllocatedInterval to conflict with a given LiveRange, and then for efficient
+// traversal of conflicts.
+class CoalescedLiveRanges : public ZoneObject {
+ public:
+  explicit CoalescedLiveRanges(Zone* zone) : intervals_(zone) {}
+  void clear() { intervals_.clear(); }
+
+  bool empty() const { return intervals_.empty(); }
+
+  // Iterate over each live range conflicting with the provided one.
+  // The same live range may be observed multiple, but non-consecutive times.
+  LiveRangeConflictIterator GetConflicts(const LiveRange* range);
+
+
+  // Allocates a range with a pre-calculated candidate weight.
+  void AllocateRange(LiveRange* range);
+
+  // Unit testing API, verifying that allocated intervals do not overlap.
+  bool VerifyAllocationsAreValidForTesting() const;
+
+ private:
+  static const float kAllocatedRangeMultiplier;
+
+  IntervalStore& intervals() { return intervals_; }
+  const IntervalStore& intervals() const { return intervals_; }
+
+  // Augment the weight of a range that is about to be allocated.
+  static void UpdateWeightAtAllocation(LiveRange* range);
+
+  // Reduce the weight of a range that has lost allocation.
+  static void UpdateWeightAtEviction(LiveRange* range);
+
+
+  IntervalStore intervals_;
+  DISALLOW_COPY_AND_ASSIGN(CoalescedLiveRanges);
+};
+
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+#endif  // V8_COALESCED_LIVE_RANGES_H_
diff --git a/src/compiler/code-generator-impl.h b/src/compiler/code-generator-impl.h
index 7942344..7295948 100644
--- a/src/compiler/code-generator-impl.h
+++ b/src/compiler/code-generator-impl.h
@@ -27,49 +27,63 @@
 
   // -- Instruction operand accesses with conversions --------------------------
 
-  Register InputRegister(int index) {
+  Register InputRegister(size_t index) {
     return ToRegister(instr_->InputAt(index));
   }
 
-  DoubleRegister InputDoubleRegister(int index) {
+  DoubleRegister InputDoubleRegister(size_t index) {
     return ToDoubleRegister(instr_->InputAt(index));
   }
 
-  double InputDouble(int index) { return ToDouble(instr_->InputAt(index)); }
+  double InputDouble(size_t index) { return ToDouble(instr_->InputAt(index)); }
 
-  int32_t InputInt32(int index) {
+  float InputFloat32(size_t index) { return ToFloat32(instr_->InputAt(index)); }
+
+  int32_t InputInt32(size_t index) {
     return ToConstant(instr_->InputAt(index)).ToInt32();
   }
 
-  int8_t InputInt8(int index) { return static_cast<int8_t>(InputInt32(index)); }
+  int64_t InputInt64(size_t index) {
+    return ToConstant(instr_->InputAt(index)).ToInt64();
+  }
 
-  int16_t InputInt16(int index) {
+  int8_t InputInt8(size_t index) {
+    return static_cast<int8_t>(InputInt32(index));
+  }
+
+  int16_t InputInt16(size_t index) {
     return static_cast<int16_t>(InputInt32(index));
   }
 
-  uint8_t InputInt5(int index) {
+  uint8_t InputInt5(size_t index) {
     return static_cast<uint8_t>(InputInt32(index) & 0x1F);
   }
 
-  uint8_t InputInt6(int index) {
+  uint8_t InputInt6(size_t index) {
     return static_cast<uint8_t>(InputInt32(index) & 0x3F);
   }
 
-  Handle<HeapObject> InputHeapObject(int index) {
+  ExternalReference InputExternalReference(size_t index) {
+    return ToExternalReference(instr_->InputAt(index));
+  }
+
+  Handle<HeapObject> InputHeapObject(size_t index) {
     return ToHeapObject(instr_->InputAt(index));
   }
 
-  Label* InputLabel(int index) { return ToLabel(instr_->InputAt(index)); }
+  Label* InputLabel(size_t index) { return ToLabel(instr_->InputAt(index)); }
 
-  BasicBlock::RpoNumber InputRpo(int index) {
+  RpoNumber InputRpo(size_t index) {
     return ToRpoNumber(instr_->InputAt(index));
   }
 
-  Register OutputRegister(int index = 0) {
+  Register OutputRegister(size_t index = 0) {
     return ToRegister(instr_->OutputAt(index));
   }
 
-  Register TempRegister(int index) { return ToRegister(instr_->TempAt(index)); }
+  Register TempRegister(size_t index) {
+    return ToRegister(instr_->TempAt(index));
+  }
 
   DoubleRegister OutputDoubleRegister() {
     return ToDoubleRegister(instr_->Output());
@@ -81,34 +95,42 @@
     return gen_->GetLabel(ToRpoNumber(op));
   }
 
-  BasicBlock::RpoNumber ToRpoNumber(InstructionOperand* op) {
+  RpoNumber ToRpoNumber(InstructionOperand* op) {
     return ToConstant(op).ToRpoNumber();
   }
 
   Register ToRegister(InstructionOperand* op) {
-    DCHECK(op->IsRegister());
-    return Register::FromAllocationIndex(op->index());
+    return LocationOperand::cast(op)->GetRegister();
   }
 
   DoubleRegister ToDoubleRegister(InstructionOperand* op) {
-    DCHECK(op->IsDoubleRegister());
-    return DoubleRegister::FromAllocationIndex(op->index());
+    return LocationOperand::cast(op)->GetDoubleRegister();
   }
 
   Constant ToConstant(InstructionOperand* op) {
     if (op->IsImmediate()) {
-      return gen_->code()->GetImmediate(op->index());
+      return gen_->code()->GetImmediate(ImmediateOperand::cast(op));
     }
-    return gen_->code()->GetConstant(op->index());
+    return gen_->code()->GetConstant(
+        ConstantOperand::cast(op)->virtual_register());
   }
 
   double ToDouble(InstructionOperand* op) { return ToConstant(op).ToFloat64(); }
 
+  float ToFloat32(InstructionOperand* op) { return ToConstant(op).ToFloat32(); }
+
+  ExternalReference ToExternalReference(InstructionOperand* op) {
+    return ToConstant(op).ToExternalReference();
+  }
+
   Handle<HeapObject> ToHeapObject(InstructionOperand* op) {
     return ToConstant(op).ToHeapObject();
   }
 
   Frame* frame() const { return gen_->frame(); }
+  FrameAccessState* frame_access_state() const {
+    return gen_->frame_access_state();
+  }
   Isolate* isolate() const { return gen_->isolate(); }
   Linkage* linkage() const { return gen_->linkage(); }
 
@@ -128,12 +150,15 @@
 
   Label* entry() { return &entry_; }
   Label* exit() { return &exit_; }
+  Frame* frame() const { return frame_; }
+  Isolate* isolate() const { return masm()->isolate(); }
   MacroAssembler* masm() const { return masm_; }
   OutOfLineCode* next() const { return next_; }
 
  private:
   Label entry_;
   Label exit_;
+  Frame* const frame_;
   MacroAssembler* const masm_;
   OutOfLineCode* const next_;
 };
@@ -144,6 +169,8 @@
 static inline void FinishCode(MacroAssembler* masm) {
 #if V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_ARM
   masm->CheckConstPool(true, false);
+#elif V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X64
+  masm->ud2();
 #endif
 }
 
diff --git a/src/compiler/code-generator.cc b/src/compiler/code-generator.cc
index cfe4f06..313567e 100644
--- a/src/compiler/code-generator.cc
+++ b/src/compiler/code-generator.cc
@@ -4,40 +4,72 @@
 
 #include "src/compiler/code-generator.h"
 
+#include "src/address-map.h"
 #include "src/compiler/code-generator-impl.h"
 #include "src/compiler/linkage.h"
 #include "src/compiler/pipeline.h"
+#include "src/frames-inl.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
+class CodeGenerator::JumpTable final : public ZoneObject {
+ public:
+  JumpTable(JumpTable* next, Label** targets, size_t target_count)
+      : next_(next), targets_(targets), target_count_(target_count) {}
+
+  Label* label() { return &label_; }
+  JumpTable* next() const { return next_; }
+  Label** targets() const { return targets_; }
+  size_t target_count() const { return target_count_; }
+
+ private:
+  Label label_;
+  JumpTable* const next_;
+  Label** const targets_;
+  size_t const target_count_;
+};
+
+
 CodeGenerator::CodeGenerator(Frame* frame, Linkage* linkage,
                              InstructionSequence* code, CompilationInfo* info)
-    : frame_(frame),
+    : frame_access_state_(new (code->zone()) FrameAccessState(frame)),
       linkage_(linkage),
       code_(code),
       info_(info),
       labels_(zone()->NewArray<Label>(code->InstructionBlockCount())),
-      current_block_(BasicBlock::RpoNumber::Invalid()),
-      current_source_position_(SourcePosition::Invalid()),
-      masm_(code->zone()->isolate(), NULL, 0),
+      current_block_(RpoNumber::Invalid()),
+      current_source_position_(SourcePosition::Unknown()),
+      masm_(info->isolate(), nullptr, 0, CodeObjectRequired::kYes),
       resolver_(this),
       safepoints_(code->zone()),
+      handlers_(code->zone()),
       deoptimization_states_(code->zone()),
       deoptimization_literals_(code->zone()),
+      inlined_function_count_(0),
       translations_(code->zone()),
       last_lazy_deopt_pc_(0),
-      ools_(nullptr) {
+      jump_tables_(nullptr),
+      ools_(nullptr),
+      osr_pc_offset_(-1) {
   for (int i = 0; i < code->InstructionBlockCount(); ++i) {
     new (&labels_[i]) Label;
   }
+  if (code->ContainsCall()) {
+    frame->MarkNeedsFrame();
+  }
 }
 
 
 Handle<Code> CodeGenerator::GenerateCode() {
   CompilationInfo* info = this->info();
 
+  // Open a frame scope to indicate that there is a frame on the stack.  The
+  // MANUAL indicates that the scope shouldn't actually generate code to set up
+  // the frame (that is done in AssemblePrologue).
+  FrameScope frame_scope(masm(), StackFrame::MANUAL);
+
   // Emit a code line info recording start event.
   PositionsRecorder* recorder = masm()->positions_recorder();
   LOG_CODE_EVENT(isolate(), CodeStartLinePosInfoRecordEvent(recorder));
@@ -51,6 +83,23 @@
   info->set_prologue_offset(masm()->pc_offset());
   AssemblePrologue();
 
+  // Define deoptimization literals for all inlined functions.
+  DCHECK_EQ(0u, deoptimization_literals_.size());
+  for (auto& inlined : info->inlined_functions()) {
+    if (!inlined.shared_info.is_identical_to(info->shared_info())) {
+      DefineDeoptimizationLiteral(inlined.shared_info);
+    }
+  }
+  inlined_function_count_ = deoptimization_literals_.size();
+
+  // Define deoptimization literals for all unoptimized code objects of inlined
+  // functions. This ensures unoptimized code is kept alive by optimized code.
+  for (auto& inlined : info->inlined_functions()) {
+    if (!inlined.shared_info.is_identical_to(info->shared_info())) {
+      DefineDeoptimizationLiteral(inlined.inlined_code_object_root);
+    }
+  }
+
   // Assemble all non-deferred blocks, followed by deferred ones.
   for (int deferred = 0; deferred < 2; ++deferred) {
     for (auto const block : code()->instruction_blocks()) {
@@ -59,13 +108,36 @@
       }
       // Align loop headers on 16-byte boundaries.
       if (block->IsLoopHeader()) masm()->Align(16);
+      // Ensure lazy deopt doesn't patch handler entry points.
+      if (block->IsHandler()) EnsureSpaceForLazyDeopt();
       // Bind a label for a block.
       current_block_ = block->rpo_number();
       if (FLAG_code_comments) {
         // TODO(titzer): these code comments are a giant memory leak.
-        Vector<char> buffer = Vector<char>::New(32);
-        SNPrintF(buffer, "-- B%d start --", block->id().ToInt());
-        masm()->RecordComment(buffer.start());
+        Vector<char> buffer = Vector<char>::New(200);
+        char* buffer_start = buffer.start();
+
+        int next = SNPrintF(
+            buffer, "-- B%d start%s%s%s%s", block->rpo_number().ToInt(),
+            block->IsDeferred() ? " (deferred)" : "",
+            block->needs_frame() ? "" : " (no frame)",
+            block->must_construct_frame() ? " (construct frame)" : "",
+            block->must_deconstruct_frame() ? " (deconstruct frame)" : "");
+
+        buffer = buffer.SubVector(next, buffer.length());
+
+        if (block->IsLoopHeader()) {
+          next =
+              SNPrintF(buffer, " (loop up to %d)", block->loop_end().ToInt());
+          buffer = buffer.SubVector(next, buffer.length());
+        }
+        if (block->loop_header().IsValid()) {
+          next =
+              SNPrintF(buffer, " (in loop %d)", block->loop_header().ToInt());
+          buffer = buffer.SubVector(next, buffer.length());
+        }
+        SNPrintF(buffer, " --");
+        masm()->RecordComment(buffer_start);
       }
       masm()->bind(GetLabel(current_block_));
       for (int i = block->code_start(); i < block->code_end(); ++i) {
@@ -80,37 +152,58 @@
     for (OutOfLineCode* ool = ools_; ool; ool = ool->next()) {
       masm()->bind(ool->entry());
       ool->Generate();
-      masm()->jmp(ool->exit());
+      if (ool->exit()->is_bound()) masm()->jmp(ool->exit());
     }
   }
 
-  FinishCode(masm());
-
   // Ensure there is space for lazy deoptimization in the code.
-  if (!info->IsStub()) {
+  if (info->ShouldEnsureSpaceForLazyDeopt()) {
     int target_offset = masm()->pc_offset() + Deoptimizer::patch_size();
     while (masm()->pc_offset() < target_offset) {
       masm()->nop();
     }
   }
 
+  FinishCode(masm());
+
+  // Emit the jump tables.
+  if (jump_tables_) {
+    masm()->Align(kPointerSize);
+    for (JumpTable* table = jump_tables_; table; table = table->next()) {
+      masm()->bind(table->label());
+      AssembleJumpTable(table->targets(), table->target_count());
+    }
+  }
+
   safepoints()->Emit(masm(), frame()->GetSpillSlotCount());
 
-  // TODO(titzer): what are the right code flags here?
-  Code::Kind kind = Code::STUB;
-  if (linkage()->GetIncomingDescriptor()->IsJSFunctionCall()) {
-    kind = Code::OPTIMIZED_FUNCTION;
-  }
-  Handle<Code> result = v8::internal::CodeGenerator::MakeCodeEpilogue(
-      masm(), Code::ComputeFlags(kind), info);
+  Handle<Code> result =
+      v8::internal::CodeGenerator::MakeCodeEpilogue(masm(), info);
   result->set_is_turbofanned(true);
   result->set_stack_slots(frame()->GetSpillSlotCount());
   result->set_safepoint_table_offset(safepoints()->GetCodeOffset());
 
+  // Emit exception handler table.
+  if (!handlers_.empty()) {
+    Handle<HandlerTable> table =
+        Handle<HandlerTable>::cast(isolate()->factory()->NewFixedArray(
+            HandlerTable::LengthForReturn(static_cast<int>(handlers_.size())),
+            TENURED));
+    for (size_t i = 0; i < handlers_.size(); ++i) {
+      int position = handlers_[i].handler->pos();
+      HandlerTable::CatchPrediction prediction = handlers_[i].caught_locally
+                                                     ? HandlerTable::CAUGHT
+                                                     : HandlerTable::UNCAUGHT;
+      table->SetReturnOffset(static_cast<int>(i), handlers_[i].pc_offset);
+      table->SetReturnHandler(static_cast<int>(i), position, prediction);
+    }
+    result->set_handler_table(*table);
+  }
+
   PopulateDeoptimizationData(result);
 
   // Ensure there is space for lazy deoptimization in the relocation info.
-  if (!info->IsStub()) {
+  if (info->ShouldEnsureSpaceForLazyDeopt()) {
     Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(result);
   }
 
@@ -122,113 +215,143 @@
 }
 
 
-bool CodeGenerator::IsNextInAssemblyOrder(BasicBlock::RpoNumber block) const {
-  return code()->InstructionBlockAt(current_block_)->ao_number().IsNext(
-      code()->InstructionBlockAt(block)->ao_number());
+bool CodeGenerator::IsNextInAssemblyOrder(RpoNumber block) const {
+  return code()
+      ->InstructionBlockAt(current_block_)
+      ->ao_number()
+      .IsNext(code()->InstructionBlockAt(block)->ao_number());
 }
 
 
-void CodeGenerator::RecordSafepoint(PointerMap* pointers, Safepoint::Kind kind,
-                                    int arguments,
+void CodeGenerator::RecordSafepoint(ReferenceMap* references,
+                                    Safepoint::Kind kind, int arguments,
                                     Safepoint::DeoptMode deopt_mode) {
-  const ZoneList<InstructionOperand*>* operands =
-      pointers->GetNormalizedOperands();
   Safepoint safepoint =
       safepoints()->DefineSafepoint(masm(), kind, arguments, deopt_mode);
-  for (int i = 0; i < operands->length(); i++) {
-    InstructionOperand* pointer = operands->at(i);
-    if (pointer->IsStackSlot()) {
-      safepoint.DefinePointerSlot(pointer->index(), zone());
-    } else if (pointer->IsRegister() && (kind & Safepoint::kWithRegisters)) {
-      Register reg = Register::FromAllocationIndex(pointer->index());
+  int stackSlotToSpillSlotDelta =
+      frame()->GetTotalFrameSlotCount() - frame()->GetSpillSlotCount();
+  for (auto& operand : references->reference_operands()) {
+    if (operand.IsStackSlot()) {
+      int index = LocationOperand::cast(operand).index();
+      DCHECK(index >= 0);
+      // Safepoint table indices are 0-based from the beginning of the spill
+      // slot area, adjust appropriately.
+      index -= stackSlotToSpillSlotDelta;
+      safepoint.DefinePointerSlot(index, zone());
+    } else if (operand.IsRegister() && (kind & Safepoint::kWithRegisters)) {
+      Register reg = LocationOperand::cast(operand).GetRegister();
       safepoint.DefinePointerRegister(reg, zone());
     }
   }
 }
 
 
+bool CodeGenerator::IsMaterializableFromFrame(Handle<HeapObject> object,
+                                              int* offset_return) {
+  if (linkage()->GetIncomingDescriptor()->IsJSFunctionCall()) {
+    if (info()->has_context() && object.is_identical_to(info()->context()) &&
+        !info()->is_osr()) {
+      *offset_return = StandardFrameConstants::kContextOffset;
+      return true;
+    } else if (object.is_identical_to(info()->closure())) {
+      *offset_return = JavaScriptFrameConstants::kFunctionOffset;
+      return true;
+    }
+  }
+  return false;
+}
+
+
+bool CodeGenerator::IsMaterializableFromRoot(
+    Handle<HeapObject> object, Heap::RootListIndex* index_return) {
+  const CallDescriptor* incoming_descriptor =
+      linkage()->GetIncomingDescriptor();
+  if (incoming_descriptor->flags() & CallDescriptor::kCanUseRoots) {
+    RootIndexMap map(isolate());
+    int root_index = map.Lookup(*object);
+    if (root_index != RootIndexMap::kInvalidRootIndex) {
+      *index_return = static_cast<Heap::RootListIndex>(root_index);
+      return true;
+    }
+  }
+  return false;
+}
+
+
 void CodeGenerator::AssembleInstruction(Instruction* instr) {
-  if (instr->IsGapMoves()) {
-    // Handle parallel moves associated with the gap instruction.
-    AssembleGap(GapInstruction::cast(instr));
-  } else if (instr->IsSourcePosition()) {
-    AssembleSourcePosition(SourcePositionInstruction::cast(instr));
-  } else {
-    // Assemble architecture-specific code for the instruction.
-    AssembleArchInstruction(instr);
+  AssembleGaps(instr);
+  AssembleSourcePosition(instr);
+  // Assemble architecture-specific code for the instruction.
+  AssembleArchInstruction(instr);
 
-    FlagsMode mode = FlagsModeField::decode(instr->opcode());
-    FlagsCondition condition = FlagsConditionField::decode(instr->opcode());
-    if (mode == kFlags_branch) {
-      // Assemble a branch after this instruction.
-      InstructionOperandConverter i(this, instr);
-      BasicBlock::RpoNumber true_rpo =
-          i.InputRpo(static_cast<int>(instr->InputCount()) - 2);
-      BasicBlock::RpoNumber false_rpo =
-          i.InputRpo(static_cast<int>(instr->InputCount()) - 1);
+  FlagsMode mode = FlagsModeField::decode(instr->opcode());
+  FlagsCondition condition = FlagsConditionField::decode(instr->opcode());
+  if (mode == kFlags_branch) {
+    // Assemble a branch after this instruction.
+    InstructionOperandConverter i(this, instr);
+    RpoNumber true_rpo = i.InputRpo(instr->InputCount() - 2);
+    RpoNumber false_rpo = i.InputRpo(instr->InputCount() - 1);
 
-      if (true_rpo == false_rpo) {
-        // redundant branch.
-        if (!IsNextInAssemblyOrder(true_rpo)) {
-          AssembleArchJump(true_rpo);
-        }
-        return;
+    if (true_rpo == false_rpo) {
+      // redundant branch.
+      if (!IsNextInAssemblyOrder(true_rpo)) {
+        AssembleArchJump(true_rpo);
       }
-      if (IsNextInAssemblyOrder(true_rpo)) {
-        // true block is next, can fall through if condition negated.
-        std::swap(true_rpo, false_rpo);
-        condition = NegateFlagsCondition(condition);
-      }
-      BranchInfo branch;
-      branch.condition = condition;
-      branch.true_label = GetLabel(true_rpo);
-      branch.false_label = GetLabel(false_rpo);
-      branch.fallthru = IsNextInAssemblyOrder(false_rpo);
-      // Assemble architecture-specific branch.
-      AssembleArchBranch(instr, &branch);
-    } else if (mode == kFlags_set) {
-      // Assemble a boolean materialization after this instruction.
-      AssembleArchBoolean(instr, condition);
+      return;
     }
+    if (IsNextInAssemblyOrder(true_rpo)) {
+      // true block is next, can fall through if condition negated.
+      std::swap(true_rpo, false_rpo);
+      condition = NegateFlagsCondition(condition);
+    }
+    BranchInfo branch;
+    branch.condition = condition;
+    branch.true_label = GetLabel(true_rpo);
+    branch.false_label = GetLabel(false_rpo);
+    branch.fallthru = IsNextInAssemblyOrder(false_rpo);
+    // Assemble architecture-specific branch.
+    AssembleArchBranch(instr, &branch);
+  } else if (mode == kFlags_set) {
+    // Assemble a boolean materialization after this instruction.
+    AssembleArchBoolean(instr, condition);
   }
 }
 
 
-void CodeGenerator::AssembleSourcePosition(SourcePositionInstruction* instr) {
-  SourcePosition source_position = instr->source_position();
+void CodeGenerator::AssembleSourcePosition(Instruction* instr) {
+  SourcePosition source_position;
+  if (!code()->GetSourcePosition(instr, &source_position)) return;
   if (source_position == current_source_position_) return;
-  DCHECK(!source_position.IsInvalid());
-  if (!source_position.IsUnknown()) {
-    int code_pos = source_position.raw();
-    masm()->positions_recorder()->RecordPosition(source_position.raw());
-    masm()->positions_recorder()->WriteRecordedPositions();
-    if (FLAG_code_comments) {
-      Vector<char> buffer = Vector<char>::New(256);
-      CompilationInfo* info = this->info();
-      int ln = Script::GetLineNumber(info->script(), code_pos);
-      int cn = Script::GetColumnNumber(info->script(), code_pos);
-      if (info->script()->name()->IsString()) {
-        Handle<String> file(String::cast(info->script()->name()));
-        base::OS::SNPrintF(buffer.start(), buffer.length(), "-- %s:%d:%d --",
-                           file->ToCString().get(), ln, cn);
-      } else {
-        base::OS::SNPrintF(buffer.start(), buffer.length(),
-                           "-- <unknown>:%d:%d --", ln, cn);
-      }
-      masm()->RecordComment(buffer.start());
-    }
-  }
   current_source_position_ = source_position;
+  if (source_position.IsUnknown()) return;
+  int code_pos = source_position.raw();
+  masm()->positions_recorder()->RecordPosition(code_pos);
+  masm()->positions_recorder()->WriteRecordedPositions();
+  if (FLAG_code_comments) {
+    Vector<char> buffer = Vector<char>::New(256);
+    CompilationInfo* info = this->info();
+    int ln = Script::GetLineNumber(info->script(), code_pos);
+    int cn = Script::GetColumnNumber(info->script(), code_pos);
+    if (info->script()->name()->IsString()) {
+      Handle<String> file(String::cast(info->script()->name()));
+      base::OS::SNPrintF(buffer.start(), buffer.length(), "-- %s:%d:%d --",
+                         file->ToCString().get(), ln, cn);
+    } else {
+      base::OS::SNPrintF(buffer.start(), buffer.length(),
+                         "-- <unknown>:%d:%d --", ln, cn);
+    }
+    masm()->RecordComment(buffer.start());
+  }
 }
 
 
-void CodeGenerator::AssembleGap(GapInstruction* instr) {
-  for (int i = GapInstruction::FIRST_INNER_POSITION;
-       i <= GapInstruction::LAST_INNER_POSITION; i++) {
-    GapInstruction::InnerPosition inner_pos =
-        static_cast<GapInstruction::InnerPosition>(i);
+void CodeGenerator::AssembleGaps(Instruction* instr) {
+  for (int i = Instruction::FIRST_GAP_POSITION;
+       i <= Instruction::LAST_GAP_POSITION; i++) {
+    Instruction::GapPosition inner_pos =
+        static_cast<Instruction::GapPosition>(i);
     ParallelMove* move = instr->GetParallelMove(inner_pos);
-    if (move != NULL) resolver()->Resolve(move);
+    if (move != nullptr) resolver()->Resolve(move);
   }
 }
 
@@ -236,7 +359,7 @@
 void CodeGenerator::PopulateDeoptimizationData(Handle<Code> code_object) {
   CompilationInfo* info = this->info();
   int deopt_count = static_cast<int>(deoptimization_states_.size());
-  if (deopt_count == 0) return;
+  if (deopt_count == 0 && !info->is_osr()) return;
   Handle<DeoptimizationInputData> data =
       DeoptimizationInputData::New(isolate(), deopt_count, TENURED);
 
@@ -244,13 +367,11 @@
       translations_.CreateByteArray(isolate()->factory());
 
   data->SetTranslationByteArray(*translation_array);
-  data->SetInlinedFunctionCount(Smi::FromInt(0));
+  data->SetInlinedFunctionCount(
+      Smi::FromInt(static_cast<int>(inlined_function_count_)));
   data->SetOptimizationId(Smi::FromInt(info->optimization_id()));
-  // TODO(jarin) The following code was copied over from Lithium, not sure
-  // whether the scope or the IsOptimizing condition are really needed.
-  if (info->IsOptimizing()) {
-    // Reference to shared function info does not change between phases.
-    AllowDeferredHandleDereference allow_handle_dereference;
+
+  if (info->has_shared_info()) {
     data->SetSharedFunctionInfo(*info->shared_info());
   } else {
     data->SetSharedFunctionInfo(Smi::FromInt(0));
@@ -266,16 +387,21 @@
     data->SetLiteralArray(*literals);
   }
 
-  // No OSR in Turbofan yet...
-  BailoutId osr_ast_id = BailoutId::None();
-  data->SetOsrAstId(Smi::FromInt(osr_ast_id.ToInt()));
-  data->SetOsrPcOffset(Smi::FromInt(-1));
+  if (info->is_osr()) {
+    DCHECK(osr_pc_offset_ >= 0);
+    data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id().ToInt()));
+    data->SetOsrPcOffset(Smi::FromInt(osr_pc_offset_));
+  } else {
+    BailoutId osr_ast_id = BailoutId::None();
+    data->SetOsrAstId(Smi::FromInt(osr_ast_id.ToInt()));
+    data->SetOsrPcOffset(Smi::FromInt(-1));
+  }
 
   // Populate deoptimization entries.
   for (int i = 0; i < deopt_count; i++) {
     DeoptimizationState* deoptimization_state = deoptimization_states_[i];
     data->SetAstId(i, deoptimization_state->bailout_id());
-    CHECK_NE(NULL, deoptimization_states_[i]);
+    CHECK(deoptimization_states_[i]);
     data->SetTranslationIndex(
         i, Smi::FromInt(deoptimization_states_[i]->translation_id()));
     data->SetArgumentsStackHeight(i, Smi::FromInt(0));
@@ -286,25 +412,36 @@
 }
 
 
-void CodeGenerator::AddSafepointAndDeopt(Instruction* instr) {
+Label* CodeGenerator::AddJumpTable(Label** targets, size_t target_count) {
+  jump_tables_ = new (zone()) JumpTable(jump_tables_, targets, target_count);
+  return jump_tables_->label();
+}
+
+
+void CodeGenerator::RecordCallPosition(Instruction* instr) {
   CallDescriptor::Flags flags(MiscField::decode(instr->opcode()));
 
   bool needs_frame_state = (flags & CallDescriptor::kNeedsFrameState);
 
   RecordSafepoint(
-      instr->pointer_map(), Safepoint::kSimple, 0,
+      instr->reference_map(), Safepoint::kSimple, 0,
       needs_frame_state ? Safepoint::kLazyDeopt : Safepoint::kNoLazyDeopt);
 
+  if (flags & CallDescriptor::kHasExceptionHandler) {
+    InstructionOperandConverter i(this, instr);
+    bool caught = flags & CallDescriptor::kHasLocalCatchHandler;
+    RpoNumber handler_rpo = i.InputRpo(instr->InputCount() - 1);
+    handlers_.push_back({caught, GetLabel(handler_rpo), masm()->pc_offset()});
+  }
+
   if (flags & CallDescriptor::kNeedsNopAfterCall) {
     AddNopForSmiCodeInlining();
   }
 
   if (needs_frame_state) {
     MarkLazyDeoptSite();
-    // If the frame state is present, it starts at argument 1
-    // (just after the code address).
-    InstructionOperandConverter converter(this, instr);
-    // Deoptimization info starts at argument 1
+    // If the frame state is present, it starts at argument 1 (just after the
+    // code address).
     size_t frame_state_offset = 1;
     FrameStateDescriptor* descriptor =
         GetFrameStateDescriptor(instr, frame_state_offset);
@@ -348,86 +485,120 @@
 FrameStateDescriptor* CodeGenerator::GetFrameStateDescriptor(
     Instruction* instr, size_t frame_state_offset) {
   InstructionOperandConverter i(this, instr);
-  InstructionSequence::StateId state_id = InstructionSequence::StateId::FromInt(
-      i.InputInt32(static_cast<int>(frame_state_offset)));
+  InstructionSequence::StateId state_id =
+      InstructionSequence::StateId::FromInt(i.InputInt32(frame_state_offset));
   return code()->GetFrameStateDescriptor(state_id);
 }
 
-struct OperandAndType {
-  OperandAndType(InstructionOperand* operand, MachineType type)
-      : operand_(operand), type_(type) {}
 
-  InstructionOperand* operand_;
-  MachineType type_;
-};
-
-static OperandAndType TypedOperandForFrameState(
-    FrameStateDescriptor* descriptor, Instruction* instr,
-    size_t frame_state_offset, size_t index, OutputFrameStateCombine combine) {
-  DCHECK(index < descriptor->GetSize(combine));
-  switch (combine.kind()) {
-    case OutputFrameStateCombine::kPushOutput: {
-      DCHECK(combine.GetPushCount() <= instr->OutputCount());
-      size_t size_without_output =
-          descriptor->GetSize(OutputFrameStateCombine::Ignore());
-      // If the index is past the existing stack items, return the output.
-      if (index >= size_without_output) {
-        return OperandAndType(instr->OutputAt(index - size_without_output),
-                              kMachAnyTagged);
-      }
-      break;
+void CodeGenerator::TranslateStateValueDescriptor(
+    StateValueDescriptor* desc, Translation* translation,
+    InstructionOperandIterator* iter) {
+  if (desc->IsNested()) {
+    translation->BeginCapturedObject(static_cast<int>(desc->size()));
+    for (size_t index = 0; index < desc->fields().size(); index++) {
+      TranslateStateValueDescriptor(&desc->fields()[index], translation, iter);
     }
-    case OutputFrameStateCombine::kPokeAt:
-      size_t index_from_top =
-          descriptor->GetSize(combine) - 1 - combine.GetOffsetToPokeAt();
-      if (index >= index_from_top &&
-          index < index_from_top + instr->OutputCount()) {
-        return OperandAndType(instr->OutputAt(index - index_from_top),
-                              kMachAnyTagged);
-      }
-      break;
+  } else if (desc->IsDuplicate()) {
+    translation->DuplicateObject(static_cast<int>(desc->id()));
+  } else {
+    DCHECK(desc->IsPlain());
+    AddTranslationForOperand(translation, iter->instruction(), iter->Advance(),
+                             desc->type());
   }
-  return OperandAndType(instr->InputAt(frame_state_offset + index),
-                        descriptor->GetType(index));
+}
+
+
+void CodeGenerator::TranslateFrameStateDescriptorOperands(
+    FrameStateDescriptor* desc, InstructionOperandIterator* iter,
+    OutputFrameStateCombine combine, Translation* translation) {
+  for (size_t index = 0; index < desc->GetSize(combine); index++) {
+    switch (combine.kind()) {
+      case OutputFrameStateCombine::kPushOutput: {
+        DCHECK(combine.GetPushCount() <= iter->instruction()->OutputCount());
+        size_t size_without_output =
+            desc->GetSize(OutputFrameStateCombine::Ignore());
+        // If the index is past the existing stack items in values_.
+        if (index >= size_without_output) {
+          // Materialize the result of the call instruction in this slot.
+          AddTranslationForOperand(
+              translation, iter->instruction(),
+              iter->instruction()->OutputAt(index - size_without_output),
+              MachineType::AnyTagged());
+          continue;
+        }
+        break;
+      }
+      case OutputFrameStateCombine::kPokeAt:
+        // The result of the call should be placed at position
+        // [index_from_top] in the stack (overwriting whatever was
+        // previously there).
+        size_t index_from_top =
+            desc->GetSize(combine) - 1 - combine.GetOffsetToPokeAt();
+        if (index >= index_from_top &&
+            index < index_from_top + iter->instruction()->OutputCount()) {
+          AddTranslationForOperand(
+              translation, iter->instruction(),
+              iter->instruction()->OutputAt(index - index_from_top),
+              MachineType::AnyTagged());
+          iter->Advance();  // We do not use this input, but we need to
+                            // advace, as the input got replaced.
+          continue;
+        }
+        break;
+    }
+    StateValueDescriptor* value_desc = desc->GetStateValueDescriptor();
+    TranslateStateValueDescriptor(&value_desc->fields()[index], translation,
+                                  iter);
+  }
 }
 
 
 void CodeGenerator::BuildTranslationForFrameStateDescriptor(
-    FrameStateDescriptor* descriptor, Instruction* instr,
-    Translation* translation, size_t frame_state_offset,
-    OutputFrameStateCombine state_combine) {
+    FrameStateDescriptor* descriptor, InstructionOperandIterator* iter,
+    Translation* translation, OutputFrameStateCombine state_combine) {
   // Outer-most state must be added to translation first.
-  if (descriptor->outer_state() != NULL) {
-    BuildTranslationForFrameStateDescriptor(descriptor->outer_state(), instr,
-                                            translation, frame_state_offset,
+  if (descriptor->outer_state() != nullptr) {
+    BuildTranslationForFrameStateDescriptor(descriptor->outer_state(), iter,
+                                            translation,
                                             OutputFrameStateCombine::Ignore());
   }
 
-  int id = Translation::kSelfLiteralId;
-  if (!descriptor->jsfunction().is_null()) {
-    id = DefineDeoptimizationLiteral(
-        Handle<Object>::cast(descriptor->jsfunction().ToHandleChecked()));
+  Handle<SharedFunctionInfo> shared_info;
+  if (!descriptor->shared_info().ToHandle(&shared_info)) {
+    if (!info()->has_shared_info()) {
+      return;  // Stub with no SharedFunctionInfo.
+    }
+    shared_info = info()->shared_info();
   }
+  int shared_info_id = DefineDeoptimizationLiteral(shared_info);
 
   switch (descriptor->type()) {
-    case JS_FRAME:
+    case FrameStateType::kJavaScriptFunction:
       translation->BeginJSFrame(
-          descriptor->bailout_id(), id,
+          descriptor->bailout_id(), shared_info_id,
           static_cast<unsigned int>(descriptor->GetSize(state_combine) -
-                                    descriptor->parameters_count()));
+                                    (1 + descriptor->parameters_count())));
       break;
-    case ARGUMENTS_ADAPTOR:
+    case FrameStateType::kInterpretedFunction:
+      translation->BeginInterpretedFrame(
+          descriptor->bailout_id(), shared_info_id,
+          static_cast<unsigned int>(descriptor->locals_count()));
+      break;
+    case FrameStateType::kArgumentsAdaptor:
       translation->BeginArgumentsAdaptorFrame(
-          id, static_cast<unsigned int>(descriptor->parameters_count()));
+          shared_info_id,
+          static_cast<unsigned int>(descriptor->parameters_count()));
+      break;
+    case FrameStateType::kConstructStub:
+      translation->BeginConstructStubFrame(
+          shared_info_id,
+          static_cast<unsigned int>(descriptor->parameters_count()));
       break;
   }
 
-  frame_state_offset += descriptor->outer_state()->GetTotalSize();
-  for (size_t i = 0; i < descriptor->GetSize(state_combine); i++) {
-    OperandAndType op = TypedOperandForFrameState(
-        descriptor, instr, frame_state_offset, i, state_combine);
-    AddTranslationForOperand(translation, instr, op.operand_, op.type_);
-  }
+  TranslateFrameStateDescriptorOperands(descriptor, iter, state_combine,
+                                        translation);
 }
 
 
@@ -441,8 +612,9 @@
   Translation translation(
       &translations_, static_cast<int>(descriptor->GetFrameCount()),
       static_cast<int>(descriptor->GetJSFrameCount()), zone());
-  BuildTranslationForFrameStateDescriptor(descriptor, instr, &translation,
-                                          frame_state_offset, state_combine);
+  InstructionOperandIterator iter(instr, frame_state_offset);
+  BuildTranslationForFrameStateDescriptor(descriptor, &iter, &translation,
+                                          state_combine);
 
   int deoptimization_id = static_cast<int>(deoptimization_states_.size());
 
@@ -458,35 +630,39 @@
                                              InstructionOperand* op,
                                              MachineType type) {
   if (op->IsStackSlot()) {
-    if (type == kMachBool || type == kMachInt32 || type == kMachInt8 ||
-        type == kMachInt16) {
-      translation->StoreInt32StackSlot(op->index());
-    } else if (type == kMachUint32 || type == kMachUint16 ||
-               type == kMachUint8) {
-      translation->StoreUint32StackSlot(op->index());
-    } else if ((type & kRepMask) == kRepTagged) {
-      translation->StoreStackSlot(op->index());
+    if (type.representation() == MachineRepresentation::kBit) {
+      translation->StoreBoolStackSlot(LocationOperand::cast(op)->index());
+    } else if (type == MachineType::Int8() || type == MachineType::Int16() ||
+               type == MachineType::Int32()) {
+      translation->StoreInt32StackSlot(LocationOperand::cast(op)->index());
+    } else if (type == MachineType::Uint8() || type == MachineType::Uint16() ||
+               type == MachineType::Uint32()) {
+      translation->StoreUint32StackSlot(LocationOperand::cast(op)->index());
+    } else if (type.representation() == MachineRepresentation::kTagged) {
+      translation->StoreStackSlot(LocationOperand::cast(op)->index());
     } else {
       CHECK(false);
     }
   } else if (op->IsDoubleStackSlot()) {
-    DCHECK((type & (kRepFloat32 | kRepFloat64)) != 0);
-    translation->StoreDoubleStackSlot(op->index());
+    DCHECK(IsFloatingPoint(type.representation()));
+    translation->StoreDoubleStackSlot(LocationOperand::cast(op)->index());
   } else if (op->IsRegister()) {
     InstructionOperandConverter converter(this, instr);
-    if (type == kMachBool || type == kMachInt32 || type == kMachInt8 ||
-        type == kMachInt16) {
+    if (type.representation() == MachineRepresentation::kBit) {
+      translation->StoreBoolRegister(converter.ToRegister(op));
+    } else if (type == MachineType::Int8() || type == MachineType::Int16() ||
+               type == MachineType::Int32()) {
       translation->StoreInt32Register(converter.ToRegister(op));
-    } else if (type == kMachUint32 || type == kMachUint16 ||
-               type == kMachUint8) {
+    } else if (type == MachineType::Uint8() || type == MachineType::Uint16() ||
+               type == MachineType::Uint32()) {
       translation->StoreUint32Register(converter.ToRegister(op));
-    } else if ((type & kRepMask) == kRepTagged) {
+    } else if (type.representation() == MachineRepresentation::kTagged) {
       translation->StoreRegister(converter.ToRegister(op));
     } else {
       CHECK(false);
     }
   } else if (op->IsDoubleRegister()) {
-    DCHECK((type & (kRepFloat32 | kRepFloat64)) != 0);
+    DCHECK(IsFloatingPoint(type.representation()));
     InstructionOperandConverter converter(this, instr);
     translation->StoreDoubleRegister(converter.ToDoubleRegister(op));
   } else if (op->IsImmediate()) {
@@ -495,23 +671,34 @@
     Handle<Object> constant_object;
     switch (constant.type()) {
       case Constant::kInt32:
-        DCHECK(type == kMachInt32 || type == kMachUint32);
+        DCHECK(type == MachineType::Int32() || type == MachineType::Uint32() ||
+               type.representation() == MachineRepresentation::kBit);
         constant_object =
             isolate()->factory()->NewNumberFromInt(constant.ToInt32());
         break;
+      case Constant::kFloat32:
+        DCHECK(type.representation() == MachineRepresentation::kFloat32 ||
+               type.representation() == MachineRepresentation::kTagged);
+        constant_object = isolate()->factory()->NewNumber(constant.ToFloat32());
+        break;
       case Constant::kFloat64:
-        DCHECK(type == kMachFloat64 || type == kMachAnyTagged);
+        DCHECK(type.representation() == MachineRepresentation::kFloat64 ||
+               type.representation() == MachineRepresentation::kTagged);
         constant_object = isolate()->factory()->NewNumber(constant.ToFloat64());
         break;
       case Constant::kHeapObject:
-        DCHECK((type & kRepMask) == kRepTagged);
+        DCHECK(type.representation() == MachineRepresentation::kTagged);
         constant_object = constant.ToHeapObject();
         break;
       default:
         CHECK(false);
     }
-    int literal_id = DefineDeoptimizationLiteral(constant_object);
-    translation->StoreLiteral(literal_id);
+    if (constant_object.is_identical_to(info()->closure())) {
+      translation->StoreJSFrameFunction();
+    } else {
+      int literal_id = DefineDeoptimizationLiteral(constant_object);
+      translation->StoreLiteral(literal_id);
+    }
   } else {
     CHECK(false);
   }
@@ -522,60 +709,23 @@
   last_lazy_deopt_pc_ = masm()->pc_offset();
 }
 
-#if !V8_TURBOFAN_BACKEND
 
-void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
-  UNIMPLEMENTED();
+int CodeGenerator::TailCallFrameStackSlotDelta(int stack_param_delta) {
+  CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
+  int spill_slots = frame()->GetSpillSlotCount();
+  bool has_frame = descriptor->IsJSFunctionCall() || spill_slots > 0;
+  // Leave the PC on the stack on platforms that have that as part of their ABI
+  int pc_slots = V8_TARGET_ARCH_STORES_RETURN_ADDRESS_ON_STACK ? 1 : 0;
+  int sp_slot_delta =
+      has_frame ? (frame()->GetTotalFrameSlotCount() - pc_slots) : 0;
+  // Discard only slots that won't be used by new parameters.
+  sp_slot_delta += stack_param_delta;
+  return sp_slot_delta;
 }
 
 
-void CodeGenerator::AssembleArchBranch(Instruction* instr,
-                                       BranchInfo* branch) {
-  UNIMPLEMENTED();
-}
-
-
-void CodeGenerator::AssembleArchBoolean(Instruction* instr,
-                                        FlagsCondition condition) {
-  UNIMPLEMENTED();
-}
-
-
-void CodeGenerator::AssembleArchJump(BasicBlock::RpoNumber target) {
-  UNIMPLEMENTED();
-}
-
-
-void CodeGenerator::AssembleDeoptimizerCall(int deoptimization_id) {
-  UNIMPLEMENTED();
-}
-
-
-void CodeGenerator::AssemblePrologue() { UNIMPLEMENTED(); }
-
-
-void CodeGenerator::AssembleReturn() { UNIMPLEMENTED(); }
-
-
-void CodeGenerator::AssembleMove(InstructionOperand* source,
-                                 InstructionOperand* destination) {
-  UNIMPLEMENTED();
-}
-
-
-void CodeGenerator::AssembleSwap(InstructionOperand* source,
-                                 InstructionOperand* destination) {
-  UNIMPLEMENTED();
-}
-
-
-void CodeGenerator::AddNopForSmiCodeInlining() { UNIMPLEMENTED(); }
-
-#endif  // !V8_TURBOFAN_BACKEND
-
-
 OutOfLineCode::OutOfLineCode(CodeGenerator* gen)
-    : masm_(gen->masm()), next_(gen->ools_) {
+    : frame_(gen->frame()), masm_(gen->masm()), next_(gen->ools_) {
   gen->ools_ = this;
 }
 
diff --git a/src/compiler/code-generator.h b/src/compiler/code-generator.h
index 747bad2..70bf81f 100644
--- a/src/compiler/code-generator.h
+++ b/src/compiler/code-generator.h
@@ -16,6 +16,7 @@
 namespace compiler {
 
 // Forward declarations.
+class FrameAccessState;
 class Linkage;
 class OutOfLineCode;
 
@@ -27,8 +28,22 @@
 };
 
 
+class InstructionOperandIterator {
+ public:
+  InstructionOperandIterator(Instruction* instr, size_t pos)
+      : instr_(instr), pos_(pos) {}
+
+  Instruction* instruction() const { return instr_; }
+  InstructionOperand* Advance() { return instr_->InputAt(pos_++); }
+
+ private:
+  Instruction* instr_;
+  size_t pos_;
+};
+
+
 // Generates native code for a sequence of instructions.
-class CodeGenerator FINAL : public GapResolver::Assembler {
+class CodeGenerator final : public GapResolver::Assembler {
  public:
   explicit CodeGenerator(Frame* frame, Linkage* linkage,
                          InstructionSequence* code, CompilationInfo* info);
@@ -37,11 +52,12 @@
   Handle<Code> GenerateCode();
 
   InstructionSequence* code() const { return code_; }
-  Frame* frame() const { return frame_; }
-  Isolate* isolate() const { return zone()->isolate(); }
+  FrameAccessState* frame_access_state() const { return frame_access_state_; }
+  Frame* frame() const { return frame_access_state_->frame(); }
+  Isolate* isolate() const { return info_->isolate(); }
   Linkage* linkage() const { return linkage_; }
 
-  Label* GetLabel(BasicBlock::RpoNumber rpo) { return &labels_[rpo.ToSize()]; }
+  Label* GetLabel(RpoNumber rpo) { return &labels_[rpo.ToSize()]; }
 
  private:
   MacroAssembler* masm() { return &masm_; }
@@ -52,27 +68,39 @@
 
   // Checks if {block} will appear directly after {current_block_} when
   // assembling code, in which case, a fall-through can be used.
-  bool IsNextInAssemblyOrder(BasicBlock::RpoNumber block) const;
+  bool IsNextInAssemblyOrder(RpoNumber block) const;
 
   // Record a safepoint with the given pointer map.
-  void RecordSafepoint(PointerMap* pointers, Safepoint::Kind kind,
+  void RecordSafepoint(ReferenceMap* references, Safepoint::Kind kind,
                        int arguments, Safepoint::DeoptMode deopt_mode);
 
+  // Check if a heap object can be materialized by loading from the frame, which
+  // is usually way cheaper than materializing the actual heap object constant.
+  bool IsMaterializableFromFrame(Handle<HeapObject> object, int* offset_return);
+  // Check if a heap object can be materialized by loading from a heap root,
+  // which is cheaper on some platforms than materializing the actual heap
+  // object constant.
+  bool IsMaterializableFromRoot(Handle<HeapObject> object,
+                                Heap::RootListIndex* index_return);
+
   // Assemble code for the specified instruction.
   void AssembleInstruction(Instruction* instr);
-  void AssembleSourcePosition(SourcePositionInstruction* instr);
-  void AssembleGap(GapInstruction* gap);
+  void AssembleSourcePosition(Instruction* instr);
+  void AssembleGaps(Instruction* instr);
 
   // ===========================================================================
   // ============= Architecture-specific code generation methods. ==============
   // ===========================================================================
 
   void AssembleArchInstruction(Instruction* instr);
-  void AssembleArchJump(BasicBlock::RpoNumber target);
+  void AssembleArchJump(RpoNumber target);
   void AssembleArchBranch(Instruction* instr, BranchInfo* branch);
   void AssembleArchBoolean(Instruction* instr, FlagsCondition condition);
+  void AssembleArchLookupSwitch(Instruction* instr);
+  void AssembleArchTableSwitch(Instruction* instr);
 
-  void AssembleDeoptimizerCall(int deoptimization_id);
+  void AssembleDeoptimizerCall(int deoptimization_id,
+                               Deoptimizer::BailoutType bailout_type);
 
   // Generates an architecture-specific, descriptor-specific prologue
   // to set up a stack frame.
@@ -81,37 +109,70 @@
   // to tear down a stack frame.
   void AssembleReturn();
 
+  // Generates code to deconstruct a the caller's frame, including arguments.
+  void AssembleDeconstructActivationRecord(int stack_param_delta);
+
+  // Generates code to manipulate the stack in preparation for a tail call.
+  void AssemblePrepareTailCall(int stack_param_delta);
+
   // ===========================================================================
   // ============== Architecture-specific gap resolver methods. ================
   // ===========================================================================
 
   // Interface used by the gap resolver to emit moves and swaps.
   void AssembleMove(InstructionOperand* source,
-                    InstructionOperand* destination) FINAL;
+                    InstructionOperand* destination) final;
   void AssembleSwap(InstructionOperand* source,
-                    InstructionOperand* destination) FINAL;
+                    InstructionOperand* destination) final;
 
   // ===========================================================================
-  // Deoptimization table construction
-  void AddSafepointAndDeopt(Instruction* instr);
+  // =================== Jump table construction methods. ======================
+  // ===========================================================================
+
+  class JumpTable;
+  // Adds a jump table that is emitted after the actual code.  Returns label
+  // pointing to the beginning of the table.  {targets} is assumed to be static
+  // or zone allocated.
+  Label* AddJumpTable(Label** targets, size_t target_count);
+  // Emits a jump table.
+  void AssembleJumpTable(Label** targets, size_t target_count);
+
+  // ===========================================================================
+  // ================== Deoptimization table construction. =====================
+  // ===========================================================================
+
+  void RecordCallPosition(Instruction* instr);
   void PopulateDeoptimizationData(Handle<Code> code);
   int DefineDeoptimizationLiteral(Handle<Object> literal);
-  FrameStateDescriptor* GetFrameStateDescriptor(Instruction* instr,
-                                                size_t frame_state_offset);
+  FrameStateDescriptor* GetFrameStateDescriptor(
+      Instruction* instr, size_t frame_access_state_offset);
   int BuildTranslation(Instruction* instr, int pc_offset,
-                       size_t frame_state_offset,
+                       size_t frame_access_state_offset,
                        OutputFrameStateCombine state_combine);
   void BuildTranslationForFrameStateDescriptor(
-      FrameStateDescriptor* descriptor, Instruction* instr,
-      Translation* translation, size_t frame_state_offset,
-      OutputFrameStateCombine state_combine);
+      FrameStateDescriptor* descriptor, InstructionOperandIterator* iter,
+      Translation* translation, OutputFrameStateCombine state_combine);
+  void TranslateStateValueDescriptor(StateValueDescriptor* desc,
+                                     Translation* translation,
+                                     InstructionOperandIterator* iter);
+  void TranslateFrameStateDescriptorOperands(FrameStateDescriptor* desc,
+                                             InstructionOperandIterator* iter,
+                                             OutputFrameStateCombine combine,
+                                             Translation* translation);
   void AddTranslationForOperand(Translation* translation, Instruction* instr,
                                 InstructionOperand* op, MachineType type);
   void AddNopForSmiCodeInlining();
   void EnsureSpaceForLazyDeopt();
   void MarkLazyDeoptSite();
 
+  // Converts the delta in the number of stack parameter passed from a tail
+  // caller to the callee into the distance (in pointers) the SP must be
+  // adjusted, taking frame elision and other relevant factors into
+  // consideration.
+  int TailCallFrameStackSlotDelta(int stack_param_delta);
+
   // ===========================================================================
+
   struct DeoptimizationState : ZoneObject {
    public:
     BailoutId bailout_id() const { return bailout_id_; }
@@ -129,23 +190,34 @@
     int pc_offset_;
   };
 
+  struct HandlerInfo {
+    bool caught_locally;
+    Label* handler;
+    int pc_offset;
+  };
+
   friend class OutOfLineCode;
 
-  Frame* const frame_;
+  FrameAccessState* frame_access_state_;
   Linkage* const linkage_;
   InstructionSequence* const code_;
   CompilationInfo* const info_;
   Label* const labels_;
-  BasicBlock::RpoNumber current_block_;
+  Label return_label_;
+  RpoNumber current_block_;
   SourcePosition current_source_position_;
   MacroAssembler masm_;
   GapResolver resolver_;
   SafepointTableBuilder safepoints_;
+  ZoneVector<HandlerInfo> handlers_;
   ZoneDeque<DeoptimizationState*> deoptimization_states_;
-  ZoneDeque<Handle<Object> > deoptimization_literals_;
+  ZoneDeque<Handle<Object>> deoptimization_literals_;
+  size_t inlined_function_count_;
   TranslationBuffer translations_;
   int last_lazy_deopt_pc_;
+  JumpTable* jump_tables_;
   OutOfLineCode* ools_;
+  int osr_pc_offset_;
 };
 
 }  // namespace compiler
diff --git a/src/compiler/code-stub-assembler.cc b/src/compiler/code-stub-assembler.cc
new file mode 100644
index 0000000..b2a05b6
--- /dev/null
+++ b/src/compiler/code-stub-assembler.cc
@@ -0,0 +1,176 @@
+// Copyright 2015 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/code-stub-assembler.h"
+
+#include <ostream>
+
+#include "src/code-factory.h"
+#include "src/compiler/graph.h"
+#include "src/compiler/instruction-selector.h"
+#include "src/compiler/linkage.h"
+#include "src/compiler/pipeline.h"
+#include "src/compiler/raw-machine-assembler.h"
+#include "src/compiler/schedule.h"
+#include "src/frames.h"
+#include "src/interface-descriptors.h"
+#include "src/interpreter/bytecodes.h"
+#include "src/machine-type.h"
+#include "src/macro-assembler.h"
+#include "src/zone.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+
+CodeStubAssembler::CodeStubAssembler(Isolate* isolate, Zone* zone,
+                                     const CallInterfaceDescriptor& descriptor,
+                                     Code::Kind kind, const char* name)
+    : raw_assembler_(new RawMachineAssembler(
+          isolate, new (zone) Graph(zone),
+          Linkage::GetStubCallDescriptor(isolate, zone, descriptor, 0,
+                                         CallDescriptor::kNoFlags))),
+      kind_(kind),
+      name_(name),
+      code_generated_(false) {}
+
+
+CodeStubAssembler::~CodeStubAssembler() {}
+
+
+Handle<Code> CodeStubAssembler::GenerateCode() {
+  DCHECK(!code_generated_);
+
+  Schedule* schedule = raw_assembler_->Export();
+  Handle<Code> code = Pipeline::GenerateCodeForCodeStub(
+      isolate(), raw_assembler_->call_descriptor(), graph(), schedule, kind_,
+      name_);
+
+  code_generated_ = true;
+  return code;
+}
+
+
+Node* CodeStubAssembler::Int32Constant(int value) {
+  return raw_assembler_->Int32Constant(value);
+}
+
+
+Node* CodeStubAssembler::IntPtrConstant(intptr_t value) {
+  return raw_assembler_->IntPtrConstant(value);
+}
+
+
+Node* CodeStubAssembler::NumberConstant(double value) {
+  return raw_assembler_->NumberConstant(value);
+}
+
+
+Node* CodeStubAssembler::HeapConstant(Handle<HeapObject> object) {
+  return raw_assembler_->HeapConstant(object);
+}
+
+
+Node* CodeStubAssembler::BooleanConstant(bool value) {
+  return raw_assembler_->BooleanConstant(value);
+}
+
+
+Node* CodeStubAssembler::Parameter(int value) {
+  return raw_assembler_->Parameter(value);
+}
+
+
+void CodeStubAssembler::Return(Node* value) {
+  return raw_assembler_->Return(value);
+}
+
+
+Node* CodeStubAssembler::SmiShiftBitsConstant() {
+  return Int32Constant(kSmiShiftSize + kSmiTagSize);
+}
+
+
+Node* CodeStubAssembler::SmiTag(Node* value) {
+  return raw_assembler_->WordShl(value, SmiShiftBitsConstant());
+}
+
+
+Node* CodeStubAssembler::SmiUntag(Node* value) {
+  return raw_assembler_->WordSar(value, SmiShiftBitsConstant());
+}
+
+
+Node* CodeStubAssembler::IntPtrAdd(Node* a, Node* b) {
+  return raw_assembler_->IntPtrAdd(a, b);
+}
+
+
+Node* CodeStubAssembler::IntPtrSub(Node* a, Node* b) {
+  return raw_assembler_->IntPtrSub(a, b);
+}
+
+
+Node* CodeStubAssembler::WordShl(Node* value, int shift) {
+  return raw_assembler_->WordShl(value, Int32Constant(shift));
+}
+
+
+Node* CodeStubAssembler::LoadObjectField(Node* object, int offset) {
+  return raw_assembler_->Load(MachineType::AnyTagged(), object,
+                              IntPtrConstant(offset - kHeapObjectTag));
+}
+
+
+Node* CodeStubAssembler::CallN(CallDescriptor* descriptor, Node* code_target,
+                               Node** args) {
+  return raw_assembler_->CallN(descriptor, code_target, args);
+}
+
+
+Node* CodeStubAssembler::TailCallN(CallDescriptor* descriptor,
+                                   Node* code_target, Node** args) {
+  return raw_assembler_->TailCallN(descriptor, code_target, args);
+}
+
+
+Node* CodeStubAssembler::CallRuntime(Runtime::FunctionId function_id,
+                                     Node* context, Node* arg1) {
+  return raw_assembler_->CallRuntime1(function_id, arg1, context);
+}
+
+
+Node* CodeStubAssembler::CallRuntime(Runtime::FunctionId function_id,
+                                     Node* context, Node* arg1, Node* arg2) {
+  return raw_assembler_->CallRuntime2(function_id, arg1, arg2, context);
+}
+
+
+Node* CodeStubAssembler::TailCallRuntime(Runtime::FunctionId function_id,
+                                         Node* context, Node* arg1) {
+  return raw_assembler_->TailCallRuntime1(function_id, arg1, context);
+}
+
+
+Node* CodeStubAssembler::TailCallRuntime(Runtime::FunctionId function_id,
+                                         Node* context, Node* arg1,
+                                         Node* arg2) {
+  return raw_assembler_->TailCallRuntime2(function_id, arg1, arg2, context);
+}
+
+
+// RawMachineAssembler delegate helpers:
+Isolate* CodeStubAssembler::isolate() { return raw_assembler_->isolate(); }
+
+
+Graph* CodeStubAssembler::graph() { return raw_assembler_->graph(); }
+
+
+Zone* CodeStubAssembler::zone() { return raw_assembler_->zone(); }
+
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/code-stub-assembler.h b/src/compiler/code-stub-assembler.h
new file mode 100644
index 0000000..3c4ae05
--- /dev/null
+++ b/src/compiler/code-stub-assembler.h
@@ -0,0 +1,96 @@
+// Copyright 2015 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.
+
+#ifndef V8_COMPILER_CODE_STUB_ASSEMBLER_H_
+#define V8_COMPILER_CODE_STUB_ASSEMBLER_H_
+
+// Clients of this interface shouldn't depend on lots of compiler internals.
+// Do not include anything from src/compiler here!
+#include "src/allocation.h"
+#include "src/builtins.h"
+#include "src/runtime/runtime.h"
+
+namespace v8 {
+namespace internal {
+
+class CallInterfaceDescriptor;
+class Isolate;
+class Zone;
+
+namespace compiler {
+
+class CallDescriptor;
+class Graph;
+class Node;
+class Operator;
+class RawMachineAssembler;
+class Schedule;
+
+class CodeStubAssembler {
+ public:
+  CodeStubAssembler(Isolate* isolate, Zone* zone,
+                    const CallInterfaceDescriptor& descriptor, Code::Kind kind,
+                    const char* name);
+  virtual ~CodeStubAssembler();
+
+  Handle<Code> GenerateCode();
+
+  // Constants.
+  Node* Int32Constant(int value);
+  Node* IntPtrConstant(intptr_t value);
+  Node* NumberConstant(double value);
+  Node* HeapConstant(Handle<HeapObject> object);
+  Node* BooleanConstant(bool value);
+
+  Node* Parameter(int value);
+  void Return(Node* value);
+
+  // Tag and untag Smi values.
+  Node* SmiTag(Node* value);
+  Node* SmiUntag(Node* value);
+
+  // Basic arithmetic operations.
+  Node* IntPtrAdd(Node* a, Node* b);
+  Node* IntPtrSub(Node* a, Node* b);
+  Node* WordShl(Node* value, int shift);
+
+  // Load a field from an object on the heap.
+  Node* LoadObjectField(Node* object, int offset);
+
+  // Call runtime function.
+  Node* CallRuntime(Runtime::FunctionId function_id, Node* context, Node* arg1);
+  Node* CallRuntime(Runtime::FunctionId function_id, Node* context, Node* arg1,
+                    Node* arg2);
+
+  Node* TailCallRuntime(Runtime::FunctionId function_id, Node* context,
+                        Node* arg1);
+  Node* TailCallRuntime(Runtime::FunctionId function_id, Node* context,
+                        Node* arg1, Node* arg2);
+
+ private:
+  friend class CodeStubAssemblerTester;
+
+  Node* CallN(CallDescriptor* descriptor, Node* code_target, Node** args);
+  Node* TailCallN(CallDescriptor* descriptor, Node* code_target, Node** args);
+
+  Node* SmiShiftBitsConstant();
+
+  // Private helpers which delegate to RawMachineAssembler.
+  Graph* graph();
+  Isolate* isolate();
+  Zone* zone();
+
+  base::SmartPointer<RawMachineAssembler> raw_assembler_;
+  Code::Kind kind_;
+  const char* name_;
+  bool code_generated_;
+
+  DISALLOW_COPY_AND_ASSIGN(CodeStubAssembler);
+};
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_CODE_STUB_ASSEMBLER_H_
diff --git a/src/compiler/common-node-cache.cc b/src/compiler/common-node-cache.cc
index ee1fa0f..a0ae6e8 100644
--- a/src/compiler/common-node-cache.cc
+++ b/src/compiler/common-node-cache.cc
@@ -5,6 +5,7 @@
 #include "src/compiler/common-node-cache.h"
 
 #include "src/assembler.h"
+#include "src/compiler/node.h"
 
 namespace v8 {
 namespace internal {
@@ -15,6 +16,11 @@
 }
 
 
+Node** CommonNodeCache::FindHeapConstant(Handle<HeapObject> value) {
+  return heap_constants_.Find(zone(), bit_cast<intptr_t>(value.location()));
+}
+
+
 void CommonNodeCache::GetCachedNodes(ZoneVector<Node*>* nodes) {
   int32_constants_.GetCachedNodes(nodes);
   int64_constants_.GetCachedNodes(nodes);
@@ -22,6 +28,7 @@
   float64_constants_.GetCachedNodes(nodes);
   external_constants_.GetCachedNodes(nodes);
   number_constants_.GetCachedNodes(nodes);
+  heap_constants_.GetCachedNodes(nodes);
 }
 
 }  // namespace compiler
diff --git a/src/compiler/common-node-cache.h b/src/compiler/common-node-cache.h
index 7ec70ae..720bc15 100644
--- a/src/compiler/common-node-cache.h
+++ b/src/compiler/common-node-cache.h
@@ -12,12 +12,15 @@
 
 // Forward declarations.
 class ExternalReference;
+class HeapObject;
+template <typename>
+class Handle;
 
 
 namespace compiler {
 
 // Bundles various caches for common nodes.
-class CommonNodeCache FINAL {
+class CommonNodeCache final {
  public:
   explicit CommonNodeCache(Zone* zone) : zone_(zone) {}
   ~CommonNodeCache() {}
@@ -47,6 +50,8 @@
     return number_constants_.Find(zone(), bit_cast<int64_t>(value));
   }
 
+  Node** FindHeapConstant(Handle<HeapObject> value);
+
   // Return all nodes from the cache.
   void GetCachedNodes(ZoneVector<Node*>* nodes);
 
@@ -59,7 +64,8 @@
   Int64NodeCache float64_constants_;
   IntPtrNodeCache external_constants_;
   Int64NodeCache number_constants_;
-  Zone* zone_;
+  IntPtrNodeCache heap_constants_;
+  Zone* const zone_;
 
   DISALLOW_COPY_AND_ASSIGN(CommonNodeCache);
 };
diff --git a/src/compiler/common-operator-reducer.cc b/src/compiler/common-operator-reducer.cc
index cf597ea..2334541 100644
--- a/src/compiler/common-operator-reducer.cc
+++ b/src/compiler/common-operator-reducer.cc
@@ -4,29 +4,354 @@
 
 #include "src/compiler/common-operator-reducer.h"
 
+#include <algorithm>
+
 #include "src/compiler/common-operator.h"
+#include "src/compiler/graph.h"
+#include "src/compiler/machine-operator.h"
+#include "src/compiler/node.h"
+#include "src/compiler/node-matchers.h"
+#include "src/compiler/node-properties.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
+namespace {
+
+enum class Decision { kUnknown, kTrue, kFalse };
+
+Decision DecideCondition(Node* const cond) {
+  switch (cond->opcode()) {
+    case IrOpcode::kInt32Constant: {
+      Int32Matcher mcond(cond);
+      return mcond.Value() ? Decision::kTrue : Decision::kFalse;
+    }
+    case IrOpcode::kInt64Constant: {
+      Int64Matcher mcond(cond);
+      return mcond.Value() ? Decision::kTrue : Decision::kFalse;
+    }
+    case IrOpcode::kHeapConstant: {
+      HeapObjectMatcher mcond(cond);
+      return mcond.Value()->BooleanValue() ? Decision::kTrue : Decision::kFalse;
+    }
+    default:
+      return Decision::kUnknown;
+  }
+}
+
+}  // namespace
+
+
+CommonOperatorReducer::CommonOperatorReducer(Editor* editor, Graph* graph,
+                                             CommonOperatorBuilder* common,
+                                             MachineOperatorBuilder* machine)
+    : AdvancedReducer(editor),
+      graph_(graph),
+      common_(common),
+      machine_(machine),
+      dead_(graph->NewNode(common->Dead())) {}
+
+
 Reduction CommonOperatorReducer::Reduce(Node* node) {
   switch (node->opcode()) {
+    case IrOpcode::kBranch:
+      return ReduceBranch(node);
+    case IrOpcode::kMerge:
+      return ReduceMerge(node);
     case IrOpcode::kEffectPhi:
-    case IrOpcode::kPhi: {
-      int const input_count = node->InputCount();
-      if (input_count > 1) {
-        Node* const replacement = node->InputAt(0);
-        for (int i = 1; i < input_count - 1; ++i) {
-          if (node->InputAt(i) != replacement) return NoChange();
+      return ReduceEffectPhi(node);
+    case IrOpcode::kPhi:
+      return ReducePhi(node);
+    case IrOpcode::kReturn:
+      return ReduceReturn(node);
+    case IrOpcode::kSelect:
+      return ReduceSelect(node);
+    case IrOpcode::kGuard:
+      return ReduceGuard(node);
+    default:
+      break;
+  }
+  return NoChange();
+}
+
+
+Reduction CommonOperatorReducer::ReduceBranch(Node* node) {
+  DCHECK_EQ(IrOpcode::kBranch, node->opcode());
+  Node* const cond = node->InputAt(0);
+  // Swap IfTrue/IfFalse on {branch} if {cond} is a BooleanNot and use the input
+  // to BooleanNot as new condition for {branch}. Note we assume that {cond} was
+  // already properly optimized before we get here (as guaranteed by the graph
+  // reduction logic).
+  if (cond->opcode() == IrOpcode::kBooleanNot) {
+    for (Node* const use : node->uses()) {
+      switch (use->opcode()) {
+        case IrOpcode::kIfTrue:
+          NodeProperties::ChangeOp(use, common()->IfFalse());
+          break;
+        case IrOpcode::kIfFalse:
+          NodeProperties::ChangeOp(use, common()->IfTrue());
+          break;
+        default:
+          UNREACHABLE();
+      }
+    }
+    // Update the condition of {branch}. No need to mark the uses for revisit,
+    // since we tell the graph reducer that the {branch} was changed and the
+    // graph reduction logic will ensure that the uses are revisited properly.
+    node->ReplaceInput(0, cond->InputAt(0));
+    // Negate the hint for {branch}.
+    NodeProperties::ChangeOp(
+        node, common()->Branch(NegateBranchHint(BranchHintOf(node->op()))));
+    return Changed(node);
+  }
+  Decision const decision = DecideCondition(cond);
+  if (decision == Decision::kUnknown) return NoChange();
+  Node* const control = node->InputAt(1);
+  for (Node* const use : node->uses()) {
+    switch (use->opcode()) {
+      case IrOpcode::kIfTrue:
+        Replace(use, (decision == Decision::kTrue) ? control : dead());
+        break;
+      case IrOpcode::kIfFalse:
+        Replace(use, (decision == Decision::kFalse) ? control : dead());
+        break;
+      default:
+        UNREACHABLE();
+    }
+  }
+  return Replace(dead());
+}
+
+
+Reduction CommonOperatorReducer::ReduceMerge(Node* node) {
+  DCHECK_EQ(IrOpcode::kMerge, node->opcode());
+  //
+  // Check if this is a merge that belongs to an unused diamond, which means
+  // that:
+  //
+  //  a) the {Merge} has no {Phi} or {EffectPhi} uses, and
+  //  b) the {Merge} has two inputs, one {IfTrue} and one {IfFalse}, which are
+  //     both owned by the Merge, and
+  //  c) and the {IfTrue} and {IfFalse} nodes point to the same {Branch}.
+  //
+  if (node->InputCount() == 2) {
+    for (Node* const use : node->uses()) {
+      if (IrOpcode::IsPhiOpcode(use->opcode())) return NoChange();
+    }
+    Node* if_true = node->InputAt(0);
+    Node* if_false = node->InputAt(1);
+    if (if_true->opcode() != IrOpcode::kIfTrue) std::swap(if_true, if_false);
+    if (if_true->opcode() == IrOpcode::kIfTrue &&
+        if_false->opcode() == IrOpcode::kIfFalse &&
+        if_true->InputAt(0) == if_false->InputAt(0) && if_true->OwnedBy(node) &&
+        if_false->OwnedBy(node)) {
+      Node* const branch = if_true->InputAt(0);
+      DCHECK_EQ(IrOpcode::kBranch, branch->opcode());
+      DCHECK(branch->OwnedBy(if_true, if_false));
+      Node* const control = branch->InputAt(1);
+      // Mark the {branch} as {Dead}.
+      branch->TrimInputCount(0);
+      NodeProperties::ChangeOp(branch, common()->Dead());
+      return Replace(control);
+    }
+  }
+  return NoChange();
+}
+
+
+Reduction CommonOperatorReducer::ReduceEffectPhi(Node* node) {
+  DCHECK_EQ(IrOpcode::kEffectPhi, node->opcode());
+  int const input_count = node->InputCount() - 1;
+  DCHECK_LE(1, input_count);
+  Node* const merge = node->InputAt(input_count);
+  DCHECK(IrOpcode::IsMergeOpcode(merge->opcode()));
+  DCHECK_EQ(input_count, merge->InputCount());
+  Node* const effect = node->InputAt(0);
+  DCHECK_NE(node, effect);
+  for (int i = 1; i < input_count; ++i) {
+    Node* const input = node->InputAt(i);
+    if (input == node) {
+      // Ignore redundant inputs.
+      DCHECK_EQ(IrOpcode::kLoop, merge->opcode());
+      continue;
+    }
+    if (input != effect) return NoChange();
+  }
+  // We might now be able to further reduce the {merge} node.
+  Revisit(merge);
+  return Replace(effect);
+}
+
+
+Reduction CommonOperatorReducer::ReducePhi(Node* node) {
+  DCHECK_EQ(IrOpcode::kPhi, node->opcode());
+  int const input_count = node->InputCount() - 1;
+  DCHECK_LE(1, input_count);
+  Node* const merge = node->InputAt(input_count);
+  DCHECK(IrOpcode::IsMergeOpcode(merge->opcode()));
+  DCHECK_EQ(input_count, merge->InputCount());
+  if (input_count == 2) {
+    Node* vtrue = node->InputAt(0);
+    Node* vfalse = node->InputAt(1);
+    Node* if_true = merge->InputAt(0);
+    Node* if_false = merge->InputAt(1);
+    if (if_true->opcode() != IrOpcode::kIfTrue) {
+      std::swap(if_true, if_false);
+      std::swap(vtrue, vfalse);
+    }
+    if (if_true->opcode() == IrOpcode::kIfTrue &&
+        if_false->opcode() == IrOpcode::kIfFalse &&
+        if_true->InputAt(0) == if_false->InputAt(0)) {
+      Node* const branch = if_true->InputAt(0);
+      // Check that the branch is not dead already.
+      if (branch->opcode() != IrOpcode::kBranch) return NoChange();
+      Node* const cond = branch->InputAt(0);
+      if (cond->opcode() == IrOpcode::kFloat32LessThan) {
+        Float32BinopMatcher mcond(cond);
+        if (mcond.left().Is(0.0) && mcond.right().Equals(vtrue) &&
+            vfalse->opcode() == IrOpcode::kFloat32Sub) {
+          Float32BinopMatcher mvfalse(vfalse);
+          if (mvfalse.left().IsZero() && mvfalse.right().Equals(vtrue)) {
+            // We might now be able to further reduce the {merge} node.
+            Revisit(merge);
+            return Change(node, machine()->Float32Abs(), vtrue);
+          }
         }
-        return Replace(replacement);
+        if (mcond.left().Equals(vtrue) && mcond.right().Equals(vfalse) &&
+            machine()->Float32Min().IsSupported()) {
+          // We might now be able to further reduce the {merge} node.
+          Revisit(merge);
+          return Change(node, machine()->Float32Min().op(), vtrue, vfalse);
+        } else if (mcond.left().Equals(vfalse) && mcond.right().Equals(vtrue) &&
+                   machine()->Float32Max().IsSupported()) {
+          // We might now be able to further reduce the {merge} node.
+          Revisit(merge);
+          return Change(node, machine()->Float32Max().op(), vtrue, vfalse);
+        }
+      } else if (cond->opcode() == IrOpcode::kFloat64LessThan) {
+        Float64BinopMatcher mcond(cond);
+        if (mcond.left().Is(0.0) && mcond.right().Equals(vtrue) &&
+            vfalse->opcode() == IrOpcode::kFloat64Sub) {
+          Float64BinopMatcher mvfalse(vfalse);
+          if (mvfalse.left().IsZero() && mvfalse.right().Equals(vtrue)) {
+            // We might now be able to further reduce the {merge} node.
+            Revisit(merge);
+            return Change(node, machine()->Float64Abs(), vtrue);
+          }
+        }
+        if (mcond.left().Equals(vtrue) && mcond.right().Equals(vfalse) &&
+            machine()->Float64Min().IsSupported()) {
+          // We might now be able to further reduce the {merge} node.
+          Revisit(merge);
+          return Change(node, machine()->Float64Min().op(), vtrue, vfalse);
+        } else if (mcond.left().Equals(vfalse) && mcond.right().Equals(vtrue) &&
+                   machine()->Float64Max().IsSupported()) {
+          // We might now be able to further reduce the {merge} node.
+          Revisit(merge);
+          return Change(node, machine()->Float64Max().op(), vtrue, vfalse);
+        }
+      }
+    }
+  }
+  Node* const value = node->InputAt(0);
+  DCHECK_NE(node, value);
+  for (int i = 1; i < input_count; ++i) {
+    Node* const input = node->InputAt(i);
+    if (input == node) {
+      // Ignore redundant inputs.
+      DCHECK_EQ(IrOpcode::kLoop, merge->opcode());
+      continue;
+    }
+    if (input != value) return NoChange();
+  }
+  // We might now be able to further reduce the {merge} node.
+  Revisit(merge);
+  return Replace(value);
+}
+
+
+Reduction CommonOperatorReducer::ReduceReturn(Node* node) {
+  DCHECK_EQ(IrOpcode::kReturn, node->opcode());
+  Node* const value = node->InputAt(0);
+  Node* const effect = node->InputAt(1);
+  Node* const control = node->InputAt(2);
+  if (value->opcode() == IrOpcode::kPhi &&
+      NodeProperties::GetControlInput(value) == control &&
+      effect->opcode() == IrOpcode::kEffectPhi &&
+      NodeProperties::GetControlInput(effect) == control &&
+      control->opcode() == IrOpcode::kMerge) {
+    int const control_input_count = control->InputCount();
+    DCHECK_NE(0, control_input_count);
+    DCHECK_EQ(control_input_count, value->InputCount() - 1);
+    DCHECK_EQ(control_input_count, effect->InputCount() - 1);
+    DCHECK_EQ(IrOpcode::kEnd, graph()->end()->opcode());
+    DCHECK_NE(0, graph()->end()->InputCount());
+    for (int i = 0; i < control_input_count; ++i) {
+      // Create a new {Return} and connect it to {end}. We don't need to mark
+      // {end} as revisit, because we mark {node} as {Dead} below, which was
+      // previously connected to {end}, so we know for sure that at some point
+      // the reducer logic will visit {end} again.
+      Node* ret = graph()->NewNode(common()->Return(), value->InputAt(i),
+                                   effect->InputAt(i), control->InputAt(i));
+      NodeProperties::MergeControlToEnd(graph(), common(), ret);
+    }
+    // Mark the merge {control} and return {node} as {dead}.
+    Replace(control, dead());
+    return Replace(dead());
+  }
+  return NoChange();
+}
+
+
+Reduction CommonOperatorReducer::ReduceSelect(Node* node) {
+  DCHECK_EQ(IrOpcode::kSelect, node->opcode());
+  Node* const cond = node->InputAt(0);
+  Node* const vtrue = node->InputAt(1);
+  Node* const vfalse = node->InputAt(2);
+  if (vtrue == vfalse) return Replace(vtrue);
+  switch (DecideCondition(cond)) {
+    case Decision::kTrue:
+      return Replace(vtrue);
+    case Decision::kFalse:
+      return Replace(vfalse);
+    case Decision::kUnknown:
+      break;
+  }
+  switch (cond->opcode()) {
+    case IrOpcode::kFloat32LessThan: {
+      Float32BinopMatcher mcond(cond);
+      if (mcond.left().Is(0.0) && mcond.right().Equals(vtrue) &&
+          vfalse->opcode() == IrOpcode::kFloat32Sub) {
+        Float32BinopMatcher mvfalse(vfalse);
+        if (mvfalse.left().IsZero() && mvfalse.right().Equals(vtrue)) {
+          return Change(node, machine()->Float32Abs(), vtrue);
+        }
+      }
+      if (mcond.left().Equals(vtrue) && mcond.right().Equals(vfalse) &&
+          machine()->Float32Min().IsSupported()) {
+        return Change(node, machine()->Float32Min().op(), vtrue, vfalse);
+      } else if (mcond.left().Equals(vfalse) && mcond.right().Equals(vtrue) &&
+                 machine()->Float32Max().IsSupported()) {
+        return Change(node, machine()->Float32Max().op(), vtrue, vfalse);
       }
       break;
     }
-    case IrOpcode::kSelect: {
-      if (node->InputAt(1) == node->InputAt(2)) {
-        return Replace(node->InputAt(1));
+    case IrOpcode::kFloat64LessThan: {
+      Float64BinopMatcher mcond(cond);
+      if (mcond.left().Is(0.0) && mcond.right().Equals(vtrue) &&
+          vfalse->opcode() == IrOpcode::kFloat64Sub) {
+        Float64BinopMatcher mvfalse(vfalse);
+        if (mvfalse.left().IsZero() && mvfalse.right().Equals(vtrue)) {
+          return Change(node, machine()->Float64Abs(), vtrue);
+        }
+      }
+      if (mcond.left().Equals(vtrue) && mcond.right().Equals(vfalse) &&
+          machine()->Float64Min().IsSupported()) {
+        return Change(node, machine()->Float64Min().op(), vtrue, vfalse);
+      } else if (mcond.left().Equals(vfalse) && mcond.right().Equals(vtrue) &&
+                 machine()->Float64Max().IsSupported()) {
+        return Change(node, machine()->Float64Max().op(), vtrue, vfalse);
       }
       break;
     }
@@ -36,6 +361,35 @@
   return NoChange();
 }
 
+
+Reduction CommonOperatorReducer::ReduceGuard(Node* node) {
+  DCHECK_EQ(IrOpcode::kGuard, node->opcode());
+  Node* const input = NodeProperties::GetValueInput(node, 0);
+  Type* const input_type = NodeProperties::GetTypeOrAny(input);
+  Type* const guard_type = OpParameter<Type*>(node);
+  if (input_type->Is(guard_type)) return Replace(input);
+  return NoChange();
+}
+
+
+Reduction CommonOperatorReducer::Change(Node* node, Operator const* op,
+                                        Node* a) {
+  node->ReplaceInput(0, a);
+  node->TrimInputCount(1);
+  NodeProperties::ChangeOp(node, op);
+  return Changed(node);
+}
+
+
+Reduction CommonOperatorReducer::Change(Node* node, Operator const* op, Node* a,
+                                        Node* b) {
+  node->ReplaceInput(0, a);
+  node->ReplaceInput(1, b);
+  node->TrimInputCount(2);
+  NodeProperties::ChangeOp(node, op);
+  return Changed(node);
+}
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/src/compiler/common-operator-reducer.h b/src/compiler/common-operator-reducer.h
index 10543db..7184755 100644
--- a/src/compiler/common-operator-reducer.h
+++ b/src/compiler/common-operator-reducer.h
@@ -11,13 +11,44 @@
 namespace internal {
 namespace compiler {
 
-// Performs strength reduction on nodes that have common operators.
-class CommonOperatorReducer FINAL : public Reducer {
- public:
-  CommonOperatorReducer() {}
-  ~CommonOperatorReducer() FINAL {}
+// Forward declarations.
+class CommonOperatorBuilder;
+class Graph;
+class MachineOperatorBuilder;
+class Operator;
 
-  Reduction Reduce(Node* node) FINAL;
+
+// Performs strength reduction on nodes that have common operators.
+class CommonOperatorReducer final : public AdvancedReducer {
+ public:
+  CommonOperatorReducer(Editor* editor, Graph* graph,
+                        CommonOperatorBuilder* common,
+                        MachineOperatorBuilder* machine);
+  ~CommonOperatorReducer() final {}
+
+  Reduction Reduce(Node* node) final;
+
+ private:
+  Reduction ReduceBranch(Node* node);
+  Reduction ReduceMerge(Node* node);
+  Reduction ReduceEffectPhi(Node* node);
+  Reduction ReducePhi(Node* node);
+  Reduction ReduceReturn(Node* node);
+  Reduction ReduceSelect(Node* node);
+  Reduction ReduceGuard(Node* node);
+
+  Reduction Change(Node* node, Operator const* op, Node* a);
+  Reduction Change(Node* node, Operator const* op, Node* a, Node* b);
+
+  Graph* graph() const { return graph_; }
+  CommonOperatorBuilder* common() const { return common_; }
+  MachineOperatorBuilder* machine() const { return machine_; }
+  Node* dead() const { return dead_; }
+
+  Graph* const graph_;
+  CommonOperatorBuilder* const common_;
+  MachineOperatorBuilder* const machine_;
+  Node* const dead_;
 };
 
 }  // namespace compiler
diff --git a/src/compiler/common-operator.cc b/src/compiler/common-operator.cc
index a6cca45..be77309 100644
--- a/src/compiler/common-operator.cc
+++ b/src/compiler/common-operator.cc
@@ -9,7 +9,7 @@
 #include "src/compiler/linkage.h"
 #include "src/compiler/opcodes.h"
 #include "src/compiler/operator.h"
-#include "src/unique.h"
+#include "src/handles-inl.h"
 #include "src/zone.h"
 
 namespace v8 {
@@ -36,8 +36,45 @@
 }
 
 
+size_t hash_value(DeoptimizeKind kind) { return static_cast<size_t>(kind); }
+
+
+std::ostream& operator<<(std::ostream& os, DeoptimizeKind kind) {
+  switch (kind) {
+    case DeoptimizeKind::kEager:
+      return os << "Eager";
+    case DeoptimizeKind::kSoft:
+      return os << "Soft";
+  }
+  UNREACHABLE();
+  return os;
+}
+
+
+DeoptimizeKind DeoptimizeKindOf(const Operator* const op) {
+  DCHECK_EQ(IrOpcode::kDeoptimize, op->opcode());
+  return OpParameter<DeoptimizeKind>(op);
+}
+
+
+size_t hash_value(IfExceptionHint hint) { return static_cast<size_t>(hint); }
+
+
+std::ostream& operator<<(std::ostream& os, IfExceptionHint hint) {
+  switch (hint) {
+    case IfExceptionHint::kLocallyCaught:
+      return os << "Caught";
+    case IfExceptionHint::kLocallyUncaught:
+      return os << "Uncaught";
+  }
+  UNREACHABLE();
+  return os;
+}
+
+
 bool operator==(SelectParameters const& lhs, SelectParameters const& rhs) {
-  return lhs.type() == rhs.type() && lhs.hint() == rhs.hint();
+  return lhs.representation() == rhs.representation() &&
+         lhs.hint() == rhs.hint();
 }
 
 
@@ -47,12 +84,12 @@
 
 
 size_t hash_value(SelectParameters const& p) {
-  return base::hash_combine(p.type(), p.hint());
+  return base::hash_combine(p.representation(), p.hint());
 }
 
 
 std::ostream& operator<<(std::ostream& os, SelectParameters const& p) {
-  return os << p.type() << "|" << p.hint();
+  return os << p.representation() << "|" << p.hint();
 }
 
 
@@ -62,54 +99,88 @@
 }
 
 
-size_t hash_value(OutputFrameStateCombine const& sc) {
-  return base::hash_combine(sc.kind_, sc.parameter_);
+size_t ProjectionIndexOf(const Operator* const op) {
+  DCHECK_EQ(IrOpcode::kProjection, op->opcode());
+  return OpParameter<size_t>(op);
 }
 
 
-std::ostream& operator<<(std::ostream& os, OutputFrameStateCombine const& sc) {
-  switch (sc.kind_) {
-    case OutputFrameStateCombine::kPushOutput:
-      if (sc.parameter_ == 0) return os << "Ignore";
-      return os << "Push(" << sc.parameter_ << ")";
-    case OutputFrameStateCombine::kPokeAt:
-      return os << "PokeAt(" << sc.parameter_ << ")";
-  }
-  UNREACHABLE();
-  return os;
+MachineRepresentation PhiRepresentationOf(const Operator* const op) {
+  DCHECK_EQ(IrOpcode::kPhi, op->opcode());
+  return OpParameter<MachineRepresentation>(op);
 }
 
 
-bool operator==(FrameStateCallInfo const& lhs, FrameStateCallInfo const& rhs) {
-  return lhs.type() == rhs.type() && lhs.bailout_id() == rhs.bailout_id() &&
-         lhs.state_combine() == rhs.state_combine();
+int ParameterIndexOf(const Operator* const op) {
+  DCHECK_EQ(IrOpcode::kParameter, op->opcode());
+  return OpParameter<ParameterInfo>(op).index();
 }
 
 
-bool operator!=(FrameStateCallInfo const& lhs, FrameStateCallInfo const& rhs) {
+const ParameterInfo& ParameterInfoOf(const Operator* const op) {
+  DCHECK_EQ(IrOpcode::kParameter, op->opcode());
+  return OpParameter<ParameterInfo>(op);
+}
+
+
+bool operator==(ParameterInfo const& lhs, ParameterInfo const& rhs) {
+  return lhs.index() == rhs.index();
+}
+
+
+bool operator!=(ParameterInfo const& lhs, ParameterInfo const& rhs) {
   return !(lhs == rhs);
 }
 
 
-size_t hash_value(FrameStateCallInfo const& info) {
-  return base::hash_combine(info.type(), info.bailout_id(),
-                            info.state_combine());
+size_t hash_value(ParameterInfo const& p) { return p.index(); }
+
+
+std::ostream& operator<<(std::ostream& os, ParameterInfo const& i) {
+  if (i.debug_name()) os << i.debug_name() << '#';
+  os << i.index();
+  return os;
 }
 
 
-std::ostream& operator<<(std::ostream& os, FrameStateCallInfo const& info) {
-  return os << info.type() << ", " << info.bailout_id() << ", "
-            << info.state_combine();
-}
+#define CACHED_OP_LIST(V)                                  \
+  V(Dead, Operator::kFoldable, 0, 0, 0, 1, 1, 1)           \
+  V(IfTrue, Operator::kKontrol, 0, 0, 1, 0, 0, 1)          \
+  V(IfFalse, Operator::kKontrol, 0, 0, 1, 0, 0, 1)         \
+  V(IfSuccess, Operator::kKontrol, 0, 0, 1, 0, 0, 1)       \
+  V(IfDefault, Operator::kKontrol, 0, 0, 1, 0, 0, 1)       \
+  V(Throw, Operator::kKontrol, 1, 1, 1, 0, 0, 1)           \
+  V(Terminate, Operator::kKontrol, 0, 1, 1, 0, 0, 1)       \
+  V(OsrNormalEntry, Operator::kFoldable, 0, 1, 1, 0, 1, 1) \
+  V(OsrLoopEntry, Operator::kFoldable, 0, 1, 1, 0, 1, 1)   \
+  V(BeginRegion, Operator::kNoThrow, 0, 1, 0, 0, 1, 0)     \
+  V(FinishRegion, Operator::kNoThrow, 1, 1, 0, 1, 1, 0)
 
 
-#define CACHED_OP_LIST(V)                     \
-  V(Dead, Operator::kFoldable, 0, 0, 0, 1)    \
-  V(End, Operator::kFoldable, 0, 0, 1, 0)     \
-  V(IfTrue, Operator::kFoldable, 0, 0, 1, 1)  \
-  V(IfFalse, Operator::kFoldable, 0, 0, 1, 1) \
-  V(Throw, Operator::kFoldable, 1, 1, 1, 1)   \
-  V(Return, Operator::kNoProperties, 1, 1, 1, 1)
+#define CACHED_RETURN_LIST(V) \
+  V(1)                        \
+  V(2)                        \
+  V(3)
+
+
+#define CACHED_END_LIST(V) \
+  V(1)                     \
+  V(2)                     \
+  V(3)                     \
+  V(4)                     \
+  V(5)                     \
+  V(6)                     \
+  V(7)                     \
+  V(8)
+
+
+#define CACHED_EFFECT_PHI_LIST(V) \
+  V(1)                            \
+  V(2)                            \
+  V(3)                            \
+  V(4)                            \
+  V(5)                            \
+  V(6)
 
 
 #define CACHED_LOOP_LIST(V) \
@@ -138,39 +209,138 @@
   V(6)
 
 
-struct CommonOperatorGlobalCache FINAL {
-#define CACHED(Name, properties, value_input_count, effect_input_count,     \
-               control_input_count, control_output_count)                   \
-  struct Name##Operator FINAL : public Operator {                           \
-    Name##Operator()                                                        \
-        : Operator(IrOpcode::k##Name, properties, #Name, value_input_count, \
-                   effect_input_count, control_input_count, 0, 0,           \
-                   control_output_count) {}                                 \
-  };                                                                        \
+#define CACHED_PHI_LIST(V) \
+  V(kTagged, 1)            \
+  V(kTagged, 2)            \
+  V(kTagged, 3)            \
+  V(kTagged, 4)            \
+  V(kTagged, 5)            \
+  V(kTagged, 6)            \
+  V(kBit, 2)               \
+  V(kFloat64, 2)           \
+  V(kWord32, 2)
+
+
+#define CACHED_PROJECTION_LIST(V) \
+  V(0)                            \
+  V(1)
+
+
+#define CACHED_STATE_VALUES_LIST(V) \
+  V(0)                              \
+  V(1)                              \
+  V(2)                              \
+  V(3)                              \
+  V(4)                              \
+  V(5)                              \
+  V(6)                              \
+  V(7)                              \
+  V(8)                              \
+  V(10)                             \
+  V(11)                             \
+  V(12)                             \
+  V(13)                             \
+  V(14)
+
+
+struct CommonOperatorGlobalCache final {
+#define CACHED(Name, properties, value_input_count, effect_input_count,      \
+               control_input_count, value_output_count, effect_output_count, \
+               control_output_count)                                         \
+  struct Name##Operator final : public Operator {                            \
+    Name##Operator()                                                         \
+        : Operator(IrOpcode::k##Name, properties, #Name, value_input_count,  \
+                   effect_input_count, control_input_count,                  \
+                   value_output_count, effect_output_count,                  \
+                   control_output_count) {}                                  \
+  };                                                                         \
   Name##Operator k##Name##Operator;
   CACHED_OP_LIST(CACHED)
 #undef CACHED
 
+  template <DeoptimizeKind kKind>
+  struct DeoptimizeOperator final : public Operator1<DeoptimizeKind> {
+    DeoptimizeOperator()
+        : Operator1<DeoptimizeKind>(                      // --
+              IrOpcode::kDeoptimize, Operator::kNoThrow,  // opcode
+              "Deoptimize",                               // name
+              1, 1, 1, 0, 0, 1,                           // counts
+              kKind) {}                                   // parameter
+  };
+  DeoptimizeOperator<DeoptimizeKind::kEager> kDeoptimizeEagerOperator;
+  DeoptimizeOperator<DeoptimizeKind::kSoft> kDeoptimizeSoftOperator;
+
+  template <IfExceptionHint kCaughtLocally>
+  struct IfExceptionOperator final : public Operator1<IfExceptionHint> {
+    IfExceptionOperator()
+        : Operator1<IfExceptionHint>(                      // --
+              IrOpcode::kIfException, Operator::kKontrol,  // opcode
+              "IfException",                               // name
+              0, 1, 1, 1, 1, 1,                            // counts
+              kCaughtLocally) {}                           // parameter
+  };
+  IfExceptionOperator<IfExceptionHint::kLocallyCaught> kIfExceptionCOperator;
+  IfExceptionOperator<IfExceptionHint::kLocallyUncaught> kIfExceptionUOperator;
+
+  template <size_t kInputCount>
+  struct EndOperator final : public Operator {
+    EndOperator()
+        : Operator(                                // --
+              IrOpcode::kEnd, Operator::kKontrol,  // opcode
+              "End",                               // name
+              0, 0, kInputCount, 0, 0, 0) {}       // counts
+  };
+#define CACHED_END(input_count) \
+  EndOperator<input_count> kEnd##input_count##Operator;
+  CACHED_END_LIST(CACHED_END)
+#undef CACHED_END
+
+  template <size_t kInputCount>
+  struct ReturnOperator final : public Operator {
+    ReturnOperator()
+        : Operator(                                   // --
+              IrOpcode::kReturn, Operator::kNoThrow,  // opcode
+              "Return",                               // name
+              kInputCount, 1, 1, 0, 0, 1) {}          // counts
+  };
+#define CACHED_RETURN(input_count) \
+  ReturnOperator<input_count> kReturn##input_count##Operator;
+  CACHED_RETURN_LIST(CACHED_RETURN)
+#undef CACHED_RETURN
+
   template <BranchHint kBranchHint>
-  struct BranchOperator FINAL : public Operator1<BranchHint> {
+  struct BranchOperator final : public Operator1<BranchHint> {
     BranchOperator()
-        : Operator1<BranchHint>(                       // --
-              IrOpcode::kBranch, Operator::kFoldable,  // opcode
-              "Branch",                                // name
-              1, 0, 1, 0, 0, 2,                        // counts
-              kBranchHint) {}                          // parameter
+        : Operator1<BranchHint>(                      // --
+              IrOpcode::kBranch, Operator::kKontrol,  // opcode
+              "Branch",                               // name
+              1, 0, 1, 0, 0, 2,                       // counts
+              kBranchHint) {}                         // parameter
   };
   BranchOperator<BranchHint::kNone> kBranchNoneOperator;
   BranchOperator<BranchHint::kTrue> kBranchTrueOperator;
   BranchOperator<BranchHint::kFalse> kBranchFalseOperator;
 
+  template <int kEffectInputCount>
+  struct EffectPhiOperator final : public Operator {
+    EffectPhiOperator()
+        : Operator(                                   // --
+              IrOpcode::kEffectPhi, Operator::kPure,  // opcode
+              "EffectPhi",                            // name
+              0, kEffectInputCount, 1, 0, 1, 0) {}    // counts
+  };
+#define CACHED_EFFECT_PHI(input_count) \
+  EffectPhiOperator<input_count> kEffectPhi##input_count##Operator;
+  CACHED_EFFECT_PHI_LIST(CACHED_EFFECT_PHI)
+#undef CACHED_EFFECT_PHI
+
   template <size_t kInputCount>
-  struct LoopOperator FINAL : public Operator {
+  struct LoopOperator final : public Operator {
     LoopOperator()
-        : Operator(                                  // --
-              IrOpcode::kLoop, Operator::kFoldable,  // opcode
-              "Loop",                                // name
-              0, 0, kInputCount, 0, 0, 1) {}         // counts
+        : Operator(                                 // --
+              IrOpcode::kLoop, Operator::kKontrol,  // opcode
+              "Loop",                               // name
+              0, 0, kInputCount, 0, 0, 1) {}        // counts
   };
 #define CACHED_LOOP(input_count) \
   LoopOperator<input_count> kLoop##input_count##Operator;
@@ -178,31 +348,75 @@
 #undef CACHED_LOOP
 
   template <size_t kInputCount>
-  struct MergeOperator FINAL : public Operator {
+  struct MergeOperator final : public Operator {
     MergeOperator()
-        : Operator(                                   // --
-              IrOpcode::kMerge, Operator::kFoldable,  // opcode
-              "Merge",                                // name
-              0, 0, kInputCount, 0, 0, 1) {}          // counts
+        : Operator(                                  // --
+              IrOpcode::kMerge, Operator::kKontrol,  // opcode
+              "Merge",                               // name
+              0, 0, kInputCount, 0, 0, 1) {}         // counts
   };
 #define CACHED_MERGE(input_count) \
   MergeOperator<input_count> kMerge##input_count##Operator;
   CACHED_MERGE_LIST(CACHED_MERGE)
 #undef CACHED_MERGE
 
+  template <MachineRepresentation kRep, int kInputCount>
+  struct PhiOperator final : public Operator1<MachineRepresentation> {
+    PhiOperator()
+        : Operator1<MachineRepresentation>(     //--
+              IrOpcode::kPhi, Operator::kPure,  // opcode
+              "Phi",                            // name
+              kInputCount, 0, 1, 1, 0, 0,       // counts
+              kRep) {}                          // parameter
+  };
+#define CACHED_PHI(rep, input_count)                   \
+  PhiOperator<MachineRepresentation::rep, input_count> \
+      kPhi##rep##input_count##Operator;
+  CACHED_PHI_LIST(CACHED_PHI)
+#undef CACHED_PHI
+
   template <int kIndex>
-  struct ParameterOperator FINAL : public Operator1<int> {
+  struct ParameterOperator final : public Operator1<ParameterInfo> {
     ParameterOperator()
-        : Operator1<int>(                             // --
+        : Operator1<ParameterInfo>(                   // --
               IrOpcode::kParameter, Operator::kPure,  // opcode
               "Parameter",                            // name
               1, 0, 0, 1, 0, 0,                       // counts,
-              kIndex) {}                              // parameter
+              ParameterInfo(kIndex, nullptr)) {}      // parameter and name
   };
 #define CACHED_PARAMETER(index) \
   ParameterOperator<index> kParameter##index##Operator;
   CACHED_PARAMETER_LIST(CACHED_PARAMETER)
 #undef CACHED_PARAMETER
+
+  template <size_t kIndex>
+  struct ProjectionOperator final : public Operator1<size_t> {
+    ProjectionOperator()
+        : Operator1<size_t>(          // --
+              IrOpcode::kProjection,  // opcode
+              Operator::kPure,        // flags
+              "Projection",           // name
+              1, 0, 0, 1, 0, 0,       // counts,
+              kIndex) {}              // parameter
+  };
+#define CACHED_PROJECTION(index) \
+  ProjectionOperator<index> kProjection##index##Operator;
+  CACHED_PROJECTION_LIST(CACHED_PROJECTION)
+#undef CACHED_PROJECTION
+
+  template <int kInputCount>
+  struct StateValuesOperator final : public Operator {
+    StateValuesOperator()
+        : Operator(                           // --
+              IrOpcode::kStateValues,         // opcode
+              Operator::kPure,                // flags
+              "StateValues",                  // name
+              kInputCount, 0, 0, 1, 0, 0) {}  // counts
+  };
+#define CACHED_STATE_VALUES(input_count) \
+  StateValuesOperator<input_count> kStateValues##input_count##Operator;
+  CACHED_STATE_VALUES_LIST(CACHED_STATE_VALUES)
+#undef CACHED_STATE_VALUES
 };
 
 
@@ -214,15 +428,52 @@
     : cache_(kCache.Get()), zone_(zone) {}
 
 
-#define CACHED(Name, properties, value_input_count, effect_input_count, \
-               control_input_count, control_output_count)               \
-  const Operator* CommonOperatorBuilder::Name() {                       \
-    return &cache_.k##Name##Operator;                                   \
+#define CACHED(Name, properties, value_input_count, effect_input_count,      \
+               control_input_count, value_output_count, effect_output_count, \
+               control_output_count)                                         \
+  const Operator* CommonOperatorBuilder::Name() {                            \
+    return &cache_.k##Name##Operator;                                        \
   }
 CACHED_OP_LIST(CACHED)
 #undef CACHED
 
 
+const Operator* CommonOperatorBuilder::End(size_t control_input_count) {
+  switch (control_input_count) {
+#define CACHED_END(input_count) \
+  case input_count:             \
+    return &cache_.kEnd##input_count##Operator;
+    CACHED_END_LIST(CACHED_END)
+#undef CACHED_END
+    default:
+      break;
+  }
+  // Uncached.
+  return new (zone()) Operator(             //--
+      IrOpcode::kEnd, Operator::kKontrol,   // opcode
+      "End",                                // name
+      0, 0, control_input_count, 0, 0, 0);  // counts
+}
+
+
+const Operator* CommonOperatorBuilder::Return(int value_input_count) {
+  switch (value_input_count) {
+#define CACHED_RETURN(input_count) \
+  case input_count:                \
+    return &cache_.kReturn##input_count##Operator;
+    CACHED_RETURN_LIST(CACHED_RETURN)
+#undef CACHED_RETURN
+    default:
+      break;
+  }
+  // Uncached.
+  return new (zone()) Operator(               //--
+      IrOpcode::kReturn, Operator::kNoThrow,  // opcode
+      "Return",                               // name
+      value_input_count, 1, 1, 0, 0, 1);      // counts
+}
+
+
 const Operator* CommonOperatorBuilder::Branch(BranchHint hint) {
   switch (hint) {
     case BranchHint::kNone:
@@ -237,9 +488,48 @@
 }
 
 
-const Operator* CommonOperatorBuilder::Start(int num_formal_parameters) {
-  // Outputs are formal parameters, plus context, receiver, and JSFunction.
-  const int value_output_count = num_formal_parameters + 3;
+const Operator* CommonOperatorBuilder::Deoptimize(DeoptimizeKind kind) {
+  switch (kind) {
+    case DeoptimizeKind::kEager:
+      return &cache_.kDeoptimizeEagerOperator;
+    case DeoptimizeKind::kSoft:
+      return &cache_.kDeoptimizeSoftOperator;
+  }
+  UNREACHABLE();
+  return nullptr;
+}
+
+
+const Operator* CommonOperatorBuilder::IfException(IfExceptionHint hint) {
+  switch (hint) {
+    case IfExceptionHint::kLocallyCaught:
+      return &cache_.kIfExceptionCOperator;
+    case IfExceptionHint::kLocallyUncaught:
+      return &cache_.kIfExceptionUOperator;
+  }
+  UNREACHABLE();
+  return nullptr;
+}
+
+
+const Operator* CommonOperatorBuilder::Switch(size_t control_output_count) {
+  return new (zone()) Operator(               // --
+      IrOpcode::kSwitch, Operator::kKontrol,  // opcode
+      "Switch",                               // name
+      1, 0, 1, 0, 0, control_output_count);   // counts
+}
+
+
+const Operator* CommonOperatorBuilder::IfValue(int32_t index) {
+  return new (zone()) Operator1<int32_t>(      // --
+      IrOpcode::kIfValue, Operator::kKontrol,  // opcode
+      "IfValue",                               // name
+      0, 0, 1, 0, 0, 1,                        // counts
+      index);                                  // parameter
+}
+
+
+const Operator* CommonOperatorBuilder::Start(int value_output_count) {
   return new (zone()) Operator(               // --
       IrOpcode::kStart, Operator::kFoldable,  // opcode
       "Start",                                // name
@@ -258,10 +548,10 @@
       break;
   }
   // Uncached.
-  return new (zone()) Operator(              // --
-      IrOpcode::kLoop, Operator::kFoldable,  // opcode
-      "Loop",                                // name
-      0, 0, control_input_count, 0, 0, 1);   // counts
+  return new (zone()) Operator(             // --
+      IrOpcode::kLoop, Operator::kKontrol,  // opcode
+      "Loop",                               // name
+      0, 0, control_input_count, 0, 0, 1);  // counts
 }
 
 
@@ -276,37 +566,41 @@
       break;
   }
   // Uncached.
-  return new (zone()) Operator(               // --
-      IrOpcode::kMerge, Operator::kFoldable,  // opcode
-      "Merge",                                // name
-      0, 0, control_input_count, 0, 0, 1);    // counts
+  return new (zone()) Operator(              // --
+      IrOpcode::kMerge, Operator::kKontrol,  // opcode
+      "Merge",                               // name
+      0, 0, control_input_count, 0, 0, 1);   // counts
 }
 
 
-const Operator* CommonOperatorBuilder::Terminate(int effects) {
-  return new (zone()) Operator(               // --
-      IrOpcode::kTerminate, Operator::kPure,  // opcode
-      "Terminate",                            // name
-      0, effects, 1, 0, 0, 1);                // counts
-}
-
-
-const Operator* CommonOperatorBuilder::Parameter(int index) {
-  switch (index) {
+const Operator* CommonOperatorBuilder::Parameter(int index,
+                                                 const char* debug_name) {
+  if (!debug_name) {
+    switch (index) {
 #define CACHED_PARAMETER(index) \
   case index:                   \
     return &cache_.kParameter##index##Operator;
-    CACHED_PARAMETER_LIST(CACHED_PARAMETER)
+      CACHED_PARAMETER_LIST(CACHED_PARAMETER)
 #undef CACHED_PARAMETER
-    default:
-      break;
+      default:
+        break;
+    }
   }
   // Uncached.
-  return new (zone()) Operator1<int>(         // --
-      IrOpcode::kParameter, Operator::kPure,  // opcode
-      "Parameter",                            // name
-      1, 0, 0, 1, 0, 0,                       // counts
-      index);                                 // parameter
+  return new (zone()) Operator1<ParameterInfo>(  // --
+      IrOpcode::kParameter, Operator::kPure,     // opcode
+      "Parameter",                               // name
+      1, 0, 0, 1, 0, 0,                          // counts
+      ParameterInfo(index, debug_name));         // parameter info
+}
+
+
+const Operator* CommonOperatorBuilder::OsrValue(int index) {
+  return new (zone()) Operator1<int>(                // --
+      IrOpcode::kOsrValue, Operator::kNoProperties,  // opcode
+      "OsrValue",                                    // name
+      0, 0, 1, 1, 0, 0,                              // counts
+      index);                                        // parameter
 }
 
 
@@ -329,22 +623,20 @@
 
 
 const Operator* CommonOperatorBuilder::Float32Constant(volatile float value) {
-  return new (zone())
-      Operator1<float, base::bit_equal_to<float>, base::bit_hash<float>>(  // --
-          IrOpcode::kFloat32Constant, Operator::kPure,  // opcode
-          "Float32Constant",                            // name
-          0, 0, 0, 1, 0, 0,                             // counts
-          value);                                       // parameter
+  return new (zone()) Operator1<float>(             // --
+      IrOpcode::kFloat32Constant, Operator::kPure,  // opcode
+      "Float32Constant",                            // name
+      0, 0, 0, 1, 0, 0,                             // counts
+      value);                                       // parameter
 }
 
 
 const Operator* CommonOperatorBuilder::Float64Constant(volatile double value) {
-  return new (zone()) Operator1<double, base::bit_equal_to<double>,
-                                base::bit_hash<double>>(  // --
-      IrOpcode::kFloat64Constant, Operator::kPure,        // opcode
-      "Float64Constant",                                  // name
-      0, 0, 0, 1, 0, 0,                                   // counts
-      value);                                             // parameter
+  return new (zone()) Operator1<double>(            // --
+      IrOpcode::kFloat64Constant, Operator::kPure,  // opcode
+      "Float64Constant",                            // name
+      0, 0, 0, 1, 0, 0,                             // counts
+      value);                                       // parameter
 }
 
 
@@ -359,18 +651,17 @@
 
 
 const Operator* CommonOperatorBuilder::NumberConstant(volatile double value) {
-  return new (zone()) Operator1<double, base::bit_equal_to<double>,
-                                base::bit_hash<double>>(  // --
-      IrOpcode::kNumberConstant, Operator::kPure,         // opcode
-      "NumberConstant",                                   // name
-      0, 0, 0, 1, 0, 0,                                   // counts
-      value);                                             // parameter
+  return new (zone()) Operator1<double>(           // --
+      IrOpcode::kNumberConstant, Operator::kPure,  // opcode
+      "NumberConstant",                            // name
+      0, 0, 0, 1, 0, 0,                            // counts
+      value);                                      // parameter
 }
 
 
 const Operator* CommonOperatorBuilder::HeapConstant(
-    const Unique<HeapObject>& value) {
-  return new (zone()) Operator1<Unique<HeapObject>>(  // --
+    const Handle<HeapObject>& value) {
+  return new (zone()) Operator1<Handle<HeapObject>>(  // --
       IrOpcode::kHeapConstant, Operator::kPure,       // opcode
       "HeapConstant",                                 // name
       0, 0, 0, 1, 0, 0,                               // counts
@@ -378,54 +669,83 @@
 }
 
 
-const Operator* CommonOperatorBuilder::Select(MachineType type,
+const Operator* CommonOperatorBuilder::Select(MachineRepresentation rep,
                                               BranchHint hint) {
   return new (zone()) Operator1<SelectParameters>(  // --
       IrOpcode::kSelect, Operator::kPure,           // opcode
       "Select",                                     // name
       3, 0, 0, 1, 0, 0,                             // counts
-      SelectParameters(type, hint));                // parameter
+      SelectParameters(rep, hint));                 // parameter
 }
 
 
-const Operator* CommonOperatorBuilder::Phi(MachineType type, int arguments) {
-  DCHECK(arguments > 0);                       // Disallow empty phis.
-  return new (zone()) Operator1<MachineType>(  // --
-      IrOpcode::kPhi, Operator::kPure,         // opcode
-      "Phi",                                   // name
-      arguments, 0, 1, 1, 0, 0,                // counts
-      type);                                   // parameter
+const Operator* CommonOperatorBuilder::Phi(MachineRepresentation rep,
+                                           int value_input_count) {
+  DCHECK(value_input_count > 0);  // Disallow empty phis.
+#define CACHED_PHI(kRep, kValueInputCount)                 \
+  if (MachineRepresentation::kRep == rep &&                \
+      kValueInputCount == value_input_count) {             \
+    return &cache_.kPhi##kRep##kValueInputCount##Operator; \
+  }
+  CACHED_PHI_LIST(CACHED_PHI)
+#undef CACHED_PHI
+  // Uncached.
+  return new (zone()) Operator1<MachineRepresentation>(  // --
+      IrOpcode::kPhi, Operator::kPure,                   // opcode
+      "Phi",                                             // name
+      value_input_count, 0, 1, 1, 0, 0,                  // counts
+      rep);                                              // parameter
 }
 
 
-const Operator* CommonOperatorBuilder::EffectPhi(int arguments) {
-  DCHECK(arguments > 0);                      // Disallow empty phis.
+const Operator* CommonOperatorBuilder::EffectPhi(int effect_input_count) {
+  DCHECK(effect_input_count > 0);  // Disallow empty effect phis.
+  switch (effect_input_count) {
+#define CACHED_EFFECT_PHI(input_count) \
+  case input_count:                    \
+    return &cache_.kEffectPhi##input_count##Operator;
+    CACHED_EFFECT_PHI_LIST(CACHED_EFFECT_PHI)
+#undef CACHED_EFFECT_PHI
+    default:
+      break;
+  }
+  // Uncached.
   return new (zone()) Operator(               // --
       IrOpcode::kEffectPhi, Operator::kPure,  // opcode
       "EffectPhi",                            // name
-      0, arguments, 1, 0, 1, 0);              // counts
+      0, effect_input_count, 1, 0, 1, 0);     // counts
 }
 
 
-const Operator* CommonOperatorBuilder::ValueEffect(int arguments) {
-  DCHECK(arguments > 0);                        // Disallow empty value effects.
-  return new (zone()) Operator(                 // --
-      IrOpcode::kValueEffect, Operator::kPure,  // opcode
-      "ValueEffect",                            // name
-      arguments, 0, 0, 0, 1, 0);                // counts
+const Operator* CommonOperatorBuilder::Guard(Type* type) {
+  return new (zone()) Operator1<Type*>(      // --
+      IrOpcode::kGuard, Operator::kKontrol,  // opcode
+      "Guard",                               // name
+      1, 0, 1, 1, 0, 0,                      // counts
+      type);                                 // parameter
 }
 
 
-const Operator* CommonOperatorBuilder::Finish(int arguments) {
-  DCHECK(arguments > 0);                   // Disallow empty finishes.
-  return new (zone()) Operator(            // --
-      IrOpcode::kFinish, Operator::kPure,  // opcode
-      "Finish",                            // name
-      1, arguments, 0, 1, 0, 0);           // counts
+const Operator* CommonOperatorBuilder::EffectSet(int arguments) {
+  DCHECK(arguments > 1);                      // Disallow empty/singleton sets.
+  return new (zone()) Operator(               // --
+      IrOpcode::kEffectSet, Operator::kPure,  // opcode
+      "EffectSet",                            // name
+      0, arguments, 0, 0, 1, 0);              // counts
 }
 
 
 const Operator* CommonOperatorBuilder::StateValues(int arguments) {
+  switch (arguments) {
+#define CACHED_STATE_VALUES(arguments) \
+  case arguments:                      \
+    return &cache_.kStateValues##arguments##Operator;
+    CACHED_STATE_VALUES_LIST(CACHED_STATE_VALUES)
+#undef CACHED_STATE_VALUES
+    default:
+      break;
+  }
+  // Uncached.
   return new (zone()) Operator(                 // --
       IrOpcode::kStateValues, Operator::kPure,  // opcode
       "StateValues",                            // name
@@ -433,43 +753,124 @@
 }
 
 
+const Operator* CommonOperatorBuilder::ObjectState(int pointer_slots, int id) {
+  return new (zone()) Operator1<int>(           // --
+      IrOpcode::kObjectState, Operator::kPure,  // opcode
+      "ObjectState",                            // name
+      pointer_slots, 0, 0, 1, 0, 0, id);        // counts
+}
+
+
+const Operator* CommonOperatorBuilder::TypedStateValues(
+    const ZoneVector<MachineType>* types) {
+  return new (zone()) Operator1<const ZoneVector<MachineType>*>(  // --
+      IrOpcode::kTypedStateValues, Operator::kPure,               // opcode
+      "TypedStateValues",                                         // name
+      static_cast<int>(types->size()), 0, 0, 1, 0, 0, types);     // counts
+}
+
+
 const Operator* CommonOperatorBuilder::FrameState(
-    FrameStateType type, BailoutId bailout_id,
-    OutputFrameStateCombine state_combine, MaybeHandle<JSFunction> jsfunction) {
-  return new (zone()) Operator1<FrameStateCallInfo>(  // --
-      IrOpcode::kFrameState, Operator::kPure,         // opcode
-      "FrameState",                                   // name
-      4, 0, 0, 1, 0, 0,                               // counts
-      FrameStateCallInfo(type, bailout_id, state_combine, jsfunction));
+    BailoutId bailout_id, OutputFrameStateCombine state_combine,
+    const FrameStateFunctionInfo* function_info) {
+  FrameStateInfo state_info(bailout_id, state_combine, function_info);
+  return new (zone()) Operator1<FrameStateInfo>(  // --
+      IrOpcode::kFrameState, Operator::kPure,     // opcode
+      "FrameState",                               // name
+      5, 0, 0, 1, 0, 0,                           // counts
+      state_info);                                // parameter
 }
 
 
 const Operator* CommonOperatorBuilder::Call(const CallDescriptor* descriptor) {
-  class CallOperator FINAL : public Operator1<const CallDescriptor*> {
+  class CallOperator final : public Operator1<const CallDescriptor*> {
    public:
-    CallOperator(const CallDescriptor* descriptor, const char* mnemonic)
+    explicit CallOperator(const CallDescriptor* descriptor)
         : Operator1<const CallDescriptor*>(
-              IrOpcode::kCall, descriptor->properties(), mnemonic,
+              IrOpcode::kCall, descriptor->properties(), "Call",
               descriptor->InputCount() + descriptor->FrameStateCount(),
               Operator::ZeroIfPure(descriptor->properties()),
-              Operator::ZeroIfPure(descriptor->properties()),
+              Operator::ZeroIfEliminatable(descriptor->properties()),
               descriptor->ReturnCount(),
-              Operator::ZeroIfPure(descriptor->properties()), 0, descriptor) {}
+              Operator::ZeroIfPure(descriptor->properties()),
+              Operator::ZeroIfNoThrow(descriptor->properties()), descriptor) {}
 
-    void PrintParameter(std::ostream& os) const OVERRIDE {
+    void PrintParameter(std::ostream& os) const override {
       os << "[" << *parameter() << "]";
     }
   };
-  return new (zone()) CallOperator(descriptor, "Call");
+  return new (zone()) CallOperator(descriptor);
+}
+
+
+const Operator* CommonOperatorBuilder::LazyBailout() {
+  return Call(Linkage::GetLazyBailoutDescriptor(zone()));
+}
+
+
+const Operator* CommonOperatorBuilder::TailCall(
+    const CallDescriptor* descriptor) {
+  class TailCallOperator final : public Operator1<const CallDescriptor*> {
+   public:
+    explicit TailCallOperator(const CallDescriptor* descriptor)
+        : Operator1<const CallDescriptor*>(
+              IrOpcode::kTailCall, descriptor->properties(), "TailCall",
+              descriptor->InputCount() + descriptor->FrameStateCount(), 1, 1, 0,
+              0, 1, descriptor) {}
+
+    void PrintParameter(std::ostream& os) const override {
+      os << "[" << *parameter() << "]";
+    }
+  };
+  return new (zone()) TailCallOperator(descriptor);
 }
 
 
 const Operator* CommonOperatorBuilder::Projection(size_t index) {
-  return new (zone()) Operator1<size_t>(       // --
-      IrOpcode::kProjection, Operator::kPure,  // opcode
-      "Projection",                            // name
-      1, 0, 0, 1, 0, 0,                        // counts
-      index);                                  // parameter
+  switch (index) {
+#define CACHED_PROJECTION(index) \
+  case index:                    \
+    return &cache_.kProjection##index##Operator;
+    CACHED_PROJECTION_LIST(CACHED_PROJECTION)
+#undef CACHED_PROJECTION
+    default:
+      break;
+  }
+  // Uncached.
+  return new (zone()) Operator1<size_t>(         // --
+      IrOpcode::kProjection,                     // opcode
+      Operator::kFoldable | Operator::kNoThrow,  // flags
+      "Projection",                              // name
+      1, 0, 0, 1, 0, 0,                          // counts
+      index);                                    // parameter
+}
+
+
+const Operator* CommonOperatorBuilder::ResizeMergeOrPhi(const Operator* op,
+                                                        int size) {
+  if (op->opcode() == IrOpcode::kPhi) {
+    return Phi(PhiRepresentationOf(op), size);
+  } else if (op->opcode() == IrOpcode::kEffectPhi) {
+    return EffectPhi(size);
+  } else if (op->opcode() == IrOpcode::kMerge) {
+    return Merge(size);
+  } else if (op->opcode() == IrOpcode::kLoop) {
+    return Loop(size);
+  } else {
+    UNREACHABLE();
+    return nullptr;
+  }
+}
+
+
+const FrameStateFunctionInfo*
+CommonOperatorBuilder::CreateFrameStateFunctionInfo(
+    FrameStateType type, int parameter_count, int local_count,
+    Handle<SharedFunctionInfo> shared_info,
+    ContextCallingMode context_calling_mode) {
+  return new (zone()->New(sizeof(FrameStateFunctionInfo)))
+      FrameStateFunctionInfo(type, parameter_count, local_count, shared_info,
+                             context_calling_mode);
 }
 
 }  // namespace compiler
diff --git a/src/compiler/common-operator.h b/src/compiler/common-operator.h
index af6066b..83cb5b2 100644
--- a/src/compiler/common-operator.h
+++ b/src/compiler/common-operator.h
@@ -1,18 +1,23 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
+// 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.
 
 #ifndef V8_COMPILER_COMMON_OPERATOR_H_
 #define V8_COMPILER_COMMON_OPERATOR_H_
 
-#include "src/compiler/machine-type.h"
-#include "src/unique.h"
+#include "src/compiler/frame-states.h"
+#include "src/machine-type.h"
+#include "src/zone-containers.h"
 
 namespace v8 {
 namespace internal {
 
 // Forward declarations.
 class ExternalReference;
+template <class>
+class TypeImpl;
+struct ZoneTypeConfig;
+typedef TypeImpl<ZoneTypeConfig> Type;
 
 
 namespace compiler {
@@ -26,6 +31,19 @@
 // Prediction hint for branches.
 enum class BranchHint : uint8_t { kNone, kTrue, kFalse };
 
+inline BranchHint NegateBranchHint(BranchHint hint) {
+  switch (hint) {
+    case BranchHint::kNone:
+      return hint;
+    case BranchHint::kTrue:
+      return BranchHint::kFalse;
+    case BranchHint::kFalse:
+      return BranchHint::kTrue;
+  }
+  UNREACHABLE();
+  return hint;
+}
+
 inline size_t hash_value(BranchHint hint) { return static_cast<size_t>(hint); }
 
 std::ostream& operator<<(std::ostream&, BranchHint);
@@ -33,17 +51,35 @@
 BranchHint BranchHintOf(const Operator* const);
 
 
-class SelectParameters FINAL {
- public:
-  explicit SelectParameters(MachineType type,
-                            BranchHint hint = BranchHint::kNone)
-      : type_(type), hint_(hint) {}
+// Deoptimize bailout kind.
+enum class DeoptimizeKind : uint8_t { kEager, kSoft };
 
-  MachineType type() const { return type_; }
+size_t hash_value(DeoptimizeKind kind);
+
+std::ostream& operator<<(std::ostream&, DeoptimizeKind);
+
+DeoptimizeKind DeoptimizeKindOf(const Operator* const);
+
+
+// Prediction whether throw-site is surrounded by any local catch-scope.
+enum class IfExceptionHint { kLocallyUncaught, kLocallyCaught };
+
+size_t hash_value(IfExceptionHint hint);
+
+std::ostream& operator<<(std::ostream&, IfExceptionHint);
+
+
+class SelectParameters final {
+ public:
+  explicit SelectParameters(MachineRepresentation representation,
+                            BranchHint hint = BranchHint::kNone)
+      : representation_(representation), hint_(hint) {}
+
+  MachineRepresentation representation() const { return representation_; }
   BranchHint hint() const { return hint_; }
 
  private:
-  const MachineType type_;
+  const MachineRepresentation representation_;
   const BranchHint hint_;
 };
 
@@ -57,121 +93,61 @@
 SelectParameters const& SelectParametersOf(const Operator* const);
 
 
-// Flag that describes how to combine the current environment with
-// the output of a node to obtain a framestate for lazy bailout.
-class OutputFrameStateCombine {
+size_t ProjectionIndexOf(const Operator* const);
+
+MachineRepresentation PhiRepresentationOf(const Operator* const);
+
+
+// The {IrOpcode::kParameter} opcode represents an incoming parameter to the
+// function. This class bundles the index and a debug name for such operators.
+class ParameterInfo final {
  public:
-  enum Kind {
-    kPushOutput,  // Push the output on the expression stack.
-    kPokeAt       // Poke at the given environment location,
-                  // counting from the top of the stack.
-  };
+  ParameterInfo(int index, const char* debug_name)
+      : index_(index), debug_name_(debug_name) {}
 
-  static OutputFrameStateCombine Ignore() {
-    return OutputFrameStateCombine(kPushOutput, 0);
-  }
-  static OutputFrameStateCombine Push(size_t count = 1) {
-    return OutputFrameStateCombine(kPushOutput, count);
-  }
-  static OutputFrameStateCombine PokeAt(size_t index) {
-    return OutputFrameStateCombine(kPokeAt, index);
-  }
-
-  Kind kind() const { return kind_; }
-  size_t GetPushCount() const {
-    DCHECK_EQ(kPushOutput, kind());
-    return parameter_;
-  }
-  size_t GetOffsetToPokeAt() const {
-    DCHECK_EQ(kPokeAt, kind());
-    return parameter_;
-  }
-
-  bool IsOutputIgnored() const {
-    return kind_ == kPushOutput && parameter_ == 0;
-  }
-
-  size_t ConsumedOutputCount() const {
-    return kind_ == kPushOutput ? GetPushCount() : 1;
-  }
-
-  bool operator==(OutputFrameStateCombine const& other) const {
-    return kind_ == other.kind_ && parameter_ == other.parameter_;
-  }
-  bool operator!=(OutputFrameStateCombine const& other) const {
-    return !(*this == other);
-  }
-
-  friend size_t hash_value(OutputFrameStateCombine const&);
-  friend std::ostream& operator<<(std::ostream&,
-                                  OutputFrameStateCombine const&);
+  int index() const { return index_; }
+  const char* debug_name() const { return debug_name_; }
 
  private:
-  OutputFrameStateCombine(Kind kind, size_t parameter)
-      : kind_(kind), parameter_(parameter) {}
-
-  Kind const kind_;
-  size_t const parameter_;
+  int index_;
+  const char* debug_name_;
 };
 
+std::ostream& operator<<(std::ostream&, ParameterInfo const&);
 
-// The type of stack frame that a FrameState node represents.
-enum FrameStateType {
-  JS_FRAME,          // Represents an unoptimized JavaScriptFrame.
-  ARGUMENTS_ADAPTOR  // Represents an ArgumentsAdaptorFrame.
-};
-
-
-class FrameStateCallInfo FINAL {
- public:
-  FrameStateCallInfo(
-      FrameStateType type, BailoutId bailout_id,
-      OutputFrameStateCombine state_combine,
-      MaybeHandle<JSFunction> jsfunction = MaybeHandle<JSFunction>())
-      : type_(type),
-        bailout_id_(bailout_id),
-        frame_state_combine_(state_combine),
-        jsfunction_(jsfunction) {}
-
-  FrameStateType type() const { return type_; }
-  BailoutId bailout_id() const { return bailout_id_; }
-  OutputFrameStateCombine state_combine() const { return frame_state_combine_; }
-  MaybeHandle<JSFunction> jsfunction() const { return jsfunction_; }
-
- private:
-  FrameStateType type_;
-  BailoutId bailout_id_;
-  OutputFrameStateCombine frame_state_combine_;
-  MaybeHandle<JSFunction> jsfunction_;
-};
-
-bool operator==(FrameStateCallInfo const&, FrameStateCallInfo const&);
-bool operator!=(FrameStateCallInfo const&, FrameStateCallInfo const&);
-
-size_t hash_value(FrameStateCallInfo const&);
-
-std::ostream& operator<<(std::ostream&, FrameStateCallInfo const&);
+int ParameterIndexOf(const Operator* const);
+const ParameterInfo& ParameterInfoOf(const Operator* const);
 
 
 // Interface for building common operators that can be used at any level of IR,
 // including JavaScript, mid-level, and low-level.
-class CommonOperatorBuilder FINAL : public ZoneObject {
+class CommonOperatorBuilder final : public ZoneObject {
  public:
   explicit CommonOperatorBuilder(Zone* zone);
 
   const Operator* Dead();
-  const Operator* End();
+  const Operator* End(size_t control_input_count);
   const Operator* Branch(BranchHint = BranchHint::kNone);
   const Operator* IfTrue();
   const Operator* IfFalse();
+  const Operator* IfSuccess();
+  const Operator* IfException(IfExceptionHint hint);
+  const Operator* Switch(size_t control_output_count);
+  const Operator* IfValue(int32_t value);
+  const Operator* IfDefault();
   const Operator* Throw();
-  const Operator* Terminate(int effects);
-  const Operator* Return();
+  const Operator* Deoptimize(DeoptimizeKind kind);
+  const Operator* Return(int value_input_count = 1);
+  const Operator* Terminate();
 
-  const Operator* Start(int num_formal_parameters);
+  const Operator* Start(int value_output_count);
   const Operator* Loop(int control_input_count);
   const Operator* Merge(int control_input_count);
-  const Operator* Parameter(int index);
+  const Operator* Parameter(int index, const char* debug_name = nullptr);
+
+  const Operator* OsrNormalEntry();
+  const Operator* OsrLoopEntry();
+  const Operator* OsrValue(int index);
 
   const Operator* Int32Constant(int32_t);
   const Operator* Int64Constant(int64_t);
@@ -179,20 +155,36 @@
   const Operator* Float64Constant(volatile double);
   const Operator* ExternalConstant(const ExternalReference&);
   const Operator* NumberConstant(volatile double);
-  const Operator* HeapConstant(const Unique<HeapObject>&);
+  const Operator* HeapConstant(const Handle<HeapObject>&);
 
-  const Operator* Select(MachineType, BranchHint = BranchHint::kNone);
-  const Operator* Phi(MachineType type, int arguments);
-  const Operator* EffectPhi(int arguments);
-  const Operator* ValueEffect(int arguments);
-  const Operator* Finish(int arguments);
+  const Operator* Select(MachineRepresentation, BranchHint = BranchHint::kNone);
+  const Operator* Phi(MachineRepresentation representation,
+                      int value_input_count);
+  const Operator* EffectPhi(int effect_input_count);
+  const Operator* EffectSet(int arguments);
+  const Operator* Guard(Type* type);
+  const Operator* BeginRegion();
+  const Operator* FinishRegion();
   const Operator* StateValues(int arguments);
-  const Operator* FrameState(
-      FrameStateType type, BailoutId bailout_id,
-      OutputFrameStateCombine state_combine,
-      MaybeHandle<JSFunction> jsfunction = MaybeHandle<JSFunction>());
+  const Operator* ObjectState(int pointer_slots, int id);
+  const Operator* TypedStateValues(const ZoneVector<MachineType>* types);
+  const Operator* FrameState(BailoutId bailout_id,
+                             OutputFrameStateCombine state_combine,
+                             const FrameStateFunctionInfo* function_info);
   const Operator* Call(const CallDescriptor* descriptor);
+  const Operator* TailCall(const CallDescriptor* descriptor);
   const Operator* Projection(size_t index);
+  const Operator* LazyBailout();
+
+  // Constructs a new merge or phi operator with the same opcode as {op}, but
+  // with {size} inputs.
+  const Operator* ResizeMergeOrPhi(const Operator* op, int size);
+
+  // Constructs function info for frame state construction.
+  const FrameStateFunctionInfo* CreateFrameStateFunctionInfo(
+      FrameStateType type, int parameter_count, int local_count,
+      Handle<SharedFunctionInfo> shared_info,
+      ContextCallingMode context_calling_mode);
 
  private:
   Zone* zone() const { return zone_; }
diff --git a/src/compiler/control-builders.cc b/src/compiler/control-builders.cc
index 8725244..6905ef5 100644
--- a/src/compiler/control-builders.cc
+++ b/src/compiler/control-builders.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "control-builders.h"
+#include "src/compiler/control-builders.h"
 
 namespace v8 {
 namespace internal {
@@ -32,9 +32,8 @@
 }
 
 
-void LoopBuilder::BeginLoop(BitVector* assigned) {
-  builder_->NewLoop();
-  loop_environment_ = environment()->CopyForLoop(assigned);
+void LoopBuilder::BeginLoop(BitVector* assigned, bool is_osr) {
+  loop_environment_ = environment()->CopyForLoop(assigned, is_osr);
   continue_environment_ = environment()->CopyAsUnreachable();
   break_environment_ = environment()->CopyAsUnreachable();
 }
@@ -74,6 +73,16 @@
 }
 
 
+void LoopBuilder::BreakWhen(Node* condition) {
+  IfBuilder control_if(builder_);
+  control_if.If(condition);
+  control_if.Then();
+  Break();
+  control_if.Else();
+  control_if.End();
+}
+
+
 void SwitchBuilder::BeginSwitch() {
   body_environment_ = environment()->CopyAsUnreachable();
   label_environment_ = environment()->CopyAsUnreachable();
@@ -134,10 +143,90 @@
 }
 
 
+void BlockBuilder::BreakWhen(Node* condition, BranchHint hint) {
+  IfBuilder control_if(builder_);
+  control_if.If(condition, hint);
+  control_if.Then();
+  Break();
+  control_if.Else();
+  control_if.End();
+}
+
+
+void BlockBuilder::BreakUnless(Node* condition, BranchHint hint) {
+  IfBuilder control_if(builder_);
+  control_if.If(condition, hint);
+  control_if.Then();
+  control_if.Else();
+  Break();
+  control_if.End();
+}
+
+
 void BlockBuilder::EndBlock() {
   break_environment_->Merge(environment());
   set_environment(break_environment_);
 }
+
+
+void TryCatchBuilder::BeginTry() {
+  exit_environment_ = environment()->CopyAsUnreachable();
+  catch_environment_ = environment()->CopyAsUnreachable();
+  catch_environment_->Push(the_hole());
 }
+
+
+void TryCatchBuilder::Throw(Node* exception) {
+  environment()->Push(exception);
+  catch_environment_->Merge(environment());
+  environment()->Pop();
+  environment()->MarkAsUnreachable();
 }
-}  // namespace v8::internal::compiler
+
+
+void TryCatchBuilder::EndTry() {
+  exit_environment_->Merge(environment());
+  exception_node_ = catch_environment_->Pop();
+  set_environment(catch_environment_);
+}
+
+
+void TryCatchBuilder::EndCatch() {
+  exit_environment_->Merge(environment());
+  set_environment(exit_environment_);
+}
+
+
+void TryFinallyBuilder::BeginTry() {
+  finally_environment_ = environment()->CopyAsUnreachable();
+  finally_environment_->Push(the_hole());
+  finally_environment_->Push(the_hole());
+}
+
+
+void TryFinallyBuilder::LeaveTry(Node* token, Node* value) {
+  environment()->Push(value);
+  environment()->Push(token);
+  finally_environment_->Merge(environment());
+  environment()->Drop(2);
+}
+
+
+void TryFinallyBuilder::EndTry(Node* fallthrough_token, Node* value) {
+  environment()->Push(value);
+  environment()->Push(fallthrough_token);
+  finally_environment_->Merge(environment());
+  environment()->Drop(2);
+  token_node_ = finally_environment_->Pop();
+  value_node_ = finally_environment_->Pop();
+  set_environment(finally_environment_);
+}
+
+
+void TryFinallyBuilder::EndFinally() {
+  // Nothing to be done here.
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/control-builders.h b/src/compiler/control-builders.h
index 11adfdb..6ff00be 100644
--- a/src/compiler/control-builders.h
+++ b/src/compiler/control-builders.h
@@ -5,9 +5,7 @@
 #ifndef V8_COMPILER_CONTROL_BUILDERS_H_
 #define V8_COMPILER_CONTROL_BUILDERS_H_
 
-#include "src/v8.h"
-
-#include "src/compiler/graph-builder.h"
+#include "src/compiler/ast-graph-builder.h"
 #include "src/compiler/node.h"
 
 namespace v8 {
@@ -15,37 +13,36 @@
 namespace compiler {
 
 // Base class for all control builders. Also provides a common interface for
-// control builders to handle 'break' and 'continue' statements when they are
-// used to model breakable statements.
+// control builders to handle 'break' statements when they are used to model
+// breakable statements.
 class ControlBuilder {
  public:
-  explicit ControlBuilder(StructuredGraphBuilder* builder)
-      : builder_(builder) {}
+  explicit ControlBuilder(AstGraphBuilder* builder) : builder_(builder) {}
   virtual ~ControlBuilder() {}
 
-  // Interface for break and continue.
+  // Interface for break.
   virtual void Break() { UNREACHABLE(); }
-  virtual void Continue() { UNREACHABLE(); }
 
  protected:
-  typedef StructuredGraphBuilder Builder;
-  typedef StructuredGraphBuilder::Environment Environment;
+  typedef AstGraphBuilder Builder;
+  typedef AstGraphBuilder::Environment Environment;
 
   Zone* zone() const { return builder_->local_zone(); }
   Environment* environment() { return builder_->environment(); }
   void set_environment(Environment* env) { builder_->set_environment(env); }
+  Node* the_hole() const { return builder_->jsgraph()->TheHoleConstant(); }
 
   Builder* builder_;
 };
 
 
 // Tracks control flow for a conditional statement.
-class IfBuilder FINAL : public ControlBuilder {
+class IfBuilder final : public ControlBuilder {
  public:
-  explicit IfBuilder(StructuredGraphBuilder* builder)
+  explicit IfBuilder(AstGraphBuilder* builder)
       : ControlBuilder(builder),
-        then_environment_(NULL),
-        else_environment_(NULL) {}
+        then_environment_(nullptr),
+        else_environment_(nullptr) {}
 
   // Primitive control commands.
   void If(Node* condition, BranchHint hint = BranchHint::kNone);
@@ -60,25 +57,26 @@
 
 
 // Tracks control flow for an iteration statement.
-class LoopBuilder FINAL : public ControlBuilder {
+class LoopBuilder final : public ControlBuilder {
  public:
-  explicit LoopBuilder(StructuredGraphBuilder* builder)
+  explicit LoopBuilder(AstGraphBuilder* builder)
       : ControlBuilder(builder),
-        loop_environment_(NULL),
-        continue_environment_(NULL),
-        break_environment_(NULL) {}
+        loop_environment_(nullptr),
+        continue_environment_(nullptr),
+        break_environment_(nullptr) {}
 
   // Primitive control commands.
-  void BeginLoop(BitVector* assigned);
+  void BeginLoop(BitVector* assigned, bool is_osr = false);
+  void Continue();
   void EndBody();
   void EndLoop();
 
-  // Primitive support for break and continue.
-  void Continue() FINAL;
-  void Break() FINAL;
+  // Primitive support for break.
+  void Break() final;
 
-  // Compound control command for conditional break.
+  // Compound control commands for conditional break.
   void BreakUnless(Node* condition);
+  void BreakWhen(Node* condition);
 
  private:
   Environment* loop_environment_;      // Environment of the loop header.
@@ -88,13 +86,13 @@
 
 
 // Tracks control flow for a switch statement.
-class SwitchBuilder FINAL : public ControlBuilder {
+class SwitchBuilder final : public ControlBuilder {
  public:
-  explicit SwitchBuilder(StructuredGraphBuilder* builder, int case_count)
+  explicit SwitchBuilder(AstGraphBuilder* builder, int case_count)
       : ControlBuilder(builder),
-        body_environment_(NULL),
-        label_environment_(NULL),
-        break_environment_(NULL),
+        body_environment_(nullptr),
+        label_environment_(nullptr),
+        break_environment_(nullptr),
         body_environments_(case_count, zone()) {}
 
   // Primitive control commands.
@@ -107,7 +105,7 @@
   void EndSwitch();
 
   // Primitive support for break.
-  void Break() FINAL;
+  void Break() final;
 
   // The number of cases within a switch is statically known.
   size_t case_count() const { return body_environments_.size(); }
@@ -121,22 +119,79 @@
 
 
 // Tracks control flow for a block statement.
-class BlockBuilder FINAL : public ControlBuilder {
+class BlockBuilder final : public ControlBuilder {
  public:
-  explicit BlockBuilder(StructuredGraphBuilder* builder)
-      : ControlBuilder(builder), break_environment_(NULL) {}
+  explicit BlockBuilder(AstGraphBuilder* builder)
+      : ControlBuilder(builder), break_environment_(nullptr) {}
 
   // Primitive control commands.
   void BeginBlock();
   void EndBlock();
 
   // Primitive support for break.
-  void Break() FINAL;
+  void Break() final;
+
+  // Compound control commands for conditional break.
+  void BreakWhen(Node* condition, BranchHint = BranchHint::kNone);
+  void BreakUnless(Node* condition, BranchHint hint = BranchHint::kNone);
 
  private:
   Environment* break_environment_;  // Environment after the block exits.
 };
 
+
+// Tracks control flow for a try-catch statement.
+class TryCatchBuilder final : public ControlBuilder {
+ public:
+  explicit TryCatchBuilder(AstGraphBuilder* builder)
+      : ControlBuilder(builder),
+        catch_environment_(nullptr),
+        exit_environment_(nullptr),
+        exception_node_(nullptr) {}
+
+  // Primitive control commands.
+  void BeginTry();
+  void Throw(Node* exception);
+  void EndTry();
+  void EndCatch();
+
+  // Returns the exception value inside the 'catch' body.
+  Node* GetExceptionNode() const { return exception_node_; }
+
+ private:
+  Environment* catch_environment_;  // Environment for the 'catch' body.
+  Environment* exit_environment_;   // Environment after the statement.
+  Node* exception_node_;            // Node for exception in 'catch' body.
+};
+
+
+// Tracks control flow for a try-finally statement.
+class TryFinallyBuilder final : public ControlBuilder {
+ public:
+  explicit TryFinallyBuilder(AstGraphBuilder* builder)
+      : ControlBuilder(builder),
+        finally_environment_(nullptr),
+        token_node_(nullptr),
+        value_node_(nullptr) {}
+
+  // Primitive control commands.
+  void BeginTry();
+  void LeaveTry(Node* token, Node* value);
+  void EndTry(Node* token, Node* value);
+  void EndFinally();
+
+  // Returns the dispatch token value inside the 'finally' body.
+  Node* GetDispatchTokenNode() const { return token_node_; }
+
+  // Returns the saved result value inside the 'finally' body.
+  Node* GetResultValueNode() const { return value_node_; }
+
+ private:
+  Environment* finally_environment_;  // Environment for the 'finally' body.
+  Node* token_node_;                  // Node for token in 'finally' body.
+  Node* value_node_;                  // Node for value in 'finally' body.
+};
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/src/compiler/control-equivalence.cc b/src/compiler/control-equivalence.cc
new file mode 100644
index 0000000..af1a115
--- /dev/null
+++ b/src/compiler/control-equivalence.cc
@@ -0,0 +1,237 @@
+// Copyright 2015 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/control-equivalence.h"
+#include "src/compiler/node-properties.h"
+
+#define TRACE(...)                                 \
+  do {                                             \
+    if (FLAG_trace_turbo_ceq) PrintF(__VA_ARGS__); \
+  } while (false)
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+void ControlEquivalence::Run(Node* exit) {
+  if (GetClass(exit) == kInvalidClass) {
+    DetermineParticipation(exit);
+    RunUndirectedDFS(exit);
+  }
+}
+
+
+// static
+STATIC_CONST_MEMBER_DEFINITION const size_t ControlEquivalence::kInvalidClass;
+
+
+void ControlEquivalence::VisitPre(Node* node) {
+  TRACE("CEQ: Pre-visit of #%d:%s\n", node->id(), node->op()->mnemonic());
+
+  // Dispense a new pre-order number.
+  SetNumber(node, NewDFSNumber());
+  TRACE("  Assigned DFS number is %zu\n", GetNumber(node));
+}
+
+
+void ControlEquivalence::VisitMid(Node* node, DFSDirection direction) {
+  TRACE("CEQ: Mid-visit of #%d:%s\n", node->id(), node->op()->mnemonic());
+  BracketList& blist = GetBracketList(node);
+
+  // Remove brackets pointing to this node [line:19].
+  BracketListDelete(blist, node, direction);
+
+  // Potentially introduce artificial dependency from start to end.
+  if (blist.empty()) {
+    DCHECK_EQ(kInputDirection, direction);
+    VisitBackedge(node, graph_->end(), kInputDirection);
+  }
+
+  // Potentially start a new equivalence class [line:37].
+  BracketListTRACE(blist);
+  Bracket* recent = &blist.back();
+  if (recent->recent_size != blist.size()) {
+    recent->recent_size = blist.size();
+    recent->recent_class = NewClassNumber();
+  }
+
+  // Assign equivalence class to node.
+  SetClass(node, recent->recent_class);
+  TRACE("  Assigned class number is %zu\n", GetClass(node));
+}
+
+
+void ControlEquivalence::VisitPost(Node* node, Node* parent_node,
+                                   DFSDirection direction) {
+  TRACE("CEQ: Post-visit of #%d:%s\n", node->id(), node->op()->mnemonic());
+  BracketList& blist = GetBracketList(node);
+
+  // Remove brackets pointing to this node [line:19].
+  BracketListDelete(blist, node, direction);
+
+  // Propagate bracket list up the DFS tree [line:13].
+  if (parent_node != nullptr) {
+    BracketList& parent_blist = GetBracketList(parent_node);
+    parent_blist.splice(parent_blist.end(), blist);
+  }
+}
+
+
+void ControlEquivalence::VisitBackedge(Node* from, Node* to,
+                                       DFSDirection direction) {
+  TRACE("CEQ: Backedge from #%d:%s to #%d:%s\n", from->id(),
+        from->op()->mnemonic(), to->id(), to->op()->mnemonic());
+
+  // Push backedge onto the bracket list [line:25].
+  Bracket bracket = {direction, kInvalidClass, 0, from, to};
+  GetBracketList(from).push_back(bracket);
+}
+
+
+void ControlEquivalence::RunUndirectedDFS(Node* exit) {
+  ZoneStack<DFSStackEntry> stack(zone_);
+  DFSPush(stack, exit, nullptr, kInputDirection);
+  VisitPre(exit);
+
+  while (!stack.empty()) {  // Undirected depth-first backwards traversal.
+    DFSStackEntry& entry = stack.top();
+    Node* node = entry.node;
+
+    if (entry.direction == kInputDirection) {
+      if (entry.input != node->input_edges().end()) {
+        Edge edge = *entry.input;
+        Node* input = edge.to();
+        ++(entry.input);
+        if (NodeProperties::IsControlEdge(edge)) {
+          // Visit next control input.
+          if (!GetData(input)->participates) continue;
+          if (GetData(input)->visited) continue;
+          if (GetData(input)->on_stack) {
+            // Found backedge if input is on stack.
+            if (input != entry.parent_node) {
+              VisitBackedge(node, input, kInputDirection);
+            }
+          } else {
+            // Push input onto stack.
+            DFSPush(stack, input, node, kInputDirection);
+            VisitPre(input);
+          }
+        }
+        continue;
+      }
+      if (entry.use != node->use_edges().end()) {
+        // Switch direction to uses.
+        entry.direction = kUseDirection;
+        VisitMid(node, kInputDirection);
+        continue;
+      }
+    }
+
+    if (entry.direction == kUseDirection) {
+      if (entry.use != node->use_edges().end()) {
+        Edge edge = *entry.use;
+        Node* use = edge.from();
+        ++(entry.use);
+        if (NodeProperties::IsControlEdge(edge)) {
+          // Visit next control use.
+          if (!GetData(use)->participates) continue;
+          if (GetData(use)->visited) continue;
+          if (GetData(use)->on_stack) {
+            // Found backedge if use is on stack.
+            if (use != entry.parent_node) {
+              VisitBackedge(node, use, kUseDirection);
+            }
+          } else {
+            // Push use onto stack.
+            DFSPush(stack, use, node, kUseDirection);
+            VisitPre(use);
+          }
+        }
+        continue;
+      }
+      if (entry.input != node->input_edges().end()) {
+        // Switch direction to inputs.
+        entry.direction = kInputDirection;
+        VisitMid(node, kUseDirection);
+        continue;
+      }
+    }
+
+    // Pop node from stack when done with all inputs and uses.
+    DCHECK(entry.input == node->input_edges().end());
+    DCHECK(entry.use == node->use_edges().end());
+    DFSPop(stack, node);
+    VisitPost(node, entry.parent_node, entry.direction);
+  }
+}
+
+void ControlEquivalence::DetermineParticipationEnqueue(ZoneQueue<Node*>& queue,
+                                                       Node* node) {
+  if (!GetData(node)->participates) {
+    GetData(node)->participates = true;
+    queue.push(node);
+  }
+}
+
+
+void ControlEquivalence::DetermineParticipation(Node* exit) {
+  ZoneQueue<Node*> queue(zone_);
+  DetermineParticipationEnqueue(queue, exit);
+  while (!queue.empty()) {  // Breadth-first backwards traversal.
+    Node* node = queue.front();
+    queue.pop();
+    int max = NodeProperties::PastControlIndex(node);
+    for (int i = NodeProperties::FirstControlIndex(node); i < max; i++) {
+      DetermineParticipationEnqueue(queue, node->InputAt(i));
+    }
+  }
+}
+
+
+void ControlEquivalence::DFSPush(DFSStack& stack, Node* node, Node* from,
+                                 DFSDirection dir) {
+  DCHECK(GetData(node)->participates);
+  DCHECK(!GetData(node)->visited);
+  GetData(node)->on_stack = true;
+  Node::InputEdges::iterator input = node->input_edges().begin();
+  Node::UseEdges::iterator use = node->use_edges().begin();
+  stack.push({dir, input, use, from, node});
+}
+
+
+void ControlEquivalence::DFSPop(DFSStack& stack, Node* node) {
+  DCHECK_EQ(stack.top().node, node);
+  GetData(node)->on_stack = false;
+  GetData(node)->visited = true;
+  stack.pop();
+}
+
+
+void ControlEquivalence::BracketListDelete(BracketList& blist, Node* to,
+                                           DFSDirection direction) {
+  // TODO(mstarzinger): Optimize this to avoid linear search.
+  for (BracketList::iterator i = blist.begin(); i != blist.end(); /*nop*/) {
+    if (i->to == to && i->direction != direction) {
+      TRACE("  BList erased: {%d->%d}\n", i->from->id(), i->to->id());
+      i = blist.erase(i);
+    } else {
+      ++i;
+    }
+  }
+}
+
+
+void ControlEquivalence::BracketListTRACE(BracketList& blist) {
+  if (FLAG_trace_turbo_ceq) {
+    TRACE("  BList: ");
+    for (Bracket bracket : blist) {
+      TRACE("{%d->%d} ", bracket.from->id(), bracket.to->id());
+    }
+    TRACE("\n");
+  }
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/control-equivalence.h b/src/compiler/control-equivalence.h
index cca087f..478e48b 100644
--- a/src/compiler/control-equivalence.h
+++ b/src/compiler/control-equivalence.h
@@ -5,11 +5,8 @@
 #ifndef V8_COMPILER_CONTROL_EQUIVALENCE_H_
 #define V8_COMPILER_CONTROL_EQUIVALENCE_H_
 
-#include "src/v8.h"
-
 #include "src/compiler/graph.h"
 #include "src/compiler/node.h"
-#include "src/compiler/node-properties.h"
 #include "src/zone-containers.h"
 
 namespace v8 {
@@ -31,7 +28,7 @@
 // control regions in linear time" by Johnson, Pearson & Pingali (PLDI94) which
 // also contains proofs for the aforementioned equivalence. References to line
 // numbers in the algorithm from figure 4 have been added [line:x].
-class ControlEquivalence : public ZoneObject {
+class ControlEquivalence final : public ZoneObject {
  public:
   ControlEquivalence(Zone* zone, Graph* graph)
       : zone_(zone),
@@ -46,15 +43,11 @@
   //     participate in the next step. Takes O(E) time and O(N) space.
   //  2) An undirected depth-first backwards traversal that determines class
   //     numbers for all participating nodes. Takes O(E) time and O(N) space.
-  void Run(Node* exit) {
-    if (GetClass(exit) != kInvalidClass) return;
-    DetermineParticipation(exit);
-    RunUndirectedDFS(exit);
-  }
+  void Run(Node* exit);
 
   // Retrieves a previously computed class number.
   size_t ClassOf(Node* node) {
-    DCHECK(GetClass(node) != kInvalidClass);
+    DCHECK_NE(kInvalidClass, GetClass(node));
     return GetClass(node);
   }
 
@@ -97,65 +90,16 @@
   typedef ZoneVector<NodeData> Data;
 
   // Called at pre-visit during DFS walk.
-  void VisitPre(Node* node) {
-    Trace("CEQ: Pre-visit of #%d:%s\n", node->id(), node->op()->mnemonic());
-
-    // Dispense a new pre-order number.
-    SetNumber(node, NewDFSNumber());
-    Trace("  Assigned DFS number is %d\n", GetNumber(node));
-  }
+  void VisitPre(Node* node);
 
   // Called at mid-visit during DFS walk.
-  void VisitMid(Node* node, DFSDirection direction) {
-    Trace("CEQ: Mid-visit of #%d:%s\n", node->id(), node->op()->mnemonic());
-    BracketList& blist = GetBracketList(node);
-
-    // Remove brackets pointing to this node [line:19].
-    BracketListDelete(blist, node, direction);
-
-    // Potentially introduce artificial dependency from start to end.
-    if (blist.empty()) {
-      DCHECK_EQ(kInputDirection, direction);
-      VisitBackedge(node, graph_->end(), kInputDirection);
-    }
-
-    // Potentially start a new equivalence class [line:37].
-    BracketListTrace(blist);
-    Bracket* recent = &blist.back();
-    if (recent->recent_size != blist.size()) {
-      recent->recent_size = blist.size();
-      recent->recent_class = NewClassNumber();
-    }
-
-    // Assign equivalence class to node.
-    SetClass(node, recent->recent_class);
-    Trace("  Assigned class number is %d\n", GetClass(node));
-  }
+  void VisitMid(Node* node, DFSDirection direction);
 
   // Called at post-visit during DFS walk.
-  void VisitPost(Node* node, Node* parent_node, DFSDirection direction) {
-    Trace("CEQ: Post-visit of #%d:%s\n", node->id(), node->op()->mnemonic());
-    BracketList& blist = GetBracketList(node);
-
-    // Remove brackets pointing to this node [line:19].
-    BracketListDelete(blist, node, direction);
-
-    // Propagate bracket list up the DFS tree [line:13].
-    if (parent_node != NULL) {
-      BracketList& parent_blist = GetBracketList(parent_node);
-      parent_blist.splice(parent_blist.end(), blist);
-    }
-  }
+  void VisitPost(Node* node, Node* parent_node, DFSDirection direction);
 
   // Called when hitting a back edge in the DFS walk.
-  void VisitBackedge(Node* from, Node* to, DFSDirection direction) {
-    Trace("CEQ: Backedge from #%d:%s to #%d:%s\n", from->id(),
-          from->op()->mnemonic(), to->id(), to->op()->mnemonic());
-
-    // Push backedge onto the bracket list [line:25].
-    Bracket bracket = {direction, kInvalidClass, 0, from, to};
-    GetBracketList(from).push_back(bracket);
-  }
+  void VisitBackedge(Node* from, Node* to, DFSDirection direction);
 
   // Performs and undirected DFS walk of the graph. Conceptually all nodes are
   // expanded, splitting "input" and "use" out into separate nodes. During the
@@ -171,104 +115,10 @@
   //
   // This will yield a true spanning tree (without cross or forward edges) and
   // also discover proper back edges in both directions.
-  void RunUndirectedDFS(Node* exit) {
-    ZoneStack<DFSStackEntry> stack(zone_);
-    DFSPush(stack, exit, NULL, kInputDirection);
-    VisitPre(exit);
+  void RunUndirectedDFS(Node* exit);
 
-    while (!stack.empty()) {  // Undirected depth-first backwards traversal.
-      DFSStackEntry& entry = stack.top();
-      Node* node = entry.node;
-
-      if (entry.direction == kInputDirection) {
-        if (entry.input != node->input_edges().end()) {
-          Edge edge = *entry.input;
-          Node* input = edge.to();
-          ++(entry.input);
-          if (NodeProperties::IsControlEdge(edge) &&
-              NodeProperties::IsControl(input)) {
-            // Visit next control input.
-            if (!GetData(input)->participates) continue;
-            if (GetData(input)->visited) continue;
-            if (GetData(input)->on_stack) {
-              // Found backedge if input is on stack.
-              if (input != entry.parent_node) {
-                VisitBackedge(node, input, kInputDirection);
-              }
-            } else {
-              // Push input onto stack.
-              DFSPush(stack, input, node, kInputDirection);
-              VisitPre(input);
-            }
-          }
-          continue;
-        }
-        if (entry.use != node->use_edges().end()) {
-          // Switch direction to uses.
-          entry.direction = kUseDirection;
-          VisitMid(node, kInputDirection);
-          continue;
-        }
-      }
-
-      if (entry.direction == kUseDirection) {
-        if (entry.use != node->use_edges().end()) {
-          Edge edge = *entry.use;
-          Node* use = edge.from();
-          ++(entry.use);
-          if (NodeProperties::IsControlEdge(edge) &&
-              NodeProperties::IsControl(use)) {
-            // Visit next control use.
-            if (!GetData(use)->participates) continue;
-            if (GetData(use)->visited) continue;
-            if (GetData(use)->on_stack) {
-              // Found backedge if use is on stack.
-              if (use != entry.parent_node) {
-                VisitBackedge(node, use, kUseDirection);
-              }
-            } else {
-              // Push use onto stack.
-              DFSPush(stack, use, node, kUseDirection);
-              VisitPre(use);
-            }
-          }
-          continue;
-        }
-        if (entry.input != node->input_edges().end()) {
-          // Switch direction to inputs.
-          entry.direction = kInputDirection;
-          VisitMid(node, kUseDirection);
-          continue;
-        }
-      }
-
-      // Pop node from stack when done with all inputs and uses.
-      DCHECK(entry.input == node->input_edges().end());
-      DCHECK(entry.use == node->use_edges().end());
-      DFSPop(stack, node);
-      VisitPost(node, entry.parent_node, entry.direction);
-    }
-  }
-
-  void DetermineParticipationEnqueue(ZoneQueue<Node*>& queue, Node* node) {
-    if (!GetData(node)->participates) {
-      GetData(node)->participates = true;
-      queue.push(node);
-    }
-  }
-
-  void DetermineParticipation(Node* exit) {
-    ZoneQueue<Node*> queue(zone_);
-    DetermineParticipationEnqueue(queue, exit);
-    while (!queue.empty()) {  // Breadth-first backwards traversal.
-      Node* node = queue.front();
-      queue.pop();
-      int max = NodeProperties::PastControlIndex(node);
-      for (int i = NodeProperties::FirstControlIndex(node); i < max; i++) {
-        DetermineParticipationEnqueue(queue, node->InputAt(i));
-      }
-    }
-  }
+  void DetermineParticipationEnqueue(ZoneQueue<Node*>& queue, Node* node);
+  void DetermineParticipation(Node* exit);
 
  private:
   NodeData* GetData(Node* node) { return &node_data_[node->id()]; }
@@ -299,56 +149,16 @@
   }
 
   // Mutates the DFS stack by pushing an entry.
-  void DFSPush(DFSStack& stack, Node* node, Node* from, DFSDirection dir) {
-    DCHECK(GetData(node)->participates);
-    DCHECK(!GetData(node)->visited);
-    GetData(node)->on_stack = true;
-    Node::InputEdges::iterator input = node->input_edges().begin();
-    Node::UseEdges::iterator use = node->use_edges().begin();
-    stack.push({dir, input, use, from, node});
-  }
+  void DFSPush(DFSStack& stack, Node* node, Node* from, DFSDirection dir);
 
   // Mutates the DFS stack by popping an entry.
-  void DFSPop(DFSStack& stack, Node* node) {
-    DCHECK_EQ(stack.top().node, node);
-    GetData(node)->on_stack = false;
-    GetData(node)->visited = true;
-    stack.pop();
-  }
+  void DFSPop(DFSStack& stack, Node* node);
 
-  // TODO(mstarzinger): Optimize this to avoid linear search.
-  void BracketListDelete(BracketList& blist, Node* to, DFSDirection direction) {
-    for (BracketList::iterator i = blist.begin(); i != blist.end(); /*nop*/) {
-      if (i->to == to && i->direction != direction) {
-        Trace("  BList erased: {%d->%d}\n", i->from->id(), i->to->id());
-        i = blist.erase(i);
-      } else {
-        ++i;
-      }
-    }
-  }
+  void BracketListDelete(BracketList& blist, Node* to, DFSDirection direction);
+  void BracketListTRACE(BracketList& blist);
 
-  void BracketListTrace(BracketList& blist) {
-    if (FLAG_trace_turbo_scheduler) {
-      Trace("  BList: ");
-      for (Bracket bracket : blist) {
-        Trace("{%d->%d} ", bracket.from->id(), bracket.to->id());
-      }
-      Trace("\n");
-    }
-  }
-
-  void Trace(const char* msg, ...) {
-    if (FLAG_trace_turbo_scheduler) {
-      va_list arguments;
-      va_start(arguments, msg);
-      base::OS::VPrint(msg, arguments);
-      va_end(arguments);
-    }
-  }
-
-  Zone* zone_;
-  Graph* graph_;
+  Zone* const zone_;
+  Graph* const graph_;
   int dfs_number_;    // Generates new DFS pre-order numbers on demand.
   int class_number_;  // Generates new equivalence class numbers on demand.
   Data node_data_;    // Per-node data stored as a side-table.
diff --git a/src/compiler/control-flow-optimizer.cc b/src/compiler/control-flow-optimizer.cc
new file mode 100644
index 0000000..3fc3bce
--- /dev/null
+++ b/src/compiler/control-flow-optimizer.cc
@@ -0,0 +1,278 @@
+// Copyright 2015 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/control-flow-optimizer.h"
+
+#include "src/compiler/common-operator.h"
+#include "src/compiler/graph.h"
+#include "src/compiler/node-matchers.h"
+#include "src/compiler/node-properties.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+ControlFlowOptimizer::ControlFlowOptimizer(Graph* graph,
+                                           CommonOperatorBuilder* common,
+                                           MachineOperatorBuilder* machine,
+                                           Zone* zone)
+    : graph_(graph),
+      common_(common),
+      machine_(machine),
+      queue_(zone),
+      queued_(graph, 2),
+      zone_(zone) {}
+
+
+void ControlFlowOptimizer::Optimize() {
+  Enqueue(graph()->start());
+  while (!queue_.empty()) {
+    Node* node = queue_.front();
+    queue_.pop();
+    if (node->IsDead()) continue;
+    switch (node->opcode()) {
+      case IrOpcode::kBranch:
+        VisitBranch(node);
+        break;
+      default:
+        VisitNode(node);
+        break;
+    }
+  }
+}
+
+
+void ControlFlowOptimizer::Enqueue(Node* node) {
+  DCHECK_NOT_NULL(node);
+  if (node->IsDead() || queued_.Get(node)) return;
+  queued_.Set(node, true);
+  queue_.push(node);
+}
+
+
+void ControlFlowOptimizer::VisitNode(Node* node) {
+  for (Edge edge : node->use_edges()) {
+    if (NodeProperties::IsControlEdge(edge)) {
+      Enqueue(edge.from());
+    }
+  }
+}
+
+
+void ControlFlowOptimizer::VisitBranch(Node* node) {
+  DCHECK_EQ(IrOpcode::kBranch, node->opcode());
+  if (TryBuildSwitch(node)) return;
+  if (TryCloneBranch(node)) return;
+  VisitNode(node);
+}
+
+
+bool ControlFlowOptimizer::TryCloneBranch(Node* node) {
+  DCHECK_EQ(IrOpcode::kBranch, node->opcode());
+
+  // This optimization is a special case of (super)block cloning. It takes an
+  // input graph as shown below and clones the Branch node for every predecessor
+  // to the Merge, essentially removing the Merge completely. This avoids
+  // materializing the bit for the Phi and may offer potential for further
+  // branch folding optimizations (i.e. because one or more inputs to the Phi is
+  // a constant). Note that there may be more Phi nodes hanging off the Merge,
+  // but we can only a certain subset of them currently (actually only Phi and
+  // EffectPhi nodes whose uses have either the IfTrue or IfFalse as control
+  // input).
+
+  //   Control1 ... ControlN
+  //      ^            ^
+  //      |            |   Cond1 ... CondN
+  //      +----+  +----+     ^         ^
+  //           |  |          |         |
+  //           |  |     +----+         |
+  //          Merge<--+ | +------------+
+  //            ^      \|/
+  //            |      Phi
+  //            |       |
+  //          Branch----+
+  //            ^
+  //            |
+  //      +-----+-----+
+  //      |           |
+  //    IfTrue     IfFalse
+  //      ^           ^
+  //      |           |
+
+  // The resulting graph (modulo the Phi and EffectPhi nodes) looks like this:
+
+  // Control1 Cond1 ... ControlN CondN
+  //    ^      ^           ^      ^
+  //    \      /           \      /
+  //     Branch     ...     Branch
+  //       ^                  ^
+  //       |                  |
+  //   +---+---+          +---+----+
+  //   |       |          |        |
+  // IfTrue IfFalse ... IfTrue  IfFalse
+  //   ^       ^          ^        ^
+  //   |       |          |        |
+  //   +--+ +-------------+        |
+  //      | |  +--------------+ +--+
+  //      | |                 | |
+  //     Merge               Merge
+  //       ^                   ^
+  //       |                   |
+
+  Node* branch = node;
+  Node* cond = NodeProperties::GetValueInput(branch, 0);
+  if (!cond->OwnedBy(branch) || cond->opcode() != IrOpcode::kPhi) return false;
+  Node* merge = NodeProperties::GetControlInput(branch);
+  if (merge->opcode() != IrOpcode::kMerge ||
+      NodeProperties::GetControlInput(cond) != merge) {
+    return false;
+  }
+  // Grab the IfTrue/IfFalse projections of the Branch.
+  BranchMatcher matcher(branch);
+  // Check/collect other Phi/EffectPhi nodes hanging off the Merge.
+  NodeVector phis(zone());
+  for (Node* const use : merge->uses()) {
+    if (use == branch || use == cond) continue;
+    // We cannot currently deal with non-Phi/EffectPhi nodes hanging off the
+    // Merge. Ideally, we would just clone the nodes (and everything that
+    // depends on it to some distant join point), but that requires knowledge
+    // about dominance/post-dominance.
+    if (!NodeProperties::IsPhi(use)) return false;
+    for (Edge edge : use->use_edges()) {
+      // Right now we can only handle Phi/EffectPhi nodes whose uses are
+      // directly control-dependend on either the IfTrue or the IfFalse
+      // successor, because we know exactly how to update those uses.
+      // TODO(turbofan): Generalize this to all Phi/EffectPhi nodes using
+      // dominance/post-dominance on the sea of nodes.
+      if (edge.from()->op()->ControlInputCount() != 1) return false;
+      Node* control = NodeProperties::GetControlInput(edge.from());
+      if (NodeProperties::IsPhi(edge.from())) {
+        control = NodeProperties::GetControlInput(control, edge.index());
+      }
+      if (control != matcher.IfTrue() && control != matcher.IfFalse())
+        return false;
+    }
+    phis.push_back(use);
+  }
+  BranchHint const hint = BranchHintOf(branch->op());
+  int const input_count = merge->op()->ControlInputCount();
+  DCHECK_LE(1, input_count);
+  Node** const inputs = zone()->NewArray<Node*>(2 * input_count);
+  Node** const merge_true_inputs = &inputs[0];
+  Node** const merge_false_inputs = &inputs[input_count];
+  for (int index = 0; index < input_count; ++index) {
+    Node* cond1 = NodeProperties::GetValueInput(cond, index);
+    Node* control1 = NodeProperties::GetControlInput(merge, index);
+    Node* branch1 = graph()->NewNode(common()->Branch(hint), cond1, control1);
+    merge_true_inputs[index] = graph()->NewNode(common()->IfTrue(), branch1);
+    merge_false_inputs[index] = graph()->NewNode(common()->IfFalse(), branch1);
+    Enqueue(branch1);
+  }
+  Node* const merge_true = graph()->NewNode(common()->Merge(input_count),
+                                            input_count, merge_true_inputs);
+  Node* const merge_false = graph()->NewNode(common()->Merge(input_count),
+                                             input_count, merge_false_inputs);
+  for (Node* const phi : phis) {
+    for (int index = 0; index < input_count; ++index) {
+      inputs[index] = phi->InputAt(index);
+    }
+    inputs[input_count] = merge_true;
+    Node* phi_true = graph()->NewNode(phi->op(), input_count + 1, inputs);
+    inputs[input_count] = merge_false;
+    Node* phi_false = graph()->NewNode(phi->op(), input_count + 1, inputs);
+    for (Edge edge : phi->use_edges()) {
+      Node* control = NodeProperties::GetControlInput(edge.from());
+      if (NodeProperties::IsPhi(edge.from())) {
+        control = NodeProperties::GetControlInput(control, edge.index());
+      }
+      DCHECK(control == matcher.IfTrue() || control == matcher.IfFalse());
+      edge.UpdateTo((control == matcher.IfTrue()) ? phi_true : phi_false);
+    }
+    phi->Kill();
+  }
+  // Fix up IfTrue and IfFalse and kill all dead nodes.
+  matcher.IfFalse()->ReplaceUses(merge_false);
+  matcher.IfTrue()->ReplaceUses(merge_true);
+  matcher.IfFalse()->Kill();
+  matcher.IfTrue()->Kill();
+  branch->Kill();
+  cond->Kill();
+  merge->Kill();
+  return true;
+}
+
+
+bool ControlFlowOptimizer::TryBuildSwitch(Node* node) {
+  DCHECK_EQ(IrOpcode::kBranch, node->opcode());
+
+  Node* branch = node;
+  if (BranchHintOf(branch->op()) != BranchHint::kNone) return false;
+  Node* cond = NodeProperties::GetValueInput(branch, 0);
+  if (cond->opcode() != IrOpcode::kWord32Equal) return false;
+  Int32BinopMatcher m(cond);
+  Node* index = m.left().node();
+  if (!m.right().HasValue()) return false;
+  int32_t value = m.right().Value();
+  ZoneSet<int32_t> values(zone());
+  values.insert(value);
+
+  Node* if_false;
+  Node* if_true;
+  while (true) {
+    BranchMatcher matcher(branch);
+    DCHECK(matcher.Matched());
+
+    if_true = matcher.IfTrue();
+    if_false = matcher.IfFalse();
+
+    auto it = if_false->uses().begin();
+    if (it == if_false->uses().end()) break;
+    Node* branch1 = *it++;
+    if (branch1->opcode() != IrOpcode::kBranch) break;
+    if (BranchHintOf(branch1->op()) != BranchHint::kNone) break;
+    if (it != if_false->uses().end()) break;
+    Node* cond1 = branch1->InputAt(0);
+    if (cond1->opcode() != IrOpcode::kWord32Equal) break;
+    Int32BinopMatcher m1(cond1);
+    if (m1.left().node() != index) break;
+    if (!m1.right().HasValue()) break;
+    int32_t value1 = m1.right().Value();
+    if (values.find(value1) != values.end()) break;
+    DCHECK_NE(value, value1);
+
+    if (branch != node) {
+      branch->NullAllInputs();
+      if_true->ReplaceInput(0, node);
+    }
+    NodeProperties::ChangeOp(if_true, common()->IfValue(value));
+    if_false->NullAllInputs();
+    Enqueue(if_true);
+
+    branch = branch1;
+    value = value1;
+    values.insert(value);
+  }
+
+  DCHECK_EQ(IrOpcode::kBranch, node->opcode());
+  DCHECK_EQ(IrOpcode::kBranch, branch->opcode());
+  if (branch == node) {
+    DCHECK_EQ(1u, values.size());
+    return false;
+  }
+  DCHECK_LT(1u, values.size());
+  node->ReplaceInput(0, index);
+  NodeProperties::ChangeOp(node, common()->Switch(values.size() + 1));
+  if_true->ReplaceInput(0, node);
+  NodeProperties::ChangeOp(if_true, common()->IfValue(value));
+  Enqueue(if_true);
+  if_false->ReplaceInput(0, node);
+  NodeProperties::ChangeOp(if_false, common()->IfDefault());
+  Enqueue(if_false);
+  branch->NullAllInputs();
+  return true;
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/control-flow-optimizer.h b/src/compiler/control-flow-optimizer.h
new file mode 100644
index 0000000..f72fa58
--- /dev/null
+++ b/src/compiler/control-flow-optimizer.h
@@ -0,0 +1,56 @@
+// Copyright 2015 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.
+
+#ifndef V8_COMPILER_CONTROL_FLOW_OPTIMIZER_H_
+#define V8_COMPILER_CONTROL_FLOW_OPTIMIZER_H_
+
+#include "src/compiler/node-marker.h"
+#include "src/zone-containers.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+// Forward declarations.
+class CommonOperatorBuilder;
+class Graph;
+class MachineOperatorBuilder;
+class Node;
+
+
+class ControlFlowOptimizer final {
+ public:
+  ControlFlowOptimizer(Graph* graph, CommonOperatorBuilder* common,
+                       MachineOperatorBuilder* machine, Zone* zone);
+
+  void Optimize();
+
+ private:
+  void Enqueue(Node* node);
+  void VisitNode(Node* node);
+  void VisitBranch(Node* node);
+
+  bool TryBuildSwitch(Node* node);
+  bool TryCloneBranch(Node* node);
+
+  Graph* graph() const { return graph_; }
+  CommonOperatorBuilder* common() const { return common_; }
+  MachineOperatorBuilder* machine() const { return machine_; }
+  Zone* zone() const { return zone_; }
+
+  Graph* const graph_;
+  CommonOperatorBuilder* const common_;
+  MachineOperatorBuilder* const machine_;
+  ZoneQueue<Node*> queue_;
+  NodeMarker<bool> queued_;
+  Zone* const zone_;
+
+  DISALLOW_COPY_AND_ASSIGN(ControlFlowOptimizer);
+};
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_CONTROL_FLOW_OPTIMIZER_H_
diff --git a/src/compiler/control-reducer.cc b/src/compiler/control-reducer.cc
deleted file mode 100644
index eef8a49..0000000
--- a/src/compiler/control-reducer.cc
+++ /dev/null
@@ -1,592 +0,0 @@
-// 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/common-operator.h"
-#include "src/compiler/control-reducer.h"
-#include "src/compiler/graph.h"
-#include "src/compiler/js-graph.h"
-#include "src/compiler/node-matchers.h"
-#include "src/compiler/node-properties-inl.h"
-#include "src/zone-containers.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-enum VisitState { kUnvisited = 0, kOnStack = 1, kRevisit = 2, kVisited = 3 };
-enum Decision { kFalse, kUnknown, kTrue };
-
-class ReachabilityMarker : public NodeMarker<uint8_t> {
- public:
-  explicit ReachabilityMarker(Graph* graph) : NodeMarker<uint8_t>(graph, 8) {}
-  bool SetReachableFromEnd(Node* node) {
-    uint8_t before = Get(node);
-    Set(node, before | kFromEnd);
-    return before & kFromEnd;
-  }
-  bool IsReachableFromEnd(Node* node) { return Get(node) & kFromEnd; }
-  bool SetReachableFromStart(Node* node) {
-    uint8_t before = Get(node);
-    Set(node, before | kFromStart);
-    return before & kFromStart;
-  }
-  bool IsReachableFromStart(Node* node) { return Get(node) & kFromStart; }
-  void Push(Node* node) { Set(node, Get(node) | kFwStack); }
-  void Pop(Node* node) { Set(node, Get(node) & ~kFwStack); }
-  bool IsOnStack(Node* node) { return Get(node) & kFwStack; }
-
- private:
-  enum Bit { kFromEnd = 1, kFromStart = 2, kFwStack = 4 };
-};
-
-
-#define TRACE(x) \
-  if (FLAG_trace_turbo_reduction) PrintF x
-
-class ControlReducerImpl {
- public:
-  ControlReducerImpl(Zone* zone, JSGraph* jsgraph,
-                     CommonOperatorBuilder* common)
-      : zone_(zone),
-        jsgraph_(jsgraph),
-        common_(common),
-        state_(jsgraph->graph()->NodeCount(), kUnvisited, zone_),
-        stack_(zone_),
-        revisit_(zone_),
-        dead_(NULL) {}
-
-  Zone* zone_;
-  JSGraph* jsgraph_;
-  CommonOperatorBuilder* common_;
-  ZoneVector<VisitState> state_;
-  ZoneDeque<Node*> stack_;
-  ZoneDeque<Node*> revisit_;
-  Node* dead_;
-
-  void Reduce() {
-    Push(graph()->end());
-    do {
-      // Process the node on the top of the stack, potentially pushing more
-      // or popping the node off the stack.
-      ReduceTop();
-      // If the stack becomes empty, revisit any nodes in the revisit queue.
-      // If no nodes in the revisit queue, try removing dead loops.
-      // If no dead loops, then finish.
-    } while (!stack_.empty() || TryRevisit() || RepairAndRemoveLoops());
-  }
-
-  bool TryRevisit() {
-    while (!revisit_.empty()) {
-      Node* n = revisit_.back();
-      revisit_.pop_back();
-      if (state_[n->id()] == kRevisit) {  // state can change while in queue.
-        Push(n);
-        return true;
-      }
-    }
-    return false;
-  }
-
-  // Repair the graph after the possible creation of non-terminating or dead
-  // loops. Removing dead loops can produce more opportunities for reduction.
-  bool RepairAndRemoveLoops() {
-    // TODO(turbofan): we can skip this if the graph has no loops, but
-    // we have to be careful about proper loop detection during reduction.
-
-    // Gather all nodes backwards-reachable from end (through inputs).
-    ReachabilityMarker marked(graph());
-    NodeVector nodes(zone_);
-    AddNodesReachableFromEnd(marked, nodes);
-
-    // Walk forward through control nodes, looking for back edges to nodes
-    // that are not connected to end. Those are non-terminating loops (NTLs).
-    Node* start = graph()->start();
-    marked.Push(start);
-    marked.SetReachableFromStart(start);
-
-    // We use a stack of (Node, UseIter) pairs to avoid O(n^2) traversal.
-    typedef std::pair<Node*, UseIter> FwIter;
-    ZoneVector<FwIter> fw_stack(zone_);
-    fw_stack.push_back(FwIter(start, start->uses().begin()));
-
-    while (!fw_stack.empty()) {
-      Node* node = fw_stack.back().first;
-      TRACE(("ControlFw: #%d:%s\n", node->id(), node->op()->mnemonic()));
-      bool pop = true;
-      while (fw_stack.back().second != node->uses().end()) {
-        Node* succ = *(fw_stack.back().second);
-        if (marked.IsOnStack(succ) && !marked.IsReachableFromEnd(succ)) {
-          // {succ} is on stack and not reachable from end.
-          Node* added = ConnectNTL(succ);
-          nodes.push_back(added);
-          marked.SetReachableFromEnd(added);
-          AddBackwardsReachableNodes(marked, nodes, nodes.size() - 1);
-
-          // Reset the use iterators for the entire stack.
-          for (size_t i = 0; i < fw_stack.size(); i++) {
-            FwIter& iter = fw_stack[i];
-            fw_stack[i] = FwIter(iter.first, iter.first->uses().begin());
-          }
-          pop = false;  // restart traversing successors of this node.
-          break;
-        }
-        if (IrOpcode::IsControlOpcode(succ->opcode()) &&
-            !marked.IsReachableFromStart(succ)) {
-          // {succ} is a control node and not yet reached from start.
-          marked.Push(succ);
-          marked.SetReachableFromStart(succ);
-          fw_stack.push_back(FwIter(succ, succ->uses().begin()));
-          pop = false;  // "recurse" into successor control node.
-          break;
-        }
-        ++fw_stack.back().second;
-      }
-      if (pop) {
-        marked.Pop(node);
-        fw_stack.pop_back();
-      }
-    }
-
-    // Trim references from dead nodes to live nodes first.
-    jsgraph_->GetCachedNodes(&nodes);
-    TrimNodes(marked, nodes);
-
-    // Any control nodes not reachable from start are dead, even loops.
-    for (size_t i = 0; i < nodes.size(); i++) {
-      Node* node = nodes[i];
-      if (IrOpcode::IsControlOpcode(node->opcode()) &&
-          !marked.IsReachableFromStart(node)) {
-        ReplaceNode(node, dead());  // uses will be added to revisit queue.
-      }
-    }
-    return TryRevisit();  // try to push a node onto the stack.
-  }
-
-  // Connect {loop}, the header of a non-terminating loop, to the end node.
-  Node* ConnectNTL(Node* loop) {
-    TRACE(("ConnectNTL: #%d:%s\n", loop->id(), loop->op()->mnemonic()));
-
-    if (loop->opcode() != IrOpcode::kTerminate) {
-      // Insert a {Terminate} node if the loop has effects.
-      ZoneDeque<Node*> effects(zone_);
-      for (Node* const use : loop->uses()) {
-        if (use->opcode() == IrOpcode::kEffectPhi) effects.push_back(use);
-      }
-      int count = static_cast<int>(effects.size());
-      if (count > 0) {
-        Node** inputs = zone_->NewArray<Node*>(1 + count);
-        for (int i = 0; i < count; i++) inputs[i] = effects[i];
-        inputs[count] = loop;
-        loop = graph()->NewNode(common_->Terminate(count), 1 + count, inputs);
-        TRACE(("AddTerminate: #%d:%s[%d]\n", loop->id(), loop->op()->mnemonic(),
-               count));
-      }
-    }
-
-    Node* to_add = loop;
-    Node* end = graph()->end();
-    CHECK_EQ(IrOpcode::kEnd, end->opcode());
-    Node* merge = end->InputAt(0);
-    if (merge == NULL || merge->opcode() == IrOpcode::kDead) {
-      // The end node died; just connect end to {loop}.
-      end->ReplaceInput(0, loop);
-    } else if (merge->opcode() != IrOpcode::kMerge) {
-      // Introduce a final merge node for {end->InputAt(0)} and {loop}.
-      merge = graph()->NewNode(common_->Merge(2), merge, loop);
-      end->ReplaceInput(0, merge);
-      to_add = merge;
-      // Mark the node as visited so that we can revisit later.
-      EnsureStateSize(merge->id());
-      state_[merge->id()] = kVisited;
-    } else {
-      // Append a new input to the final merge at the end.
-      merge->AppendInput(graph()->zone(), loop);
-      merge->set_op(common_->Merge(merge->InputCount()));
-    }
-    return to_add;
-  }
-
-  void AddNodesReachableFromEnd(ReachabilityMarker& marked, NodeVector& nodes) {
-    Node* end = graph()->end();
-    marked.SetReachableFromEnd(end);
-    if (!end->IsDead()) {
-      nodes.push_back(end);
-      AddBackwardsReachableNodes(marked, nodes, nodes.size() - 1);
-    }
-  }
-
-  void AddBackwardsReachableNodes(ReachabilityMarker& marked, NodeVector& nodes,
-                                  size_t cursor) {
-    while (cursor < nodes.size()) {
-      Node* node = nodes[cursor++];
-      for (Node* const input : node->inputs()) {
-        if (!marked.SetReachableFromEnd(input)) {
-          nodes.push_back(input);
-        }
-      }
-    }
-  }
-
-  void Trim() {
-    // Gather all nodes backwards-reachable from end through inputs.
-    ReachabilityMarker marked(graph());
-    NodeVector nodes(zone_);
-    AddNodesReachableFromEnd(marked, nodes);
-
-    // Process cached nodes in the JSGraph too.
-    jsgraph_->GetCachedNodes(&nodes);
-    TrimNodes(marked, nodes);
-  }
-
-  void TrimNodes(ReachabilityMarker& marked, NodeVector& nodes) {
-    // Remove dead->live edges.
-    for (size_t j = 0; j < nodes.size(); j++) {
-      Node* node = nodes[j];
-      for (Edge edge : node->use_edges()) {
-        Node* use = edge.from();
-        if (!marked.IsReachableFromEnd(use)) {
-          TRACE(("DeadLink: #%d:%s(%d) -> #%d:%s\n", use->id(),
-                 use->op()->mnemonic(), edge.index(), node->id(),
-                 node->op()->mnemonic()));
-          edge.UpdateTo(NULL);
-        }
-      }
-    }
-#if DEBUG
-    // Verify that no inputs to live nodes are NULL.
-    for (size_t j = 0; j < nodes.size(); j++) {
-      Node* node = nodes[j];
-      for (Node* const input : node->inputs()) {
-        CHECK_NE(NULL, input);
-      }
-      for (Node* const use : node->uses()) {
-        CHECK(marked.IsReachableFromEnd(use));
-      }
-    }
-#endif
-  }
-
-  // Reduce the node on the top of the stack.
-  // If an input {i} is not yet visited or needs to be revisited, push {i} onto
-  // the stack and return. Otherwise, all inputs are visited, so apply
-  // reductions for {node} and pop it off the stack.
-  void ReduceTop() {
-    size_t height = stack_.size();
-    Node* node = stack_.back();
-
-    if (node->IsDead()) return Pop();  // Node was killed while on stack.
-
-    TRACE(("ControlReduce: #%d:%s\n", node->id(), node->op()->mnemonic()));
-
-    // Recurse on an input if necessary.
-    for (Node* const input : node->inputs()) {
-      if (Recurse(input)) return;
-    }
-
-    // All inputs should be visited or on stack. Apply reductions to node.
-    Node* replacement = ReduceNode(node);
-    if (replacement != node) ReplaceNode(node, replacement);
-
-    // After reducing the node, pop it off the stack.
-    CHECK_EQ(static_cast<int>(height), static_cast<int>(stack_.size()));
-    Pop();
-
-    // If there was a replacement, reduce it after popping {node}.
-    if (replacement != node) Recurse(replacement);
-  }
-
-  void EnsureStateSize(size_t id) {
-    if (id >= state_.size()) {
-      state_.resize((3 * id) / 2, kUnvisited);
-    }
-  }
-
-  // Push a node onto the stack if its state is {kUnvisited} or {kRevisit}.
-  bool Recurse(Node* node) {
-    size_t id = static_cast<size_t>(node->id());
-    EnsureStateSize(id);
-    if (state_[id] != kRevisit && state_[id] != kUnvisited) return false;
-    Push(node);
-    return true;
-  }
-
-  void Push(Node* node) {
-    state_[node->id()] = kOnStack;
-    stack_.push_back(node);
-  }
-
-  void Pop() {
-    int pos = static_cast<int>(stack_.size()) - 1;
-    DCHECK_GE(pos, 0);
-    DCHECK_EQ(kOnStack, state_[stack_[pos]->id()]);
-    state_[stack_[pos]->id()] = kVisited;
-    stack_.pop_back();
-  }
-
-  // Queue a node to be revisited if it has been visited once already.
-  void Revisit(Node* node) {
-    size_t id = static_cast<size_t>(node->id());
-    if (id < state_.size() && state_[id] == kVisited) {
-      TRACE(("  Revisit #%d:%s\n", node->id(), node->op()->mnemonic()));
-      state_[id] = kRevisit;
-      revisit_.push_back(node);
-    }
-  }
-
-  Node* dead() {
-    if (dead_ == NULL) dead_ = graph()->NewNode(common_->Dead());
-    return dead_;
-  }
-
-  //===========================================================================
-  // Reducer implementation: perform reductions on a node.
-  //===========================================================================
-  Node* ReduceNode(Node* node) {
-    if (node->op()->ControlInputCount() == 1) {
-      // If a node has only one control input and it is dead, replace with dead.
-      Node* control = NodeProperties::GetControlInput(node);
-      if (control->opcode() == IrOpcode::kDead) {
-        TRACE(("ControlDead: #%d:%s\n", node->id(), node->op()->mnemonic()));
-        return control;
-      }
-    }
-
-    // Reduce branches, phis, and merges.
-    switch (node->opcode()) {
-      case IrOpcode::kBranch:
-        return ReduceBranch(node);
-      case IrOpcode::kLoop:
-      case IrOpcode::kMerge:
-        return ReduceMerge(node);
-      case IrOpcode::kSelect:
-        return ReduceSelect(node);
-      case IrOpcode::kPhi:
-      case IrOpcode::kEffectPhi:
-        return ReducePhi(node);
-      default:
-        return node;
-    }
-  }
-
-  // Try to statically fold a condition.
-  Decision DecideCondition(Node* cond) {
-    switch (cond->opcode()) {
-      case IrOpcode::kInt32Constant:
-        return Int32Matcher(cond).Is(0) ? kFalse : kTrue;
-      case IrOpcode::kInt64Constant:
-        return Int64Matcher(cond).Is(0) ? kFalse : kTrue;
-      case IrOpcode::kNumberConstant:
-        return NumberMatcher(cond).Is(0) ? kFalse : kTrue;
-      case IrOpcode::kHeapConstant: {
-        Handle<Object> object =
-            HeapObjectMatcher<Object>(cond).Value().handle();
-        if (object->IsTrue()) return kTrue;
-        if (object->IsFalse()) return kFalse;
-        // TODO(turbofan): decide more conditions for heap constants.
-        break;
-      }
-      default:
-        break;
-    }
-    return kUnknown;
-  }
-
-  // Reduce redundant selects.
-  Node* ReduceSelect(Node* const node) {
-    Node* const tvalue = node->InputAt(1);
-    Node* const fvalue = node->InputAt(2);
-    if (tvalue == fvalue) return tvalue;
-    Decision result = DecideCondition(node->InputAt(0));
-    if (result == kTrue) return tvalue;
-    if (result == kFalse) return fvalue;
-    return node;
-  }
-
-  // Reduce redundant phis.
-  Node* ReducePhi(Node* node) {
-    int n = node->InputCount();
-    if (n <= 1) return dead();            // No non-control inputs.
-    if (n == 2) return node->InputAt(0);  // Only one non-control input.
-
-    // Never remove an effect phi from a (potentially non-terminating) loop.
-    // Otherwise, we might end up eliminating effect nodes, such as calls,
-    // before the loop.
-    if (node->opcode() == IrOpcode::kEffectPhi &&
-        NodeProperties::GetControlInput(node)->opcode() == IrOpcode::kLoop) {
-      return node;
-    }
-
-    Node* replacement = NULL;
-    Node::Inputs inputs = node->inputs();
-    for (InputIter it = inputs.begin(); n > 1; --n, ++it) {
-      Node* input = *it;
-      if (input->opcode() == IrOpcode::kDead) continue;  // ignore dead inputs.
-      if (input != node && input != replacement) {       // non-redundant input.
-        if (replacement != NULL) return node;
-        replacement = input;
-      }
-    }
-    return replacement == NULL ? dead() : replacement;
-  }
-
-  // Reduce merges by trimming away dead inputs from the merge and phis.
-  Node* ReduceMerge(Node* node) {
-    // Count the number of live inputs.
-    int live = 0;
-    int index = 0;
-    int live_index = 0;
-    for (Node* const input : node->inputs()) {
-      if (input->opcode() != IrOpcode::kDead) {
-        live++;
-        live_index = index;
-      }
-      index++;
-    }
-
-    if (live > 1 && live == node->InputCount()) return node;  // nothing to do.
-
-    TRACE(("ReduceMerge: #%d:%s (%d live)\n", node->id(),
-           node->op()->mnemonic(), live));
-
-    if (live == 0) return dead();  // no remaining inputs.
-
-    // Gather phis and effect phis to be edited.
-    ZoneVector<Node*> phis(zone_);
-    for (Node* const use : node->uses()) {
-      if (use->opcode() == IrOpcode::kPhi ||
-          use->opcode() == IrOpcode::kEffectPhi) {
-        phis.push_back(use);
-      }
-    }
-
-    if (live == 1) {
-      // All phis are redundant. Replace them with their live input.
-      for (Node* const phi : phis) ReplaceNode(phi, phi->InputAt(live_index));
-      // The merge itself is redundant.
-      return node->InputAt(live_index);
-    }
-
-    // Edit phis in place, removing dead inputs and revisiting them.
-    for (Node* const phi : phis) {
-      TRACE(("  PhiInMerge: #%d:%s (%d live)\n", phi->id(),
-             phi->op()->mnemonic(), live));
-      RemoveDeadInputs(node, phi);
-      Revisit(phi);
-    }
-    // Edit the merge in place, removing dead inputs.
-    RemoveDeadInputs(node, node);
-    return node;
-  }
-
-  // Reduce branches if they have constant inputs.
-  Node* ReduceBranch(Node* node) {
-    Decision result = DecideCondition(node->InputAt(0));
-    if (result == kUnknown) return node;
-
-    TRACE(("BranchReduce: #%d:%s = %s\n", node->id(), node->op()->mnemonic(),
-           (result == kTrue) ? "true" : "false"));
-
-    // Replace IfTrue and IfFalse projections from this branch.
-    Node* control = NodeProperties::GetControlInput(node);
-    for (Edge edge : node->use_edges()) {
-      Node* use = edge.from();
-      if (use->opcode() == IrOpcode::kIfTrue) {
-        TRACE(("  IfTrue: #%d:%s\n", use->id(), use->op()->mnemonic()));
-        edge.UpdateTo(NULL);
-        ReplaceNode(use, (result == kTrue) ? control : dead());
-      } else if (use->opcode() == IrOpcode::kIfFalse) {
-        TRACE(("  IfFalse: #%d:%s\n", use->id(), use->op()->mnemonic()));
-        edge.UpdateTo(NULL);
-        ReplaceNode(use, (result == kTrue) ? dead() : control);
-      }
-    }
-    return control;
-  }
-
-  // Remove inputs to {node} corresponding to the dead inputs to {merge}
-  // and compact the remaining inputs, updating the operator.
-  void RemoveDeadInputs(Node* merge, Node* node) {
-    int pos = 0;
-    for (int i = 0; i < node->InputCount(); i++) {
-      // skip dead inputs.
-      if (i < merge->InputCount() &&
-          merge->InputAt(i)->opcode() == IrOpcode::kDead)
-        continue;
-      // compact live inputs.
-      if (pos != i) node->ReplaceInput(pos, node->InputAt(i));
-      pos++;
-    }
-    node->TrimInputCount(pos);
-    if (node->opcode() == IrOpcode::kPhi) {
-      node->set_op(common_->Phi(OpParameter<MachineType>(node->op()), pos - 1));
-    } else if (node->opcode() == IrOpcode::kEffectPhi) {
-      node->set_op(common_->EffectPhi(pos - 1));
-    } else if (node->opcode() == IrOpcode::kMerge) {
-      node->set_op(common_->Merge(pos));
-    } else if (node->opcode() == IrOpcode::kLoop) {
-      node->set_op(common_->Loop(pos));
-    } else {
-      UNREACHABLE();
-    }
-  }
-
-  // Replace uses of {node} with {replacement} and revisit the uses.
-  void ReplaceNode(Node* node, Node* replacement) {
-    if (node == replacement) return;
-    TRACE(("  Replace: #%d:%s with #%d:%s\n", node->id(),
-           node->op()->mnemonic(), replacement->id(),
-           replacement->op()->mnemonic()));
-    for (Node* const use : node->uses()) {
-      // Don't revisit this node if it refers to itself.
-      if (use != node) Revisit(use);
-    }
-    node->ReplaceUses(replacement);
-    node->Kill();
-  }
-
-  Graph* graph() { return jsgraph_->graph(); }
-};
-
-
-void ControlReducer::ReduceGraph(Zone* zone, JSGraph* jsgraph,
-                                 CommonOperatorBuilder* common) {
-  ControlReducerImpl impl(zone, jsgraph, common);
-  impl.Reduce();
-}
-
-
-void ControlReducer::TrimGraph(Zone* zone, JSGraph* jsgraph) {
-  ControlReducerImpl impl(zone, jsgraph, NULL);
-  impl.Trim();
-}
-
-
-Node* ControlReducer::ReducePhiForTesting(JSGraph* jsgraph,
-                                          CommonOperatorBuilder* common,
-                                          Node* node) {
-  Zone zone(jsgraph->graph()->zone()->isolate());
-  ControlReducerImpl impl(&zone, jsgraph, common);
-  return impl.ReducePhi(node);
-}
-
-
-Node* ControlReducer::ReduceMergeForTesting(JSGraph* jsgraph,
-                                            CommonOperatorBuilder* common,
-                                            Node* node) {
-  Zone zone(jsgraph->graph()->zone()->isolate());
-  ControlReducerImpl impl(&zone, jsgraph, common);
-  return impl.ReduceMerge(node);
-}
-
-
-Node* ControlReducer::ReduceBranchForTesting(JSGraph* jsgraph,
-                                             CommonOperatorBuilder* common,
-                                             Node* node) {
-  Zone zone(jsgraph->graph()->zone()->isolate());
-  ControlReducerImpl impl(&zone, jsgraph, common);
-  return impl.ReduceBranch(node);
-}
-}
-}
-}  // namespace v8::internal::compiler
diff --git a/src/compiler/control-reducer.h b/src/compiler/control-reducer.h
deleted file mode 100644
index e25bb88..0000000
--- a/src/compiler/control-reducer.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// 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.
-
-#ifndef V8_COMPILER_CONTROL_REDUCER_H_
-#define V8_COMPILER_CONTROL_REDUCER_H_
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-class JSGraph;
-class CommonOperatorBuilder;
-class Node;
-
-class ControlReducer {
- public:
-  // Perform branch folding and dead code elimination on the graph.
-  static void ReduceGraph(Zone* zone, JSGraph* graph,
-                          CommonOperatorBuilder* builder);
-
-  // Trim nodes in the graph that are not reachable from end.
-  static void TrimGraph(Zone* zone, JSGraph* graph);
-
-  // Testing interface.
-  static Node* ReducePhiForTesting(JSGraph* graph,
-                                   CommonOperatorBuilder* builder, Node* node);
-  static Node* ReduceBranchForTesting(JSGraph* graph,
-                                      CommonOperatorBuilder* builder,
-                                      Node* node);
-  static Node* ReduceMergeForTesting(JSGraph* graph,
-                                     CommonOperatorBuilder* builder,
-                                     Node* node);
-};
-}
-}
-}  // namespace v8::internal::compiler
-
-#endif  // V8_COMPILER_CONTROL_REDUCER_H_
diff --git a/src/compiler/dead-code-elimination.cc b/src/compiler/dead-code-elimination.cc
new file mode 100644
index 0000000..697d7f8
--- /dev/null
+++ b/src/compiler/dead-code-elimination.cc
@@ -0,0 +1,145 @@
+// Copyright 2015 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/dead-code-elimination.h"
+
+#include "src/compiler/common-operator.h"
+#include "src/compiler/graph.h"
+#include "src/compiler/node-properties.h"
+#include "src/compiler/operator-properties.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+DeadCodeElimination::DeadCodeElimination(Editor* editor, Graph* graph,
+                                         CommonOperatorBuilder* common)
+    : AdvancedReducer(editor),
+      graph_(graph),
+      common_(common),
+      dead_(graph->NewNode(common->Dead())) {}
+
+
+Reduction DeadCodeElimination::Reduce(Node* node) {
+  switch (node->opcode()) {
+    case IrOpcode::kEnd:
+      return ReduceEnd(node);
+    case IrOpcode::kLoop:
+    case IrOpcode::kMerge:
+      return ReduceLoopOrMerge(node);
+    default:
+      return ReduceNode(node);
+  }
+  UNREACHABLE();
+  return NoChange();
+}
+
+
+Reduction DeadCodeElimination::ReduceEnd(Node* node) {
+  DCHECK_EQ(IrOpcode::kEnd, node->opcode());
+  int const input_count = node->InputCount();
+  DCHECK_LE(1, input_count);
+  int live_input_count = 0;
+  for (int i = 0; i < input_count; ++i) {
+    Node* const input = node->InputAt(i);
+    // Skip dead inputs.
+    if (input->opcode() == IrOpcode::kDead) continue;
+    // Compact live inputs.
+    if (i != live_input_count) node->ReplaceInput(live_input_count, input);
+    ++live_input_count;
+  }
+  if (live_input_count == 0) {
+    return Replace(dead());
+  } else if (live_input_count < input_count) {
+    node->TrimInputCount(live_input_count);
+    NodeProperties::ChangeOp(node, common()->End(live_input_count));
+    return Changed(node);
+  }
+  DCHECK_EQ(input_count, live_input_count);
+  return NoChange();
+}
+
+
+Reduction DeadCodeElimination::ReduceLoopOrMerge(Node* node) {
+  DCHECK(IrOpcode::IsMergeOpcode(node->opcode()));
+  int const input_count = node->InputCount();
+  DCHECK_LE(1, input_count);
+  // Count the number of live inputs to {node} and compact them on the fly, also
+  // compacting the inputs of the associated {Phi} and {EffectPhi} uses at the
+  // same time.  We consider {Loop}s dead even if only the first control input
+  // is dead.
+  int live_input_count = 0;
+  if (node->opcode() != IrOpcode::kLoop ||
+      node->InputAt(0)->opcode() != IrOpcode::kDead) {
+    for (int i = 0; i < input_count; ++i) {
+      Node* const input = node->InputAt(i);
+      // Skip dead inputs.
+      if (input->opcode() == IrOpcode::kDead) continue;
+      // Compact live inputs.
+      if (live_input_count != i) {
+        node->ReplaceInput(live_input_count, input);
+        for (Node* const use : node->uses()) {
+          if (NodeProperties::IsPhi(use)) {
+            DCHECK_EQ(input_count + 1, use->InputCount());
+            use->ReplaceInput(live_input_count, use->InputAt(i));
+          }
+        }
+      }
+      ++live_input_count;
+    }
+  }
+  if (live_input_count == 0) {
+    return Replace(dead());
+  } else if (live_input_count == 1) {
+    // Due to compaction above, the live input is at offset 0.
+    for (Node* const use : node->uses()) {
+      if (NodeProperties::IsPhi(use)) {
+        Replace(use, use->InputAt(0));
+      } else if (use->opcode() == IrOpcode::kTerminate) {
+        DCHECK_EQ(IrOpcode::kLoop, node->opcode());
+        Replace(use, dead());
+      }
+    }
+    return Replace(node->InputAt(0));
+  }
+  DCHECK_LE(2, live_input_count);
+  DCHECK_LE(live_input_count, input_count);
+  // Trim input count for the {Merge} or {Loop} node.
+  if (live_input_count < input_count) {
+    // Trim input counts for all phi uses and revisit them.
+    for (Node* const use : node->uses()) {
+      if (NodeProperties::IsPhi(use)) {
+        use->ReplaceInput(live_input_count, node);
+        TrimMergeOrPhi(use, live_input_count);
+        Revisit(use);
+      }
+    }
+    TrimMergeOrPhi(node, live_input_count);
+    return Changed(node);
+  }
+  return NoChange();
+}
+
+
+Reduction DeadCodeElimination::ReduceNode(Node* node) {
+  // If {node} has exactly one control input and this is {Dead},
+  // replace {node} with {Dead}.
+  int const control_input_count = node->op()->ControlInputCount();
+  if (control_input_count == 0) return NoChange();
+  DCHECK_EQ(1, control_input_count);
+  Node* control = NodeProperties::GetControlInput(node);
+  if (control->opcode() == IrOpcode::kDead) return Replace(control);
+  return NoChange();
+}
+
+
+void DeadCodeElimination::TrimMergeOrPhi(Node* node, int size) {
+  const Operator* const op = common()->ResizeMergeOrPhi(node->op(), size);
+  node->TrimInputCount(OperatorProperties::GetTotalInputCount(op));
+  NodeProperties::ChangeOp(node, op);
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/dead-code-elimination.h b/src/compiler/dead-code-elimination.h
new file mode 100644
index 0000000..e5996c8
--- /dev/null
+++ b/src/compiler/dead-code-elimination.h
@@ -0,0 +1,52 @@
+// Copyright 2015 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.
+
+#ifndef V8_COMPILER_DEAD_CODE_ELIMINATION_H_
+#define V8_COMPILER_DEAD_CODE_ELIMINATION_H_
+
+#include "src/compiler/graph-reducer.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+// Forward declarations.
+class CommonOperatorBuilder;
+
+
+// Propagates {Dead} control through the graph and thereby removes dead code.
+// Note that this does not include trimming dead uses from the graph, and it
+// also does not include detecting dead code by any other means than seeing a
+// {Dead} control input; that is left to other reducers.
+class DeadCodeElimination final : public AdvancedReducer {
+ public:
+  DeadCodeElimination(Editor* editor, Graph* graph,
+                      CommonOperatorBuilder* common);
+  ~DeadCodeElimination() final {}
+
+  Reduction Reduce(Node* node) final;
+
+ private:
+  Reduction ReduceEnd(Node* node);
+  Reduction ReduceLoopOrMerge(Node* node);
+  Reduction ReduceNode(Node* node);
+
+  void TrimMergeOrPhi(Node* node, int size);
+
+  Graph* graph() const { return graph_; }
+  CommonOperatorBuilder* common() const { return common_; }
+  Node* dead() const { return dead_; }
+
+  Graph* const graph_;
+  CommonOperatorBuilder* const common_;
+  Node* const dead_;
+
+  DISALLOW_COPY_AND_ASSIGN(DeadCodeElimination);
+};
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_DEAD_CODE_ELIMINATION_H_
diff --git a/src/compiler/diamond.h b/src/compiler/diamond.h
index 6133cc5..e133305 100644
--- a/src/compiler/diamond.h
+++ b/src/compiler/diamond.h
@@ -5,10 +5,8 @@
 #ifndef V8_COMPILER_DIAMOND_H_
 #define V8_COMPILER_DIAMOND_H_
 
-#include "src/v8.h"
-
 #include "src/compiler/common-operator.h"
-#include "src/compiler/graph-inl.h"
+#include "src/compiler/graph.h"
 #include "src/compiler/node.h"
 
 namespace v8 {
@@ -51,35 +49,13 @@
     }
   }
 
-  Node* Phi(MachineType machine_type, Node* tv, Node* fv) {
-    return graph->NewNode(common->Phi(machine_type, 2), tv, fv, merge);
-  }
-
-  Node* EffectPhi(Node* tv, Node* fv) {
-    return graph->NewNode(common->EffectPhi(2), tv, fv, merge);
-  }
-
-  void OverwriteWithPhi(Node* node, MachineType machine_type, Node* tv,
-                        Node* fv) {
-    DCHECK(node->InputCount() >= 3);
-    node->set_op(common->Phi(machine_type, 2));
-    node->ReplaceInput(0, tv);
-    node->ReplaceInput(1, fv);
-    node->ReplaceInput(2, merge);
-    node->TrimInputCount(3);
-  }
-
-  void OverwriteWithEffectPhi(Node* node, Node* te, Node* fe) {
-    DCHECK(node->InputCount() >= 3);
-    node->set_op(common->EffectPhi(2));
-    node->ReplaceInput(0, te);
-    node->ReplaceInput(1, fe);
-    node->ReplaceInput(2, merge);
-    node->TrimInputCount(3);
+  Node* Phi(MachineRepresentation rep, Node* tv, Node* fv) {
+    return graph->NewNode(common->Phi(rep, 2), tv, fv, merge);
   }
 };
-}
-}
-}  // namespace v8::internal::compiler
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
 
 #endif  // V8_COMPILER_DIAMOND_H_
diff --git a/src/compiler/escape-analysis-reducer.cc b/src/compiler/escape-analysis-reducer.cc
new file mode 100644
index 0000000..df8b65d
--- /dev/null
+++ b/src/compiler/escape-analysis-reducer.cc
@@ -0,0 +1,313 @@
+// Copyright 2015 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/escape-analysis-reducer.h"
+
+#include "src/compiler/js-graph.h"
+#include "src/counters.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+EscapeAnalysisReducer::EscapeAnalysisReducer(Editor* editor, JSGraph* jsgraph,
+                                             EscapeAnalysis* escape_analysis,
+                                             Zone* zone)
+    : AdvancedReducer(editor),
+      jsgraph_(jsgraph),
+      escape_analysis_(escape_analysis),
+      zone_(zone),
+      visited_(static_cast<int>(jsgraph->graph()->NodeCount()), zone) {}
+
+
+Reduction EscapeAnalysisReducer::Reduce(Node* node) {
+  switch (node->opcode()) {
+    case IrOpcode::kLoadField:
+    case IrOpcode::kLoadElement:
+      return ReduceLoad(node);
+    case IrOpcode::kStoreField:
+    case IrOpcode::kStoreElement:
+      return ReduceStore(node);
+    case IrOpcode::kAllocate:
+      return ReduceAllocate(node);
+    case IrOpcode::kFinishRegion:
+      return ReduceFinishRegion(node);
+    case IrOpcode::kReferenceEqual:
+      return ReduceReferenceEqual(node);
+    case IrOpcode::kObjectIsSmi:
+      return ReduceObjectIsSmi(node);
+    default:
+      // TODO(sigurds): Change this to GetFrameStateInputCount once
+      // it is working. For now we use EffectInputCount > 0 to determine
+      // whether a node might have a frame state input.
+      if (node->op()->EffectInputCount() > 0) {
+        return ReduceFrameStateUses(node);
+      }
+      break;
+  }
+  return NoChange();
+}
+
+
+Reduction EscapeAnalysisReducer::ReduceLoad(Node* node) {
+  DCHECK(node->opcode() == IrOpcode::kLoadField ||
+         node->opcode() == IrOpcode::kLoadElement);
+  if (visited_.Contains(node->id())) return NoChange();
+  visited_.Add(node->id());
+  if (Node* rep = escape_analysis()->GetReplacement(node)) {
+    visited_.Add(node->id());
+    counters()->turbo_escape_loads_replaced()->Increment();
+    if (FLAG_trace_turbo_escape) {
+      PrintF("Replaced #%d (%s) with #%d (%s)\n", node->id(),
+             node->op()->mnemonic(), rep->id(), rep->op()->mnemonic());
+    }
+    ReplaceWithValue(node, rep);
+    return Changed(rep);
+  }
+  return NoChange();
+}
+
+
+Reduction EscapeAnalysisReducer::ReduceStore(Node* node) {
+  DCHECK(node->opcode() == IrOpcode::kStoreField ||
+         node->opcode() == IrOpcode::kStoreElement);
+  if (visited_.Contains(node->id())) return NoChange();
+  visited_.Add(node->id());
+  if (escape_analysis()->IsVirtual(NodeProperties::GetValueInput(node, 0))) {
+    if (FLAG_trace_turbo_escape) {
+      PrintF("Removed #%d (%s) from effect chain\n", node->id(),
+             node->op()->mnemonic());
+    }
+    RelaxEffectsAndControls(node);
+    return Changed(node);
+  }
+  return NoChange();
+}
+
+
+Reduction EscapeAnalysisReducer::ReduceAllocate(Node* node) {
+  DCHECK_EQ(node->opcode(), IrOpcode::kAllocate);
+  if (visited_.Contains(node->id())) return NoChange();
+  visited_.Add(node->id());
+  if (escape_analysis()->IsVirtual(node)) {
+    RelaxEffectsAndControls(node);
+    counters()->turbo_escape_allocs_replaced()->Increment();
+    if (FLAG_trace_turbo_escape) {
+      PrintF("Removed allocate #%d from effect chain\n", node->id());
+    }
+    return Changed(node);
+  }
+  return NoChange();
+}
+
+
+Reduction EscapeAnalysisReducer::ReduceFinishRegion(Node* node) {
+  DCHECK_EQ(node->opcode(), IrOpcode::kFinishRegion);
+  Node* effect = NodeProperties::GetEffectInput(node, 0);
+  if (effect->opcode() == IrOpcode::kBeginRegion) {
+    RelaxEffectsAndControls(effect);
+    RelaxEffectsAndControls(node);
+    if (FLAG_trace_turbo_escape) {
+      PrintF("Removed region #%d / #%d from effect chain,", effect->id(),
+             node->id());
+      PrintF(" %d user(s) of #%d remain(s):", node->UseCount(), node->id());
+      for (Edge edge : node->use_edges()) {
+        PrintF(" #%d", edge.from()->id());
+      }
+      PrintF("\n");
+    }
+    return Changed(node);
+  }
+  return NoChange();
+}
+
+
+Reduction EscapeAnalysisReducer::ReduceReferenceEqual(Node* node) {
+  DCHECK_EQ(node->opcode(), IrOpcode::kReferenceEqual);
+  Node* left = NodeProperties::GetValueInput(node, 0);
+  Node* right = NodeProperties::GetValueInput(node, 1);
+  if (escape_analysis()->IsVirtual(left)) {
+    if (escape_analysis()->IsVirtual(right) &&
+        escape_analysis()->CompareVirtualObjects(left, right)) {
+      ReplaceWithValue(node, jsgraph()->TrueConstant());
+      if (FLAG_trace_turbo_escape) {
+        PrintF("Replaced ref eq #%d with true\n", node->id());
+      }
+    }
+    // Right-hand side is not a virtual object, or a different one.
+    ReplaceWithValue(node, jsgraph()->FalseConstant());
+    if (FLAG_trace_turbo_escape) {
+      PrintF("Replaced ref eq #%d with false\n", node->id());
+    }
+    return Replace(node);
+  } else if (escape_analysis()->IsVirtual(right)) {
+    // Left-hand side is not a virtual object.
+    ReplaceWithValue(node, jsgraph()->FalseConstant());
+    if (FLAG_trace_turbo_escape) {
+      PrintF("Replaced ref eq #%d with false\n", node->id());
+    }
+  }
+  return NoChange();
+}
+
+
+Reduction EscapeAnalysisReducer::ReduceObjectIsSmi(Node* node) {
+  DCHECK_EQ(node->opcode(), IrOpcode::kObjectIsSmi);
+  Node* input = NodeProperties::GetValueInput(node, 0);
+  if (escape_analysis()->IsVirtual(input)) {
+    ReplaceWithValue(node, jsgraph()->FalseConstant());
+    if (FLAG_trace_turbo_escape) {
+      PrintF("Replaced ObjectIsSmi #%d with false\n", node->id());
+    }
+    return Replace(node);
+  }
+  return NoChange();
+}
+
+
+Reduction EscapeAnalysisReducer::ReduceFrameStateUses(Node* node) {
+  if (visited_.Contains(node->id())) return NoChange();
+  visited_.Add(node->id());
+  DCHECK_GE(node->op()->EffectInputCount(), 1);
+  bool changed = false;
+  for (int i = 0; i < node->InputCount(); ++i) {
+    Node* input = node->InputAt(i);
+    if (input->opcode() == IrOpcode::kFrameState) {
+      if (Node* ret = ReduceFrameState(input, node, false)) {
+        node->ReplaceInput(i, ret);
+        changed = true;
+      }
+    }
+  }
+  if (changed) {
+    return Changed(node);
+  }
+  return NoChange();
+}
+
+
+// Returns the clone if it duplicated the node, and null otherwise.
+Node* EscapeAnalysisReducer::ReduceFrameState(Node* node, Node* effect,
+                                              bool multiple_users) {
+  DCHECK(node->opcode() == IrOpcode::kFrameState);
+  if (FLAG_trace_turbo_escape) {
+    PrintF("Reducing FrameState %d\n", node->id());
+  }
+  Node* clone = nullptr;
+  for (int i = 0; i < node->op()->ValueInputCount(); ++i) {
+    Node* input = NodeProperties::GetValueInput(node, i);
+    Node* ret =
+        input->opcode() == IrOpcode::kStateValues
+            ? ReduceStateValueInputs(input, effect, node->UseCount() > 1)
+            : ReduceStateValueInput(node, i, effect, node->UseCount() > 1);
+    if (ret) {
+      if (node->UseCount() > 1 || multiple_users) {
+        if (FLAG_trace_turbo_escape) {
+          PrintF("  Cloning #%d", node->id());
+        }
+        node = clone = jsgraph()->graph()->CloneNode(node);
+        if (FLAG_trace_turbo_escape) {
+          PrintF(" to #%d\n", node->id());
+        }
+        multiple_users = false;  // Don't clone anymore.
+      }
+      NodeProperties::ReplaceValueInput(node, ret, i);
+    }
+  }
+  Node* outer_frame_state = NodeProperties::GetFrameStateInput(node, 0);
+  if (outer_frame_state->opcode() == IrOpcode::kFrameState) {
+    if (Node* ret =
+            ReduceFrameState(outer_frame_state, effect, node->UseCount() > 1)) {
+      if (node->UseCount() > 1 || multiple_users) {
+        if (FLAG_trace_turbo_escape) {
+          PrintF("  Cloning #%d", node->id());
+        }
+        node = clone = jsgraph()->graph()->CloneNode(node);
+        if (FLAG_trace_turbo_escape) {
+          PrintF(" to #%d\n", node->id());
+        }
+        multiple_users = false;
+      }
+      NodeProperties::ReplaceFrameStateInput(node, 0, ret);
+    }
+  }
+  return clone;
+}
+
+
+// Returns the clone if it duplicated the node, and null otherwise.
+Node* EscapeAnalysisReducer::ReduceStateValueInputs(Node* node, Node* effect,
+                                                    bool multiple_users) {
+  if (FLAG_trace_turbo_escape) {
+    PrintF("Reducing StateValue #%d\n", node->id());
+  }
+  DCHECK(node->opcode() == IrOpcode::kStateValues);
+  DCHECK_NOT_NULL(effect);
+  Node* clone = nullptr;
+  for (int i = 0; i < node->op()->ValueInputCount(); ++i) {
+    Node* input = NodeProperties::GetValueInput(node, i);
+    Node* ret = nullptr;
+    if (input->opcode() == IrOpcode::kStateValues) {
+      ret = ReduceStateValueInputs(input, effect, multiple_users);
+    } else {
+      ret = ReduceStateValueInput(node, i, effect, multiple_users);
+    }
+    if (ret) {
+      node = ret;
+      DCHECK_NULL(clone);
+      clone = ret;
+      multiple_users = false;
+    }
+  }
+  return clone;
+}
+
+
+// Returns the clone if it duplicated the node, and null otherwise.
+Node* EscapeAnalysisReducer::ReduceStateValueInput(Node* node, int node_index,
+                                                   Node* effect,
+                                                   bool multiple_users) {
+  Node* input = NodeProperties::GetValueInput(node, node_index);
+  if (FLAG_trace_turbo_escape) {
+    PrintF("Reducing State Input #%d (%s)\n", input->id(),
+           input->op()->mnemonic());
+  }
+  Node* clone = nullptr;
+  if (input->opcode() == IrOpcode::kFinishRegion ||
+      input->opcode() == IrOpcode::kAllocate) {
+    if (escape_analysis()->IsVirtual(input)) {
+      if (Node* object_state =
+              escape_analysis()->GetOrCreateObjectState(effect, input)) {
+        if (node->UseCount() > 1 || multiple_users) {
+          if (FLAG_trace_turbo_escape) {
+            PrintF("Cloning #%d", node->id());
+          }
+          node = clone = jsgraph()->graph()->CloneNode(node);
+          if (FLAG_trace_turbo_escape) {
+            PrintF(" to #%d\n", node->id());
+          }
+        }
+        NodeProperties::ReplaceValueInput(node, object_state, node_index);
+        if (FLAG_trace_turbo_escape) {
+          PrintF("Replaced state #%d input #%d with object state #%d\n",
+                 node->id(), input->id(), object_state->id());
+        }
+      } else {
+        if (FLAG_trace_turbo_escape) {
+          PrintF("No object state replacement available.\n");
+        }
+      }
+    }
+  }
+  return clone;
+}
+
+
+Counters* EscapeAnalysisReducer::counters() const {
+  return jsgraph_->isolate()->counters();
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/escape-analysis-reducer.h b/src/compiler/escape-analysis-reducer.h
new file mode 100644
index 0000000..1c0da16
--- /dev/null
+++ b/src/compiler/escape-analysis-reducer.h
@@ -0,0 +1,63 @@
+// Copyright 2015 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.
+
+#ifndef V8_COMPILER_ESCAPE_ANALYSIS_REDUCER_H_
+#define V8_COMPILER_ESCAPE_ANALYSIS_REDUCER_H_
+
+#include "src/bit-vector.h"
+#include "src/compiler/escape-analysis.h"
+#include "src/compiler/graph-reducer.h"
+
+
+namespace v8 {
+namespace internal {
+
+// Forward declarations.
+class Counters;
+
+
+namespace compiler {
+
+// Forward declarations.
+class JSGraph;
+
+
+class EscapeAnalysisReducer final : public AdvancedReducer {
+ public:
+  EscapeAnalysisReducer(Editor* editor, JSGraph* jsgraph,
+                        EscapeAnalysis* escape_analysis, Zone* zone);
+
+  Reduction Reduce(Node* node) final;
+
+ private:
+  Reduction ReduceLoad(Node* node);
+  Reduction ReduceStore(Node* node);
+  Reduction ReduceAllocate(Node* node);
+  Reduction ReduceFinishRegion(Node* node);
+  Reduction ReduceReferenceEqual(Node* node);
+  Reduction ReduceObjectIsSmi(Node* node);
+  Reduction ReduceFrameStateUses(Node* node);
+  Node* ReduceFrameState(Node* node, Node* effect, bool multiple_users);
+  Node* ReduceStateValueInputs(Node* node, Node* effect, bool multiple_users);
+  Node* ReduceStateValueInput(Node* node, int node_index, Node* effect,
+                              bool multiple_users);
+
+  JSGraph* jsgraph() const { return jsgraph_; }
+  EscapeAnalysis* escape_analysis() const { return escape_analysis_; }
+  Zone* zone() const { return zone_; }
+  Counters* counters() const;
+
+  JSGraph* const jsgraph_;
+  EscapeAnalysis* escape_analysis_;
+  Zone* const zone_;
+  BitVector visited_;
+
+  DISALLOW_COPY_AND_ASSIGN(EscapeAnalysisReducer);
+};
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_ESCAPE_ANALYSIS_REDUCER_H_
diff --git a/src/compiler/escape-analysis.cc b/src/compiler/escape-analysis.cc
new file mode 100644
index 0000000..af0ba6a
--- /dev/null
+++ b/src/compiler/escape-analysis.cc
@@ -0,0 +1,1471 @@
+// Copyright 2015 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/escape-analysis.h"
+
+#include <limits>
+
+#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.h"
+#include "src/compiler/node-matchers.h"
+#include "src/compiler/node-properties.h"
+#include "src/compiler/operator-properties.h"
+#include "src/compiler/simplified-operator.h"
+#include "src/objects-inl.h"
+#include "src/type-cache.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+const EscapeAnalysis::Alias EscapeAnalysis::kNotReachable =
+    std::numeric_limits<Alias>::max();
+const EscapeAnalysis::Alias EscapeAnalysis::kUntrackable =
+    std::numeric_limits<Alias>::max() - 1;
+
+
+class VirtualObject : public ZoneObject {
+ public:
+  enum Status { kUntracked = 0, kTracked = 1 };
+  VirtualObject(NodeId id, Zone* zone)
+      : id_(id),
+        status_(kUntracked),
+        fields_(zone),
+        phi_(zone),
+        object_state_(nullptr) {}
+
+  VirtualObject(const VirtualObject& other)
+      : id_(other.id_),
+        status_(other.status_),
+        fields_(other.fields_),
+        phi_(other.phi_),
+        object_state_(other.object_state_) {}
+
+  VirtualObject(NodeId id, Zone* zone, size_t field_number)
+      : id_(id),
+        status_(kTracked),
+        fields_(zone),
+        phi_(zone),
+        object_state_(nullptr) {
+    fields_.resize(field_number);
+    phi_.resize(field_number, false);
+  }
+
+  Node* GetField(size_t offset) {
+    if (offset < fields_.size()) {
+      return fields_[offset];
+    }
+    return nullptr;
+  }
+
+  bool IsCreatedPhi(size_t offset) {
+    if (offset < phi_.size()) {
+      return phi_[offset];
+    }
+    return false;
+  }
+
+  bool SetField(size_t offset, Node* node, bool created_phi = false) {
+    bool changed = fields_[offset] != node || phi_[offset] != created_phi;
+    fields_[offset] = node;
+    phi_[offset] = created_phi;
+    if (changed && FLAG_trace_turbo_escape && node) {
+      PrintF("Setting field %zu of #%d to #%d (%s)\n", offset, id(), node->id(),
+             node->op()->mnemonic());
+    }
+    return changed;
+  }
+  bool IsVirtual() const { return status_ == kTracked; }
+  bool IsTracked() const { return status_ != kUntracked; }
+
+  Node** fields_array() { return &fields_.front(); }
+  size_t field_count() { return fields_.size(); }
+  bool ResizeFields(size_t field_count) {
+    if (field_count != fields_.size()) {
+      fields_.resize(field_count);
+      phi_.resize(field_count);
+      return true;
+    }
+    return false;
+  }
+  bool ClearAllFields() {
+    bool changed = false;
+    for (size_t i = 0; i < fields_.size(); ++i) {
+      if (fields_[i] != nullptr) {
+        fields_[i] = nullptr;
+        changed = true;
+      }
+      phi_[i] = false;
+    }
+    return changed;
+  }
+  bool UpdateFrom(const VirtualObject& other);
+  void SetObjectState(Node* node) { object_state_ = node; }
+  Node* GetObjectState() const { return object_state_; }
+
+  NodeId id() const { return id_; }
+  void id(NodeId id) { id_ = id; }
+
+ private:
+  NodeId id_;
+  Status status_;
+  ZoneVector<Node*> fields_;
+  ZoneVector<bool> phi_;
+  Node* object_state_;
+};
+
+
+bool VirtualObject::UpdateFrom(const VirtualObject& other) {
+  bool changed = status_ != other.status_;
+  status_ = other.status_;
+  if (fields_.size() != other.fields_.size()) {
+    fields_ = other.fields_;
+    return true;
+  }
+  for (size_t i = 0; i < fields_.size(); ++i) {
+    if (fields_[i] != other.fields_[i]) {
+      changed = true;
+      fields_[i] = other.fields_[i];
+    }
+  }
+  return changed;
+}
+
+
+class VirtualState : public ZoneObject {
+ public:
+  VirtualState(Zone* zone, size_t size);
+  VirtualState(const VirtualState& states);
+
+  VirtualObject* VirtualObjectFromAlias(size_t alias);
+  VirtualObject* GetOrCreateTrackedVirtualObject(EscapeAnalysis::Alias alias,
+                                                 NodeId id, Zone* zone);
+  void SetVirtualObject(EscapeAnalysis::Alias alias, VirtualObject* state);
+  void LastChangedAt(Node* node) { last_changed_ = node; }
+  Node* GetLastChanged() { return last_changed_; }
+  bool UpdateFrom(VirtualState* state, Zone* zone);
+  bool MergeFrom(MergeCache* cache, Zone* zone, Graph* graph,
+                 CommonOperatorBuilder* common, Node* control);
+  size_t size() const { return info_.size(); }
+
+ private:
+  ZoneVector<VirtualObject*> info_;
+  Node* last_changed_;
+};
+
+
+class MergeCache : public ZoneObject {
+ public:
+  explicit MergeCache(Zone* zone)
+      : states_(zone), objects_(zone), fields_(zone) {
+    states_.reserve(4);
+    objects_.reserve(4);
+    fields_.reserve(4);
+  }
+  ZoneVector<VirtualState*>& states() { return states_; }
+  ZoneVector<VirtualObject*>& objects() { return objects_; }
+  ZoneVector<Node*>& fields() { return fields_; }
+  void Clear() {
+    states_.clear();
+    objects_.clear();
+    fields_.clear();
+  }
+  size_t LoadVirtualObjectsFromStatesFor(EscapeAnalysis::Alias alias);
+  void LoadVirtualObjectsForFieldsFrom(
+      VirtualState* state, const ZoneVector<EscapeAnalysis::Alias>& aliases);
+  Node* GetFields(size_t pos);
+
+ private:
+  ZoneVector<VirtualState*> states_;
+  ZoneVector<VirtualObject*> objects_;
+  ZoneVector<Node*> fields_;
+};
+
+
+size_t MergeCache::LoadVirtualObjectsFromStatesFor(
+    EscapeAnalysis::Alias alias) {
+  objects_.clear();
+  DCHECK_GT(states_.size(), 0u);
+  size_t min = std::numeric_limits<size_t>::max();
+  for (VirtualState* state : states_) {
+    if (VirtualObject* obj = state->VirtualObjectFromAlias(alias)) {
+      objects_.push_back(obj);
+      min = std::min(obj->field_count(), min);
+    }
+  }
+  return min;
+}
+
+
+void MergeCache::LoadVirtualObjectsForFieldsFrom(
+    VirtualState* state, const ZoneVector<EscapeAnalysis::Alias>& aliases) {
+  objects_.clear();
+  size_t max_alias = state->size();
+  for (Node* field : fields_) {
+    EscapeAnalysis::Alias alias = aliases[field->id()];
+    if (alias >= max_alias) continue;
+    if (VirtualObject* obj = state->VirtualObjectFromAlias(alias)) {
+      objects_.push_back(obj);
+    }
+  }
+}
+
+
+Node* MergeCache::GetFields(size_t pos) {
+  fields_.clear();
+  Node* rep = objects_.front()->GetField(pos);
+  for (VirtualObject* obj : objects_) {
+    Node* field = obj->GetField(pos);
+    if (field) {
+      fields_.push_back(field);
+    }
+    if (field != rep) {
+      rep = nullptr;
+    }
+  }
+  return rep;
+}
+
+
+VirtualState::VirtualState(Zone* zone, size_t size)
+    : info_(size, nullptr, zone), last_changed_(nullptr) {}
+
+
+VirtualState::VirtualState(const VirtualState& state)
+    : info_(state.info_.size(), nullptr, state.info_.get_allocator().zone()),
+      last_changed_(state.last_changed_) {
+  for (size_t i = 0; i < state.info_.size(); ++i) {
+    if (state.info_[i]) {
+      info_[i] =
+          new (info_.get_allocator().zone()) VirtualObject(*state.info_[i]);
+    }
+  }
+}
+
+
+VirtualObject* VirtualState::VirtualObjectFromAlias(size_t alias) {
+  return info_[alias];
+}
+
+
+VirtualObject* VirtualState::GetOrCreateTrackedVirtualObject(
+    EscapeAnalysis::Alias alias, NodeId id, Zone* zone) {
+  if (VirtualObject* obj = VirtualObjectFromAlias(alias)) {
+    return obj;
+  }
+  VirtualObject* obj = new (zone) VirtualObject(id, zone, 0);
+  SetVirtualObject(alias, obj);
+  return obj;
+}
+
+
+void VirtualState::SetVirtualObject(EscapeAnalysis::Alias alias,
+                                    VirtualObject* obj) {
+  info_[alias] = obj;
+}
+
+
+bool VirtualState::UpdateFrom(VirtualState* from, Zone* zone) {
+  bool changed = false;
+  for (EscapeAnalysis::Alias alias = 0; alias < size(); ++alias) {
+    VirtualObject* ls = VirtualObjectFromAlias(alias);
+    VirtualObject* rs = from->VirtualObjectFromAlias(alias);
+
+    if (rs == nullptr) {
+      continue;
+    }
+
+    if (ls == nullptr) {
+      ls = new (zone) VirtualObject(*rs);
+      SetVirtualObject(alias, ls);
+      changed = true;
+      continue;
+    }
+
+    if (FLAG_trace_turbo_escape) {
+      PrintF("  Updating fields of @%d\n", alias);
+    }
+
+    changed = ls->UpdateFrom(*rs) || changed;
+  }
+  return false;
+}
+
+
+namespace {
+
+bool IsEquivalentPhi(Node* node1, Node* node2) {
+  if (node1 == node2) return true;
+  if (node1->opcode() != IrOpcode::kPhi || node2->opcode() != IrOpcode::kPhi ||
+      node1->op()->ValueInputCount() != node2->op()->ValueInputCount()) {
+    return false;
+  }
+  for (int i = 0; i < node1->op()->ValueInputCount(); ++i) {
+    Node* input1 = NodeProperties::GetValueInput(node1, i);
+    Node* input2 = NodeProperties::GetValueInput(node2, i);
+    if (!IsEquivalentPhi(input1, input2)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+
+bool IsEquivalentPhi(Node* phi, ZoneVector<Node*>& inputs) {
+  if (phi->opcode() != IrOpcode::kPhi) return false;
+  if (phi->op()->ValueInputCount() != inputs.size()) {
+    return false;
+  }
+  for (size_t i = 0; i < inputs.size(); ++i) {
+    Node* input = NodeProperties::GetValueInput(phi, static_cast<int>(i));
+    if (!IsEquivalentPhi(input, inputs[i])) {
+      return false;
+    }
+  }
+  return true;
+}
+
+}  // namespace
+
+
+Node* EscapeAnalysis::GetReplacementIfSame(ZoneVector<VirtualObject*>& objs) {
+  Node* rep = GetReplacement(objs.front()->id());
+  for (VirtualObject* obj : objs) {
+    if (GetReplacement(obj->id()) != rep) {
+      return nullptr;
+    }
+  }
+  return rep;
+}
+
+
+bool VirtualState::MergeFrom(MergeCache* cache, Zone* zone, Graph* graph,
+                             CommonOperatorBuilder* common, Node* control) {
+  DCHECK_GT(cache->states().size(), 0u);
+  bool changed = false;
+  for (EscapeAnalysis::Alias alias = 0; alias < size(); ++alias) {
+    size_t fields = cache->LoadVirtualObjectsFromStatesFor(alias);
+    if (cache->objects().size() == cache->states().size()) {
+      if (FLAG_trace_turbo_escape) {
+        PrintF("  Merging virtual objects of @%d\n", alias);
+      }
+      VirtualObject* mergeObject = GetOrCreateTrackedVirtualObject(
+          alias, cache->objects().front()->id(), zone);
+      changed = mergeObject->ResizeFields(fields) || changed;
+      for (size_t i = 0; i < fields; ++i) {
+        if (Node* field = cache->GetFields(i)) {
+          changed = mergeObject->SetField(i, field) || changed;
+          if (FLAG_trace_turbo_escape) {
+            PrintF("    Field %zu agree on rep #%d\n", i, field->id());
+          }
+        } else {
+          int value_input_count = static_cast<int>(cache->fields().size());
+          if (cache->fields().size() == cache->objects().size()) {
+            Node* rep = mergeObject->GetField(i);
+            if (!rep || !mergeObject->IsCreatedPhi(i)) {
+              cache->fields().push_back(control);
+              Node* phi = graph->NewNode(
+                  common->Phi(MachineRepresentation::kTagged,
+                              value_input_count),
+                  value_input_count + 1, &cache->fields().front());
+              mergeObject->SetField(i, phi, true);
+              if (FLAG_trace_turbo_escape) {
+                PrintF("    Creating Phi #%d as merge of", phi->id());
+                for (int i = 0; i < value_input_count; i++) {
+                  PrintF(" #%d (%s)", cache->fields()[i]->id(),
+                         cache->fields()[i]->op()->mnemonic());
+                }
+                PrintF("\n");
+              }
+              changed = true;
+            } else {
+              DCHECK(rep->opcode() == IrOpcode::kPhi);
+              for (int n = 0; n < value_input_count; ++n) {
+                if (n < rep->op()->ValueInputCount()) {
+                  Node* old = NodeProperties::GetValueInput(rep, n);
+                  if (old != cache->fields()[n]) {
+                    changed = true;
+                    NodeProperties::ReplaceValueInput(rep, cache->fields()[n],
+                                                      n);
+                  }
+                } else {
+                  changed = true;
+                  rep->InsertInput(graph->zone(), n, cache->fields()[n]);
+                }
+              }
+              if (rep->op()->ValueInputCount() != value_input_count) {
+                if (FLAG_trace_turbo_escape) {
+                  PrintF("    Widening Phi #%d of arity %d to %d", rep->id(),
+                         rep->op()->ValueInputCount(), value_input_count);
+                }
+                NodeProperties::ChangeOp(
+                    rep, common->Phi(MachineRepresentation::kTagged,
+                                     value_input_count));
+              }
+            }
+          } else {
+            changed = mergeObject->SetField(i, nullptr) || changed;
+          }
+        }
+      }
+    } else {
+      SetVirtualObject(alias, nullptr);
+    }
+  }
+  return changed;
+}
+
+
+EscapeStatusAnalysis::EscapeStatusAnalysis(EscapeAnalysis* object_analysis,
+                                           Graph* graph, Zone* zone)
+    : object_analysis_(object_analysis),
+      graph_(graph),
+      zone_(zone),
+      status_(graph->NodeCount(), kUnknown, zone),
+      queue_(zone) {}
+
+
+EscapeStatusAnalysis::~EscapeStatusAnalysis() {}
+
+
+bool EscapeStatusAnalysis::HasEntry(Node* node) {
+  return status_[node->id()] & (kTracked | kEscaped);
+}
+
+
+bool EscapeStatusAnalysis::IsVirtual(Node* node) {
+  return (status_[node->id()] & kTracked) && !(status_[node->id()] & kEscaped);
+}
+
+
+bool EscapeStatusAnalysis::IsEscaped(Node* node) {
+  return status_[node->id()] & kEscaped;
+}
+
+
+bool EscapeStatusAnalysis::IsAllocation(Node* node) {
+  return node->opcode() == IrOpcode::kAllocate ||
+         node->opcode() == IrOpcode::kFinishRegion;
+}
+
+
+bool EscapeStatusAnalysis::SetEscaped(Node* node) {
+  bool changed = !(status_[node->id()] & kEscaped);
+  status_[node->id()] |= kEscaped | kTracked;
+  return changed;
+}
+
+
+void EscapeStatusAnalysis::Resize() {
+  status_.resize(graph()->NodeCount(), kUnknown);
+}
+
+
+size_t EscapeStatusAnalysis::size() { return status_.size(); }
+
+
+void EscapeStatusAnalysis::Run() {
+  Resize();
+  queue_.push_back(graph()->end());
+  status_[graph()->end()->id()] |= kOnStack;
+  while (!queue_.empty()) {
+    Node* node = queue_.front();
+    queue_.pop_front();
+    status_[node->id()] &= ~kOnStack;
+    Process(node);
+    status_[node->id()] |= kVisited;
+    for (Edge edge : node->input_edges()) {
+      Node* input = edge.to();
+      if (!(status_[input->id()] & (kVisited | kOnStack))) {
+        queue_.push_back(input);
+        status_[input->id()] |= kOnStack;
+      }
+    }
+  }
+}
+
+
+void EscapeStatusAnalysis::RevisitInputs(Node* node) {
+  for (Edge edge : node->input_edges()) {
+    Node* input = edge.to();
+    if (!(status_[input->id()] & kOnStack)) {
+      queue_.push_back(input);
+      status_[input->id()] |= kOnStack;
+    }
+  }
+}
+
+
+void EscapeStatusAnalysis::RevisitUses(Node* node) {
+  for (Edge edge : node->use_edges()) {
+    Node* use = edge.from();
+    if (!(status_[use->id()] & kOnStack)) {
+      queue_.push_back(use);
+      status_[use->id()] |= kOnStack;
+    }
+  }
+}
+
+
+void EscapeStatusAnalysis::Process(Node* node) {
+  switch (node->opcode()) {
+    case IrOpcode::kAllocate:
+      ProcessAllocate(node);
+      break;
+    case IrOpcode::kFinishRegion:
+      ProcessFinishRegion(node);
+      break;
+    case IrOpcode::kStoreField:
+      ProcessStoreField(node);
+      break;
+    case IrOpcode::kStoreElement:
+      ProcessStoreElement(node);
+      break;
+    case IrOpcode::kLoadField:
+    case IrOpcode::kLoadElement: {
+      if (Node* rep = object_analysis_->GetReplacement(node)) {
+        if (IsAllocation(rep) && CheckUsesForEscape(node, rep)) {
+          RevisitInputs(rep);
+          RevisitUses(rep);
+        }
+      }
+      break;
+    }
+    case IrOpcode::kPhi:
+      if (!HasEntry(node)) {
+        status_[node->id()] |= kTracked;
+        if (!IsAllocationPhi(node)) {
+          SetEscaped(node);
+          RevisitUses(node);
+        }
+      }
+      CheckUsesForEscape(node);
+    default:
+      break;
+  }
+}
+
+
+bool EscapeStatusAnalysis::IsAllocationPhi(Node* node) {
+  for (Edge edge : node->input_edges()) {
+    Node* input = edge.to();
+    if (input->opcode() == IrOpcode::kPhi && !IsEscaped(input)) continue;
+    if (IsAllocation(input)) continue;
+    return false;
+  }
+  return true;
+}
+
+
+void EscapeStatusAnalysis::ProcessStoreField(Node* node) {
+  DCHECK_EQ(node->opcode(), IrOpcode::kStoreField);
+  Node* to = NodeProperties::GetValueInput(node, 0);
+  Node* val = NodeProperties::GetValueInput(node, 1);
+  if ((IsEscaped(to) || !IsAllocation(to)) && SetEscaped(val)) {
+    RevisitUses(val);
+    RevisitInputs(val);
+    if (FLAG_trace_turbo_escape) {
+      PrintF("Setting #%d (%s) to escaped because of store to field of #%d\n",
+             val->id(), val->op()->mnemonic(), to->id());
+    }
+  }
+}
+
+
+void EscapeStatusAnalysis::ProcessStoreElement(Node* node) {
+  DCHECK_EQ(node->opcode(), IrOpcode::kStoreElement);
+  Node* to = NodeProperties::GetValueInput(node, 0);
+  Node* val = NodeProperties::GetValueInput(node, 2);
+  if ((IsEscaped(to) || !IsAllocation(to)) && SetEscaped(val)) {
+    RevisitUses(val);
+    RevisitInputs(val);
+    if (FLAG_trace_turbo_escape) {
+      PrintF("Setting #%d (%s) to escaped because of store to field of #%d\n",
+             val->id(), val->op()->mnemonic(), to->id());
+    }
+  }
+}
+
+
+void EscapeStatusAnalysis::ProcessAllocate(Node* node) {
+  DCHECK_EQ(node->opcode(), IrOpcode::kAllocate);
+  if (!HasEntry(node)) {
+    status_[node->id()] |= kTracked;
+    if (FLAG_trace_turbo_escape) {
+      PrintF("Created status entry for node #%d (%s)\n", node->id(),
+             node->op()->mnemonic());
+    }
+    NumberMatcher size(node->InputAt(0));
+    DCHECK(node->InputAt(0)->opcode() != IrOpcode::kInt32Constant &&
+           node->InputAt(0)->opcode() != IrOpcode::kInt64Constant &&
+           node->InputAt(0)->opcode() != IrOpcode::kFloat32Constant &&
+           node->InputAt(0)->opcode() != IrOpcode::kFloat64Constant);
+    if (!size.HasValue() && SetEscaped(node)) {
+      RevisitUses(node);
+      if (FLAG_trace_turbo_escape) {
+        PrintF("Setting #%d to escaped because of non-const alloc\n",
+               node->id());
+      }
+      // This node is known to escape, uses do not have to be checked.
+      return;
+    }
+  }
+  if (CheckUsesForEscape(node, true)) {
+    RevisitUses(node);
+  }
+}
+
+
+bool EscapeStatusAnalysis::CheckUsesForEscape(Node* uses, Node* rep,
+                                              bool phi_escaping) {
+  for (Edge edge : uses->use_edges()) {
+    Node* use = edge.from();
+    if (edge.index() >= use->op()->ValueInputCount() +
+                            OperatorProperties::GetContextInputCount(use->op()))
+      continue;
+    switch (use->opcode()) {
+      case IrOpcode::kPhi:
+        if (phi_escaping && SetEscaped(rep)) {
+          if (FLAG_trace_turbo_escape) {
+            PrintF(
+                "Setting #%d (%s) to escaped because of use by phi node "
+                "#%d (%s)\n",
+                rep->id(), rep->op()->mnemonic(), use->id(),
+                use->op()->mnemonic());
+          }
+          return true;
+        }
+      // Fallthrough.
+      case IrOpcode::kStoreField:
+      case IrOpcode::kLoadField:
+      case IrOpcode::kStoreElement:
+      case IrOpcode::kLoadElement:
+      case IrOpcode::kFrameState:
+      case IrOpcode::kStateValues:
+      case IrOpcode::kReferenceEqual:
+      case IrOpcode::kFinishRegion:
+        if (IsEscaped(use) && SetEscaped(rep)) {
+          if (FLAG_trace_turbo_escape) {
+            PrintF(
+                "Setting #%d (%s) to escaped because of use by escaping node "
+                "#%d (%s)\n",
+                rep->id(), rep->op()->mnemonic(), use->id(),
+                use->op()->mnemonic());
+          }
+          return true;
+        }
+        break;
+      case IrOpcode::kObjectIsSmi:
+        if (!IsAllocation(rep) && SetEscaped(rep)) {
+          PrintF("Setting #%d (%s) to escaped because of use by #%d (%s)\n",
+                 rep->id(), rep->op()->mnemonic(), use->id(),
+                 use->op()->mnemonic());
+          return true;
+        }
+        break;
+      default:
+        if (use->op()->EffectInputCount() == 0 &&
+            uses->op()->EffectInputCount() > 0) {
+          PrintF("Encountered unaccounted use by #%d (%s)\n", use->id(),
+                 use->op()->mnemonic());
+          UNREACHABLE();
+        }
+        if (SetEscaped(rep)) {
+          if (FLAG_trace_turbo_escape) {
+            PrintF("Setting #%d (%s) to escaped because of use by #%d (%s)\n",
+                   rep->id(), rep->op()->mnemonic(), use->id(),
+                   use->op()->mnemonic());
+          }
+          return true;
+        }
+    }
+  }
+  return false;
+}
+
+
+void EscapeStatusAnalysis::ProcessFinishRegion(Node* node) {
+  DCHECK_EQ(node->opcode(), IrOpcode::kFinishRegion);
+  if (!HasEntry(node)) {
+    status_[node->id()] |= kTracked;
+    RevisitUses(node);
+  }
+  if (CheckUsesForEscape(node, true)) {
+    RevisitInputs(node);
+  }
+}
+
+
+void EscapeStatusAnalysis::DebugPrint() {
+  for (NodeId id = 0; id < status_.size(); id++) {
+    if (status_[id] & kTracked) {
+      PrintF("Node #%d is %s\n", id,
+             (status_[id] & kEscaped) ? "escaping" : "virtual");
+    }
+  }
+}
+
+
+EscapeAnalysis::EscapeAnalysis(Graph* graph, CommonOperatorBuilder* common,
+                               Zone* zone)
+    : graph_(graph),
+      common_(common),
+      zone_(zone),
+      virtual_states_(zone),
+      replacements_(zone),
+      escape_status_(this, graph, zone),
+      cache_(new (zone) MergeCache(zone)),
+      aliases_(zone),
+      next_free_alias_(0) {}
+
+
+EscapeAnalysis::~EscapeAnalysis() {}
+
+
+void EscapeAnalysis::Run() {
+  replacements_.resize(graph()->NodeCount());
+  AssignAliases();
+  RunObjectAnalysis();
+  escape_status_.Run();
+}
+
+
+void EscapeAnalysis::AssignAliases() {
+  ZoneVector<Node*> stack(zone());
+  stack.push_back(graph()->end());
+  CHECK_LT(graph()->NodeCount(), kUntrackable);
+  aliases_.resize(graph()->NodeCount(), kNotReachable);
+  aliases_[graph()->end()->id()] = kUntrackable;
+  while (!stack.empty()) {
+    Node* node = stack.back();
+    stack.pop_back();
+    switch (node->opcode()) {
+      case IrOpcode::kAllocate:
+        if (aliases_[node->id()] >= kUntrackable) {
+          aliases_[node->id()] = NextAlias();
+        }
+        break;
+      case IrOpcode::kFinishRegion: {
+        Node* allocate = NodeProperties::GetValueInput(node, 0);
+        if (allocate->opcode() == IrOpcode::kAllocate) {
+          if (aliases_[allocate->id()] >= kUntrackable) {
+            if (aliases_[allocate->id()] == kNotReachable) {
+              stack.push_back(allocate);
+            }
+            aliases_[allocate->id()] = NextAlias();
+          }
+          aliases_[node->id()] = aliases_[allocate->id()];
+        } else {
+          aliases_[node->id()] = NextAlias();
+        }
+        break;
+      }
+      default:
+        DCHECK_EQ(aliases_[node->id()], kUntrackable);
+        break;
+    }
+    for (Edge edge : node->input_edges()) {
+      Node* input = edge.to();
+      if (aliases_[input->id()] == kNotReachable) {
+        stack.push_back(input);
+        aliases_[input->id()] = kUntrackable;
+      }
+    }
+  }
+
+  if (FLAG_trace_turbo_escape) {
+    PrintF("Discovered trackable nodes");
+    for (EscapeAnalysis::Alias id = 0; id < graph()->NodeCount(); ++id) {
+      if (aliases_[id] < kUntrackable) {
+        if (FLAG_trace_turbo_escape) {
+          PrintF(" #%u", id);
+        }
+      }
+    }
+    PrintF("\n");
+  }
+}
+
+
+void EscapeAnalysis::RunObjectAnalysis() {
+  virtual_states_.resize(graph()->NodeCount());
+  ZoneVector<Node*> stack(zone());
+  stack.push_back(graph()->start());
+  while (!stack.empty()) {
+    Node* node = stack.back();
+    stack.pop_back();
+    if (aliases_[node->id()] != kNotReachable && Process(node)) {
+      for (Edge edge : node->use_edges()) {
+        if (NodeProperties::IsEffectEdge(edge)) {
+          Node* use = edge.from();
+          if ((use->opcode() != IrOpcode::kLoadField &&
+               use->opcode() != IrOpcode::kLoadElement) ||
+              !IsDanglingEffectNode(use)) {
+            stack.push_back(use);
+          }
+        }
+      }
+      // First process loads: dangling loads are a problem otherwise.
+      for (Edge edge : node->use_edges()) {
+        if (NodeProperties::IsEffectEdge(edge)) {
+          Node* use = edge.from();
+          if ((use->opcode() == IrOpcode::kLoadField ||
+               use->opcode() == IrOpcode::kLoadElement) &&
+              IsDanglingEffectNode(use)) {
+            stack.push_back(use);
+          }
+        }
+      }
+    }
+  }
+  if (FLAG_trace_turbo_escape) {
+    DebugPrint();
+  }
+}
+
+
+bool EscapeAnalysis::IsDanglingEffectNode(Node* node) {
+  if (node->op()->EffectInputCount() == 0) return false;
+  if (node->op()->EffectOutputCount() == 0) return false;
+  if (node->op()->EffectInputCount() == 1 &&
+      NodeProperties::GetEffectInput(node)->opcode() == IrOpcode::kStart) {
+    // The start node is used as sentinel for nodes that are in general
+    // effectful, but of which an analysis has determined that they do not
+    // produce effects in this instance. We don't consider these nodes dangling.
+    return false;
+  }
+  for (Edge edge : node->use_edges()) {
+    if (NodeProperties::IsEffectEdge(edge)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+
+bool EscapeAnalysis::Process(Node* node) {
+  switch (node->opcode()) {
+    case IrOpcode::kAllocate:
+      ProcessAllocation(node);
+      break;
+    case IrOpcode::kBeginRegion:
+      ForwardVirtualState(node);
+      break;
+    case IrOpcode::kFinishRegion:
+      ProcessFinishRegion(node);
+      break;
+    case IrOpcode::kStoreField:
+      ProcessStoreField(node);
+      break;
+    case IrOpcode::kLoadField:
+      ProcessLoadField(node);
+      break;
+    case IrOpcode::kStoreElement:
+      ProcessStoreElement(node);
+      break;
+    case IrOpcode::kLoadElement:
+      ProcessLoadElement(node);
+      break;
+    case IrOpcode::kStart:
+      ProcessStart(node);
+      break;
+    case IrOpcode::kEffectPhi:
+      return ProcessEffectPhi(node);
+      break;
+    default:
+      if (node->op()->EffectInputCount() > 0) {
+        ForwardVirtualState(node);
+      }
+      ProcessAllocationUsers(node);
+      break;
+  }
+  return true;
+}
+
+
+void EscapeAnalysis::ProcessAllocationUsers(Node* node) {
+  for (Edge edge : node->input_edges()) {
+    Node* input = edge.to();
+    if (!NodeProperties::IsValueEdge(edge) &&
+        !NodeProperties::IsContextEdge(edge))
+      continue;
+    switch (node->opcode()) {
+      case IrOpcode::kStoreField:
+      case IrOpcode::kLoadField:
+      case IrOpcode::kStoreElement:
+      case IrOpcode::kLoadElement:
+      case IrOpcode::kFrameState:
+      case IrOpcode::kStateValues:
+      case IrOpcode::kReferenceEqual:
+      case IrOpcode::kFinishRegion:
+      case IrOpcode::kPhi:
+        break;
+      default:
+        VirtualState* state = virtual_states_[node->id()];
+        if (VirtualObject* obj = ResolveVirtualObject(state, input)) {
+          if (obj->ClearAllFields()) {
+            state->LastChangedAt(node);
+          }
+        }
+        break;
+    }
+  }
+}
+
+
+bool EscapeAnalysis::IsEffectBranchPoint(Node* node) {
+  int count = 0;
+  for (Edge edge : node->use_edges()) {
+    if (NodeProperties::IsEffectEdge(edge)) {
+      if (++count > 1) {
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
+
+void EscapeAnalysis::ForwardVirtualState(Node* node) {
+  DCHECK_EQ(node->op()->EffectInputCount(), 1);
+  if (node->opcode() != IrOpcode::kLoadField &&
+      node->opcode() != IrOpcode::kLoadElement &&
+      node->opcode() != IrOpcode::kLoad && IsDanglingEffectNode(node)) {
+    PrintF("Dangeling effect node: #%d (%s)\n", node->id(),
+           node->op()->mnemonic());
+    UNREACHABLE();
+  }
+  Node* effect = NodeProperties::GetEffectInput(node);
+  // Break the cycle for effect phis.
+  if (effect->opcode() == IrOpcode::kEffectPhi) {
+    if (virtual_states_[effect->id()] == nullptr) {
+      virtual_states_[effect->id()] =
+          new (zone()) VirtualState(zone(), AliasCount());
+    }
+  }
+  DCHECK_NOT_NULL(virtual_states_[effect->id()]);
+  if (IsEffectBranchPoint(effect)) {
+    if (FLAG_trace_turbo_escape) {
+      PrintF("Copying object state %p from #%d (%s) to #%d (%s)\n",
+             static_cast<void*>(virtual_states_[effect->id()]), effect->id(),
+             effect->op()->mnemonic(), node->id(), node->op()->mnemonic());
+    }
+    if (!virtual_states_[node->id()]) {
+      virtual_states_[node->id()] =
+          new (zone()) VirtualState(*virtual_states_[effect->id()]);
+    } else {
+      virtual_states_[node->id()]->UpdateFrom(virtual_states_[effect->id()],
+                                              zone());
+    }
+  } else {
+    virtual_states_[node->id()] = virtual_states_[effect->id()];
+    if (FLAG_trace_turbo_escape) {
+      PrintF("Forwarding object state %p from #%d (%s) to #%d (%s)\n",
+             static_cast<void*>(virtual_states_[effect->id()]), effect->id(),
+             effect->op()->mnemonic(), node->id(), node->op()->mnemonic());
+    }
+  }
+}
+
+
+void EscapeAnalysis::ProcessStart(Node* node) {
+  DCHECK_EQ(node->opcode(), IrOpcode::kStart);
+  virtual_states_[node->id()] = new (zone()) VirtualState(zone(), AliasCount());
+}
+
+
+bool EscapeAnalysis::ProcessEffectPhi(Node* node) {
+  DCHECK_EQ(node->opcode(), IrOpcode::kEffectPhi);
+  bool changed = false;
+
+  VirtualState* mergeState = virtual_states_[node->id()];
+  if (!mergeState) {
+    mergeState = new (zone()) VirtualState(zone(), AliasCount());
+    virtual_states_[node->id()] = mergeState;
+    changed = true;
+    if (FLAG_trace_turbo_escape) {
+      PrintF("Effect Phi #%d got new states map %p.\n", node->id(),
+             static_cast<void*>(mergeState));
+    }
+  } else if (mergeState->GetLastChanged() != node) {
+    changed = true;
+  }
+
+  cache_->Clear();
+
+  if (FLAG_trace_turbo_escape) {
+    PrintF("At Effect Phi #%d, merging states into %p:", node->id(),
+           static_cast<void*>(mergeState));
+  }
+
+  for (int i = 0; i < node->op()->EffectInputCount(); ++i) {
+    Node* input = NodeProperties::GetEffectInput(node, i);
+    VirtualState* state = virtual_states_[input->id()];
+    if (state) {
+      cache_->states().push_back(state);
+    }
+    if (FLAG_trace_turbo_escape) {
+      PrintF(" %p (from %d %s)", static_cast<void*>(state), input->id(),
+             input->op()->mnemonic());
+    }
+  }
+  if (FLAG_trace_turbo_escape) {
+    PrintF("\n");
+  }
+
+  if (cache_->states().size() == 0) {
+    return changed;
+  }
+
+  changed = mergeState->MergeFrom(cache_, zone(), graph(), common(),
+                                  NodeProperties::GetControlInput(node)) ||
+            changed;
+
+  if (FLAG_trace_turbo_escape) {
+    PrintF("Merge %s the node.\n", changed ? "changed" : "did not change");
+  }
+
+  if (changed) {
+    mergeState->LastChangedAt(node);
+    escape_status_.Resize();
+  }
+  return changed;
+}
+
+
+void EscapeAnalysis::ProcessAllocation(Node* node) {
+  DCHECK_EQ(node->opcode(), IrOpcode::kAllocate);
+  ForwardVirtualState(node);
+
+  // Check if we have already processed this node.
+  if (virtual_states_[node->id()]->VirtualObjectFromAlias(
+          aliases_[node->id()])) {
+    return;
+  }
+
+  NumberMatcher size(node->InputAt(0));
+  DCHECK(node->InputAt(0)->opcode() != IrOpcode::kInt32Constant &&
+         node->InputAt(0)->opcode() != IrOpcode::kInt64Constant &&
+         node->InputAt(0)->opcode() != IrOpcode::kFloat32Constant &&
+         node->InputAt(0)->opcode() != IrOpcode::kFloat64Constant);
+  if (size.HasValue()) {
+    virtual_states_[node->id()]->SetVirtualObject(
+        aliases_[node->id()],
+        new (zone())
+            VirtualObject(node->id(), zone(), size.Value() / kPointerSize));
+  } else {
+    virtual_states_[node->id()]->SetVirtualObject(
+        aliases_[node->id()], new (zone()) VirtualObject(node->id(), zone()));
+  }
+  virtual_states_[node->id()]->LastChangedAt(node);
+}
+
+
+void EscapeAnalysis::ProcessFinishRegion(Node* node) {
+  DCHECK_EQ(node->opcode(), IrOpcode::kFinishRegion);
+  ForwardVirtualState(node);
+  Node* allocation = NodeProperties::GetValueInput(node, 0);
+  if (allocation->opcode() == IrOpcode::kAllocate) {
+    VirtualState* state = virtual_states_[node->id()];
+    if (!state->VirtualObjectFromAlias(aliases_[node->id()])) {
+      VirtualObject* vobj_alloc =
+          state->VirtualObjectFromAlias(aliases_[allocation->id()]);
+      DCHECK_NOT_NULL(vobj_alloc);
+      state->SetVirtualObject(aliases_[node->id()], vobj_alloc);
+      if (FLAG_trace_turbo_escape) {
+        PrintF("Linked finish region node #%d to node #%d\n", node->id(),
+               allocation->id());
+      }
+      state->LastChangedAt(node);
+    }
+  }
+}
+
+
+Node* EscapeAnalysis::replacement(NodeId id) {
+  if (id >= replacements_.size()) return nullptr;
+  return replacements_[id];
+}
+
+
+Node* EscapeAnalysis::replacement(Node* node) {
+  return replacement(node->id());
+}
+
+
+bool EscapeAnalysis::SetReplacement(Node* node, Node* rep) {
+  bool changed = replacements_[node->id()] != rep;
+  replacements_[node->id()] = rep;
+  return changed;
+}
+
+
+bool EscapeAnalysis::UpdateReplacement(VirtualState* state, Node* node,
+                                       Node* rep) {
+  if (SetReplacement(node, rep)) {
+    state->LastChangedAt(node);
+    if (FLAG_trace_turbo_escape) {
+      if (rep) {
+        PrintF("Replacement of #%d is #%d (%s)\n", node->id(), rep->id(),
+               rep->op()->mnemonic());
+      } else {
+        PrintF("Replacement of #%d cleared\n", node->id());
+      }
+    }
+    return true;
+  }
+  return false;
+}
+
+
+Node* EscapeAnalysis::ResolveReplacement(Node* node) {
+  while (replacement(node)) {
+    node = replacement(node);
+  }
+  return node;
+}
+
+
+Node* EscapeAnalysis::GetReplacement(Node* node) {
+  return GetReplacement(node->id());
+}
+
+
+Node* EscapeAnalysis::GetReplacement(NodeId id) {
+  Node* node = nullptr;
+  while (replacement(id)) {
+    node = replacement(id);
+    id = node->id();
+  }
+  return node;
+}
+
+
+bool EscapeAnalysis::IsVirtual(Node* node) {
+  if (node->id() >= escape_status_.size()) {
+    return false;
+  }
+  return escape_status_.IsVirtual(node);
+}
+
+
+bool EscapeAnalysis::IsEscaped(Node* node) {
+  if (node->id() >= escape_status_.size()) {
+    return false;
+  }
+  return escape_status_.IsEscaped(node);
+}
+
+
+bool EscapeAnalysis::SetEscaped(Node* node) {
+  return escape_status_.SetEscaped(node);
+}
+
+
+VirtualObject* EscapeAnalysis::GetVirtualObject(Node* at, NodeId id) {
+  if (VirtualState* states = virtual_states_[at->id()]) {
+    return states->VirtualObjectFromAlias(aliases_[id]);
+  }
+  return nullptr;
+}
+
+
+VirtualObject* EscapeAnalysis::ResolveVirtualObject(VirtualState* state,
+                                                    Node* node) {
+  VirtualObject* obj = GetVirtualObject(state, ResolveReplacement(node));
+  while (obj && replacement(obj->id())) {
+    if (VirtualObject* next = GetVirtualObject(state, replacement(obj->id()))) {
+      obj = next;
+    } else {
+      break;
+    }
+  }
+  return obj;
+}
+
+
+bool EscapeAnalysis::CompareVirtualObjects(Node* left, Node* right) {
+  DCHECK(IsVirtual(left) && IsVirtual(right));
+  left = ResolveReplacement(left);
+  right = ResolveReplacement(right);
+  if (IsEquivalentPhi(left, right)) {
+    return true;
+  }
+  return false;
+}
+
+
+int EscapeAnalysis::OffsetFromAccess(Node* node) {
+  DCHECK(OpParameter<FieldAccess>(node).offset % kPointerSize == 0);
+  return OpParameter<FieldAccess>(node).offset / kPointerSize;
+}
+
+
+void EscapeAnalysis::ProcessLoadFromPhi(int offset, Node* from, Node* node,
+                                        VirtualState* state) {
+  if (FLAG_trace_turbo_escape) {
+    PrintF("Load #%d from phi #%d", node->id(), from->id());
+  }
+
+  cache_->fields().clear();
+  for (int i = 0; i < node->op()->ValueInputCount(); ++i) {
+    Node* input = NodeProperties::GetValueInput(node, i);
+    cache_->fields().push_back(input);
+  }
+
+  cache_->LoadVirtualObjectsForFieldsFrom(state, aliases_);
+  if (cache_->objects().size() == cache_->fields().size()) {
+    cache_->GetFields(offset);
+    if (cache_->fields().size() == cache_->objects().size()) {
+      Node* rep = replacement(node);
+      if (!rep || !IsEquivalentPhi(rep, cache_->fields())) {
+        int value_input_count = static_cast<int>(cache_->fields().size());
+        cache_->fields().push_back(NodeProperties::GetControlInput(from));
+        Node* phi = graph()->NewNode(
+            common()->Phi(MachineRepresentation::kTagged, value_input_count),
+            value_input_count + 1, &cache_->fields().front());
+        escape_status_.Resize();
+        SetReplacement(node, phi);
+        state->LastChangedAt(node);
+        if (FLAG_trace_turbo_escape) {
+          PrintF(" got phi created.\n");
+        }
+      } else if (FLAG_trace_turbo_escape) {
+        PrintF(" has already phi #%d.\n", rep->id());
+      }
+    } else if (FLAG_trace_turbo_escape) {
+      PrintF(" has incomplete field info.\n");
+    }
+  } else if (FLAG_trace_turbo_escape) {
+    PrintF(" has incomplete virtual object info.\n");
+  }
+}
+
+
+void EscapeAnalysis::ProcessLoadField(Node* node) {
+  DCHECK_EQ(node->opcode(), IrOpcode::kLoadField);
+  ForwardVirtualState(node);
+  Node* from = NodeProperties::GetValueInput(node, 0);
+  VirtualState* state = virtual_states_[node->id()];
+  if (VirtualObject* object = ResolveVirtualObject(state, from)) {
+    int offset = OffsetFromAccess(node);
+    if (!object->IsTracked()) return;
+    Node* value = object->GetField(offset);
+    if (value) {
+      value = ResolveReplacement(value);
+    }
+    // Record that the load has this alias.
+    UpdateReplacement(state, node, value);
+  } else {
+    if (from->opcode() == IrOpcode::kPhi &&
+        OpParameter<FieldAccess>(node).offset % kPointerSize == 0) {
+      int offset = OffsetFromAccess(node);
+      // Only binary phis are supported for now.
+      ProcessLoadFromPhi(offset, from, node, state);
+    }
+  }
+}
+
+
+void EscapeAnalysis::ProcessLoadElement(Node* node) {
+  DCHECK_EQ(node->opcode(), IrOpcode::kLoadElement);
+  ForwardVirtualState(node);
+  Node* from = NodeProperties::GetValueInput(node, 0);
+  VirtualState* state = virtual_states_[node->id()];
+  Node* index_node = node->InputAt(1);
+  NumberMatcher index(index_node);
+  DCHECK(index_node->opcode() != IrOpcode::kInt32Constant &&
+         index_node->opcode() != IrOpcode::kInt64Constant &&
+         index_node->opcode() != IrOpcode::kFloat32Constant &&
+         index_node->opcode() != IrOpcode::kFloat64Constant);
+  ElementAccess access = OpParameter<ElementAccess>(node);
+  if (index.HasValue()) {
+    int offset = index.Value() + access.header_size / kPointerSize;
+    if (VirtualObject* object = ResolveVirtualObject(state, from)) {
+      CHECK_GE(ElementSizeLog2Of(access.machine_type.representation()),
+               kPointerSizeLog2);
+      CHECK_EQ(access.header_size % kPointerSize, 0);
+
+      if (!object->IsTracked()) return;
+      Node* value = object->GetField(offset);
+      if (value) {
+        value = ResolveReplacement(value);
+      }
+      // Record that the load has this alias.
+      UpdateReplacement(state, node, value);
+    } else if (from->opcode() == IrOpcode::kPhi) {
+      ElementAccess access = OpParameter<ElementAccess>(node);
+      int offset = index.Value() + access.header_size / kPointerSize;
+      ProcessLoadFromPhi(offset, from, node, state);
+    }
+  } else {
+    // We have a load from a non-const index, cannot eliminate object.
+    if (SetEscaped(from)) {
+      if (FLAG_trace_turbo_escape) {
+        PrintF(
+            "Setting #%d (%s) to escaped because store element #%d to "
+            "non-const "
+            "index #%d (%s)\n",
+            from->id(), from->op()->mnemonic(), node->id(), index_node->id(),
+            index_node->op()->mnemonic());
+      }
+    }
+  }
+}
+
+
+void EscapeAnalysis::ProcessStoreField(Node* node) {
+  DCHECK_EQ(node->opcode(), IrOpcode::kStoreField);
+  ForwardVirtualState(node);
+  Node* to = NodeProperties::GetValueInput(node, 0);
+  Node* val = NodeProperties::GetValueInput(node, 1);
+  VirtualState* state = virtual_states_[node->id()];
+  if (VirtualObject* obj = ResolveVirtualObject(state, to)) {
+    if (!obj->IsTracked()) return;
+    int offset = OffsetFromAccess(node);
+    if (obj->SetField(offset, ResolveReplacement(val))) {
+      state->LastChangedAt(node);
+    }
+  }
+}
+
+
+void EscapeAnalysis::ProcessStoreElement(Node* node) {
+  DCHECK_EQ(node->opcode(), IrOpcode::kStoreElement);
+  ForwardVirtualState(node);
+  Node* to = NodeProperties::GetValueInput(node, 0);
+  Node* index_node = node->InputAt(1);
+  NumberMatcher index(index_node);
+  DCHECK(index_node->opcode() != IrOpcode::kInt32Constant &&
+         index_node->opcode() != IrOpcode::kInt64Constant &&
+         index_node->opcode() != IrOpcode::kFloat32Constant &&
+         index_node->opcode() != IrOpcode::kFloat64Constant);
+  ElementAccess access = OpParameter<ElementAccess>(node);
+  Node* val = NodeProperties::GetValueInput(node, 2);
+  if (index.HasValue()) {
+    int offset = index.Value() + access.header_size / kPointerSize;
+    VirtualState* states = virtual_states_[node->id()];
+    if (VirtualObject* obj = ResolveVirtualObject(states, to)) {
+      if (!obj->IsTracked()) return;
+      CHECK_GE(ElementSizeLog2Of(access.machine_type.representation()),
+               kPointerSizeLog2);
+      CHECK_EQ(access.header_size % kPointerSize, 0);
+      if (obj->SetField(offset, ResolveReplacement(val))) {
+        states->LastChangedAt(node);
+      }
+    }
+  } else {
+    // We have a store to a non-const index, cannot eliminate object.
+    if (SetEscaped(to)) {
+      if (FLAG_trace_turbo_escape) {
+        PrintF(
+            "Setting #%d (%s) to escaped because store element #%d to "
+            "non-const "
+            "index #%d (%s)\n",
+            to->id(), to->op()->mnemonic(), node->id(), index_node->id(),
+            index_node->op()->mnemonic());
+      }
+    }
+  }
+}
+
+
+Node* EscapeAnalysis::GetOrCreateObjectState(Node* effect, Node* node) {
+  if ((node->opcode() == IrOpcode::kFinishRegion ||
+       node->opcode() == IrOpcode::kAllocate) &&
+      IsVirtual(node)) {
+    if (VirtualObject* vobj =
+            ResolveVirtualObject(virtual_states_[effect->id()], node)) {
+      if (Node* object_state = vobj->GetObjectState()) {
+        return object_state;
+      } else {
+        cache_->fields().clear();
+        for (size_t i = 0; i < vobj->field_count(); ++i) {
+          if (Node* field = vobj->GetField(i)) {
+            cache_->fields().push_back(field);
+          }
+        }
+        int input_count = static_cast<int>(cache_->fields().size());
+        Node* new_object_state =
+            graph()->NewNode(common()->ObjectState(input_count, vobj->id()),
+                             input_count, &cache_->fields().front());
+        vobj->SetObjectState(new_object_state);
+        if (FLAG_trace_turbo_escape) {
+          PrintF(
+              "Creating object state #%d for vobj %p (from node #%d) at effect "
+              "#%d\n",
+              new_object_state->id(), static_cast<void*>(vobj), node->id(),
+              effect->id());
+        }
+        // Now fix uses of other objects.
+        for (size_t i = 0; i < vobj->field_count(); ++i) {
+          if (Node* field = vobj->GetField(i)) {
+            if (Node* field_object_state =
+                    GetOrCreateObjectState(effect, field)) {
+              NodeProperties::ReplaceValueInput(
+                  new_object_state, field_object_state, static_cast<int>(i));
+            }
+          }
+        }
+        return new_object_state;
+      }
+    }
+  }
+  return nullptr;
+}
+
+
+void EscapeAnalysis::DebugPrintObject(VirtualObject* object, Alias alias) {
+  PrintF("  Alias @%d: Object #%d with %zu fields\n", alias, object->id(),
+         object->field_count());
+  for (size_t i = 0; i < object->field_count(); ++i) {
+    if (Node* f = object->GetField(i)) {
+      PrintF("    Field %zu = #%d (%s)\n", i, f->id(), f->op()->mnemonic());
+    }
+  }
+}
+
+
+void EscapeAnalysis::DebugPrintState(VirtualState* state) {
+  PrintF("Dumping object state %p\n", static_cast<void*>(state));
+  for (Alias alias = 0; alias < AliasCount(); ++alias) {
+    if (VirtualObject* object = state->VirtualObjectFromAlias(alias)) {
+      DebugPrintObject(object, alias);
+    }
+  }
+}
+
+
+void EscapeAnalysis::DebugPrint() {
+  ZoneVector<VirtualState*> object_states(zone());
+  for (NodeId id = 0; id < virtual_states_.size(); id++) {
+    if (VirtualState* states = virtual_states_[id]) {
+      if (std::find(object_states.begin(), object_states.end(), states) ==
+          object_states.end()) {
+        object_states.push_back(states);
+      }
+    }
+  }
+  for (size_t n = 0; n < object_states.size(); n++) {
+    DebugPrintState(object_states[n]);
+  }
+}
+
+
+VirtualObject* EscapeAnalysis::GetVirtualObject(VirtualState* state,
+                                                Node* node) {
+  if (node->id() >= aliases_.size()) return nullptr;
+  Alias alias = aliases_[node->id()];
+  if (alias >= state->size()) return nullptr;
+  return state->VirtualObjectFromAlias(alias);
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/escape-analysis.h b/src/compiler/escape-analysis.h
new file mode 100644
index 0000000..ea7b11e
--- /dev/null
+++ b/src/compiler/escape-analysis.h
@@ -0,0 +1,169 @@
+// Copyright 2015 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.
+
+#ifndef V8_COMPILER_ESCAPE_ANALYSIS_H_
+#define V8_COMPILER_ESCAPE_ANALYSIS_H_
+
+#include "src/base/flags.h"
+#include "src/compiler/graph.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+// Forward declarations.
+class CommonOperatorBuilder;
+class EscapeAnalysis;
+class VirtualState;
+class VirtualObject;
+
+
+// EscapeStatusAnalysis determines for each allocation whether it escapes.
+class EscapeStatusAnalysis {
+ public:
+  ~EscapeStatusAnalysis();
+
+  enum EscapeStatusFlag {
+    kUnknown = 0u,
+    kTracked = 1u << 0,
+    kEscaped = 1u << 1,
+    kOnStack = 1u << 2,
+    kVisited = 1u << 3,
+  };
+  typedef base::Flags<EscapeStatusFlag, unsigned char> EscapeStatusFlags;
+
+  void Run();
+
+  bool IsVirtual(Node* node);
+  bool IsEscaped(Node* node);
+  bool IsAllocation(Node* node);
+
+  void DebugPrint();
+
+  friend class EscapeAnalysis;
+
+ private:
+  EscapeStatusAnalysis(EscapeAnalysis* object_analysis, Graph* graph,
+                       Zone* zone);
+  void Process(Node* node);
+  void ProcessAllocate(Node* node);
+  void ProcessFinishRegion(Node* node);
+  void ProcessStoreField(Node* node);
+  void ProcessStoreElement(Node* node);
+  bool CheckUsesForEscape(Node* node, bool phi_escaping = false) {
+    return CheckUsesForEscape(node, node, phi_escaping);
+  }
+  bool CheckUsesForEscape(Node* node, Node* rep, bool phi_escaping = false);
+  void RevisitUses(Node* node);
+  void RevisitInputs(Node* node);
+  bool SetEscaped(Node* node);
+  bool HasEntry(Node* node);
+  void Resize();
+  size_t size();
+  bool IsAllocationPhi(Node* node);
+
+  Graph* graph() const { return graph_; }
+  Zone* zone() const { return zone_; }
+
+  EscapeAnalysis* object_analysis_;
+  Graph* const graph_;
+  Zone* const zone_;
+  ZoneVector<EscapeStatusFlags> status_;
+  ZoneDeque<Node*> queue_;
+
+  DISALLOW_COPY_AND_ASSIGN(EscapeStatusAnalysis);
+};
+
+
+DEFINE_OPERATORS_FOR_FLAGS(EscapeStatusAnalysis::EscapeStatusFlags)
+
+
+// Forward Declaration.
+class MergeCache;
+
+
+// EscapeObjectAnalysis simulates stores to determine values of loads if
+// an object is virtual and eliminated.
+class EscapeAnalysis {
+ public:
+  typedef NodeId Alias;
+
+  EscapeAnalysis(Graph* graph, CommonOperatorBuilder* common, Zone* zone);
+  ~EscapeAnalysis();
+
+  void Run();
+
+  Node* GetReplacement(Node* node);
+  bool IsVirtual(Node* node);
+  bool IsEscaped(Node* node);
+  bool CompareVirtualObjects(Node* left, Node* right);
+  Node* GetOrCreateObjectState(Node* effect, Node* node);
+
+ private:
+  void RunObjectAnalysis();
+  void AssignAliases();
+  bool Process(Node* node);
+  void ProcessLoadField(Node* node);
+  void ProcessStoreField(Node* node);
+  void ProcessLoadElement(Node* node);
+  void ProcessStoreElement(Node* node);
+  void ProcessAllocationUsers(Node* node);
+  void ProcessAllocation(Node* node);
+  void ProcessFinishRegion(Node* node);
+  void ProcessCall(Node* node);
+  void ProcessStart(Node* node);
+  bool ProcessEffectPhi(Node* node);
+  void ProcessLoadFromPhi(int offset, Node* from, Node* node,
+                          VirtualState* states);
+
+  void ForwardVirtualState(Node* node);
+  bool IsEffectBranchPoint(Node* node);
+  bool IsDanglingEffectNode(Node* node);
+  int OffsetFromAccess(Node* node);
+
+  VirtualObject* GetVirtualObject(Node* at, NodeId id);
+  VirtualObject* ResolveVirtualObject(VirtualState* state, Node* node);
+  Node* GetReplacementIfSame(ZoneVector<VirtualObject*>& objs);
+
+  bool SetEscaped(Node* node);
+  Node* replacement(NodeId id);
+  Node* replacement(Node* node);
+  Node* ResolveReplacement(Node* node);
+  Node* GetReplacement(NodeId id);
+  bool SetReplacement(Node* node, Node* rep);
+  bool UpdateReplacement(VirtualState* state, Node* node, Node* rep);
+
+  VirtualObject* GetVirtualObject(VirtualState* state, Node* node);
+
+  void DebugPrint();
+  void DebugPrintState(VirtualState* state);
+  void DebugPrintObject(VirtualObject* state, Alias id);
+
+  Alias NextAlias() { return next_free_alias_++; }
+  Alias AliasCount() const { return next_free_alias_; }
+
+  Graph* graph() const { return graph_; }
+  CommonOperatorBuilder* common() const { return common_; }
+  Zone* zone() const { return zone_; }
+
+  static const Alias kNotReachable;
+  static const Alias kUntrackable;
+  Graph* const graph_;
+  CommonOperatorBuilder* const common_;
+  Zone* const zone_;
+  ZoneVector<VirtualState*> virtual_states_;
+  ZoneVector<Node*> replacements_;
+  EscapeStatusAnalysis escape_status_;
+  MergeCache* cache_;
+  ZoneVector<Alias> aliases_;
+  Alias next_free_alias_;
+
+  DISALLOW_COPY_AND_ASSIGN(EscapeAnalysis);
+};
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_ESCAPE_ANALYSIS_H_
diff --git a/src/compiler/fast-accessor-assembler.cc b/src/compiler/fast-accessor-assembler.cc
new file mode 100644
index 0000000..09d513f
--- /dev/null
+++ b/src/compiler/fast-accessor-assembler.cc
@@ -0,0 +1,220 @@
+// Copyright 2015 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/fast-accessor-assembler.h"
+
+#include "src/base/logging.h"
+#include "src/compiler/graph.h"
+#include "src/compiler/linkage.h"
+#include "src/compiler/pipeline.h"
+#include "src/compiler/raw-machine-assembler.h"
+#include "src/compiler/schedule.h"
+#include "src/compiler/verifier.h"
+#include "src/handles-inl.h"
+#include "src/objects.h"  // For FAA::GetInternalField impl.
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+FastAccessorAssembler::FastAccessorAssembler(Isolate* isolate)
+    : zone_(),
+      assembler_(new RawMachineAssembler(
+          isolate, new (zone()) Graph(zone()),
+          Linkage::GetJSCallDescriptor(&zone_, false, 1,
+                                       CallDescriptor::kNoFlags))),
+      state_(kBuilding) {}
+
+
+FastAccessorAssembler::~FastAccessorAssembler() {}
+
+
+FastAccessorAssembler::ValueId FastAccessorAssembler::IntegerConstant(
+    int const_value) {
+  CHECK_EQ(kBuilding, state_);
+  return FromRaw(assembler_->NumberConstant(const_value));
+}
+
+
+FastAccessorAssembler::ValueId FastAccessorAssembler::GetReceiver() {
+  CHECK_EQ(kBuilding, state_);
+
+  // For JS call descriptor, the receiver is parameter 0. If we use other
+  // call descriptors, this may or may not hold. So let's check.
+  CHECK(assembler_->call_descriptor()->IsJSFunctionCall());
+  return FromRaw(assembler_->Parameter(0));
+}
+
+
+FastAccessorAssembler::ValueId FastAccessorAssembler::LoadInternalField(
+    ValueId value, int field_no) {
+  CHECK_EQ(kBuilding, state_);
+  // Determine the 'value' object's instance type.
+  Node* object_map =
+      assembler_->Load(MachineType::Pointer(), FromId(value),
+                       assembler_->IntPtrConstant(
+                           Internals::kHeapObjectMapOffset - kHeapObjectTag));
+  Node* instance_type = assembler_->WordAnd(
+      assembler_->Load(
+          MachineType::Uint16(), object_map,
+          assembler_->IntPtrConstant(
+              Internals::kMapInstanceTypeAndBitFieldOffset - kHeapObjectTag)),
+      assembler_->IntPtrConstant(0xff));
+
+  // Check whether we have a proper JSObject.
+  RawMachineLabel is_jsobject, is_not_jsobject, merge;
+  assembler_->Branch(
+      assembler_->WordEqual(
+          instance_type, assembler_->IntPtrConstant(Internals::kJSObjectType)),
+      &is_jsobject, &is_not_jsobject);
+
+  // JSObject? Then load the internal field field_no.
+  assembler_->Bind(&is_jsobject);
+  Node* internal_field = assembler_->Load(
+      MachineType::Pointer(), FromId(value),
+      assembler_->IntPtrConstant(JSObject::kHeaderSize - kHeapObjectTag +
+                                 kPointerSize * field_no));
+  assembler_->Goto(&merge);
+
+  // No JSObject? Return undefined.
+  // TODO(vogelheim): Check whether this is the appropriate action, or whether
+  //                  the method should take a label instead.
+  assembler_->Bind(&is_not_jsobject);
+  Node* fail_value = assembler_->UndefinedConstant();
+  assembler_->Goto(&merge);
+
+  // Return.
+  assembler_->Bind(&merge);
+  Node* phi = assembler_->Phi(MachineRepresentation::kTagged, internal_field,
+                              fail_value);
+  return FromRaw(phi);
+}
+
+
+FastAccessorAssembler::ValueId FastAccessorAssembler::LoadValue(ValueId value,
+                                                                int offset) {
+  CHECK_EQ(kBuilding, state_);
+  return FromRaw(assembler_->Load(MachineType::IntPtr(), FromId(value),
+                                  assembler_->IntPtrConstant(offset)));
+}
+
+
+FastAccessorAssembler::ValueId FastAccessorAssembler::LoadObject(ValueId value,
+                                                                 int offset) {
+  CHECK_EQ(kBuilding, state_);
+  return FromRaw(
+      assembler_->Load(MachineType::AnyTagged(),
+                       assembler_->Load(MachineType::Pointer(), FromId(value),
+                                        assembler_->IntPtrConstant(offset))));
+}
+
+
+void FastAccessorAssembler::ReturnValue(ValueId value) {
+  CHECK_EQ(kBuilding, state_);
+  assembler_->Return(FromId(value));
+}
+
+
+void FastAccessorAssembler::CheckFlagSetOrReturnNull(ValueId value, int mask) {
+  CHECK_EQ(kBuilding, state_);
+  RawMachineLabel pass, fail;
+  assembler_->Branch(
+      assembler_->Word32Equal(
+          assembler_->Word32And(FromId(value), assembler_->Int32Constant(mask)),
+          assembler_->Int32Constant(0)),
+      &pass, &fail);
+  assembler_->Bind(&fail);
+  assembler_->Return(assembler_->NullConstant());
+  assembler_->Bind(&pass);
+}
+
+
+void FastAccessorAssembler::CheckNotZeroOrReturnNull(ValueId value) {
+  CHECK_EQ(kBuilding, state_);
+  RawMachineLabel is_null, not_null;
+  assembler_->Branch(
+      assembler_->IntPtrEqual(FromId(value), assembler_->IntPtrConstant(0)),
+      &is_null, &not_null);
+  assembler_->Bind(&is_null);
+  assembler_->Return(assembler_->NullConstant());
+  assembler_->Bind(&not_null);
+}
+
+
+FastAccessorAssembler::LabelId FastAccessorAssembler::MakeLabel() {
+  CHECK_EQ(kBuilding, state_);
+  RawMachineLabel* label =
+      new (zone()->New(sizeof(RawMachineLabel))) RawMachineLabel;
+  return FromRaw(label);
+}
+
+
+void FastAccessorAssembler::SetLabel(LabelId label_id) {
+  CHECK_EQ(kBuilding, state_);
+  assembler_->Bind(FromId(label_id));
+}
+
+
+void FastAccessorAssembler::CheckNotZeroOrJump(ValueId value_id,
+                                               LabelId label_id) {
+  CHECK_EQ(kBuilding, state_);
+  RawMachineLabel pass;
+  assembler_->Branch(
+      assembler_->IntPtrEqual(FromId(value_id), assembler_->IntPtrConstant(0)),
+      &pass, FromId(label_id));
+  assembler_->Bind(&pass);
+}
+
+
+MaybeHandle<Code> FastAccessorAssembler::Build() {
+  CHECK_EQ(kBuilding, state_);
+
+  // Cleanup: We no longer need this.
+  nodes_.clear();
+  labels_.clear();
+
+  // Export the schedule and call the compiler.
+  Schedule* schedule = assembler_->Export();
+  MaybeHandle<Code> code = Pipeline::GenerateCodeForCodeStub(
+      assembler_->isolate(), assembler_->call_descriptor(), assembler_->graph(),
+      schedule, Code::STUB, "FastAccessorAssembler");
+
+  // Update state & return.
+  state_ = !code.is_null() ? kBuilt : kError;
+  return code;
+}
+
+
+FastAccessorAssembler::ValueId FastAccessorAssembler::FromRaw(Node* node) {
+  nodes_.push_back(node);
+  ValueId value = {nodes_.size() - 1};
+  return value;
+}
+
+
+FastAccessorAssembler::LabelId FastAccessorAssembler::FromRaw(
+    RawMachineLabel* label) {
+  labels_.push_back(label);
+  LabelId label_id = {labels_.size() - 1};
+  return label_id;
+}
+
+
+Node* FastAccessorAssembler::FromId(ValueId value) const {
+  CHECK_LT(value.value_id, nodes_.size());
+  CHECK_NOT_NULL(nodes_.at(value.value_id));
+  return nodes_.at(value.value_id);
+}
+
+
+RawMachineLabel* FastAccessorAssembler::FromId(LabelId label) const {
+  CHECK_LT(label.label_id, labels_.size());
+  CHECK_NOT_NULL(labels_.at(label.label_id));
+  return labels_.at(label.label_id);
+}
+
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/fast-accessor-assembler.h b/src/compiler/fast-accessor-assembler.h
new file mode 100644
index 0000000..a9df3f0
--- /dev/null
+++ b/src/compiler/fast-accessor-assembler.h
@@ -0,0 +1,106 @@
+// Copyright 2015 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.
+
+#ifndef V8_COMPILER_FAST_ACCESSOR_ASSEMBLER_H_
+#define V8_COMPILER_FAST_ACCESSOR_ASSEMBLER_H_
+
+#include <stdint.h>
+#include <vector>
+
+// Clients of this interface shouldn't depend on lots of compiler internals.
+// Do not include anything from src/compiler here!
+#include "include/v8-experimental.h"
+#include "src/base/macros.h"
+#include "src/base/smart-pointers.h"
+#include "src/handles.h"
+
+
+namespace v8 {
+namespace internal {
+
+class Code;
+class Isolate;
+class Zone;
+
+namespace compiler {
+
+class Node;
+class RawMachineAssembler;
+class RawMachineLabel;
+
+
+// This interface "exports" an aggregated subset of RawMachineAssembler, for
+// use by the API to implement Fast Dom Accessors.
+//
+// This interface is made for this single purpose only and does not attempt
+// to implement a general purpose solution. If you need one, please look at
+// RawMachineAssembler instead.
+//
+// The life cycle of a FastAccessorAssembler has two phases:
+// - After creating the instance, you can call an arbitrary sequence of
+//   builder functions to build the desired function.
+// - When done, you can Build() the accessor and query for the build results.
+//
+// You cannot call any result getters before Build() was called & successful;
+// and you cannot call any builder functions after Build() was called.
+class FastAccessorAssembler {
+ public:
+  typedef v8::experimental::FastAccessorBuilder::ValueId ValueId;
+  typedef v8::experimental::FastAccessorBuilder::LabelId LabelId;
+
+  explicit FastAccessorAssembler(Isolate* isolate);
+  ~FastAccessorAssembler();
+
+  // Builder / assembler functions:
+  ValueId IntegerConstant(int int_constant);
+  ValueId GetReceiver();
+  ValueId LoadInternalField(ValueId value_id, int field_no);
+  ValueId LoadValue(ValueId value_id, int offset);
+  ValueId LoadObject(ValueId value_id, int offset);
+
+  // Builder / assembler functions for control flow.
+  void ReturnValue(ValueId value_id);
+  void CheckFlagSetOrReturnNull(ValueId value_id, int mask);
+  void CheckNotZeroOrReturnNull(ValueId value_id);
+
+  // TODO(vogelheim): Implement a C++ callback.
+  //  void CheckNotNullOrCallback(ValueId value_id, ..c++-callback type...,
+  //     ValueId arg1, ValueId arg2, ...);
+
+  LabelId MakeLabel();
+  void SetLabel(LabelId label_id);
+  void CheckNotZeroOrJump(ValueId value_id, LabelId label_id);
+
+  // Assemble the code.
+  MaybeHandle<Code> Build();
+
+ private:
+  ValueId FromRaw(Node* node);
+  LabelId FromRaw(RawMachineLabel* label);
+  Node* FromId(ValueId value) const;
+  RawMachineLabel* FromId(LabelId value) const;
+
+  Zone* zone() { return &zone_; }
+
+  Zone zone_;
+  base::SmartPointer<RawMachineAssembler> assembler_;
+
+  // To prevent exposing the RMA internals to the outside world, we'll map
+  // Node + Label pointers integers wrapped in ValueId and LabelId instances.
+  // These vectors maintain this mapping.
+  std::vector<Node*> nodes_;
+  std::vector<RawMachineLabel*> labels_;
+
+  // Remember the current state for easy error checking. (We prefer to be
+  // strict as this class will be exposed at the API.)
+  enum { kBuilding, kBuilt, kError } state_;
+
+  DISALLOW_COPY_AND_ASSIGN(FastAccessorAssembler);
+};
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_FAST_ACCESSOR_ASSEMBLER_H_
diff --git a/src/compiler/frame-elider.cc b/src/compiler/frame-elider.cc
new file mode 100644
index 0000000..7c3f9b2
--- /dev/null
+++ b/src/compiler/frame-elider.cc
@@ -0,0 +1,131 @@
+// Copyright 2015 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/base/adapters.h"
+#include "src/compiler/frame-elider.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+FrameElider::FrameElider(InstructionSequence* code) : code_(code) {}
+
+void FrameElider::Run() {
+  MarkBlocks();
+  PropagateMarks();
+  MarkDeConstruction();
+}
+
+
+void FrameElider::MarkBlocks() {
+  for (auto block : instruction_blocks()) {
+    if (block->needs_frame()) continue;
+    for (auto i = block->code_start(); i < block->code_end(); ++i) {
+      if (InstructionAt(i)->IsCall() ||
+          InstructionAt(i)->opcode() == ArchOpcode::kArchDeoptimize) {
+        block->mark_needs_frame();
+        break;
+      }
+    }
+  }
+}
+
+
+void FrameElider::PropagateMarks() {
+  while (PropagateInOrder() && PropagateReversed()) {
+  }
+}
+
+
+void FrameElider::MarkDeConstruction() {
+  for (auto block : instruction_blocks()) {
+    if (block->needs_frame()) {
+      // Special case: The start block needs a frame.
+      if (block->predecessors().empty()) {
+        block->mark_must_construct_frame();
+      }
+      // Find "frame -> no frame" transitions, inserting frame
+      // deconstructions.
+      for (auto succ : block->successors()) {
+        if (!InstructionBlockAt(succ)->needs_frame()) {
+          DCHECK_EQ(1U, block->SuccessorCount());
+          block->mark_must_deconstruct_frame();
+        }
+      }
+    } else {
+      // Find "no frame -> frame" transitions, inserting frame constructions.
+      for (auto succ : block->successors()) {
+        if (InstructionBlockAt(succ)->needs_frame()) {
+          DCHECK_NE(1U, block->SuccessorCount());
+          InstructionBlockAt(succ)->mark_must_construct_frame();
+        }
+      }
+    }
+  }
+}
+
+
+bool FrameElider::PropagateInOrder() {
+  bool changed = false;
+  for (auto block : instruction_blocks()) {
+    changed |= PropagateIntoBlock(block);
+  }
+  return changed;
+}
+
+
+bool FrameElider::PropagateReversed() {
+  bool changed = false;
+  for (auto block : base::Reversed(instruction_blocks())) {
+    changed |= PropagateIntoBlock(block);
+  }
+  return changed;
+}
+
+
+bool FrameElider::PropagateIntoBlock(InstructionBlock* block) {
+  // Already marked, nothing to do...
+  if (block->needs_frame()) return false;
+
+  // Never mark the dummy end node, otherwise we might incorrectly decide to
+  // put frame deconstruction code there later,
+  if (block->successors().empty()) return false;
+
+  // Propagate towards the end ("downwards") if there is a predecessor needing
+  // a frame, but don't "bleed" from deferred code to non-deferred code.
+  for (auto pred : block->predecessors()) {
+    if (InstructionBlockAt(pred)->needs_frame() &&
+        (!InstructionBlockAt(pred)->IsDeferred() || block->IsDeferred())) {
+      block->mark_needs_frame();
+      return true;
+    }
+  }
+
+  // Propagate towards start ("upwards") if there are successors and all of
+  // them need a frame.
+  for (auto succ : block->successors()) {
+    if (!InstructionBlockAt(succ)->needs_frame()) return false;
+  }
+  block->mark_needs_frame();
+  return true;
+}
+
+
+const InstructionBlocks& FrameElider::instruction_blocks() const {
+  return code_->instruction_blocks();
+}
+
+
+InstructionBlock* FrameElider::InstructionBlockAt(RpoNumber rpo_number) const {
+  return code_->InstructionBlockAt(rpo_number);
+}
+
+
+Instruction* FrameElider::InstructionAt(int index) const {
+  return code_->InstructionAt(index);
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/frame-elider.h b/src/compiler/frame-elider.h
new file mode 100644
index 0000000..7d31619
--- /dev/null
+++ b/src/compiler/frame-elider.h
@@ -0,0 +1,41 @@
+// Copyright 2015 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.
+
+#ifndef V8_COMPILER_FRAME_ELIDER_H_
+#define V8_COMPILER_FRAME_ELIDER_H_
+
+#include "src/compiler/instruction.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+
+// Determine which instruction blocks need a frame and where frames must be
+// constructed/deconstructed.
+class FrameElider {
+ public:
+  explicit FrameElider(InstructionSequence* code);
+  void Run();
+
+
+ private:
+  void MarkBlocks();
+  void PropagateMarks();
+  void MarkDeConstruction();
+  bool PropagateInOrder();
+  bool PropagateReversed();
+  bool PropagateIntoBlock(InstructionBlock* block);
+  const InstructionBlocks& instruction_blocks() const;
+  InstructionBlock* InstructionBlockAt(RpoNumber rpo_number) const;
+  Instruction* InstructionAt(int index) const;
+
+  InstructionSequence* const code_;
+};
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_FRAME_ELIDER_H_
diff --git a/src/compiler/frame-states.cc b/src/compiler/frame-states.cc
new file mode 100644
index 0000000..387d6a9
--- /dev/null
+++ b/src/compiler/frame-states.cc
@@ -0,0 +1,81 @@
+// Copyright 2015 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/frame-states.h"
+
+#include "src/base/functional.h"
+#include "src/handles-inl.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+size_t hash_value(OutputFrameStateCombine const& sc) {
+  return base::hash_combine(sc.kind_, sc.parameter_);
+}
+
+
+std::ostream& operator<<(std::ostream& os, OutputFrameStateCombine const& sc) {
+  switch (sc.kind_) {
+    case OutputFrameStateCombine::kPushOutput:
+      if (sc.parameter_ == 0) return os << "Ignore";
+      return os << "Push(" << sc.parameter_ << ")";
+    case OutputFrameStateCombine::kPokeAt:
+      return os << "PokeAt(" << sc.parameter_ << ")";
+  }
+  UNREACHABLE();
+  return os;
+}
+
+
+bool operator==(FrameStateInfo const& lhs, FrameStateInfo const& rhs) {
+  return lhs.type() == rhs.type() && lhs.bailout_id() == rhs.bailout_id() &&
+         lhs.state_combine() == rhs.state_combine() &&
+         lhs.function_info() == rhs.function_info();
+}
+
+
+bool operator!=(FrameStateInfo const& lhs, FrameStateInfo const& rhs) {
+  return !(lhs == rhs);
+}
+
+
+size_t hash_value(FrameStateInfo const& info) {
+  return base::hash_combine(static_cast<int>(info.type()), info.bailout_id(),
+                            info.state_combine());
+}
+
+
+std::ostream& operator<<(std::ostream& os, FrameStateType type) {
+  switch (type) {
+    case FrameStateType::kJavaScriptFunction:
+      os << "JS_FRAME";
+      break;
+    case FrameStateType::kInterpretedFunction:
+      os << "INTERPRETED_FRAME";
+      break;
+    case FrameStateType::kArgumentsAdaptor:
+      os << "ARGUMENTS_ADAPTOR";
+      break;
+    case FrameStateType::kConstructStub:
+      os << "CONSTRUCT_STUB";
+      break;
+  }
+  return os;
+}
+
+
+std::ostream& operator<<(std::ostream& os, FrameStateInfo const& info) {
+  os << info.type() << ", " << info.bailout_id() << ", "
+     << info.state_combine();
+  Handle<SharedFunctionInfo> shared_info;
+  if (info.shared_info().ToHandle(&shared_info)) {
+    os << ", " << Brief(*shared_info);
+  }
+  return os;
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/frame-states.h b/src/compiler/frame-states.h
new file mode 100644
index 0000000..ddb55c3
--- /dev/null
+++ b/src/compiler/frame-states.h
@@ -0,0 +1,177 @@
+// Copyright 2015 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.
+
+#ifndef V8_COMPILER_FRAME_STATES_H_
+#define V8_COMPILER_FRAME_STATES_H_
+
+#include "src/handles.h"
+#include "src/utils.h"
+
+namespace v8 {
+namespace internal {
+
+// Forward declarations.
+class SharedFunctionInfo;
+
+namespace compiler {
+
+// Flag that describes how to combine the current environment with
+// the output of a node to obtain a framestate for lazy bailout.
+class OutputFrameStateCombine {
+ public:
+  enum Kind {
+    kPushOutput,  // Push the output on the expression stack.
+    kPokeAt       // Poke at the given environment location,
+                  // counting from the top of the stack.
+  };
+
+  static OutputFrameStateCombine Ignore() {
+    return OutputFrameStateCombine(kPushOutput, 0);
+  }
+  static OutputFrameStateCombine Push(size_t count = 1) {
+    return OutputFrameStateCombine(kPushOutput, count);
+  }
+  static OutputFrameStateCombine PokeAt(size_t index) {
+    return OutputFrameStateCombine(kPokeAt, index);
+  }
+
+  Kind kind() const { return kind_; }
+  size_t GetPushCount() const {
+    DCHECK_EQ(kPushOutput, kind());
+    return parameter_;
+  }
+  size_t GetOffsetToPokeAt() const {
+    DCHECK_EQ(kPokeAt, kind());
+    return parameter_;
+  }
+
+  bool IsOutputIgnored() const {
+    return kind_ == kPushOutput && parameter_ == 0;
+  }
+
+  size_t ConsumedOutputCount() const {
+    return kind_ == kPushOutput ? GetPushCount() : 1;
+  }
+
+  bool operator==(OutputFrameStateCombine const& other) const {
+    return kind_ == other.kind_ && parameter_ == other.parameter_;
+  }
+  bool operator!=(OutputFrameStateCombine const& other) const {
+    return !(*this == other);
+  }
+
+  friend size_t hash_value(OutputFrameStateCombine const&);
+  friend std::ostream& operator<<(std::ostream&,
+                                  OutputFrameStateCombine const&);
+
+ private:
+  OutputFrameStateCombine(Kind kind, size_t parameter)
+      : kind_(kind), parameter_(parameter) {}
+
+  Kind const kind_;
+  size_t const parameter_;
+};
+
+
+// The type of stack frame that a FrameState node represents.
+enum class FrameStateType {
+  kJavaScriptFunction,   // Represents an unoptimized JavaScriptFrame.
+  kInterpretedFunction,  // Represents an InterpretedFrame.
+  kArgumentsAdaptor,     // Represents an ArgumentsAdaptorFrame.
+  kConstructStub         // Represents a ConstructStubFrame.
+};
+
+
+enum ContextCallingMode {
+  CALL_MAINTAINS_NATIVE_CONTEXT,
+  CALL_CHANGES_NATIVE_CONTEXT
+};
+
+
+class FrameStateFunctionInfo {
+ public:
+  FrameStateFunctionInfo(FrameStateType type, int parameter_count,
+                         int local_count,
+                         Handle<SharedFunctionInfo> shared_info,
+                         ContextCallingMode context_calling_mode)
+      : type_(type),
+        parameter_count_(parameter_count),
+        local_count_(local_count),
+        shared_info_(shared_info),
+        context_calling_mode_(context_calling_mode) {}
+
+  int local_count() const { return local_count_; }
+  int parameter_count() const { return parameter_count_; }
+  Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
+  FrameStateType type() const { return type_; }
+  ContextCallingMode context_calling_mode() const {
+    return context_calling_mode_;
+  }
+
+  static bool IsJSFunctionType(FrameStateType type) {
+    return type == FrameStateType::kJavaScriptFunction ||
+           type == FrameStateType::kInterpretedFunction;
+  }
+
+ private:
+  FrameStateType const type_;
+  int const parameter_count_;
+  int const local_count_;
+  Handle<SharedFunctionInfo> const shared_info_;
+  ContextCallingMode context_calling_mode_;
+};
+
+
+class FrameStateInfo final {
+ public:
+  FrameStateInfo(BailoutId bailout_id, OutputFrameStateCombine state_combine,
+                 const FrameStateFunctionInfo* info)
+      : bailout_id_(bailout_id),
+        frame_state_combine_(state_combine),
+        info_(info) {}
+
+  FrameStateType type() const {
+    return info_ == nullptr ? FrameStateType::kJavaScriptFunction
+                            : info_->type();
+  }
+  BailoutId bailout_id() const { return bailout_id_; }
+  OutputFrameStateCombine state_combine() const { return frame_state_combine_; }
+  MaybeHandle<SharedFunctionInfo> shared_info() const {
+    return info_ == nullptr ? MaybeHandle<SharedFunctionInfo>()
+                            : info_->shared_info();
+  }
+  int parameter_count() const {
+    return info_ == nullptr ? 0 : info_->parameter_count();
+  }
+  int local_count() const {
+    return info_ == nullptr ? 0 : info_->local_count();
+  }
+  const FrameStateFunctionInfo* function_info() const { return info_; }
+
+ private:
+  BailoutId const bailout_id_;
+  OutputFrameStateCombine const frame_state_combine_;
+  const FrameStateFunctionInfo* const info_;
+};
+
+bool operator==(FrameStateInfo const&, FrameStateInfo const&);
+bool operator!=(FrameStateInfo const&, FrameStateInfo const&);
+
+size_t hash_value(FrameStateInfo const&);
+
+std::ostream& operator<<(std::ostream&, FrameStateInfo const&);
+
+static const int kFrameStateParametersInput = 0;
+static const int kFrameStateLocalsInput = 1;
+static const int kFrameStateStackInput = 2;
+static const int kFrameStateContextInput = 3;
+static const int kFrameStateFunctionInput = 4;
+static const int kFrameStateOuterStateInput = 5;
+static const int kFrameStateInputCount = kFrameStateOuterStateInput + 1;
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_FRAME_STATES_H_
diff --git a/src/compiler/frame.cc b/src/compiler/frame.cc
new file mode 100644
index 0000000..b08030b
--- /dev/null
+++ b/src/compiler/frame.cc
@@ -0,0 +1,52 @@
+// Copyright 2015 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/frame.h"
+
+#include "src/compiler/linkage.h"
+#include "src/compiler/register-allocator.h"
+#include "src/macro-assembler.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+Frame::Frame(int fixed_frame_size_in_slots, const CallDescriptor* descriptor)
+    : needs_frame_((descriptor != nullptr) &&
+                   descriptor->RequiresFrameAsIncoming()),
+      frame_slot_count_(fixed_frame_size_in_slots),
+      callee_saved_slot_count_(0),
+      spill_slot_count_(0),
+      allocated_registers_(nullptr),
+      allocated_double_registers_(nullptr) {}
+
+
+void FrameAccessState::SetFrameAccessToDefault() {
+  if (frame()->needs_frame() && !FLAG_turbo_sp_frame_access) {
+    SetFrameAccessToFP();
+  } else {
+    SetFrameAccessToSP();
+  }
+}
+
+
+FrameOffset FrameAccessState::GetFrameOffset(int spill_slot) const {
+  const int offset =
+      (StandardFrameConstants::kFixedSlotCountAboveFp - spill_slot - 1) *
+      kPointerSize;
+  if (access_frame_with_fp()) {
+    DCHECK(frame()->needs_frame());
+    return FrameOffset::FromFramePointer(offset);
+  } else {
+    // No frame. Retrieve all parameters relative to stack pointer.
+    int sp_offset =
+        offset + ((frame()->GetSpToFpSlotCount() + sp_delta()) * kPointerSize);
+    return FrameOffset::FromStackPointer(sp_offset);
+  }
+}
+
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/frame.h b/src/compiler/frame.h
index f99d7bd..72f756b 100644
--- a/src/compiler/frame.h
+++ b/src/compiler/frame.h
@@ -5,68 +5,187 @@
 #ifndef V8_COMPILER_FRAME_H_
 #define V8_COMPILER_FRAME_H_
 
-#include "src/v8.h"
-
 #include "src/bit-vector.h"
+#include "src/frames.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
-// Collects the spill slot requirements and the allocated general and double
-// registers for a compiled function. Frames are usually populated by the
-// register allocator and are used by Linkage to generate code for the prologue
-// and epilogue to compiled code.
+class CallDescriptor;
+
+// Collects the spill slot and other frame slot requirements for a compiled
+// function. Frames are usually populated by the register allocator and are used
+// by Linkage to generate code for the prologue and epilogue to compiled
+// code. Frame objects must be considered immutable once they've been
+// instantiated and the basic information about the frame has been collected
+// into them. Mutable state associated with the frame is stored separately in
+// FrameAccessState.
+//
+// Frames are divided up into three regions.
+// - The first is the fixed header, which always has a constant size and can be
+//   predicted before code generation begins depending on the type of code being
+//   generated.
+// - The second is the region for spill slots, which is immediately below the
+//   fixed header and grows as the register allocator needs to spill to the
+//   stack and asks the frame for more space.
+// - The third region, which contains the callee-saved registers must be
+//   reserved after register allocation, since its size can only be precisely
+//   determined after register allocation once the number of used callee-saved
+//   register is certain.
+//
+// Every pointer in a frame has a slot id. On 32-bit platforms, doubles consume
+// two slots.
+//
+// Stack slot indices >= 0 access the callee stack with slot 0 corresponding to
+// the callee's saved return address and 1 corresponding to the saved frame
+// pointer. Some frames have additional information stored in the fixed header,
+// for example JSFunctions store the function context and marker in the fixed
+// header, with slot index 2 corresponding to the current function context and 3
+// corresponding to the frame marker/JSFunction. The frame region immediately
+// below the fixed header contains spill slots starting at 4 for JsFunctions.
+// The callee-saved frame region below that starts at 4+spill_slot_count_.
+// Callee stack slots corresponding to parameters are accessible through
+// negative slot ids.
+//
+// Every slot of a caller or callee frame is accessible by the register
+// allocator and gap resolver with a SpillSlotOperand containing its
+// corresponding slot id.
+//
+// Below an example JSFunction Frame with slot ids, frame regions and contents:
+//
+//  slot      JS frame
+//       +-----------------+--------------------------------
+//  -n-1 |   parameter 0   |                            ^
+//       |- - - - - - - - -|                            |
+//  -n   |                 |                          Caller
+//  ...  |       ...       |                       frame slots
+//  -2   |  parameter n-1  |                       (slot < 0)
+//       |- - - - - - - - -|                            |
+//  -1   |   parameter n   |                            v
+//  -----+-----------------+--------------------------------
+//   0   |   return addr   |   ^                        ^
+//       |- - - - - - - - -|   |                        |
+//   1   | saved frame ptr | Fixed                      |
+//       |- - - - - - - - -| Header <-- frame ptr       |
+//   2   |     Context     |   |                        |
+//       |- - - - - - - - -|   |                        |
+//   3   |JSFunction/Marker|   v                        |
+//       +-----------------+----                        |
+//   4   |    spill 1      |   ^                      Callee
+//       |- - - - - - - - -|   |                   frame slots
+//  ...  |      ...        | Spill slots           (slot >= 0)
+//       |- - - - - - - - -|   |                        |
+//  m+4  |    spill m      |   v                        |
+//       +-----------------+----                        |
+//  m+5  |  callee-saved 1 |   ^                        |
+//       |- - - - - - - - -|   |                        |
+//       |      ...        | Callee-saved               |
+//       |- - - - - - - - -|   |                        |
+// m+r+4 |  callee-saved r |   v                        v
+//  -----+-----------------+----- <-- stack ptr -------------
+//
 class Frame : public ZoneObject {
  public:
-  Frame()
-      : register_save_area_size_(0),
-        spill_slot_count_(0),
-        double_spill_slot_count_(0),
-        allocated_registers_(NULL),
-        allocated_double_registers_(NULL) {}
+  explicit Frame(int fixed_frame_size_in_slots,
+                 const CallDescriptor* descriptor);
 
-  inline int GetSpillSlotCount() { return spill_slot_count_; }
-  inline int GetDoubleSpillSlotCount() { return double_spill_slot_count_; }
+  static int FPOffsetToSlot(int frame_offset) {
+    return StandardFrameConstants::kFixedSlotCountAboveFp - 1 -
+           frame_offset / kPointerSize;
+  }
+
+  static int SlotToFPOffset(int slot) {
+    return (StandardFrameConstants::kFixedSlotCountAboveFp - 1 - slot) *
+           kPointerSize;
+  }
+
+  inline bool needs_frame() const { return needs_frame_; }
+  inline void MarkNeedsFrame() { needs_frame_ = true; }
+
+  inline int GetTotalFrameSlotCount() const { return frame_slot_count_; }
+
+  inline int GetSpToFpSlotCount() const {
+    return GetTotalFrameSlotCount() -
+           StandardFrameConstants::kFixedSlotCountAboveFp;
+  }
+  inline int GetSavedCalleeRegisterSlotCount() const {
+    return callee_saved_slot_count_;
+  }
+  inline int GetSpillSlotCount() const { return spill_slot_count_; }
+
+  inline void SetElidedFrameSizeInSlots(int slots) {
+    DCHECK_EQ(0, callee_saved_slot_count_);
+    DCHECK_EQ(0, spill_slot_count_);
+    frame_slot_count_ = slots;
+  }
 
   void SetAllocatedRegisters(BitVector* regs) {
-    DCHECK(allocated_registers_ == NULL);
+    DCHECK(allocated_registers_ == nullptr);
     allocated_registers_ = regs;
   }
 
   void SetAllocatedDoubleRegisters(BitVector* regs) {
-    DCHECK(allocated_double_registers_ == NULL);
+    DCHECK(allocated_double_registers_ == nullptr);
     allocated_double_registers_ = regs;
   }
 
-  bool DidAllocateDoubleRegisters() {
+  bool DidAllocateDoubleRegisters() const {
     return !allocated_double_registers_->IsEmpty();
   }
 
-  void SetRegisterSaveAreaSize(int size) {
-    DCHECK(IsAligned(size, kPointerSize));
-    register_save_area_size_ = size;
+  int AlignSavedCalleeRegisterSlots() {
+    DCHECK_EQ(0, callee_saved_slot_count_);
+    needs_frame_ = true;
+    int delta = frame_slot_count_ & 1;
+    frame_slot_count_ += delta;
+    return delta;
   }
 
-  int GetRegisterSaveAreaSize() { return register_save_area_size_; }
+  void AllocateSavedCalleeRegisterSlots(int count) {
+    needs_frame_ = true;
+    frame_slot_count_ += count;
+    callee_saved_slot_count_ += count;
+  }
 
-  int AllocateSpillSlot(bool is_double) {
-    // If 32-bit, skip one if the new slot is a double.
-    if (is_double) {
-      if (kDoubleSize > kPointerSize) {
-        DCHECK(kDoubleSize == kPointerSize * 2);
-        spill_slot_count_++;
-        spill_slot_count_ |= 1;
-      }
-      double_spill_slot_count_++;
+  int AllocateSpillSlot(int width) {
+    DCHECK_EQ(0, callee_saved_slot_count_);
+    needs_frame_ = true;
+    int frame_slot_count_before = frame_slot_count_;
+    int slot = AllocateAlignedFrameSlot(width);
+    spill_slot_count_ += (frame_slot_count_ - frame_slot_count_before);
+    return slot;
+  }
+
+  int ReserveSpillSlots(size_t slot_count) {
+    DCHECK_EQ(0, callee_saved_slot_count_);
+    DCHECK_EQ(0, spill_slot_count_);
+    needs_frame_ = true;
+    spill_slot_count_ += static_cast<int>(slot_count);
+    frame_slot_count_ += static_cast<int>(slot_count);
+    return frame_slot_count_ - 1;
+  }
+
+  static const int kContextSlot = 2 + StandardFrameConstants::kCPSlotCount;
+  static const int kJSFunctionSlot = 3 + StandardFrameConstants::kCPSlotCount;
+
+ private:
+  int AllocateAlignedFrameSlot(int width) {
+    DCHECK(width == 4 || width == 8);
+    // Skip one slot if necessary.
+    if (width > kPointerSize) {
+      DCHECK(width == kPointerSize * 2);
+      frame_slot_count_++;
+      frame_slot_count_ |= 1;
     }
-    return spill_slot_count_++;
+    return frame_slot_count_++;
   }
 
  private:
-  int register_save_area_size_;
+  bool needs_frame_;
+  int frame_slot_count_;
+  int callee_saved_slot_count_;
   int spill_slot_count_;
-  int double_spill_slot_count_;
   BitVector* allocated_registers_;
   BitVector* allocated_double_registers_;
 
@@ -99,8 +218,40 @@
   static const int kFromSp = 1;
   static const int kFromFp = 0;
 };
-}
-}
-}  // namespace v8::internal::compiler
+
+// Encapsulates the mutable state maintained during code generation about the
+// current function's frame.
+class FrameAccessState : public ZoneObject {
+ public:
+  explicit FrameAccessState(Frame* const frame)
+      : frame_(frame), access_frame_with_fp_(false), sp_delta_(0) {
+    SetFrameAccessToDefault();
+  }
+
+  Frame* frame() const { return frame_; }
+
+  int sp_delta() const { return sp_delta_; }
+  void ClearSPDelta() { sp_delta_ = 0; }
+  void IncreaseSPDelta(int amount) { sp_delta_ += amount; }
+
+  bool access_frame_with_fp() const { return access_frame_with_fp_; }
+  void SetFrameAccessToDefault();
+  void SetFrameAccessToFP() { access_frame_with_fp_ = true; }
+  void SetFrameAccessToSP() { access_frame_with_fp_ = false; }
+
+  // Get the frame offset for a given spill slot. The location depends on the
+  // calling convention and the specific frame layout, and may thus be
+  // architecture-specific. Negative spill slots indicate arguments on the
+  // caller's frame.
+  FrameOffset GetFrameOffset(int spill_slot) const;
+
+ private:
+  Frame* const frame_;
+  bool access_frame_with_fp_;
+  int sp_delta_;
+};
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
 
 #endif  // V8_COMPILER_FRAME_H_
diff --git a/src/compiler/gap-resolver.cc b/src/compiler/gap-resolver.cc
index f369607..4107b0f 100644
--- a/src/compiler/gap-resolver.cc
+++ b/src/compiler/gap-resolver.cc
@@ -12,49 +12,30 @@
 namespace internal {
 namespace compiler {
 
-typedef ZoneList<MoveOperands>::iterator op_iterator;
+namespace {
 
-#ifdef ENABLE_SLOW_DCHECKS
-// TODO(svenpanne) Brush up InstructionOperand with comparison?
-struct InstructionOperandComparator {
-  bool operator()(const InstructionOperand* x,
-                  const InstructionOperand* y) const {
-    return (x->kind() < y->kind()) ||
-           (x->kind() == y->kind() && x->index() < y->index());
-  }
-};
-#endif
-
-// No operand should be the destination for more than one move.
-static void VerifyMovesAreInjective(ZoneList<MoveOperands>* moves) {
-#ifdef ENABLE_SLOW_DCHECKS
-  std::set<InstructionOperand*, InstructionOperandComparator> seen;
-  for (op_iterator i = moves->begin(); i != moves->end(); ++i) {
-    SLOW_DCHECK(seen.find(i->destination()) == seen.end());
-    seen.insert(i->destination());
-  }
-#endif
+inline bool Blocks(MoveOperands* move, InstructionOperand destination) {
+  return move->Blocks(destination);
 }
 
 
-void GapResolver::Resolve(ParallelMove* parallel_move) const {
-  ZoneList<MoveOperands>* moves = parallel_move->move_operands();
-  // TODO(svenpanne) Use the member version of remove_if when we use real lists.
-  op_iterator end =
-      std::remove_if(moves->begin(), moves->end(),
-                     std::mem_fun_ref(&MoveOperands::IsRedundant));
-  moves->Rewind(static_cast<int>(end - moves->begin()));
+inline bool IsRedundant(MoveOperands* move) { return move->IsRedundant(); }
 
-  VerifyMovesAreInjective(moves);
+}  // namespace
 
-  for (op_iterator move = moves->begin(); move != moves->end(); ++move) {
-    if (!move->IsEliminated()) PerformMove(moves, &*move);
+
+void GapResolver::Resolve(ParallelMove* moves) const {
+  // Clear redundant moves.
+  auto it =
+      std::remove_if(moves->begin(), moves->end(), std::ptr_fun(IsRedundant));
+  moves->erase(it, moves->end());
+  for (auto move : *moves) {
+    if (!move->IsEliminated()) PerformMove(moves, move);
   }
 }
 
 
-void GapResolver::PerformMove(ZoneList<MoveOperands>* moves,
-                              MoveOperands* move) const {
+void GapResolver::PerformMove(ParallelMove* moves, MoveOperands* move) const {
   // Each call to this function performs a move and deletes it from the move
   // graph.  We first recursively perform any move blocking this one.  We mark a
   // move as "pending" on entry to PerformMove in order to detect cycles in the
@@ -65,14 +46,14 @@
 
   // Clear this move's destination to indicate a pending move.  The actual
   // destination is saved on the side.
-  DCHECK_NOT_NULL(move->source());  // Or else it will look eliminated.
-  InstructionOperand* destination = move->destination();
-  move->set_destination(NULL);
+  DCHECK(!move->source().IsInvalid());  // Or else it will look eliminated.
+  InstructionOperand destination = move->destination();
+  move->SetPending();
 
   // Perform a depth-first traversal of the move graph to resolve dependencies.
   // Any unperformed, unpending move with a source the same as this one's
   // destination blocks this one so recursively perform all such moves.
-  for (op_iterator other = moves->begin(); other != moves->end(); ++other) {
+  for (auto other : *moves) {
     if (other->Blocks(destination) && !other->IsPending()) {
       // Though PerformMove can change any source operand in the move graph,
       // this call cannot create a blocking move via a swap (this loop does not
@@ -93,8 +74,8 @@
 
   // This move's source may have changed due to swaps to resolve cycles and so
   // it may now be the last move in the cycle.  If so remove it.
-  InstructionOperand* source = move->source();
-  if (source->Equals(destination)) {
+  InstructionOperand source = move->source();
+  if (source.EqualsCanonicalized(destination)) {
     move->Eliminate();
     return;
   }
@@ -102,28 +83,27 @@
   // The move may be blocked on a (at most one) pending move, in which case we
   // have a cycle.  Search for such a blocking move and perform a swap to
   // resolve it.
-  op_iterator blocker = std::find_if(
-      moves->begin(), moves->end(),
-      std::bind2nd(std::mem_fun_ref(&MoveOperands::Blocks), destination));
+  auto blocker = std::find_if(moves->begin(), moves->end(),
+                              std::bind2nd(std::ptr_fun(&Blocks), destination));
   if (blocker == moves->end()) {
     // The easy case: This move is not blocked.
-    assembler_->AssembleMove(source, destination);
+    assembler_->AssembleMove(&source, &destination);
     move->Eliminate();
     return;
   }
 
-  DCHECK(blocker->IsPending());
+  DCHECK((*blocker)->IsPending());
   // Ensure source is a register or both are stack slots, to limit swap cases.
-  if (source->IsStackSlot() || source->IsDoubleStackSlot()) {
+  if (source.IsStackSlot() || source.IsDoubleStackSlot()) {
     std::swap(source, destination);
   }
-  assembler_->AssembleSwap(source, destination);
+  assembler_->AssembleSwap(&source, &destination);
   move->Eliminate();
 
   // Any unperformed (including pending) move with a source of either this
   // move's source or destination needs to have their source changed to
   // reflect the state of affairs after the swap.
-  for (op_iterator other = moves->begin(); other != moves->end(); ++other) {
+  for (auto other : *moves) {
     if (other->Blocks(source)) {
       other->set_source(destination);
     } else if (other->Blocks(destination)) {
@@ -131,6 +111,6 @@
     }
   }
 }
-}
-}
-}  // namespace v8::internal::compiler
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/gap-resolver.h b/src/compiler/gap-resolver.h
index 4f4f4e4..19806f5 100644
--- a/src/compiler/gap-resolver.h
+++ b/src/compiler/gap-resolver.h
@@ -11,7 +11,7 @@
 namespace internal {
 namespace compiler {
 
-class GapResolver FINAL {
+class GapResolver final {
  public:
   // Interface used by the gap resolver to emit moves and swaps.
   class Assembler {
@@ -34,7 +34,7 @@
  private:
   // Perform the given move, possibly requiring other moves to satisfy
   // dependencies.
-  void PerformMove(ZoneList<MoveOperands>* moves, MoveOperands* move) const;
+  void PerformMove(ParallelMove* moves, MoveOperands* move) const;
 
   // Assembler used to emit moves and save registers.
   Assembler* const assembler_;
diff --git a/src/compiler/generic-algorithm.h b/src/compiler/generic-algorithm.h
deleted file mode 100644
index 391757e..0000000
--- a/src/compiler/generic-algorithm.h
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef V8_COMPILER_GENERIC_ALGORITHM_H_
-#define V8_COMPILER_GENERIC_ALGORITHM_H_
-
-#include <stack>
-#include <vector>
-
-#include "src/compiler/graph.h"
-#include "src/compiler/node.h"
-#include "src/zone-containers.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-class Graph;
-class Node;
-
-// GenericGraphVisit allows visitation of graphs of nodes and edges in pre- and
-// post-order. Visitation uses an explicitly allocated stack rather than the
-// execution stack to avoid stack overflow.
-class GenericGraphVisit {
- public:
-  // struct Visitor {
-  //   void Pre(Node* current);
-  //   void Post(Node* current);
-  //   void PreEdge(Node* from, int index, Node* to);
-  //   void PostEdge(Node* from, int index, Node* to);
-  // }
-  template <class Visitor>
-  static void Visit(Graph* graph, Zone* zone, Node** root_begin,
-                    Node** root_end, Visitor* visitor) {
-    typedef typename Node::InputEdges::iterator Iterator;
-    typedef std::pair<Iterator, Iterator> NodeState;
-    typedef std::stack<NodeState, ZoneDeque<NodeState> > NodeStateStack;
-    NodeStateStack stack((ZoneDeque<NodeState>(zone)));
-    BoolVector visited(graph->NodeCount(), false, zone);
-    Node* current = *root_begin;
-    while (true) {
-      DCHECK(current != NULL);
-      const int id = current->id();
-      DCHECK(id >= 0);
-      DCHECK(id < graph->NodeCount());  // Must be a valid id.
-      bool visit = !GetVisited(&visited, id);
-      if (visit) {
-        visitor->Pre(current);
-        SetVisited(&visited, id);
-      }
-      Iterator begin(visit ? current->input_edges().begin()
-                           : current->input_edges().end());
-      Iterator end(current->input_edges().end());
-      stack.push(NodeState(begin, end));
-      Node* post_order_node = current;
-      while (true) {
-        NodeState top = stack.top();
-        if (top.first == top.second) {
-          if (visit) {
-            visitor->Post(post_order_node);
-            SetVisited(&visited, post_order_node->id());
-          }
-          stack.pop();
-          if (stack.empty()) {
-            if (++root_begin == root_end) return;
-            current = *root_begin;
-            break;
-          }
-          post_order_node = (*stack.top().first).from();
-          visit = true;
-        } else {
-          visitor->PreEdge((*top.first).from(), (*top.first).index(),
-                           (*top.first).to());
-          current = (*top.first).to();
-          if (!GetVisited(&visited, current->id())) break;
-        }
-        top = stack.top();
-        visitor->PostEdge((*top.first).from(), (*top.first).index(),
-                          (*top.first).to());
-        ++stack.top().first;
-      }
-    }
-  }
-
-  template <class Visitor>
-  static void Visit(Graph* graph, Zone* zone, Node* current, Visitor* visitor) {
-    Node* array[] = {current};
-    Visit<Visitor>(graph, zone, &array[0], &array[1], visitor);
-  }
-
-  struct NullNodeVisitor {
-    void Pre(Node* node) {}
-    void Post(Node* node) {}
-    void PreEdge(Node* from, int index, Node* to) {}
-    void PostEdge(Node* from, int index, Node* to) {}
-  };
-
- private:
-  static void SetVisited(BoolVector* visited, int id) {
-    if (id >= static_cast<int>(visited->size())) {
-      // Resize and set all values to unvisited.
-      visited->resize((3 * id) / 2, false);
-    }
-    visited->at(id) = true;
-  }
-
-  static bool GetVisited(BoolVector* visited, int id) {
-    if (id >= static_cast<int>(visited->size())) return false;
-    return visited->at(id);
-  }
-};
-
-typedef GenericGraphVisit::NullNodeVisitor NullNodeVisitor;
-
-}  // namespace compiler
-}  // namespace internal
-}  // namespace v8
-
-#endif  // V8_COMPILER_GENERIC_ALGORITHM_H_
diff --git a/src/compiler/graph-builder.cc b/src/compiler/graph-builder.cc
deleted file mode 100644
index 6321aaa..0000000
--- a/src/compiler/graph-builder.cc
+++ /dev/null
@@ -1,279 +0,0 @@
-// Copyright 2013 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/graph-builder.h"
-
-#include "src/bit-vector.h"
-#include "src/compiler.h"
-#include "src/compiler/graph-visualizer.h"
-#include "src/compiler/node.h"
-#include "src/compiler/node-properties.h"
-#include "src/compiler/node-properties-inl.h"
-#include "src/compiler/operator-properties.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-
-StructuredGraphBuilder::StructuredGraphBuilder(Zone* local_zone, Graph* graph,
-                                               CommonOperatorBuilder* common)
-    : GraphBuilder(graph),
-      common_(common),
-      environment_(NULL),
-      local_zone_(local_zone),
-      input_buffer_size_(0),
-      input_buffer_(NULL),
-      current_context_(NULL),
-      exit_control_(NULL) {
-  EnsureInputBufferSize(kInputBufferSizeIncrement);
-}
-
-
-Node** StructuredGraphBuilder::EnsureInputBufferSize(int size) {
-  if (size > input_buffer_size_) {
-    size += kInputBufferSizeIncrement;
-    input_buffer_ = local_zone()->NewArray<Node*>(size);
-  }
-  return input_buffer_;
-}
-
-
-Node* StructuredGraphBuilder::MakeNode(const Operator* op,
-                                       int value_input_count,
-                                       Node** value_inputs, bool incomplete) {
-  DCHECK(op->ValueInputCount() == value_input_count);
-
-  bool has_context = OperatorProperties::HasContextInput(op);
-  bool has_framestate = OperatorProperties::HasFrameStateInput(op);
-  bool has_control = op->ControlInputCount() == 1;
-  bool has_effect = op->EffectInputCount() == 1;
-
-  DCHECK(op->ControlInputCount() < 2);
-  DCHECK(op->EffectInputCount() < 2);
-
-  Node* result = NULL;
-  if (!has_context && !has_framestate && !has_control && !has_effect) {
-    result = graph()->NewNode(op, value_input_count, value_inputs, incomplete);
-  } else {
-    int input_count_with_deps = value_input_count;
-    if (has_context) ++input_count_with_deps;
-    if (has_framestate) ++input_count_with_deps;
-    if (has_control) ++input_count_with_deps;
-    if (has_effect) ++input_count_with_deps;
-    Node** buffer = EnsureInputBufferSize(input_count_with_deps);
-    memcpy(buffer, value_inputs, kPointerSize * value_input_count);
-    Node** current_input = buffer + value_input_count;
-    if (has_context) {
-      *current_input++ = current_context();
-    }
-    if (has_framestate) {
-      // The frame state will be inserted later. Here we misuse
-      // the dead_control node as a sentinel to be later overwritten
-      // with the real frame state.
-      *current_input++ = dead_control();
-    }
-    if (has_effect) {
-      *current_input++ = environment_->GetEffectDependency();
-    }
-    if (has_control) {
-      *current_input++ = environment_->GetControlDependency();
-    }
-    result = graph()->NewNode(op, input_count_with_deps, buffer, incomplete);
-    if (has_effect) {
-      environment_->UpdateEffectDependency(result);
-    }
-    if (result->op()->ControlOutputCount() > 0 &&
-        !environment()->IsMarkedAsUnreachable()) {
-      environment_->UpdateControlDependency(result);
-    }
-  }
-
-  return result;
-}
-
-
-void StructuredGraphBuilder::UpdateControlDependencyToLeaveFunction(
-    Node* exit) {
-  if (environment()->IsMarkedAsUnreachable()) return;
-  if (exit_control() != NULL) {
-    exit = MergeControl(exit_control(), exit);
-  }
-  environment()->MarkAsUnreachable();
-  set_exit_control(exit);
-}
-
-
-StructuredGraphBuilder::Environment* StructuredGraphBuilder::CopyEnvironment(
-    Environment* env) {
-  return new (local_zone()) Environment(*env);
-}
-
-
-StructuredGraphBuilder::Environment::Environment(
-    StructuredGraphBuilder* builder, Node* control_dependency)
-    : builder_(builder),
-      control_dependency_(control_dependency),
-      effect_dependency_(control_dependency),
-      values_(zone()) {}
-
-
-StructuredGraphBuilder::Environment::Environment(const Environment& copy)
-    : builder_(copy.builder()),
-      control_dependency_(copy.control_dependency_),
-      effect_dependency_(copy.effect_dependency_),
-      values_(copy.zone()) {
-  const size_t kStackEstimate = 7;  // optimum from experimentation!
-  values_.reserve(copy.values_.size() + kStackEstimate);
-  values_.insert(values_.begin(), copy.values_.begin(), copy.values_.end());
-}
-
-
-void StructuredGraphBuilder::Environment::Merge(Environment* other) {
-  DCHECK(values_.size() == other->values_.size());
-
-  // Nothing to do if the other environment is dead.
-  if (other->IsMarkedAsUnreachable()) return;
-
-  // Resurrect a dead environment by copying the contents of the other one and
-  // placing a singleton merge as the new control dependency.
-  if (this->IsMarkedAsUnreachable()) {
-    Node* other_control = other->control_dependency_;
-    Node* inputs[] = {other_control};
-    control_dependency_ =
-        graph()->NewNode(common()->Merge(1), arraysize(inputs), inputs, true);
-    effect_dependency_ = other->effect_dependency_;
-    values_ = other->values_;
-    return;
-  }
-
-  // Create a merge of the control dependencies of both environments and update
-  // the current environment's control dependency accordingly.
-  Node* control = builder_->MergeControl(this->GetControlDependency(),
-                                         other->GetControlDependency());
-  UpdateControlDependency(control);
-
-  // Create a merge of the effect dependencies of both environments and update
-  // the current environment's effect dependency accordingly.
-  Node* effect = builder_->MergeEffect(this->GetEffectDependency(),
-                                       other->GetEffectDependency(), control);
-  UpdateEffectDependency(effect);
-
-  // Introduce Phi nodes for values that have differing input at merge points,
-  // potentially extending an existing Phi node if possible.
-  for (int i = 0; i < static_cast<int>(values_.size()); ++i) {
-    values_[i] = builder_->MergeValue(values_[i], other->values_[i], control);
-  }
-}
-
-
-void StructuredGraphBuilder::Environment::PrepareForLoop(BitVector* assigned) {
-  Node* control = GetControlDependency();
-  int size = static_cast<int>(values()->size());
-  if (assigned == NULL) {
-    // Assume that everything is updated in the loop.
-    for (int i = 0; i < size; ++i) {
-      Node* phi = builder_->NewPhi(1, values()->at(i), control);
-      values()->at(i) = phi;
-    }
-  } else {
-    // Only build phis for those locals assigned in this loop.
-    for (int i = 0; i < size; ++i) {
-      if (i < assigned->length() && !assigned->Contains(i)) continue;
-      Node* phi = builder_->NewPhi(1, values()->at(i), control);
-      values()->at(i) = phi;
-    }
-  }
-  Node* effect = builder_->NewEffectPhi(1, GetEffectDependency(), control);
-  UpdateEffectDependency(effect);
-}
-
-
-Node* StructuredGraphBuilder::NewPhi(int count, Node* input, Node* control) {
-  const Operator* phi_op = common()->Phi(kMachAnyTagged, count);
-  Node** buffer = EnsureInputBufferSize(count + 1);
-  MemsetPointer(buffer, input, count);
-  buffer[count] = control;
-  return graph()->NewNode(phi_op, count + 1, buffer, true);
-}
-
-
-// TODO(mstarzinger): Revisit this once we have proper effect states.
-Node* StructuredGraphBuilder::NewEffectPhi(int count, Node* input,
-                                           Node* control) {
-  const Operator* phi_op = common()->EffectPhi(count);
-  Node** buffer = EnsureInputBufferSize(count + 1);
-  MemsetPointer(buffer, input, count);
-  buffer[count] = control;
-  return graph()->NewNode(phi_op, count + 1, buffer, true);
-}
-
-
-Node* StructuredGraphBuilder::MergeControl(Node* control, Node* other) {
-  int inputs = control->op()->ControlInputCount() + 1;
-  if (control->opcode() == IrOpcode::kLoop) {
-    // Control node for loop exists, add input.
-    const Operator* op = common()->Loop(inputs);
-    control->AppendInput(graph_zone(), other);
-    control->set_op(op);
-  } else if (control->opcode() == IrOpcode::kMerge) {
-    // Control node for merge exists, add input.
-    const Operator* op = common()->Merge(inputs);
-    control->AppendInput(graph_zone(), other);
-    control->set_op(op);
-  } else {
-    // Control node is a singleton, introduce a merge.
-    const Operator* op = common()->Merge(inputs);
-    Node* inputs[] = {control, other};
-    control = graph()->NewNode(op, arraysize(inputs), inputs, true);
-  }
-  return control;
-}
-
-
-Node* StructuredGraphBuilder::MergeEffect(Node* value, Node* other,
-                                          Node* control) {
-  int inputs = control->op()->ControlInputCount();
-  if (value->opcode() == IrOpcode::kEffectPhi &&
-      NodeProperties::GetControlInput(value) == control) {
-    // Phi already exists, add input.
-    value->set_op(common()->EffectPhi(inputs));
-    value->InsertInput(graph_zone(), inputs - 1, other);
-  } else if (value != other) {
-    // Phi does not exist yet, introduce one.
-    value = NewEffectPhi(inputs, value, control);
-    value->ReplaceInput(inputs - 1, other);
-  }
-  return value;
-}
-
-
-Node* StructuredGraphBuilder::MergeValue(Node* value, Node* other,
-                                         Node* control) {
-  int inputs = control->op()->ControlInputCount();
-  if (value->opcode() == IrOpcode::kPhi &&
-      NodeProperties::GetControlInput(value) == control) {
-    // Phi already exists, add input.
-    value->set_op(common()->Phi(kMachAnyTagged, inputs));
-    value->InsertInput(graph_zone(), inputs - 1, other);
-  } else if (value != other) {
-    // Phi does not exist yet, introduce one.
-    value = NewPhi(inputs, value, control);
-    value->ReplaceInput(inputs - 1, other);
-  }
-  return value;
-}
-
-
-Node* StructuredGraphBuilder::dead_control() {
-  if (!dead_control_.is_set()) {
-    Node* dead_node = graph()->NewNode(common_->Dead());
-    dead_control_.set(dead_node);
-    return dead_node;
-  }
-  return dead_control_.get();
-}
-}
-}
-}  // namespace v8::internal::compiler
diff --git a/src/compiler/graph-builder.h b/src/compiler/graph-builder.h
deleted file mode 100644
index d88b125..0000000
--- a/src/compiler/graph-builder.h
+++ /dev/null
@@ -1,248 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef V8_COMPILER_GRAPH_BUILDER_H_
-#define V8_COMPILER_GRAPH_BUILDER_H_
-
-#include "src/v8.h"
-
-#include "src/allocation.h"
-#include "src/compiler/common-operator.h"
-#include "src/compiler/graph.h"
-#include "src/unique.h"
-
-namespace v8 {
-namespace internal {
-
-class BitVector;
-
-namespace compiler {
-
-class Node;
-
-// A common base class for anything that creates nodes in a graph.
-class GraphBuilder {
- public:
-  explicit GraphBuilder(Graph* graph) : graph_(graph) {}
-  virtual ~GraphBuilder() {}
-
-  Node* NewNode(const Operator* op, bool incomplete = false) {
-    return MakeNode(op, 0, static_cast<Node**>(NULL), incomplete);
-  }
-
-  Node* NewNode(const Operator* op, Node* n1) {
-    return MakeNode(op, 1, &n1, false);
-  }
-
-  Node* NewNode(const Operator* op, Node* n1, Node* n2) {
-    Node* buffer[] = {n1, n2};
-    return MakeNode(op, arraysize(buffer), buffer, false);
-  }
-
-  Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3) {
-    Node* buffer[] = {n1, n2, n3};
-    return MakeNode(op, arraysize(buffer), buffer, false);
-  }
-
-  Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4) {
-    Node* buffer[] = {n1, n2, n3, n4};
-    return MakeNode(op, arraysize(buffer), buffer, false);
-  }
-
-  Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
-                Node* n5) {
-    Node* buffer[] = {n1, n2, n3, n4, n5};
-    return MakeNode(op, arraysize(buffer), buffer, false);
-  }
-
-  Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
-                Node* n5, Node* n6) {
-    Node* nodes[] = {n1, n2, n3, n4, n5, n6};
-    return MakeNode(op, arraysize(nodes), nodes, false);
-  }
-
-  Node* NewNode(const Operator* op, int value_input_count, Node** value_inputs,
-                bool incomplete = false) {
-    return MakeNode(op, value_input_count, value_inputs, incomplete);
-  }
-
-  Graph* graph() const { return graph_; }
-
- protected:
-  // Base implementation used by all factory methods.
-  virtual Node* MakeNode(const Operator* op, int value_input_count,
-                         Node** value_inputs, bool incomplete) = 0;
-
- private:
-  Graph* graph_;
-};
-
-
-// The StructuredGraphBuilder produces a high-level IR graph. It is used as the
-// base class for concrete implementations (e.g the AstGraphBuilder or the
-// StubGraphBuilder).
-class StructuredGraphBuilder : public GraphBuilder {
- public:
-  StructuredGraphBuilder(Zone* zone, Graph* graph,
-                         CommonOperatorBuilder* common);
-  ~StructuredGraphBuilder() OVERRIDE {}
-
-  // Creates a new Phi node having {count} input values.
-  Node* NewPhi(int count, Node* input, Node* control);
-  Node* NewEffectPhi(int count, Node* input, Node* control);
-
-  // Helpers for merging control, effect or value dependencies.
-  Node* MergeControl(Node* control, Node* other);
-  Node* MergeEffect(Node* value, Node* other, Node* control);
-  Node* MergeValue(Node* value, Node* other, Node* control);
-
-  // Helpers to create new control nodes.
-  Node* NewIfTrue() { return NewNode(common()->IfTrue()); }
-  Node* NewIfFalse() { return NewNode(common()->IfFalse()); }
-  Node* NewMerge() { return NewNode(common()->Merge(1), true); }
-  Node* NewLoop() { return NewNode(common()->Loop(1), true); }
-  Node* NewBranch(Node* condition, BranchHint hint = BranchHint::kNone) {
-    return NewNode(common()->Branch(hint), condition);
-  }
-
- protected:
-  class Environment;
-  friend class Environment;
-  friend class ControlBuilder;
-
-  // The following method creates a new node having the specified operator and
-  // ensures effect and control dependencies are wired up. The dependencies
-  // tracked by the environment might be mutated.
-  Node* MakeNode(const Operator* op, int value_input_count, Node** value_inputs,
-                 bool incomplete) FINAL;
-
-  Environment* environment() const { return environment_; }
-  void set_environment(Environment* env) { environment_ = env; }
-
-  Node* current_context() const { return current_context_; }
-  void set_current_context(Node* context) { current_context_ = context; }
-
-  Node* exit_control() const { return exit_control_; }
-  void set_exit_control(Node* node) { exit_control_ = node; }
-
-  Node* dead_control();
-
-  Zone* graph_zone() const { return graph()->zone(); }
-  Zone* local_zone() const { return local_zone_; }
-  Isolate* isolate() const { return graph_zone()->isolate(); }
-  CommonOperatorBuilder* common() const { return common_; }
-
-  // Helper to wrap a Handle<T> into a Unique<T>.
-  template <class T>
-  Unique<T> MakeUnique(Handle<T> object) {
-    return Unique<T>::CreateUninitialized(object);
-  }
-
-  // Support for control flow builders. The concrete type of the environment
-  // depends on the graph builder, but environments themselves are not virtual.
-  virtual Environment* CopyEnvironment(Environment* env);
-
-  // Helper to indicate a node exits the function body.
-  void UpdateControlDependencyToLeaveFunction(Node* exit);
-
- private:
-  CommonOperatorBuilder* common_;
-  Environment* environment_;
-
-  // Zone local to the builder for data not leaking into the graph.
-  Zone* local_zone_;
-
-  // Temporary storage for building node input lists.
-  int input_buffer_size_;
-  Node** input_buffer_;
-
-  // Node representing the control dependency for dead code.
-  SetOncePointer<Node> dead_control_;
-
-  // Node representing the current context within the function body.
-  Node* current_context_;
-
-  // Merge of all control nodes that exit the function body.
-  Node* exit_control_;
-
-  // Growth increment for the temporary buffer used to construct input lists to
-  // new nodes.
-  static const int kInputBufferSizeIncrement = 64;
-
-  Node** EnsureInputBufferSize(int size);
-
-  DISALLOW_COPY_AND_ASSIGN(StructuredGraphBuilder);
-};
-
-
-// The abstract execution environment contains static knowledge about
-// execution state at arbitrary control-flow points. It allows for
-// simulation of the control-flow at compile time.
-class StructuredGraphBuilder::Environment : public ZoneObject {
- public:
-  Environment(StructuredGraphBuilder* builder, Node* control_dependency);
-  Environment(const Environment& copy);
-
-  // Control dependency tracked by this environment.
-  Node* GetControlDependency() { return control_dependency_; }
-  void UpdateControlDependency(Node* dependency) {
-    control_dependency_ = dependency;
-  }
-
-  // Effect dependency tracked by this environment.
-  Node* GetEffectDependency() { return effect_dependency_; }
-  void UpdateEffectDependency(Node* dependency) {
-    effect_dependency_ = dependency;
-  }
-
-  // Mark this environment as being unreachable.
-  void MarkAsUnreachable() {
-    UpdateControlDependency(builder()->dead_control());
-  }
-  bool IsMarkedAsUnreachable() {
-    return GetControlDependency()->opcode() == IrOpcode::kDead;
-  }
-
-  // Merge another environment into this one.
-  void Merge(Environment* other);
-
-  // Copies this environment at a control-flow split point.
-  Environment* CopyForConditional() { return builder()->CopyEnvironment(this); }
-
-  // Copies this environment to a potentially unreachable control-flow point.
-  Environment* CopyAsUnreachable() {
-    Environment* env = builder()->CopyEnvironment(this);
-    env->MarkAsUnreachable();
-    return env;
-  }
-
-  // Copies this environment at a loop header control-flow point.
-  Environment* CopyForLoop(BitVector* assigned) {
-    PrepareForLoop(assigned);
-    return builder()->CopyEnvironment(this);
-  }
-
-  Node* GetContext() { return builder_->current_context(); }
-
- protected:
-  Zone* zone() const { return builder_->local_zone(); }
-  Graph* graph() const { return builder_->graph(); }
-  StructuredGraphBuilder* builder() const { return builder_; }
-  CommonOperatorBuilder* common() { return builder_->common(); }
-  NodeVector* values() { return &values_; }
-
-  // Prepare environment to be used as loop header.
-  void PrepareForLoop(BitVector* assigned);
-
- private:
-  StructuredGraphBuilder* builder_;
-  Node* control_dependency_;
-  Node* effect_dependency_;
-  NodeVector values_;
-};
-}
-}
-}  // namespace v8::internal::compiler
-
-#endif  // V8_COMPILER_GRAPH_BUILDER_H__
diff --git a/src/compiler/graph-inl.h b/src/compiler/graph-inl.h
deleted file mode 100644
index c135ae5..0000000
--- a/src/compiler/graph-inl.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef V8_COMPILER_GRAPH_INL_H_
-#define V8_COMPILER_GRAPH_INL_H_
-
-#include "src/compiler/generic-algorithm.h"
-#include "src/compiler/graph.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-template <class Visitor>
-void Graph::VisitNodeInputsFromEnd(Visitor* visitor) {
-  Zone tmp_zone(zone()->isolate());
-  GenericGraphVisit::Visit<Visitor>(this, &tmp_zone, end(), visitor);
-}
-
-}  // namespace compiler
-}  // namespace internal
-}  // namespace v8
-
-#endif  // V8_COMPILER_GRAPH_INL_H_
diff --git a/src/compiler/graph-reducer.cc b/src/compiler/graph-reducer.cc
index 9a6b121..6f583d6 100644
--- a/src/compiler/graph-reducer.cc
+++ b/src/compiler/graph-reducer.cc
@@ -2,11 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "src/compiler/graph-reducer.h"
-
 #include <functional>
+#include <limits>
 
-#include "src/compiler/graph-inl.h"
+#include "src/compiler/graph.h"
+#include "src/compiler/graph-reducer.h"
+#include "src/compiler/node.h"
+#include "src/compiler/node-properties.h"
+#include "src/compiler/verifier.h"
 
 namespace v8 {
 namespace internal {
@@ -20,14 +23,21 @@
 };
 
 
-GraphReducer::GraphReducer(Graph* graph, Zone* zone)
+void Reducer::Finalize() {}
+
+
+GraphReducer::GraphReducer(Zone* zone, Graph* graph, Node* dead)
     : graph_(graph),
+      dead_(dead),
       state_(graph, 4),
       reducers_(zone),
       revisit_(zone),
       stack_(zone) {}
 
 
+GraphReducer::~GraphReducer() {}
+
+
 void GraphReducer::AddReducer(Reducer* reducer) {
   reducers_.push_back(reducer);
 }
@@ -51,7 +61,11 @@
         Push(node);
       }
     } else {
-      break;
+      // Run all finalizers.
+      for (Reducer* const reducer : reducers_) reducer->Finalize();
+
+      // Check if we have new nodes to revisit.
+      if (revisit_.empty()) break;
     }
   }
   DCHECK(revisit_.empty());
@@ -112,8 +126,8 @@
     if (input != node && Recurse(input)) return;
   }
 
-  // Remember the node count before reduction.
-  const int node_count = graph()->NodeCount();
+  // Remember the max node id before reduction.
+  NodeId const max_id = static_cast<NodeId>(graph()->NodeCount() - 1);
 
   // All inputs should be visited or on stack. Apply reductions to node.
   Reduction reduction = Reduce(node);
@@ -135,35 +149,89 @@
   // After reducing the node, pop it off the stack.
   Pop();
 
-  // Revisit all uses of the node.
-  for (Node* const use : node->uses()) {
-    // Don't revisit this node if it refers to itself.
-    if (use != node) Revisit(use);
-  }
-
   // Check if we have a new replacement.
   if (replacement != node) {
-    if (node == graph()->start()) graph()->SetStart(replacement);
-    if (node == graph()->end()) graph()->SetEnd(replacement);
-    // If {node} was replaced by an old node, unlink {node} and assume that
-    // {replacement} was already reduced and finish.
-    if (replacement->id() < node_count) {
-      node->ReplaceUses(replacement);
-      node->Kill();
-    } else {
-      // Otherwise {node} was replaced by a new node. Replace all old uses of
-      // {node} with {replacement}. New nodes created by this reduction can
-      // use {node}.
-      node->ReplaceUsesIf(
-          [node_count](Node* const node) { return node->id() < node_count; },
-          replacement);
-      // Unlink {node} if it's no longer used.
-      if (node->uses().empty()) {
-        node->Kill();
-      }
+    Replace(node, replacement, max_id);
+  } else {
+    // Revisit all uses of the node.
+    for (Node* const user : node->uses()) {
+      // Don't revisit this node if it refers to itself.
+      if (user != node) Revisit(user);
+    }
+  }
+}
 
-      // If there was a replacement, reduce it after popping {node}.
-      Recurse(replacement);
+
+void GraphReducer::Replace(Node* node, Node* replacement) {
+  Replace(node, replacement, std::numeric_limits<NodeId>::max());
+}
+
+
+void GraphReducer::Replace(Node* node, Node* replacement, NodeId max_id) {
+  if (node == graph()->start()) graph()->SetStart(replacement);
+  if (node == graph()->end()) graph()->SetEnd(replacement);
+  if (replacement->id() <= max_id) {
+    // {replacement} is an old node, so unlink {node} and assume that
+    // {replacement} was already reduced and finish.
+    for (Edge edge : node->use_edges()) {
+      Node* const user = edge.from();
+      Verifier::VerifyEdgeInputReplacement(edge, replacement);
+      edge.UpdateTo(replacement);
+      // Don't revisit this node if it refers to itself.
+      if (user != node) Revisit(user);
+    }
+    node->Kill();
+  } else {
+    // Replace all old uses of {node} with {replacement}, but allow new nodes
+    // created by this reduction to use {node}.
+    for (Edge edge : node->use_edges()) {
+      Node* const user = edge.from();
+      if (user->id() <= max_id) {
+        edge.UpdateTo(replacement);
+        // Don't revisit this node if it refers to itself.
+        if (user != node) Revisit(user);
+      }
+    }
+    // Unlink {node} if it's no longer used.
+    if (node->uses().empty()) node->Kill();
+
+    // If there was a replacement, reduce it after popping {node}.
+    Recurse(replacement);
+  }
+}
+
+
+void GraphReducer::ReplaceWithValue(Node* node, Node* value, Node* effect,
+                                    Node* control) {
+  if (effect == nullptr && node->op()->EffectInputCount() > 0) {
+    effect = NodeProperties::GetEffectInput(node);
+  }
+  if (control == nullptr && node->op()->ControlInputCount() > 0) {
+    control = NodeProperties::GetControlInput(node);
+  }
+
+  // Requires distinguishing between value, effect and control edges.
+  for (Edge edge : node->use_edges()) {
+    Node* const user = edge.from();
+    DCHECK(!user->IsDead());
+    if (NodeProperties::IsControlEdge(edge)) {
+      if (user->opcode() == IrOpcode::kIfSuccess) {
+        Replace(user, control);
+      } else if (user->opcode() == IrOpcode::kIfException) {
+        DCHECK_NOT_NULL(dead_);
+        edge.UpdateTo(dead_);
+        Revisit(user);
+      } else {
+        UNREACHABLE();
+      }
+    } else if (NodeProperties::IsEffectEdge(edge)) {
+      DCHECK_NOT_NULL(effect);
+      edge.UpdateTo(effect);
+      Revisit(user);
+    } else {
+      DCHECK_NOT_NULL(value);
+      edge.UpdateTo(value);
+      Revisit(user);
     }
   }
 }
diff --git a/src/compiler/graph-reducer.h b/src/compiler/graph-reducer.h
index 09a650c..683c345 100644
--- a/src/compiler/graph-reducer.h
+++ b/src/compiler/graph-reducer.h
@@ -5,20 +5,30 @@
 #ifndef V8_COMPILER_GRAPH_REDUCER_H_
 #define V8_COMPILER_GRAPH_REDUCER_H_
 
-#include "src/compiler/graph.h"
+#include "src/compiler/node-marker.h"
 #include "src/zone-containers.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
+// Forward declarations.
+class Graph;
+class Node;
+
+
+// NodeIds are identifying numbers for nodes that can be used to index auxiliary
+// out-of-line data associated with each node.
+typedef uint32_t NodeId;
+
+
 // Represents the result of trying to reduce a node in the graph.
-class Reduction FINAL {
+class Reduction final {
  public:
-  explicit Reduction(Node* replacement = NULL) : replacement_(replacement) {}
+  explicit Reduction(Node* replacement = nullptr) : replacement_(replacement) {}
 
   Node* replacement() const { return replacement_; }
-  bool Changed() const { return replacement() != NULL; }
+  bool Changed() const { return replacement() != nullptr; }
 
  private:
   Node* replacement_;
@@ -32,26 +42,88 @@
 // phase.
 class Reducer {
  public:
-  Reducer() {}
   virtual ~Reducer() {}
 
   // Try to reduce a node if possible.
   virtual Reduction Reduce(Node* node) = 0;
 
+  // Invoked by the {GraphReducer} when all nodes are done.  Can be used to
+  // do additional reductions at the end, which in turn can cause a new round
+  // of reductions.
+  virtual void Finalize();
+
   // Helper functions for subclasses to produce reductions for a node.
   static Reduction NoChange() { return Reduction(); }
   static Reduction Replace(Node* node) { return Reduction(node); }
   static Reduction Changed(Node* node) { return Reduction(node); }
+};
+
+
+// An advanced reducer can also edit the graphs by changing and replacing nodes
+// other than the one currently being reduced.
+class AdvancedReducer : public Reducer {
+ public:
+  // Observe the actions of this reducer.
+  class Editor {
+   public:
+    virtual ~Editor() {}
+
+    // Replace {node} with {replacement}.
+    virtual void Replace(Node* node, Node* replacement) = 0;
+    // Revisit the {node} again later.
+    virtual void Revisit(Node* node) = 0;
+    // Replace value uses of {node} with {value} and effect uses of {node} with
+    // {effect}. If {effect == nullptr}, then use the effect input to {node}.
+    // All
+    // control uses will be relaxed assuming {node} cannot throw.
+    virtual void ReplaceWithValue(Node* node, Node* value, Node* effect,
+                                  Node* control) = 0;
+  };
+
+  explicit AdvancedReducer(Editor* editor) : editor_(editor) {}
+
+ protected:
+  // Helper functions for subclasses to produce reductions for a node.
+  static Reduction Replace(Node* node) { return Reducer::Replace(node); }
+
+  // Helper functions for subclasses to edit the graph.
+  void Replace(Node* node, Node* replacement) {
+    DCHECK_NOT_NULL(editor_);
+    editor_->Replace(node, replacement);
+  }
+  void Revisit(Node* node) {
+    DCHECK_NOT_NULL(editor_);
+    editor_->Revisit(node);
+  }
+  void ReplaceWithValue(Node* node, Node* value, Node* effect = nullptr,
+                        Node* control = nullptr) {
+    DCHECK_NOT_NULL(editor_);
+    editor_->ReplaceWithValue(node, value, effect, control);
+  }
+
+  // Relax the effects of {node} by immediately replacing effect and control
+  // uses of {node} with the effect and control input to {node}.
+  // TODO(turbofan): replace the effect input to {node} with {graph->start()}.
+  void RelaxEffectsAndControls(Node* node) {
+    ReplaceWithValue(node, node, nullptr, nullptr);
+  }
+
+  // Relax the control uses of {node} by immediately replacing them with the
+  // control input to {node}.
+  void RelaxControls(Node* node) {
+    ReplaceWithValue(node, node, node, nullptr);
+  }
 
  private:
-  DISALLOW_COPY_AND_ASSIGN(Reducer);
+  Editor* const editor_;
 };
 
 
 // Performs an iterative reduction of a node graph.
-class GraphReducer FINAL {
+class GraphReducer : public AdvancedReducer::Editor {
  public:
-  GraphReducer(Graph* graph, Zone* zone);
+  GraphReducer(Zone* zone, Graph* graph, Node* dead = nullptr);
+  ~GraphReducer();
 
   Graph* graph() const { return graph_; }
 
@@ -74,15 +146,30 @@
   // Reduce the node on top of the stack.
   void ReduceTop();
 
+  // Replace {node} with {replacement}.
+  void Replace(Node* node, Node* replacement) final;
+
+  // Replace value uses of {node} with {value} and effect uses of {node} with
+  // {effect}. If {effect == nullptr}, then use the effect input to {node}. All
+  // control uses will be relaxed assuming {node} cannot throw.
+  void ReplaceWithValue(Node* node, Node* value, Node* effect,
+                        Node* control) final;
+
+  // Replace all uses of {node} with {replacement} if the id of {replacement} is
+  // less than or equal to {max_id}. Otherwise, replace all uses of {node} whose
+  // id is less than or equal to {max_id} with the {replacement}.
+  void Replace(Node* node, Node* replacement, NodeId max_id);
+
   // Node stack operations.
   void Pop();
   void Push(Node* node);
 
   // Revisit queue operations.
   bool Recurse(Node* node);
-  void Revisit(Node* node);
+  void Revisit(Node* node) final;
 
-  Graph* graph_;
+  Graph* const graph_;
+  Node* const dead_;
   NodeMarker<State> state_;
   ZoneVector<Reducer*> reducers_;
   ZoneStack<Node*> revisit_;
diff --git a/src/compiler/graph-replay.cc b/src/compiler/graph-replay.cc
index 3a0b783..7f4cc95 100644
--- a/src/compiler/graph-replay.cc
+++ b/src/compiler/graph-replay.cc
@@ -4,9 +4,9 @@
 
 #include "src/compiler/graph-replay.h"
 
+#include "src/compiler/all-nodes.h"
 #include "src/compiler/common-operator.h"
 #include "src/compiler/graph.h"
-#include "src/compiler/graph-inl.h"
 #include "src/compiler/node.h"
 #include "src/compiler/operator.h"
 #include "src/compiler/operator-properties.h"
@@ -19,46 +19,51 @@
 
 void GraphReplayPrinter::PrintReplay(Graph* graph) {
   GraphReplayPrinter replay;
-  PrintF("  Node* nil = graph.NewNode(common_builder.Dead());\n");
-  graph->VisitNodeInputsFromEnd(&replay);
-}
+  PrintF("  Node* nil = graph()->NewNode(common()->Dead());\n");
+  Zone zone;
+  AllNodes nodes(&zone, graph);
 
-
-void GraphReplayPrinter::Pre(Node* node) {
-  PrintReplayOpCreator(node->op());
-  PrintF("  Node* n%d = graph.NewNode(op", node->id());
-  for (int i = 0; i < node->InputCount(); ++i) {
-    PrintF(", nil");
+  // Allocate the nodes first.
+  for (Node* node : nodes.live) {
+    PrintReplayOpCreator(node->op());
+    PrintF("  Node* n%d = graph()->NewNode(op", node->id());
+    for (int i = 0; i < node->InputCount(); ++i) {
+      PrintF(", nil");
+    }
+    PrintF("); USE(n%d);\n", node->id());
   }
-  PrintF("); USE(n%d);\n", node->id());
-}
 
-
-void GraphReplayPrinter::PostEdge(Node* from, int index, Node* to) {
-  PrintF("  n%d->ReplaceInput(%d, n%d);\n", from->id(), index, to->id());
+  // Connect the nodes to their inputs.
+  for (Node* node : nodes.live) {
+    for (int i = 0; i < node->InputCount(); i++) {
+      PrintF("  n%d->ReplaceInput(%d, n%d);\n", node->id(), i,
+             node->InputAt(i)->id());
+    }
+  }
 }
 
 
 void GraphReplayPrinter::PrintReplayOpCreator(const Operator* op) {
   IrOpcode::Value opcode = static_cast<IrOpcode::Value>(op->opcode());
-  const char* builder =
-      IrOpcode::IsCommonOpcode(opcode) ? "common_builder" : "js_builder";
+  const char* builder = IrOpcode::IsCommonOpcode(opcode) ? "common" : "js";
   const char* mnemonic = IrOpcode::IsCommonOpcode(opcode)
                              ? IrOpcode::Mnemonic(opcode)
                              : IrOpcode::Mnemonic(opcode) + 2;
-  PrintF("  op = %s.%s(", builder, mnemonic);
+  PrintF("  op = %s()->%s(", builder, mnemonic);
   switch (opcode) {
     case IrOpcode::kParameter:
-    case IrOpcode::kNumberConstant:
-      PrintF("0");
+      PrintF("%d", ParameterIndexOf(op));
       break;
-    case IrOpcode::kLoad:
-      PrintF("unique_name");
+    case IrOpcode::kNumberConstant:
+      PrintF("%g", OpParameter<double>(op));
       break;
     case IrOpcode::kHeapConstant:
       PrintF("unique_constant");
       break;
     case IrOpcode::kPhi:
+      PrintF("kMachAnyTagged, %d", op->ValueInputCount());
+      break;
+    case IrOpcode::kStateValues:
       PrintF("%d", op->ValueInputCount());
       break;
     case IrOpcode::kEffectPhi:
@@ -68,6 +73,12 @@
     case IrOpcode::kMerge:
       PrintF("%d", op->ControlInputCount());
       break;
+    case IrOpcode::kStart:
+      PrintF("%d", op->ValueOutputCount() - 3);
+      break;
+    case IrOpcode::kFrameState:
+      PrintF("JS_FRAME, BailoutId(-1), OutputFrameStateCombine::Ignore()");
+      break;
     default:
       break;
   }
@@ -75,6 +86,7 @@
 }
 
 #endif  // DEBUG
-}
-}
-}  // namespace v8::internal::compiler
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/graph-replay.h b/src/compiler/graph-replay.h
index f41311e..be89ebd 100644
--- a/src/compiler/graph-replay.h
+++ b/src/compiler/graph-replay.h
@@ -5,7 +5,6 @@
 #ifndef V8_COMPILER_GRAPH_REPLAY_H_
 #define V8_COMPILER_GRAPH_REPLAY_H_
 
-#include "src/compiler/generic-algorithm.h"
 #include "src/compiler/node.h"
 
 namespace v8 {
@@ -18,7 +17,7 @@
 // Helper class to print a full replay of a graph. This replay can be used to
 // materialize the same graph within a C++ unit test and hence test subsequent
 // optimization passes on a graph without going through the construction steps.
-class GraphReplayPrinter FINAL : public NullNodeVisitor {
+class GraphReplayPrinter {
  public:
 #ifdef DEBUG
   static void PrintReplay(Graph* graph);
@@ -26,9 +25,6 @@
   static void PrintReplay(Graph* graph) {}
 #endif
 
-  void Pre(Node* node);
-  void PostEdge(Node* from, int index, Node* to);
-
  private:
   GraphReplayPrinter() {}
 
diff --git a/src/compiler/graph-trimmer.cc b/src/compiler/graph-trimmer.cc
new file mode 100644
index 0000000..5fae425
--- /dev/null
+++ b/src/compiler/graph-trimmer.cc
@@ -0,0 +1,48 @@
+// Copyright 2015 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/graph-trimmer.h"
+
+#include "src/compiler/graph.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+GraphTrimmer::GraphTrimmer(Zone* zone, Graph* graph)
+    : graph_(graph), is_live_(graph, 2), live_(zone) {
+  live_.reserve(graph->NodeCount());
+}
+
+
+GraphTrimmer::~GraphTrimmer() {}
+
+
+void GraphTrimmer::TrimGraph() {
+  // Mark end node as live.
+  MarkAsLive(graph()->end());
+  // Compute transitive closure of live nodes.
+  for (size_t i = 0; i < live_.size(); ++i) {
+    for (Node* const input : live_[i]->inputs()) MarkAsLive(input);
+  }
+  // Remove dead->live edges.
+  for (Node* const live : live_) {
+    DCHECK(IsLive(live));
+    for (Edge edge : live->use_edges()) {
+      Node* const user = edge.from();
+      if (!IsLive(user)) {
+        if (FLAG_trace_turbo_reduction) {
+          OFStream os(stdout);
+          os << "DeadLink: " << *user << "(" << edge.index() << ") -> " << *live
+             << std::endl;
+        }
+        edge.UpdateTo(nullptr);
+      }
+    }
+  }
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/graph-trimmer.h b/src/compiler/graph-trimmer.h
new file mode 100644
index 0000000..d8258be
--- /dev/null
+++ b/src/compiler/graph-trimmer.h
@@ -0,0 +1,57 @@
+// Copyright 2015 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.
+
+#ifndef V8_COMPILER_GRAPH_TRIMMER_H_
+#define V8_COMPILER_GRAPH_TRIMMER_H_
+
+#include "src/compiler/node-marker.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+// Forward declarations.
+class Graph;
+
+
+// Trims dead nodes from the node graph.
+class GraphTrimmer final {
+ public:
+  GraphTrimmer(Zone* zone, Graph* graph);
+  ~GraphTrimmer();
+
+  // Trim nodes in the {graph} that are not reachable from {graph->end()}.
+  void TrimGraph();
+
+  // Trim nodes in the {graph} that are not reachable from either {graph->end()}
+  // or any of the roots in the sequence [{begin},{end}[.
+  template <typename ForwardIterator>
+  void TrimGraph(ForwardIterator begin, ForwardIterator end) {
+    while (begin != end) MarkAsLive(*begin++);
+    TrimGraph();
+  }
+
+ private:
+  V8_INLINE bool IsLive(Node* const node) { return is_live_.Get(node); }
+  V8_INLINE void MarkAsLive(Node* const node) {
+    if (!node->IsDead() && !IsLive(node)) {
+      is_live_.Set(node, true);
+      live_.push_back(node);
+    }
+  }
+
+  Graph* graph() const { return graph_; }
+
+  Graph* const graph_;
+  NodeMarker<bool> is_live_;
+  NodeVector live_;
+
+  DISALLOW_COPY_AND_ASSIGN(GraphTrimmer);
+};
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_GRAPH_TRIMMER_H_
diff --git a/src/compiler/graph-visualizer.cc b/src/compiler/graph-visualizer.cc
index e018c7a..0785176 100644
--- a/src/compiler/graph-visualizer.cc
+++ b/src/compiler/graph-visualizer.cc
@@ -8,80 +8,55 @@
 #include <string>
 
 #include "src/code-stubs.h"
+#include "src/compiler/all-nodes.h"
 #include "src/compiler/graph.h"
-#include "src/compiler/graph-inl.h"
 #include "src/compiler/node.h"
 #include "src/compiler/node-properties.h"
-#include "src/compiler/node-properties-inl.h"
 #include "src/compiler/opcodes.h"
 #include "src/compiler/operator.h"
+#include "src/compiler/operator-properties.h"
 #include "src/compiler/register-allocator.h"
 #include "src/compiler/schedule.h"
 #include "src/compiler/scheduler.h"
+#include "src/interpreter/bytecodes.h"
 #include "src/ostreams.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
-static int SafeId(Node* node) { return node == NULL ? -1 : node->id(); }
+
+FILE* OpenVisualizerLogFile(CompilationInfo* info, const char* phase,
+                            const char* suffix, const char* mode) {
+  EmbeddedVector<char, 256> filename(0);
+  base::SmartArrayPointer<char> debug_name = info->GetDebugName();
+  if (strlen(debug_name.get()) > 0) {
+    SNPrintF(filename, "turbo-%s", debug_name.get());
+  } else if (info->has_shared_info()) {
+    SNPrintF(filename, "turbo-%p", static_cast<void*>(info));
+  } else {
+    SNPrintF(filename, "turbo-none-%s", phase);
+  }
+  std::replace(filename.start(), filename.start() + filename.length(), ' ',
+               '_');
+
+  EmbeddedVector<char, 256> full_filename;
+  if (phase == nullptr) {
+    SNPrintF(full_filename, "%s.%s", filename.start(), suffix);
+  } else {
+    SNPrintF(full_filename, "%s-%s.%s", filename.start(), phase, suffix);
+  }
+  return base::OS::FOpen(full_filename.start(), mode);
+}
+
+
+static int SafeId(Node* node) { return node == nullptr ? -1 : node->id(); }
 static const char* SafeMnemonic(Node* node) {
-  return node == NULL ? "null" : node->op()->mnemonic();
+  return node == nullptr ? "null" : node->op()->mnemonic();
 }
 
 #define DEAD_COLOR "#999999"
 
-class AllNodes {
- public:
-  enum State { kDead, kGray, kLive };
-
-  AllNodes(Zone* local_zone, const Graph* graph)
-      : state(graph->NodeCount(), kDead, local_zone),
-        live(local_zone),
-        gray(local_zone) {
-    Node* end = graph->end();
-    state[end->id()] = kLive;
-    live.push_back(end);
-    // Find all live nodes reachable from end.
-    for (size_t i = 0; i < live.size(); i++) {
-      for (Node* const input : live[i]->inputs()) {
-        if (input == NULL) {
-          // TODO(titzer): print a warning.
-          continue;
-        }
-        if (input->id() >= graph->NodeCount()) {
-          // TODO(titzer): print a warning.
-          continue;
-        }
-        if (state[input->id()] != kLive) {
-          live.push_back(input);
-          state[input->id()] = kLive;
-        }
-      }
-    }
-
-    // Find all nodes that are not reachable from end that use live nodes.
-    for (size_t i = 0; i < live.size(); i++) {
-      for (Node* const use : live[i]->uses()) {
-        if (state[use->id()] == kDead) {
-          gray.push_back(use);
-          state[use->id()] = kGray;
-        }
-      }
-    }
-  }
-
-  bool IsLive(Node* node) {
-    return node != NULL && node->id() < static_cast<int>(state.size()) &&
-           state[node->id()] == kLive;
-  }
-
-  ZoneVector<State> state;
-  NodeVector live;
-  NodeVector gray;
-};
-
-
 class Escaped {
  public:
   explicit Escaped(const std::ostringstream& os,
@@ -111,25 +86,27 @@
 
 class JSONGraphNodeWriter {
  public:
-  JSONGraphNodeWriter(std::ostream& os, Zone* zone, const Graph* graph)
-      : os_(os), all_(zone, graph), first_node_(true) {}
+  JSONGraphNodeWriter(std::ostream& os, Zone* zone, const Graph* graph,
+                      const SourcePositionTable* positions)
+      : os_(os), all_(zone, graph), positions_(positions), first_node_(true) {}
 
   void Print() {
     for (Node* const node : all_.live) PrintNode(node);
+    os_ << "\n";
   }
 
   void PrintNode(Node* node) {
     if (first_node_) {
       first_node_ = false;
     } else {
-      os_ << ",";
+      os_ << ",\n";
     }
     std::ostringstream label;
     label << *node->op();
     os_ << "{\"id\":" << SafeId(node) << ",\"label\":\"" << Escaped(label, "\"")
         << "\"";
     IrOpcode::Value opcode = node->opcode();
-    if (opcode == IrOpcode::kPhi || opcode == IrOpcode::kEffectPhi) {
+    if (IrOpcode::IsPhiOpcode(opcode)) {
       os_ << ",\"rankInputs\":[0," << NodeProperties::FirstControlIndex(node)
           << "]";
       os_ << ",\"rankWithInput\":[" << NodeProperties::FirstControlIndex(node)
@@ -142,15 +119,26 @@
     if (opcode == IrOpcode::kBranch) {
       os_ << ",\"rankInputs\":[0]";
     }
+    SourcePosition position = positions_->GetSourcePosition(node);
+    if (position.IsKnown()) {
+      os_ << ",\"pos\":" << position.raw();
+    }
     os_ << ",\"opcode\":\"" << IrOpcode::Mnemonic(node->opcode()) << "\"";
     os_ << ",\"control\":" << (NodeProperties::IsControl(node) ? "true"
                                                                : "false");
+    if (NodeProperties::IsTyped(node)) {
+      Type* type = NodeProperties::GetType(node);
+      std::ostringstream type_out;
+      type->PrintTo(type_out);
+      os_ << ",\"type\":\"" << Escaped(type_out, "\"") << "\"";
+    }
     os_ << "}";
   }
 
  private:
   std::ostream& os_;
   AllNodes all_;
+  const SourcePositionTable* positions_;
   bool first_node_;
 
   DISALLOW_COPY_AND_ASSIGN(JSONGraphNodeWriter);
@@ -164,12 +152,13 @@
 
   void Print() {
     for (Node* const node : all_.live) PrintEdges(node);
+    os_ << "\n";
   }
 
   void PrintEdges(Node* node) {
     for (int i = 0; i < node->InputCount(); i++) {
       Node* input = node->InputAt(i);
-      if (input == NULL) continue;
+      if (input == nullptr) continue;
       PrintEdge(node, i, input);
     }
   }
@@ -178,9 +167,9 @@
     if (first_edge_) {
       first_edge_ = false;
     } else {
-      os_ << ",";
+      os_ << ",\n";
     }
-    const char* edge_type = NULL;
+    const char* edge_type = nullptr;
     if (index < NodeProperties::FirstValueIndex(from)) {
       edge_type = "unknown";
     } else if (index < NodeProperties::FirstContextIndex(from)) {
@@ -208,195 +197,16 @@
 
 
 std::ostream& operator<<(std::ostream& os, const AsJSON& ad) {
-  Zone tmp_zone(ad.graph.zone()->isolate());
-  os << "{\"nodes\":[";
-  JSONGraphNodeWriter(os, &tmp_zone, &ad.graph).Print();
-  os << "],\"edges\":[";
+  Zone tmp_zone;
+  os << "{\n\"nodes\":[";
+  JSONGraphNodeWriter(os, &tmp_zone, &ad.graph, ad.positions).Print();
+  os << "],\n\"edges\":[";
   JSONGraphEdgeWriter(os, &tmp_zone, &ad.graph).Print();
   os << "]}";
   return os;
 }
 
 
-class GraphVisualizer {
- public:
-  GraphVisualizer(std::ostream& os, Zone* zone, const Graph* graph)
-      : all_(zone, graph), os_(os) {}
-
-  void Print();
-
-  void PrintNode(Node* node, bool gray);
-
- private:
-  void PrintEdge(Edge edge);
-
-  AllNodes all_;
-  std::ostream& os_;
-
-  DISALLOW_COPY_AND_ASSIGN(GraphVisualizer);
-};
-
-
-static Node* GetControlCluster(Node* node) {
-  if (OperatorProperties::IsBasicBlockBegin(node->op())) {
-    return node;
-  } else if (node->op()->ControlInputCount() == 1) {
-    Node* control = NodeProperties::GetControlInput(node, 0);
-    return control != NULL &&
-                   OperatorProperties::IsBasicBlockBegin(control->op())
-               ? control
-               : NULL;
-  } else {
-    return NULL;
-  }
-}
-
-
-void GraphVisualizer::PrintNode(Node* node, bool gray) {
-  Node* control_cluster = GetControlCluster(node);
-  if (control_cluster != NULL) {
-    os_ << "  subgraph cluster_BasicBlock" << control_cluster->id() << " {\n";
-  }
-  os_ << "  ID" << SafeId(node) << " [\n";
-
-  os_ << "    shape=\"record\"\n";
-  switch (node->opcode()) {
-    case IrOpcode::kEnd:
-    case IrOpcode::kDead:
-    case IrOpcode::kStart:
-      os_ << "    style=\"diagonals\"\n";
-      break;
-    case IrOpcode::kMerge:
-    case IrOpcode::kIfTrue:
-    case IrOpcode::kIfFalse:
-    case IrOpcode::kLoop:
-      os_ << "    style=\"rounded\"\n";
-      break;
-    default:
-      break;
-  }
-
-  if (gray) {
-    os_ << "    style=\"filled\"\n"
-        << "    fillcolor=\"" DEAD_COLOR "\"\n";
-  }
-
-  std::ostringstream label;
-  label << *node->op();
-  os_ << "    label=\"{{#" << SafeId(node) << ":" << Escaped(label);
-
-  auto i = node->input_edges().begin();
-  for (int j = node->op()->ValueInputCount(); j > 0; ++i, j--) {
-    os_ << "|<I" << (*i).index() << ">#" << SafeId((*i).to());
-  }
-  for (int j = OperatorProperties::GetContextInputCount(node->op()); j > 0;
-       ++i, j--) {
-    os_ << "|<I" << (*i).index() << ">X #" << SafeId((*i).to());
-  }
-  for (int j = OperatorProperties::GetFrameStateInputCount(node->op()); j > 0;
-       ++i, j--) {
-    os_ << "|<I" << (*i).index() << ">F #" << SafeId((*i).to());
-  }
-  for (int j = node->op()->EffectInputCount(); j > 0; ++i, j--) {
-    os_ << "|<I" << (*i).index() << ">E #" << SafeId((*i).to());
-  }
-
-  if (OperatorProperties::IsBasicBlockBegin(node->op()) ||
-      GetControlCluster(node) == NULL) {
-    for (int j = node->op()->ControlInputCount(); j > 0; ++i, j--) {
-      os_ << "|<I" << (*i).index() << ">C #" << SafeId((*i).to());
-    }
-  }
-  os_ << "}";
-
-  if (FLAG_trace_turbo_types && NodeProperties::IsTyped(node)) {
-    Bounds bounds = NodeProperties::GetBounds(node);
-    std::ostringstream upper;
-    bounds.upper->PrintTo(upper);
-    std::ostringstream lower;
-    bounds.lower->PrintTo(lower);
-    os_ << "|" << Escaped(upper) << "|" << Escaped(lower);
-  }
-  os_ << "}\"\n";
-
-  os_ << "  ]\n";
-  if (control_cluster != NULL) os_ << "  }\n";
-}
-
-
-static bool IsLikelyBackEdge(Node* from, int index, Node* to) {
-  if (from->opcode() == IrOpcode::kPhi ||
-      from->opcode() == IrOpcode::kEffectPhi) {
-    Node* control = NodeProperties::GetControlInput(from, 0);
-    return control != NULL && control->opcode() != IrOpcode::kMerge &&
-           control != to && index != 0;
-  } else if (from->opcode() == IrOpcode::kLoop) {
-    return index != 0;
-  } else {
-    return false;
-  }
-}
-
-
-void GraphVisualizer::PrintEdge(Edge edge) {
-  Node* from = edge.from();
-  int index = edge.index();
-  Node* to = edge.to();
-
-  if (!all_.IsLive(to)) return;  // skip inputs that point to dead or NULL.
-
-  bool unconstrained = IsLikelyBackEdge(from, index, to);
-  os_ << "  ID" << SafeId(from);
-
-  if (OperatorProperties::IsBasicBlockBegin(from->op()) ||
-      GetControlCluster(from) == NULL ||
-      (from->op()->ControlInputCount() > 0 &&
-       NodeProperties::GetControlInput(from) != to)) {
-    os_ << ":I" << index << ":n -> ID" << SafeId(to) << ":s"
-        << "[" << (unconstrained ? "constraint=false, " : "")
-        << (NodeProperties::IsControlEdge(edge) ? "style=bold, " : "")
-        << (NodeProperties::IsEffectEdge(edge) ? "style=dotted, " : "")
-        << (NodeProperties::IsContextEdge(edge) ? "style=dashed, " : "") << "]";
-  } else {
-    os_ << " -> ID" << SafeId(to) << ":s [color=transparent, "
-        << (unconstrained ? "constraint=false, " : "")
-        << (NodeProperties::IsControlEdge(edge) ? "style=dashed, " : "") << "]";
-  }
-  os_ << "\n";
-}
-
-
-void GraphVisualizer::Print() {
-  os_ << "digraph D {\n"
-      << "  node [fontsize=8,height=0.25]\n"
-      << "  rankdir=\"BT\"\n"
-      << "  ranksep=\"1.2 equally\"\n"
-      << "  overlap=\"false\"\n"
-      << "  splines=\"true\"\n"
-      << "  concentrate=\"true\"\n"
-      << "  \n";
-
-  // Make sure all nodes have been output before writing out the edges.
-  for (Node* const node : all_.live) PrintNode(node, false);
-  for (Node* const node : all_.gray) PrintNode(node, true);
-
-  // With all the nodes written, add the edges.
-  for (Node* const node : all_.live) {
-    for (Edge edge : node->use_edges()) {
-      PrintEdge(edge);
-    }
-  }
-  os_ << "}\n";
-}
-
-
-std::ostream& operator<<(std::ostream& os, const AsDOT& ad) {
-  Zone tmp_zone(ad.graph.zone()->isolate());
-  GraphVisualizer(os, &tmp_zone, &ad.graph).Print();
-  return os;
-}
-
-
 class GraphC1Visualizer {
  public:
   GraphC1Visualizer(std::ostream& os, Zone* zone);  // NOLINT
@@ -405,7 +215,7 @@
   void PrintSchedule(const char* phase, const Schedule* schedule,
                      const SourcePositionTable* positions,
                      const InstructionSequence* instructions);
-  void PrintAllocator(const char* phase, const RegisterAllocator* allocator);
+  void PrintLiveRanges(const char* phase, const RegisterAllocationData* data);
   Zone* zone() const { return zone_; }
 
  private:
@@ -413,15 +223,18 @@
   void PrintStringProperty(const char* name, const char* value);
   void PrintLongProperty(const char* name, int64_t value);
   void PrintIntProperty(const char* name, int value);
-  void PrintBlockProperty(const char* name, BasicBlock::Id block_id);
+  void PrintBlockProperty(const char* name, int rpo_number);
   void PrintNodeId(Node* n);
   void PrintNode(Node* n);
   void PrintInputs(Node* n);
-  void PrintInputs(InputIter* i, int count, const char* prefix);
+  template <typename InputIterator>
+  void PrintInputs(InputIterator* i, int count, const char* prefix);
   void PrintType(Node* node);
 
-  void PrintLiveRange(LiveRange* range, const char* type);
-  class Tag FINAL BASE_EMBEDDED {
+  void PrintLiveRange(LiveRange* range, const char* type, int vreg);
+  void PrintLiveRangeChain(TopLevelLiveRange* range, const char* type);
+
+  class Tag final BASE_EMBEDDED {
    public:
     Tag(GraphC1Visualizer* visualizer, const char* name) {
       name_ = name;
@@ -475,10 +288,9 @@
 }
 
 
-void GraphC1Visualizer::PrintBlockProperty(const char* name,
-                                           BasicBlock::Id block_id) {
+void GraphC1Visualizer::PrintBlockProperty(const char* name, int rpo_number) {
   PrintIndent();
-  os_ << name << " \"B" << block_id << "\"\n";
+  os_ << name << " \"B" << rpo_number << "\"\n";
 }
 
 
@@ -490,15 +302,14 @@
 
 void GraphC1Visualizer::PrintCompilation(const CompilationInfo* info) {
   Tag tag(this, "compilation");
+  base::SmartArrayPointer<char> name = info->GetDebugName();
   if (info->IsOptimizing()) {
-    Handle<String> name = info->function()->debug_name();
-    PrintStringProperty("name", name->ToCString().get());
+    PrintStringProperty("name", name.get());
     PrintIndent();
-    os_ << "method \"" << name->ToCString().get() << ":"
-        << info->optimization_id() << "\"\n";
+    os_ << "method \"" << name.get() << ":" << info->optimization_id()
+        << "\"\n";
   } else {
-    CodeStub::Major major_key = info->code_stub()->MajorKey();
-    PrintStringProperty("name", CodeStub::MajorName(major_key, false));
+    PrintStringProperty("name", name.get());
     PrintStringProperty("method", "stub");
   }
   PrintLongProperty("date",
@@ -516,7 +327,8 @@
 }
 
 
-void GraphC1Visualizer::PrintInputs(InputIter* i, int count,
+template <typename InputIterator>
+void GraphC1Visualizer::PrintInputs(InputIterator* i, int count,
                                     const char* prefix) {
   if (count > 0) {
     os_ << prefix;
@@ -544,11 +356,9 @@
 
 void GraphC1Visualizer::PrintType(Node* node) {
   if (NodeProperties::IsTyped(node)) {
-    Bounds bounds = NodeProperties::GetBounds(node);
+    Type* type = NodeProperties::GetType(node);
     os_ << " type:";
-    bounds.upper->PrintTo(os_);
-    os_ << "..";
-    bounds.lower->PrintTo(os_);
+    type->PrintTo(os_);
   }
 }
 
@@ -563,23 +373,21 @@
   for (size_t i = 0; i < rpo->size(); i++) {
     BasicBlock* current = (*rpo)[i];
     Tag block_tag(this, "block");
-    PrintBlockProperty("name", current->id());
+    PrintBlockProperty("name", current->rpo_number());
     PrintIntProperty("from_bci", -1);
     PrintIntProperty("to_bci", -1);
 
     PrintIndent();
     os_ << "predecessors";
-    for (BasicBlock::Predecessors::iterator j = current->predecessors_begin();
-         j != current->predecessors_end(); ++j) {
-      os_ << " \"B" << (*j)->id() << "\"";
+    for (BasicBlock* predecessor : current->predecessors()) {
+      os_ << " \"B" << predecessor->rpo_number() << "\"";
     }
     os_ << "\n";
 
     PrintIndent();
     os_ << "successors";
-    for (BasicBlock::Successors::iterator j = current->successors_begin();
-         j != current->successors_end(); ++j) {
-      os_ << " \"B" << (*j)->id() << "\"";
+    for (BasicBlock* successor : current->successors()) {
+      os_ << " \"B" << successor->rpo_number() << "\"";
     }
     os_ << "\n";
 
@@ -589,21 +397,24 @@
     PrintIndent();
     os_ << "flags\n";
 
-    if (current->dominator() != NULL) {
-      PrintBlockProperty("dominator", current->dominator()->id());
+    if (current->dominator() != nullptr) {
+      PrintBlockProperty("dominator", current->dominator()->rpo_number());
     }
 
     PrintIntProperty("loop_depth", current->loop_depth());
 
     const InstructionBlock* instruction_block =
-        instructions->InstructionBlockAt(current->GetRpoNumber());
+        instructions->InstructionBlockAt(
+            RpoNumber::FromInt(current->rpo_number()));
     if (instruction_block->code_start() >= 0) {
       int first_index = instruction_block->first_instruction_index();
       int last_index = instruction_block->last_instruction_index();
-      PrintIntProperty("first_lir_id", LifetimePosition::FromInstructionIndex(
-                                           first_index).Value());
-      PrintIntProperty("last_lir_id", LifetimePosition::FromInstructionIndex(
-                                          last_index).Value());
+      PrintIntProperty(
+          "first_lir_id",
+          LifetimePosition::GapFromInstructionIndex(first_index).value());
+      PrintIntProperty("last_lir_id",
+                       LifetimePosition::InstructionFromInstructionIndex(
+                           last_index).value());
     }
 
     {
@@ -644,10 +455,9 @@
           os_ << " ";
           PrintType(node);
         }
-        if (positions != NULL) {
+        if (positions != nullptr) {
           SourcePosition position = positions->GetSourcePosition(node);
-          if (!position.IsUnknown()) {
-            DCHECK(!position.IsInvalid());
+          if (position.IsKnown()) {
             os_ << " pos:" << position.raw();
           }
         }
@@ -658,17 +468,16 @@
       if (control != BasicBlock::kNone) {
         PrintIndent();
         os_ << "0 0 ";
-        if (current->control_input() != NULL) {
+        if (current->control_input() != nullptr) {
           PrintNode(current->control_input());
         } else {
-          os_ << -1 - current->id().ToInt() << " Goto";
+          os_ << -1 - current->rpo_number() << " Goto";
         }
         os_ << " ->";
-        for (BasicBlock::Successors::iterator j = current->successors_begin();
-             j != current->successors_end(); ++j) {
-          os_ << " B" << (*j)->id();
+        for (BasicBlock* successor : current->successors()) {
+          os_ << " B" << successor->rpo_number();
         }
-        if (FLAG_trace_turbo_types && current->control_input() != NULL) {
+        if (FLAG_trace_turbo_types && current->control_input() != nullptr) {
           os_ << " ";
           PrintType(current->control_input());
         }
@@ -676,13 +485,14 @@
       }
     }
 
-    if (instructions != NULL) {
+    if (instructions != nullptr) {
       Tag LIR_tag(this, "LIR");
       for (int j = instruction_block->first_instruction_index();
            j <= instruction_block->last_instruction_index(); j++) {
         PrintIndent();
-        PrintableInstruction printable = {RegisterConfiguration::ArchDefault(),
-                                          instructions->InstructionAt(j)};
+        PrintableInstruction printable = {
+            RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN),
+            instructions->InstructionAt(j)};
         os_ << j << " " << printable << " <|@\n";
       }
     }
@@ -690,77 +500,80 @@
 }
 
 
-void GraphC1Visualizer::PrintAllocator(const char* phase,
-                                       const RegisterAllocator* allocator) {
+void GraphC1Visualizer::PrintLiveRanges(const char* phase,
+                                        const RegisterAllocationData* data) {
   Tag tag(this, "intervals");
   PrintStringProperty("name", phase);
 
-  for (auto range : allocator->fixed_double_live_ranges()) {
-    PrintLiveRange(range, "fixed");
+  for (auto range : data->fixed_double_live_ranges()) {
+    PrintLiveRangeChain(range, "fixed");
   }
 
-  for (auto range : allocator->fixed_live_ranges()) {
-    PrintLiveRange(range, "fixed");
+  for (auto range : data->fixed_live_ranges()) {
+    PrintLiveRangeChain(range, "fixed");
   }
 
-  for (auto range : allocator->live_ranges()) {
-    PrintLiveRange(range, "object");
+  for (auto range : data->live_ranges()) {
+    PrintLiveRangeChain(range, "object");
   }
 }
 
 
-void GraphC1Visualizer::PrintLiveRange(LiveRange* range, const char* type) {
-  if (range != NULL && !range->IsEmpty()) {
+void GraphC1Visualizer::PrintLiveRangeChain(TopLevelLiveRange* range,
+                                            const char* type) {
+  if (range == nullptr || range->IsEmpty()) return;
+  int vreg = range->vreg();
+  for (LiveRange* child = range; child != nullptr; child = child->next()) {
+    PrintLiveRange(child, type, vreg);
+  }
+}
+
+
+void GraphC1Visualizer::PrintLiveRange(LiveRange* range, const char* type,
+                                       int vreg) {
+  if (range != nullptr && !range->IsEmpty()) {
     PrintIndent();
-    os_ << range->id() << " " << type;
+    os_ << vreg << ":" << range->relative_id() << " " << type;
     if (range->HasRegisterAssigned()) {
-      InstructionOperand* op = range->CreateAssignedOperand(zone());
-      int assigned_reg = op->index();
-      if (op->IsDoubleRegister()) {
-        os_ << " \"" << DoubleRegister::AllocationIndexToString(assigned_reg)
+      AllocatedOperand op = AllocatedOperand::cast(range->GetAssignedOperand());
+      if (op.IsDoubleRegister()) {
+        DoubleRegister assigned_reg = op.GetDoubleRegister();
+        os_ << " \"" << assigned_reg.ToString() << "\"";
+      } else {
+        DCHECK(op.IsRegister());
+        Register assigned_reg = op.GetRegister();
+        os_ << " \"" << assigned_reg.ToString() << "\"";
+      }
+    } else if (range->spilled()) {
+      auto top = range->TopLevel();
+      int index = -1;
+      if (top->HasSpillRange()) {
+        index = kMaxInt;  // This hasn't been set yet.
+      } else if (top->GetSpillOperand()->IsConstant()) {
+        os_ << " \"const(nostack):"
+            << ConstantOperand::cast(top->GetSpillOperand())->virtual_register()
             << "\"";
       } else {
-        DCHECK(op->IsRegister());
-        os_ << " \"" << Register::AllocationIndexToString(assigned_reg) << "\"";
-      }
-    } else if (range->IsSpilled()) {
-      int index = -1;
-      if (range->TopLevel()->HasSpillRange()) {
-        index = kMaxInt;  // This hasn't been set yet.
-      } else {
-        index = range->TopLevel()->GetSpillOperand()->index();
-      }
-      if (range->TopLevel()->Kind() == DOUBLE_REGISTERS) {
-        os_ << " \"double_stack:" << index << "\"";
-      } else if (range->TopLevel()->Kind() == GENERAL_REGISTERS) {
-        os_ << " \"stack:" << index << "\"";
-      } else {
-        os_ << " \"const(nostack):" << index << "\"";
+        index = AllocatedOperand::cast(top->GetSpillOperand())->index();
+        if (top->kind() == DOUBLE_REGISTERS) {
+          os_ << " \"double_stack:" << index << "\"";
+        } else if (top->kind() == GENERAL_REGISTERS) {
+          os_ << " \"stack:" << index << "\"";
+        }
       }
     }
-    int parent_index = -1;
-    if (range->IsChild()) {
-      parent_index = range->parent()->id();
-    } else {
-      parent_index = range->id();
-    }
-    InstructionOperand* op = range->FirstHint();
-    int hint_index = -1;
-    if (op != NULL && op->IsUnallocated()) {
-      hint_index = UnallocatedOperand::cast(op)->virtual_register();
-    }
-    os_ << " " << parent_index << " " << hint_index;
-    UseInterval* cur_interval = range->first_interval();
-    while (cur_interval != NULL && range->Covers(cur_interval->start())) {
-      os_ << " [" << cur_interval->start().Value() << ", "
-          << cur_interval->end().Value() << "[";
-      cur_interval = cur_interval->next();
+
+    os_ << " " << vreg;
+    for (auto interval = range->first_interval(); interval != nullptr;
+         interval = interval->next()) {
+      os_ << " [" << interval->start().value() << ", "
+          << interval->end().value() << "[";
     }
 
     UsePosition* current_pos = range->first_pos();
-    while (current_pos != NULL) {
+    while (current_pos != nullptr) {
       if (current_pos->RegisterIsBeneficial() || FLAG_trace_all_uses) {
-        os_ << " " << current_pos->pos().Value() << " M";
+        os_ << " " << current_pos->pos().value() << " M";
       }
       current_pos = current_pos->next();
     }
@@ -771,23 +584,24 @@
 
 
 std::ostream& operator<<(std::ostream& os, const AsC1VCompilation& ac) {
-  Zone tmp_zone(ac.info_->isolate());
+  Zone tmp_zone;
   GraphC1Visualizer(os, &tmp_zone).PrintCompilation(ac.info_);
   return os;
 }
 
 
 std::ostream& operator<<(std::ostream& os, const AsC1V& ac) {
-  Zone tmp_zone(ac.schedule_->zone()->isolate());
+  Zone tmp_zone;
   GraphC1Visualizer(os, &tmp_zone)
       .PrintSchedule(ac.phase_, ac.schedule_, ac.positions_, ac.instructions_);
   return os;
 }
 
 
-std::ostream& operator<<(std::ostream& os, const AsC1VAllocator& ac) {
-  Zone tmp_zone(ac.allocator_->code()->zone()->isolate());
-  GraphC1Visualizer(os, &tmp_zone).PrintAllocator(ac.phase_, ac.allocator_);
+std::ostream& operator<<(std::ostream& os,
+                         const AsC1VRegisterAllocationData& ac) {
+  Zone tmp_zone;
+  GraphC1Visualizer(os, &tmp_zone).PrintLiveRanges(ac.phase_, ac.data_);
   return os;
 }
 
@@ -796,7 +610,7 @@
 const int kVisited = 2;
 
 std::ostream& operator<<(std::ostream& os, const AsRPO& ar) {
-  Zone local_zone(ar.graph.zone()->isolate());
+  Zone local_zone;
   ZoneVector<byte> state(ar.graph.NodeCount(), kUnvisited, &local_zone);
   ZoneStack<Node*> stack(&local_zone);
 
@@ -816,7 +630,7 @@
     if (pop) {
       state[n->id()] = kVisited;
       stack.pop();
-      os << "#" << SafeId(n) << ":" << SafeMnemonic(n) << "(";
+      os << "#" << n->id() << ":" << *n->op() << "(";
       int j = 0;
       for (Node* const i : n->inputs()) {
         if (j++ > 0) os << ", ";
@@ -827,6 +641,6 @@
   }
   return os;
 }
-}
-}
-}  // namespace v8::internal::compiler
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/graph-visualizer.h b/src/compiler/graph-visualizer.h
index 3dd66ea..1a971a5 100644
--- a/src/compiler/graph-visualizer.h
+++ b/src/compiler/graph-visualizer.h
@@ -5,6 +5,7 @@
 #ifndef V8_COMPILER_GRAPH_VISUALIZER_H_
 #define V8_COMPILER_GRAPH_VISUALIZER_H_
 
+#include <stdio.h>
 #include <iosfwd>
 
 namespace v8 {
@@ -16,22 +17,17 @@
 
 class Graph;
 class InstructionSequence;
-class RegisterAllocator;
+class RegisterAllocationData;
 class Schedule;
 class SourcePositionTable;
 
-
-struct AsDOT {
-  explicit AsDOT(const Graph& g) : graph(g) {}
-  const Graph& graph;
-};
-
-std::ostream& operator<<(std::ostream& os, const AsDOT& ad);
-
+FILE* OpenVisualizerLogFile(CompilationInfo* info, const char* phase,
+                            const char* suffix, const char* mode);
 
 struct AsJSON {
-  explicit AsJSON(const Graph& g) : graph(g) {}
+  AsJSON(const Graph& g, SourcePositionTable* p) : graph(g), positions(p) {}
   const Graph& graph;
+  const SourcePositionTable* positions;
 };
 
 std::ostream& operator<<(std::ostream& os, const AsJSON& ad);
@@ -52,8 +48,8 @@
 
 struct AsC1V {
   AsC1V(const char* phase, const Schedule* schedule,
-        const SourcePositionTable* positions = NULL,
-        const InstructionSequence* instructions = NULL)
+        const SourcePositionTable* positions = nullptr,
+        const InstructionSequence* instructions = nullptr)
       : schedule_(schedule),
         instructions_(instructions),
         positions_(positions),
@@ -64,18 +60,18 @@
   const char* phase_;
 };
 
-struct AsC1VAllocator {
-  explicit AsC1VAllocator(const char* phase,
-                          const RegisterAllocator* allocator = NULL)
-      : phase_(phase), allocator_(allocator) {}
+struct AsC1VRegisterAllocationData {
+  explicit AsC1VRegisterAllocationData(
+      const char* phase, const RegisterAllocationData* data = nullptr)
+      : phase_(phase), data_(data) {}
   const char* phase_;
-  const RegisterAllocator* allocator_;
+  const RegisterAllocationData* data_;
 };
 
-std::ostream& operator<<(std::ostream& os, const AsDOT& ad);
 std::ostream& operator<<(std::ostream& os, const AsC1VCompilation& ac);
 std::ostream& operator<<(std::ostream& os, const AsC1V& ac);
-std::ostream& operator<<(std::ostream& os, const AsC1VAllocator& ac);
+std::ostream& operator<<(std::ostream& os,
+                         const AsC1VRegisterAllocationData& ac);
 
 }  // namespace compiler
 }  // namespace internal
diff --git a/src/compiler/graph.cc b/src/compiler/graph.cc
index 995046b..3d4d6da 100644
--- a/src/compiler/graph.cc
+++ b/src/compiler/graph.cc
@@ -4,14 +4,12 @@
 
 #include "src/compiler/graph.h"
 
-#include "src/compiler/common-operator.h"
-#include "src/compiler/graph-inl.h"
+#include <algorithm>
+
+#include "src/base/bits.h"
 #include "src/compiler/node.h"
-#include "src/compiler/node-aux-data-inl.h"
 #include "src/compiler/node-properties.h"
-#include "src/compiler/node-properties-inl.h"
-#include "src/compiler/opcodes.h"
-#include "src/compiler/operator-properties.h"
+#include "src/compiler/verifier.h"
 
 namespace v8 {
 namespace internal {
@@ -19,30 +17,61 @@
 
 Graph::Graph(Zone* zone)
     : zone_(zone),
-      start_(NULL),
-      end_(NULL),
+      start_(nullptr),
+      end_(nullptr),
       mark_max_(0),
       next_node_id_(0),
       decorators_(zone) {}
 
 
 void Graph::Decorate(Node* node) {
-  for (ZoneVector<GraphDecorator*>::iterator i = decorators_.begin();
-       i != decorators_.end(); ++i) {
-    (*i)->Decorate(node);
+  for (auto const decorator : decorators_) {
+    decorator->Decorate(node);
   }
 }
 
 
+void Graph::AddDecorator(GraphDecorator* decorator) {
+  decorators_.push_back(decorator);
+}
+
+
+void Graph::RemoveDecorator(GraphDecorator* decorator) {
+  auto const it = std::find(decorators_.begin(), decorators_.end(), decorator);
+  DCHECK(it != decorators_.end());
+  decorators_.erase(it);
+}
+
+
 Node* Graph::NewNode(const Operator* op, int input_count, Node** inputs,
                      bool incomplete) {
-  DCHECK_LE(op->ValueInputCount(), input_count);
-  Node* result = Node::New(this, input_count, inputs, incomplete);
-  result->Initialize(op);
-  if (!incomplete) {
-    Decorate(result);
-  }
-  return result;
+  Node* node = NewNodeUnchecked(op, input_count, inputs, incomplete);
+  Verifier::VerifyNode(node);
+  return node;
+}
+
+
+Node* Graph::NewNodeUnchecked(const Operator* op, int input_count,
+                              Node** inputs, bool incomplete) {
+  Node* const node =
+      Node::New(zone(), NextNodeId(), op, input_count, inputs, incomplete);
+  Decorate(node);
+  return node;
+}
+
+
+Node* Graph::CloneNode(const Node* node) {
+  DCHECK_NOT_NULL(node);
+  Node* const clone = Node::Clone(zone(), NextNodeId(), node);
+  Decorate(clone);
+  return clone;
+}
+
+
+NodeId Graph::NextNodeId() {
+  NodeId const id = next_node_id_;
+  CHECK(!base::bits::UnsignedAddOverflow32(id, 1, &next_node_id_));
+  return id;
 }
 
 }  // namespace compiler
diff --git a/src/compiler/graph.h b/src/compiler/graph.h
index d619da2..b53c7fd 100644
--- a/src/compiler/graph.h
+++ b/src/compiler/graph.h
@@ -5,12 +5,8 @@
 #ifndef V8_COMPILER_GRAPH_H_
 #define V8_COMPILER_GRAPH_H_
 
-#include <map>
-#include <set>
-
-#include "src/compiler/node.h"
-#include "src/compiler/node-aux-data.h"
-#include "src/compiler/source-position.h"
+#include "src/zone.h"
+#include "src/zone-containers.h"
 
 namespace v8 {
 namespace internal {
@@ -18,6 +14,19 @@
 
 // Forward declarations.
 class GraphDecorator;
+class Node;
+class Operator;
+
+
+// Marks are used during traversal of the graph to distinguish states of nodes.
+// Each node has a mark which is a monotonically increasing integer, and a
+// {NodeMarker} has a range of values that indicate states of a node.
+typedef uint32_t Mark;
+
+
+// NodeIds are identifying numbers for nodes that can be used to index auxiliary
+// out-of-line data associated with each node.
+typedef uint32_t NodeId;
 
 
 class Graph : public ZoneObject {
@@ -25,6 +34,10 @@
   explicit Graph(Zone* zone);
 
   // Base implementation used by all factory methods.
+  Node* NewNodeUnchecked(const Operator* op, int input_count, Node** inputs,
+                         bool incomplete = false);
+
+  // Factory that checks the input count.
   Node* NewNode(const Operator* op, int input_count, Node** inputs,
                 bool incomplete = false);
 
@@ -60,9 +73,19 @@
     Node* nodes[] = {n1, n2, n3, n4, n5, n6, n7};
     return NewNode(op, arraysize(nodes), nodes);
   }
+  Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
+                Node* n5, Node* n6, Node* n7, Node* n8) {
+    Node* nodes[] = {n1, n2, n3, n4, n5, n6, n7, n8};
+    return NewNode(op, arraysize(nodes), nodes);
+  }
+  Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
+                Node* n5, Node* n6, Node* n7, Node* n8, Node* n9) {
+    Node* nodes[] = {n1, n2, n3, n4, n5, n6, n7, n8, n9};
+    return NewNode(op, arraysize(nodes), nodes);
+  }
 
-  template <class Visitor>
-  inline void VisitNodeInputsFromEnd(Visitor* visitor);
+  // Clone the {node}, and assign a new node id to the copy.
+  Node* CloneNode(const Node* node);
 
   Zone* zone() const { return zone_; }
   Node* start() const { return start_; }
@@ -71,27 +94,18 @@
   void SetStart(Node* start) { start_ = start; }
   void SetEnd(Node* end) { end_ = end; }
 
-  NodeId NextNodeID() { return next_node_id_++; }
-  NodeId NodeCount() const { return next_node_id_; }
+  size_t NodeCount() const { return next_node_id_; }
 
   void Decorate(Node* node);
-
-  void AddDecorator(GraphDecorator* decorator) {
-    decorators_.push_back(decorator);
-  }
-
-  void RemoveDecorator(GraphDecorator* decorator) {
-    ZoneVector<GraphDecorator*>::iterator it =
-        std::find(decorators_.begin(), decorators_.end(), decorator);
-    DCHECK(it != decorators_.end());
-    decorators_.erase(it, it + 1);
-  }
+  void AddDecorator(GraphDecorator* decorator);
+  void RemoveDecorator(GraphDecorator* decorator);
 
  private:
-  template <typename State>
-  friend class NodeMarker;
+  friend class NodeMarkerBase;
 
-  Zone* zone_;
+  inline NodeId NextNodeId();
+
+  Zone* const zone_;
   Node* start_;
   Node* end_;
   Mark mark_max_;
@@ -102,40 +116,6 @@
 };
 
 
-// A NodeMarker uses monotonically increasing marks to assign local "states"
-// to nodes. Only one NodeMarker per graph is valid at a given time.
-template <typename State>
-class NodeMarker BASE_EMBEDDED {
- public:
-  NodeMarker(Graph* graph, uint32_t num_states)
-      : mark_min_(graph->mark_max_), mark_max_(graph->mark_max_ += num_states) {
-    DCHECK(num_states > 0);         // user error!
-    DCHECK(mark_max_ > mark_min_);  // check for wraparound.
-  }
-
-  State Get(Node* node) {
-    Mark mark = node->mark();
-    if (mark < mark_min_) {
-      mark = mark_min_;
-      node->set_mark(mark_min_);
-    }
-    DCHECK_LT(mark, mark_max_);
-    return static_cast<State>(mark - mark_min_);
-  }
-
-  void Set(Node* node, State state) {
-    Mark local = static_cast<Mark>(state);
-    DCHECK(local < (mark_max_ - mark_min_));
-    DCHECK_LT(node->mark(), mark_max_);
-    node->set_mark(local + mark_min_);
-  }
-
- private:
-  Mark mark_min_;
-  Mark mark_max_;
-};
-
-
 // A graph decorator can be used to add behavior to the creation of nodes
 // in a graph.
 class GraphDecorator : public ZoneObject {
diff --git a/src/compiler/greedy-allocator.cc b/src/compiler/greedy-allocator.cc
new file mode 100644
index 0000000..683b75d
--- /dev/null
+++ b/src/compiler/greedy-allocator.cc
@@ -0,0 +1,629 @@
+// Copyright 2015 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/greedy-allocator.h"
+#include "src/compiler/register-allocator.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+
+#define TRACE(...)                             \
+  do {                                         \
+    if (FLAG_trace_alloc) PrintF(__VA_ARGS__); \
+  } while (false)
+
+
+const float GreedyAllocator::kAllocatedRangeMultiplier = 10.0;
+
+
+namespace {
+
+void UpdateOperands(LiveRange* range, RegisterAllocationData* data) {
+  int reg_id = range->assigned_register();
+  range->SetUseHints(reg_id);
+  if (range->IsTopLevel() && range->TopLevel()->is_phi()) {
+    data->GetPhiMapValueFor(range->TopLevel())->set_assigned_register(reg_id);
+  }
+}
+
+
+void UnsetOperands(LiveRange* range, RegisterAllocationData* data) {
+  range->UnsetUseHints();
+  if (range->IsTopLevel() && range->TopLevel()->is_phi()) {
+    data->GetPhiMapValueFor(range->TopLevel())->UnsetAssignedRegister();
+  }
+}
+
+
+LiveRange* Split(LiveRange* range, RegisterAllocationData* data,
+                 LifetimePosition pos) {
+  DCHECK(range->Start() < pos && pos < range->End());
+  DCHECK(pos.IsStart() || pos.IsGapPosition() ||
+         (data->code()
+              ->GetInstructionBlock(pos.ToInstructionIndex())
+              ->last_instruction_index() != pos.ToInstructionIndex()));
+  LiveRange* result = range->SplitAt(pos, data->allocation_zone());
+  return result;
+}
+
+
+}  // namespace
+
+
+AllocationCandidate AllocationScheduler::GetNext() {
+  DCHECK(!queue_.empty());
+  AllocationCandidate ret = queue_.top();
+  queue_.pop();
+  return ret;
+}
+
+
+void AllocationScheduler::Schedule(LiveRange* range) {
+  TRACE("Scheduling live range %d:%d.\n", range->TopLevel()->vreg(),
+        range->relative_id());
+  queue_.push(AllocationCandidate(range));
+}
+
+
+void AllocationScheduler::Schedule(LiveRangeGroup* group) {
+  queue_.push(AllocationCandidate(group));
+}
+
+GreedyAllocator::GreedyAllocator(RegisterAllocationData* data,
+                                 RegisterKind kind, Zone* local_zone)
+    : RegisterAllocator(data, kind),
+      local_zone_(local_zone),
+      allocations_(local_zone),
+      scheduler_(local_zone),
+      groups_(local_zone) {}
+
+
+void GreedyAllocator::AssignRangeToRegister(int reg_id, LiveRange* range) {
+  TRACE("Assigning register %s to live range %d:%d\n", RegisterName(reg_id),
+        range->TopLevel()->vreg(), range->relative_id());
+
+  DCHECK(!range->HasRegisterAssigned());
+
+  AllocateRegisterToRange(reg_id, range);
+
+  TRACE("Assigning %s to range %d%d.\n", RegisterName(reg_id),
+        range->TopLevel()->vreg(), range->relative_id());
+  range->set_assigned_register(reg_id);
+  UpdateOperands(range, data());
+}
+
+
+void GreedyAllocator::PreallocateFixedRanges() {
+  allocations_.resize(num_registers());
+  for (int i = 0; i < num_registers(); i++) {
+    allocations_[i] = new (local_zone()) CoalescedLiveRanges(local_zone());
+  }
+
+  for (LiveRange* fixed_range : GetFixedRegisters()) {
+    if (fixed_range != nullptr) {
+      DCHECK_EQ(mode(), fixed_range->kind());
+      DCHECK(fixed_range->TopLevel()->IsFixed());
+
+      int reg_nr = fixed_range->assigned_register();
+      EnsureValidRangeWeight(fixed_range);
+      AllocateRegisterToRange(reg_nr, fixed_range);
+    }
+  }
+}
+
+
+void GreedyAllocator::GroupLiveRanges() {
+  CoalescedLiveRanges grouper(local_zone());
+  for (TopLevelLiveRange* range : data()->live_ranges()) {
+    grouper.clear();
+    // Skip splinters, because we do not want to optimize for them, and moves
+    // due to assigning them to different registers occur in deferred blocks.
+    if (!CanProcessRange(range) || range->IsSplinter() || !range->is_phi()) {
+      continue;
+    }
+
+    // A phi can't be a memory operand, so it couldn't have been split.
+    DCHECK(!range->spilled());
+
+    // Maybe this phi range is itself an input to another phi which was already
+    // processed.
+    LiveRangeGroup* latest_grp = range->group() != nullptr
+                                     ? range->group()
+                                     : new (local_zone())
+                                           LiveRangeGroup(local_zone());
+
+    // Populate the grouper.
+    if (range->group() == nullptr) {
+      grouper.AllocateRange(range);
+    } else {
+      for (LiveRange* member : range->group()->ranges()) {
+        grouper.AllocateRange(member);
+      }
+    }
+    for (int j : data()->GetPhiMapValueFor(range)->phi()->operands()) {
+      // skip output also in input, which may happen for loops.
+      if (j == range->vreg()) continue;
+
+      TopLevelLiveRange* other_top = data()->live_ranges()[j];
+
+      if (other_top->IsSplinter()) continue;
+      // If the other was a memory operand, it might have been split.
+      // So get the unsplit part.
+      LiveRange* other =
+          other_top->next() == nullptr ? other_top : other_top->next();
+
+      if (other->spilled()) continue;
+
+      LiveRangeGroup* other_group = other->group();
+      if (other_group != nullptr) {
+        bool can_merge = true;
+        for (LiveRange* member : other_group->ranges()) {
+          if (grouper.GetConflicts(member).Current() != nullptr) {
+            can_merge = false;
+            break;
+          }
+        }
+        // If each member doesn't conflict with the current group, then since
+        // the members don't conflict with eachother either, we can merge them.
+        if (can_merge) {
+          latest_grp->ranges().insert(latest_grp->ranges().end(),
+                                      other_group->ranges().begin(),
+                                      other_group->ranges().end());
+          for (LiveRange* member : other_group->ranges()) {
+            grouper.AllocateRange(member);
+            member->set_group(latest_grp);
+          }
+          // Clear the other range, so we avoid scheduling it.
+          other_group->ranges().clear();
+        }
+      } else if (grouper.GetConflicts(other).Current() == nullptr) {
+        grouper.AllocateRange(other);
+        latest_grp->ranges().push_back(other);
+        other->set_group(latest_grp);
+      }
+    }
+
+    if (latest_grp->ranges().size() > 0 && range->group() == nullptr) {
+      latest_grp->ranges().push_back(range);
+      DCHECK(latest_grp->ranges().size() > 1);
+      groups().push_back(latest_grp);
+      range->set_group(latest_grp);
+    }
+  }
+}
+
+
+void GreedyAllocator::ScheduleAllocationCandidates() {
+  for (LiveRangeGroup* group : groups()) {
+    if (group->ranges().size() > 0) {
+      // We shouldn't have added single-range groups.
+      DCHECK(group->ranges().size() != 1);
+      scheduler().Schedule(group);
+    }
+  }
+  for (LiveRange* range : data()->live_ranges()) {
+    if (CanProcessRange(range)) {
+      for (LiveRange* child = range; child != nullptr; child = child->next()) {
+        if (!child->spilled() && child->group() == nullptr) {
+          scheduler().Schedule(child);
+        }
+      }
+    }
+  }
+}
+
+
+void GreedyAllocator::TryAllocateCandidate(
+    const AllocationCandidate& candidate) {
+  if (candidate.is_group()) {
+    TryAllocateGroup(candidate.group());
+  } else {
+    TryAllocateLiveRange(candidate.live_range());
+  }
+}
+
+
+void GreedyAllocator::TryAllocateGroup(LiveRangeGroup* group) {
+  float group_weight = 0.0;
+  for (LiveRange* member : group->ranges()) {
+    EnsureValidRangeWeight(member);
+    group_weight = Max(group_weight, member->weight());
+  }
+
+  float eviction_weight = group_weight;
+  int eviction_reg = -1;
+  int free_reg = -1;
+  for (int i = 0; i < num_allocatable_registers(); ++i) {
+    int reg = allocatable_register_code(i);
+    float weight = GetMaximumConflictingWeight(reg, group, group_weight);
+    if (weight == LiveRange::kInvalidWeight) {
+      free_reg = reg;
+      break;
+    }
+    if (weight < eviction_weight) {
+      eviction_weight = weight;
+      eviction_reg = reg;
+    }
+  }
+  if (eviction_reg < 0 && free_reg < 0) {
+    for (LiveRange* member : group->ranges()) {
+      scheduler().Schedule(member);
+    }
+    return;
+  }
+  if (free_reg < 0) {
+    DCHECK(eviction_reg >= 0);
+    for (LiveRange* member : group->ranges()) {
+      EvictAndRescheduleConflicts(eviction_reg, member);
+    }
+    free_reg = eviction_reg;
+  }
+
+  DCHECK(free_reg >= 0);
+  for (LiveRange* member : group->ranges()) {
+    AssignRangeToRegister(free_reg, member);
+  }
+}
+
+
+void GreedyAllocator::TryAllocateLiveRange(LiveRange* range) {
+  // TODO(mtrofin): once we introduce groups, we'll want to first try and
+  // allocate at the preferred register.
+  TRACE("Attempting to allocate live range %d:%d.\n", range->TopLevel()->vreg(),
+        range->relative_id());
+  int free_reg = -1;
+  int evictable_reg = -1;
+  int hinted_reg = -1;
+
+  EnsureValidRangeWeight(range);
+  float competing_weight = range->weight();
+  DCHECK(competing_weight != LiveRange::kInvalidWeight);
+
+  // Can we allocate at the hinted register?
+  if (range->FirstHintPosition(&hinted_reg) != nullptr) {
+    DCHECK(hinted_reg >= 0);
+    float max_conflict_weight =
+        GetMaximumConflictingWeight(hinted_reg, range, competing_weight);
+    if (max_conflict_weight == LiveRange::kInvalidWeight) {
+      free_reg = hinted_reg;
+    } else if (max_conflict_weight < range->weight()) {
+      evictable_reg = hinted_reg;
+    }
+  }
+
+  if (free_reg < 0 && evictable_reg < 0) {
+    // There was no hinted reg, or we cannot allocate there.
+    float smallest_weight = LiveRange::kMaxWeight;
+
+    // Seek either the first free register, or, from the set of registers
+    // where the maximum conflict is lower than the candidate's weight, the one
+    // with the smallest such weight.
+    for (int i = 0; i < num_allocatable_registers(); i++) {
+      int reg = allocatable_register_code(i);
+      // Skip unnecessarily re-visiting the hinted register, if any.
+      if (reg == hinted_reg) continue;
+      float max_conflict_weight =
+          GetMaximumConflictingWeight(reg, range, competing_weight);
+      if (max_conflict_weight == LiveRange::kInvalidWeight) {
+        free_reg = reg;
+        break;
+      }
+      if (max_conflict_weight < range->weight() &&
+          max_conflict_weight < smallest_weight) {
+        smallest_weight = max_conflict_weight;
+        evictable_reg = reg;
+      }
+    }
+  }
+
+  // We have a free register, so we use it.
+  if (free_reg >= 0) {
+    TRACE("Found free register %s for live range %d:%d.\n",
+          RegisterName(free_reg), range->TopLevel()->vreg(),
+          range->relative_id());
+    AssignRangeToRegister(free_reg, range);
+    return;
+  }
+
+  // We found a register to perform evictions, so we evict and allocate our
+  // candidate.
+  if (evictable_reg >= 0) {
+    TRACE("Found evictable register %s for live range %d:%d.\n",
+          RegisterName(free_reg), range->TopLevel()->vreg(),
+          range->relative_id());
+    EvictAndRescheduleConflicts(evictable_reg, range);
+    AssignRangeToRegister(evictable_reg, range);
+    return;
+  }
+
+  // The range needs to be split or spilled.
+  SplitOrSpillBlockedRange(range);
+}
+
+
+void GreedyAllocator::EvictAndRescheduleConflicts(unsigned reg_id,
+                                                  const LiveRange* range) {
+  auto conflicts = current_allocations(reg_id)->GetConflicts(range);
+  for (LiveRange* conflict = conflicts.Current(); conflict != nullptr;
+       conflict = conflicts.RemoveCurrentAndGetNext()) {
+    DCHECK(conflict->HasRegisterAssigned());
+    CHECK(!conflict->TopLevel()->IsFixed());
+    conflict->UnsetAssignedRegister();
+    UnsetOperands(conflict, data());
+    UpdateWeightAtEviction(conflict);
+    scheduler().Schedule(conflict);
+    TRACE("Evicted range %d%d.\n", conflict->TopLevel()->vreg(),
+          conflict->relative_id());
+  }
+}
+
+
+void GreedyAllocator::AllocateRegisters() {
+  CHECK(scheduler().empty());
+  CHECK(allocations_.empty());
+
+  TRACE("Begin allocating function %s with the Greedy Allocator\n",
+        data()->debug_name());
+
+  SplitAndSpillRangesDefinedByMemoryOperand(true);
+  GroupLiveRanges();
+  ScheduleAllocationCandidates();
+  PreallocateFixedRanges();
+  while (!scheduler().empty()) {
+    AllocationCandidate candidate = scheduler().GetNext();
+    TryAllocateCandidate(candidate);
+  }
+
+  for (size_t i = 0; i < allocations_.size(); ++i) {
+    if (!allocations_[i]->empty()) {
+      data()->MarkAllocated(mode(), static_cast<int>(i));
+    }
+  }
+  allocations_.clear();
+
+  TryReuseSpillRangesForGroups();
+
+  TRACE("End allocating function %s with the Greedy Allocator\n",
+        data()->debug_name());
+}
+
+
+void GreedyAllocator::TryReuseSpillRangesForGroups() {
+  for (TopLevelLiveRange* top : data()->live_ranges()) {
+    if (!CanProcessRange(top) || !top->is_phi() || top->group() == nullptr) {
+      continue;
+    }
+
+    SpillRange* spill_range = nullptr;
+    for (LiveRange* member : top->group()->ranges()) {
+      if (!member->TopLevel()->HasSpillRange()) continue;
+      SpillRange* member_range = member->TopLevel()->GetSpillRange();
+      if (spill_range == nullptr) {
+        spill_range = member_range;
+      } else {
+        // This may not always succeed, because we group non-conflicting ranges
+        // that may have been splintered, and the splinters may cause conflicts
+        // in the spill ranges.
+        // TODO(mtrofin): should the splinters own their own spill ranges?
+        spill_range->TryMerge(member_range);
+      }
+    }
+  }
+}
+
+
+float GreedyAllocator::GetMaximumConflictingWeight(
+    unsigned reg_id, const LiveRange* range, float competing_weight) const {
+  float ret = LiveRange::kInvalidWeight;
+
+  auto conflicts = current_allocations(reg_id)->GetConflicts(range);
+  for (LiveRange* conflict = conflicts.Current(); conflict != nullptr;
+       conflict = conflicts.GetNext()) {
+    DCHECK_NE(conflict->weight(), LiveRange::kInvalidWeight);
+    if (competing_weight <= conflict->weight()) return LiveRange::kMaxWeight;
+    ret = Max(ret, conflict->weight());
+    DCHECK(ret < LiveRange::kMaxWeight);
+  }
+
+  return ret;
+}
+
+
+float GreedyAllocator::GetMaximumConflictingWeight(unsigned reg_id,
+                                                   const LiveRangeGroup* group,
+                                                   float group_weight) const {
+  float ret = LiveRange::kInvalidWeight;
+
+  for (LiveRange* member : group->ranges()) {
+    float member_conflict_weight =
+        GetMaximumConflictingWeight(reg_id, member, group_weight);
+    if (member_conflict_weight == LiveRange::kMaxWeight) {
+      return LiveRange::kMaxWeight;
+    }
+    if (member_conflict_weight > group_weight) return LiveRange::kMaxWeight;
+    ret = Max(member_conflict_weight, ret);
+  }
+
+  return ret;
+}
+
+
+void GreedyAllocator::EnsureValidRangeWeight(LiveRange* range) {
+  // The live range weight will be invalidated when ranges are created or split.
+  // Otherwise, it is consistently updated when the range is allocated or
+  // unallocated.
+  if (range->weight() != LiveRange::kInvalidWeight) return;
+
+  if (range->TopLevel()->IsFixed()) {
+    range->set_weight(LiveRange::kMaxWeight);
+    return;
+  }
+  if (!IsProgressPossible(range)) {
+    range->set_weight(LiveRange::kMaxWeight);
+    return;
+  }
+
+  float use_count = 0.0;
+  for (auto pos = range->first_pos(); pos != nullptr; pos = pos->next()) {
+    ++use_count;
+  }
+  range->set_weight(use_count / static_cast<float>(range->GetSize()));
+}
+
+
+void GreedyAllocator::SpillRangeAsLastResort(LiveRange* range) {
+  LifetimePosition start = range->Start();
+  CHECK(range->CanBeSpilled(start));
+
+  DCHECK(range->NextRegisterPosition(start) == nullptr);
+  Spill(range);
+}
+
+
+LiveRange* GreedyAllocator::GetRemainderAfterSplittingAroundFirstCall(
+    LiveRange* range) {
+  LiveRange* ret = range;
+  for (UseInterval* interval = range->first_interval(); interval != nullptr;
+       interval = interval->next()) {
+    LifetimePosition start = interval->start();
+    LifetimePosition end = interval->end();
+    // If the interval starts at instruction end, then the first instruction
+    // in the interval is the next one.
+    int first_full_instruction = (start.IsGapPosition() || start.IsStart())
+                                     ? start.ToInstructionIndex()
+                                     : start.ToInstructionIndex() + 1;
+    // If the interval ends in a gap or at instruction start, then the last
+    // instruction is the previous one.
+    int last_full_instruction = (end.IsGapPosition() || end.IsStart())
+                                    ? end.ToInstructionIndex() - 1
+                                    : end.ToInstructionIndex();
+
+    for (int instruction_index = first_full_instruction;
+         instruction_index <= last_full_instruction; ++instruction_index) {
+      if (!code()->InstructionAt(instruction_index)->IsCall()) continue;
+
+      LifetimePosition before =
+          GetSplitPositionForInstruction(range, instruction_index);
+      LiveRange* second_part =
+          before.IsValid() ? Split(range, data(), before) : range;
+
+      if (range != second_part) scheduler().Schedule(range);
+
+      LifetimePosition after =
+          FindSplitPositionAfterCall(second_part, instruction_index);
+
+      if (after.IsValid()) {
+        ret = Split(second_part, data(), after);
+      } else {
+        ret = nullptr;
+      }
+      Spill(second_part);
+      return ret;
+    }
+  }
+  return ret;
+}
+
+
+bool GreedyAllocator::TrySplitAroundCalls(LiveRange* range) {
+  bool modified = false;
+
+  while (range != nullptr) {
+    LiveRange* remainder = GetRemainderAfterSplittingAroundFirstCall(range);
+    // If we performed no modification, we're done.
+    if (remainder == range) {
+      break;
+    }
+    // We performed a modification.
+    modified = true;
+    range = remainder;
+  }
+  // If we have a remainder and we made modifications, it means the remainder
+  // has no calls and we should schedule it for further processing. If we made
+  // no modifications, we will just return false, because we want the algorithm
+  // to make progress by trying some other heuristic.
+  if (modified && range != nullptr) {
+    DCHECK(!range->spilled());
+    DCHECK(!range->HasRegisterAssigned());
+    scheduler().Schedule(range);
+  }
+  return modified;
+}
+
+
+LifetimePosition GreedyAllocator::FindSplitPositionAfterCall(
+    const LiveRange* range, int call_index) {
+  LifetimePosition after_call =
+      Max(range->Start(),
+          LifetimePosition::GapFromInstructionIndex(call_index + 1));
+  UsePosition* next_use = range->NextRegisterPosition(after_call);
+  if (!next_use) return LifetimePosition::Invalid();
+
+  LifetimePosition split_pos = FindOptimalSplitPos(after_call, next_use->pos());
+  split_pos =
+      GetSplitPositionForInstruction(range, split_pos.ToInstructionIndex());
+  return split_pos;
+}
+
+
+LifetimePosition GreedyAllocator::FindSplitPositionBeforeLoops(
+    LiveRange* range) {
+  LifetimePosition end = range->End();
+  if (end.ToInstructionIndex() >= code()->LastInstructionIndex()) {
+    end =
+        LifetimePosition::GapFromInstructionIndex(end.ToInstructionIndex() - 1);
+  }
+  LifetimePosition pos = FindOptimalSplitPos(range->Start(), end);
+  pos = GetSplitPositionForInstruction(range, pos.ToInstructionIndex());
+  return pos;
+}
+
+
+void GreedyAllocator::SplitOrSpillBlockedRange(LiveRange* range) {
+  if (TrySplitAroundCalls(range)) return;
+
+  LifetimePosition pos = FindSplitPositionBeforeLoops(range);
+
+  if (!pos.IsValid()) pos = GetLastResortSplitPosition(range);
+  if (pos.IsValid()) {
+    LiveRange* tail = Split(range, data(), pos);
+    DCHECK(tail != range);
+    scheduler().Schedule(tail);
+    scheduler().Schedule(range);
+    return;
+  }
+  SpillRangeAsLastResort(range);
+}
+
+
+// Basic heuristic for advancing the algorithm, if any other splitting heuristic
+// failed.
+LifetimePosition GreedyAllocator::GetLastResortSplitPosition(
+    const LiveRange* range) {
+  LifetimePosition previous = range->Start();
+  for (UsePosition *pos = range->NextRegisterPosition(previous); pos != nullptr;
+       previous = previous.NextFullStart(),
+                   pos = range->NextRegisterPosition(previous)) {
+    LifetimePosition optimal = FindOptimalSplitPos(previous, pos->pos());
+    LifetimePosition before =
+        GetSplitPositionForInstruction(range, optimal.ToInstructionIndex());
+    if (before.IsValid()) return before;
+    LifetimePosition after = GetSplitPositionForInstruction(
+        range, pos->pos().ToInstructionIndex() + 1);
+    if (after.IsValid()) return after;
+  }
+  return LifetimePosition::Invalid();
+}
+
+
+bool GreedyAllocator::IsProgressPossible(const LiveRange* range) {
+  return range->CanBeSpilled(range->Start()) ||
+         GetLastResortSplitPosition(range).IsValid();
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/greedy-allocator.h b/src/compiler/greedy-allocator.h
new file mode 100644
index 0000000..b61ba42
--- /dev/null
+++ b/src/compiler/greedy-allocator.h
@@ -0,0 +1,199 @@
+// Copyright 2015 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.
+
+#ifndef V8_GREEDY_ALLOCATOR_H_
+#define V8_GREEDY_ALLOCATOR_H_
+
+#include "src/compiler/coalesced-live-ranges.h"
+#include "src/compiler/register-allocator.h"
+#include "src/zone-containers.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+
+// The object of allocation scheduling. At minimum, this is a LiveRange, but
+// we may extend this to groups of LiveRanges. It has to be comparable.
+class AllocationCandidate {
+ public:
+  explicit AllocationCandidate(LiveRange* range)
+      : is_group_(false), size_(range->GetSize()) {
+    candidate_.range_ = range;
+  }
+
+  explicit AllocationCandidate(LiveRangeGroup* ranges)
+      : is_group_(true), size_(CalculateGroupSize(ranges)) {
+    candidate_.group_ = ranges;
+  }
+
+  // Strict ordering operators
+  bool operator<(const AllocationCandidate& other) const {
+    return size() < other.size();
+  }
+
+  bool operator>(const AllocationCandidate& other) const {
+    return size() > other.size();
+  }
+
+  bool is_group() const { return is_group_; }
+  LiveRange* live_range() const { return candidate_.range_; }
+  LiveRangeGroup* group() const { return candidate_.group_; }
+
+ private:
+  unsigned CalculateGroupSize(LiveRangeGroup* group) {
+    unsigned ret = 0;
+    for (LiveRange* range : group->ranges()) {
+      ret += range->GetSize();
+    }
+    return ret;
+  }
+
+  unsigned size() const { return size_; }
+  bool is_group_;
+  unsigned size_;
+  union {
+    LiveRange* range_;
+    LiveRangeGroup* group_;
+  } candidate_;
+};
+
+
+// Schedule processing (allocating) of AllocationCandidates.
+class AllocationScheduler final : ZoneObject {
+ public:
+  explicit AllocationScheduler(Zone* zone) : queue_(zone) {}
+  void Schedule(LiveRange* range);
+  void Schedule(LiveRangeGroup* group);
+  AllocationCandidate GetNext();
+  bool empty() const { return queue_.empty(); }
+
+ private:
+  typedef ZonePriorityQueue<AllocationCandidate> ScheduleQueue;
+  ScheduleQueue queue_;
+
+  DISALLOW_COPY_AND_ASSIGN(AllocationScheduler);
+};
+
+
+// A variant of the LLVM Greedy Register Allocator. See
+// http://blog.llvm.org/2011/09/greedy-register-allocation-in-llvm-30.html
+class GreedyAllocator final : public RegisterAllocator {
+ public:
+  explicit GreedyAllocator(RegisterAllocationData* data, RegisterKind kind,
+                           Zone* local_zone);
+
+  void AllocateRegisters();
+
+ private:
+  static const float kAllocatedRangeMultiplier;
+
+  static void UpdateWeightAtAllocation(LiveRange* range) {
+    DCHECK_NE(range->weight(), LiveRange::kInvalidWeight);
+    range->set_weight(range->weight() * kAllocatedRangeMultiplier);
+  }
+
+
+  static void UpdateWeightAtEviction(LiveRange* range) {
+    DCHECK_NE(range->weight(), LiveRange::kInvalidWeight);
+    range->set_weight(range->weight() / kAllocatedRangeMultiplier);
+  }
+
+  AllocationScheduler& scheduler() { return scheduler_; }
+  CoalescedLiveRanges* current_allocations(unsigned i) {
+    return allocations_[i];
+  }
+
+  CoalescedLiveRanges* current_allocations(unsigned i) const {
+    return allocations_[i];
+  }
+
+  Zone* local_zone() const { return local_zone_; }
+  ZoneVector<LiveRangeGroup*>& groups() { return groups_; }
+  const ZoneVector<LiveRangeGroup*>& groups() const { return groups_; }
+
+  // Insert fixed ranges.
+  void PreallocateFixedRanges();
+
+  void GroupLiveRanges();
+
+  // Schedule unassigned live ranges for allocation.
+  void ScheduleAllocationCandidates();
+
+  void AllocateRegisterToRange(unsigned reg_id, LiveRange* range) {
+    UpdateWeightAtAllocation(range);
+    current_allocations(reg_id)->AllocateRange(range);
+  }
+  // Evict and reschedule conflicts of a given range, at a given register.
+  void EvictAndRescheduleConflicts(unsigned reg_id, const LiveRange* range);
+
+  void TryAllocateCandidate(const AllocationCandidate& candidate);
+  void TryAllocateLiveRange(LiveRange* range);
+  void TryAllocateGroup(LiveRangeGroup* group);
+
+  // Calculate the weight of a candidate for allocation.
+  void EnsureValidRangeWeight(LiveRange* range);
+
+  // Calculate the new weight of a range that is about to be allocated.
+  float GetAllocatedRangeWeight(float candidate_weight);
+
+  // Returns kInvalidWeight if there are no conflicts, or the largest weight of
+  // a range conflicting with the given range, at the given register.
+  float GetMaximumConflictingWeight(unsigned reg_id, const LiveRange* range,
+                                    float competing_weight) const;
+
+  // Returns kInvalidWeight if there are no conflicts, or the largest weight of
+  // a range conflicting with the given range, at the given register.
+  float GetMaximumConflictingWeight(unsigned reg_id,
+                                    const LiveRangeGroup* group,
+                                    float group_weight) const;
+
+  // This is the extension point for splitting heuristics.
+  void SplitOrSpillBlockedRange(LiveRange* range);
+
+  // Find a good position where to fill, after a range was spilled after a call.
+  LifetimePosition FindSplitPositionAfterCall(const LiveRange* range,
+                                              int call_index);
+  // Split a range around all calls it passes over. Returns true if any changes
+  // were made, or false if no calls were found.
+  bool TrySplitAroundCalls(LiveRange* range);
+
+  // Find a split position at the outmost loop.
+  LifetimePosition FindSplitPositionBeforeLoops(LiveRange* range);
+
+  // Finds the first call instruction in the path of this range. Splits before
+  // and requeues that segment (if any), spills the section over the call, and
+  // returns the section after the call. The return is:
+  // - same range, if no call was found
+  // - nullptr, if the range finished at the call and there's no "after the
+  //   call" portion.
+  // - the portion after the call.
+  LiveRange* GetRemainderAfterSplittingAroundFirstCall(LiveRange* range);
+
+  // While we attempt to merge spill ranges later on in the allocation pipeline,
+  // we want to ensure group elements get merged. Waiting until later may hinder
+  // merge-ability, since the pipeline merger (being naive) may create conflicts
+  // between spill ranges of group members.
+  void TryReuseSpillRangesForGroups();
+
+  LifetimePosition GetLastResortSplitPosition(const LiveRange* range);
+
+  bool IsProgressPossible(const LiveRange* range);
+
+  // Necessary heuristic: spill when all else failed.
+  void SpillRangeAsLastResort(LiveRange* range);
+
+  void AssignRangeToRegister(int reg_id, LiveRange* range);
+
+  Zone* local_zone_;
+  ZoneVector<CoalescedLiveRanges*> allocations_;
+  AllocationScheduler scheduler_;
+  ZoneVector<LiveRangeGroup*> groups_;
+
+  DISALLOW_COPY_AND_ASSIGN(GreedyAllocator);
+};
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+#endif  // V8_GREEDY_ALLOCATOR_H_
diff --git a/src/compiler/ia32/code-generator-ia32.cc b/src/compiler/ia32/code-generator-ia32.cc
index 55f7426..f63bc22 100644
--- a/src/compiler/ia32/code-generator-ia32.cc
+++ b/src/compiler/ia32/code-generator-ia32.cc
@@ -4,13 +4,14 @@
 
 #include "src/compiler/code-generator.h"
 
+#include "src/ast/scopes.h"
 #include "src/compiler/code-generator-impl.h"
 #include "src/compiler/gap-resolver.h"
 #include "src/compiler/node-matchers.h"
-#include "src/compiler/node-properties-inl.h"
+#include "src/compiler/osr.h"
 #include "src/ia32/assembler-ia32.h"
+#include "src/ia32/frames-ia32.h"
 #include "src/ia32/macro-assembler-ia32.h"
-#include "src/scopes.h"
 
 namespace v8 {
 namespace internal {
@@ -19,15 +20,20 @@
 #define __ masm()->
 
 
+#define kScratchDoubleReg xmm0
+
+
 // Adds IA-32 specific methods for decoding operands.
 class IA32OperandConverter : public InstructionOperandConverter {
  public:
   IA32OperandConverter(CodeGenerator* gen, Instruction* instr)
       : InstructionOperandConverter(gen, instr) {}
 
-  Operand InputOperand(int index) { return ToOperand(instr_->InputAt(index)); }
+  Operand InputOperand(size_t index, int extra = 0) {
+    return ToOperand(instr_->InputAt(index), extra);
+  }
 
-  Immediate InputImmediate(int index) {
+  Immediate InputImmediate(size_t index) {
     return ToImmediate(instr_->InputAt(index));
   }
 
@@ -42,8 +48,15 @@
       return Operand(ToDoubleRegister(op));
     }
     DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot());
-    // The linkage computes where all spill slots are located.
-    FrameOffset offset = linkage()->GetFrameOffset(op->index(), frame(), extra);
+    FrameOffset offset = frame_access_state()->GetFrameOffset(
+        AllocatedOperand::cast(op)->index());
+    return Operand(offset.from_stack_pointer() ? esp : ebp,
+                   offset.offset() + extra);
+  }
+
+  Operand ToMaterializableOperand(int materializable_offset) {
+    FrameOffset offset = frame_access_state()->GetFrameOffset(
+        Frame::FPOffsetToSlot(materializable_offset));
     return Operand(offset.from_stack_pointer() ? esp : ebp, offset.offset());
   }
 
@@ -76,8 +89,8 @@
     return Immediate(-1);
   }
 
-  static int NextOffset(int* offset) {
-    int i = *offset;
+  static size_t NextOffset(size_t* offset) {
+    size_t i = *offset;
     (*offset)++;
     return i;
   }
@@ -92,7 +105,7 @@
     return static_cast<ScaleFactor>(scale);
   }
 
-  Operand MemoryOperand(int* offset) {
+  Operand MemoryOperand(size_t* offset) {
     AddressingMode mode = AddressingModeField::decode(instr_->opcode());
     switch (mode) {
       case kMode_MR: {
@@ -155,7 +168,7 @@
     return Operand(no_reg, 0);
   }
 
-  Operand MemoryOperand(int first_input = 0) {
+  Operand MemoryOperand(size_t first_input = 0) {
     return MemoryOperand(&first_input);
   }
 };
@@ -163,42 +176,42 @@
 
 namespace {
 
-bool HasImmediateInput(Instruction* instr, int index) {
+bool HasImmediateInput(Instruction* instr, size_t index) {
   return instr->InputAt(index)->IsImmediate();
 }
 
 
-class OutOfLineLoadInteger FINAL : public OutOfLineCode {
+class OutOfLineLoadInteger final : public OutOfLineCode {
  public:
   OutOfLineLoadInteger(CodeGenerator* gen, Register result)
       : OutOfLineCode(gen), result_(result) {}
 
-  void Generate() FINAL { __ xor_(result_, result_); }
+  void Generate() final { __ xor_(result_, result_); }
 
  private:
   Register const result_;
 };
 
 
-class OutOfLineLoadFloat FINAL : public OutOfLineCode {
+class OutOfLineLoadFloat final : public OutOfLineCode {
  public:
   OutOfLineLoadFloat(CodeGenerator* gen, XMMRegister result)
       : OutOfLineCode(gen), result_(result) {}
 
-  void Generate() FINAL { __ pcmpeqd(result_, result_); }
+  void Generate() final { __ pcmpeqd(result_, result_); }
 
  private:
   XMMRegister const result_;
 };
 
 
-class OutOfLineTruncateDoubleToI FINAL : public OutOfLineCode {
+class OutOfLineTruncateDoubleToI final : public OutOfLineCode {
  public:
   OutOfLineTruncateDoubleToI(CodeGenerator* gen, Register result,
                              XMMRegister input)
       : OutOfLineCode(gen), result_(result), input_(input) {}
 
-  void Generate() FINAL {
+  void Generate() final {
     __ sub(esp, Immediate(kDoubleSize));
     __ movsd(MemOperand(esp, 0), input_);
     __ SlowTruncateToI(result_, esp, 0);
@@ -210,6 +223,46 @@
   XMMRegister const input_;
 };
 
+
+class OutOfLineRecordWrite final : public OutOfLineCode {
+ public:
+  OutOfLineRecordWrite(CodeGenerator* gen, Register object, Operand operand,
+                       Register value, Register scratch0, Register scratch1,
+                       RecordWriteMode mode)
+      : OutOfLineCode(gen),
+        object_(object),
+        operand_(operand),
+        value_(value),
+        scratch0_(scratch0),
+        scratch1_(scratch1),
+        mode_(mode) {}
+
+  void Generate() final {
+    if (mode_ > RecordWriteMode::kValueIsPointer) {
+      __ JumpIfSmi(value_, exit());
+    }
+    if (mode_ > RecordWriteMode::kValueIsMap) {
+      __ CheckPageFlag(value_, scratch0_,
+                       MemoryChunk::kPointersToHereAreInterestingMask, zero,
+                       exit());
+    }
+    SaveFPRegsMode const save_fp_mode =
+        frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs;
+    RecordWriteStub stub(isolate(), object_, scratch0_, scratch1_,
+                         EMIT_REMEMBERED_SET, save_fp_mode);
+    __ lea(scratch1_, operand_);
+    __ CallStub(&stub);
+  }
+
+ private:
+  Register const object_;
+  Operand const operand_;
+  Register const value_;
+  Register const scratch0_;
+  Register const scratch1_;
+  RecordWriteMode const mode_;
+};
+
 }  // namespace
 
 
@@ -279,6 +332,28 @@
   } while (false)
 
 
+void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) {
+  int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta);
+  if (sp_slot_delta > 0) {
+    __ add(esp, Immediate(sp_slot_delta * kPointerSize));
+  }
+  frame_access_state()->SetFrameAccessToDefault();
+}
+
+
+void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) {
+  int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta);
+  if (sp_slot_delta < 0) {
+    __ sub(esp, Immediate(-sp_slot_delta * kPointerSize));
+    frame_access_state()->IncreaseSPDelta(-sp_slot_delta);
+  }
+  if (frame()->needs_frame()) {
+    __ mov(ebp, MemOperand(ebp, 0));
+  }
+  frame_access_state()->SetFrameAccessToSP();
+}
+
+
 // Assembles an instruction after register allocation, producing machine code.
 void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
   IA32OperandConverter i(this, instr);
@@ -291,9 +366,25 @@
         __ call(code, RelocInfo::CODE_TARGET);
       } else {
         Register reg = i.InputRegister(0);
-        __ call(Operand(reg, Code::kHeaderSize - kHeapObjectTag));
+        __ add(reg, Immediate(Code::kHeaderSize - kHeapObjectTag));
+        __ call(reg);
       }
-      AddSafepointAndDeopt(instr);
+      RecordCallPosition(instr);
+      frame_access_state()->ClearSPDelta();
+      break;
+    }
+    case kArchTailCallCodeObject: {
+      int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
+      AssembleDeconstructActivationRecord(stack_param_delta);
+      if (HasImmediateInput(instr, 0)) {
+        Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0));
+        __ jmp(code, RelocInfo::CODE_TARGET);
+      } else {
+        Register reg = i.InputRegister(0);
+        __ add(reg, Immediate(Code::kHeaderSize - kHeapObjectTag));
+        __ jmp(reg);
+      }
+      frame_access_state()->ClearSPDelta();
       break;
     }
     case kArchCallJSFunction: {
@@ -305,21 +396,81 @@
         __ Assert(equal, kWrongFunctionContext);
       }
       __ call(FieldOperand(func, JSFunction::kCodeEntryOffset));
-      AddSafepointAndDeopt(instr);
+      RecordCallPosition(instr);
+      frame_access_state()->ClearSPDelta();
+      break;
+    }
+    case kArchTailCallJSFunction: {
+      Register func = i.InputRegister(0);
+      if (FLAG_debug_code) {
+        // Check the function's context matches the context argument.
+        __ cmp(esi, FieldOperand(func, JSFunction::kContextOffset));
+        __ Assert(equal, kWrongFunctionContext);
+      }
+      int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
+      AssembleDeconstructActivationRecord(stack_param_delta);
+      __ jmp(FieldOperand(func, JSFunction::kCodeEntryOffset));
+      frame_access_state()->ClearSPDelta();
+      break;
+    }
+    case kArchLazyBailout: {
+      EnsureSpaceForLazyDeopt();
+      RecordCallPosition(instr);
+      break;
+    }
+    case kArchPrepareCallCFunction: {
+      // Frame alignment requires using FP-relative frame addressing.
+      frame_access_state()->SetFrameAccessToFP();
+      int const num_parameters = MiscField::decode(instr->opcode());
+      __ PrepareCallCFunction(num_parameters, i.TempRegister(0));
+      break;
+    }
+    case kArchPrepareTailCall:
+      AssemblePrepareTailCall(i.InputInt32(instr->InputCount() - 1));
+      break;
+    case kArchCallCFunction: {
+      int const num_parameters = MiscField::decode(instr->opcode());
+      if (HasImmediateInput(instr, 0)) {
+        ExternalReference ref = i.InputExternalReference(0);
+        __ CallCFunction(ref, num_parameters);
+      } else {
+        Register func = i.InputRegister(0);
+        __ CallCFunction(func, num_parameters);
+      }
+      frame_access_state()->SetFrameAccessToDefault();
+      frame_access_state()->ClearSPDelta();
       break;
     }
     case kArchJmp:
       AssembleArchJump(i.InputRpo(0));
       break;
+    case kArchLookupSwitch:
+      AssembleArchLookupSwitch(instr);
+      break;
+    case kArchTableSwitch:
+      AssembleArchTableSwitch(instr);
+      break;
     case kArchNop:
+    case kArchThrowTerminator:
       // don't emit code for nops.
       break;
+    case kArchDeoptimize: {
+      int deopt_state_id =
+          BuildTranslation(instr, -1, 0, OutputFrameStateCombine::Ignore());
+      Deoptimizer::BailoutType bailout_type =
+          Deoptimizer::BailoutType(MiscField::decode(instr->opcode()));
+      AssembleDeoptimizerCall(deopt_state_id, bailout_type);
+      break;
+    }
     case kArchRet:
       AssembleReturn();
       break;
     case kArchStackPointer:
       __ mov(i.OutputRegister(), esp);
       break;
+    case kArchFramePointer:
+      __ mov(i.OutputRegister(), ebp);
+      break;
     case kArchTruncateDoubleToI: {
       auto result = i.OutputRegister();
       auto input = i.InputDoubleRegister(0);
@@ -330,6 +481,24 @@
       __ bind(ool->exit());
       break;
     }
+    case kArchStoreWithWriteBarrier: {
+      RecordWriteMode mode =
+          static_cast<RecordWriteMode>(MiscField::decode(instr->opcode()));
+      Register object = i.InputRegister(0);
+      size_t index = 0;
+      Operand operand = i.MemoryOperand(&index);
+      Register value = i.InputRegister(index);
+      Register scratch0 = i.TempRegister(0);
+      Register scratch1 = i.TempRegister(1);
+      auto ool = new (zone()) OutOfLineRecordWrite(this, object, operand, value,
+                                                   scratch0, scratch1, mode);
+      __ mov(operand, value);
+      __ CheckPageFlag(object, scratch0,
+                       MemoryChunk::kPointersFromHereAreInterestingMask,
+                       not_zero, ool->entry());
+      __ bind(ool->exit());
+      break;
+    }
     case kIA32Add:
       if (HasImmediateInput(instr, 1)) {
         __ add(i.InputOperand(0), i.InputImmediate(1));
@@ -434,6 +603,63 @@
         __ ror_cl(i.OutputOperand());
       }
       break;
+    case kIA32Lzcnt:
+      __ Lzcnt(i.OutputRegister(), i.InputOperand(0));
+      break;
+    case kIA32Tzcnt:
+      __ Tzcnt(i.OutputRegister(), i.InputOperand(0));
+      break;
+    case kIA32Popcnt:
+      __ Popcnt(i.OutputRegister(), i.InputOperand(0));
+      break;
+    case kSSEFloat32Cmp:
+      __ ucomiss(i.InputDoubleRegister(0), i.InputOperand(1));
+      break;
+    case kSSEFloat32Add:
+      __ addss(i.InputDoubleRegister(0), i.InputOperand(1));
+      break;
+    case kSSEFloat32Sub:
+      __ subss(i.InputDoubleRegister(0), i.InputOperand(1));
+      break;
+    case kSSEFloat32Mul:
+      __ mulss(i.InputDoubleRegister(0), i.InputOperand(1));
+      break;
+    case kSSEFloat32Div:
+      __ divss(i.InputDoubleRegister(0), i.InputOperand(1));
+      // Don't delete this mov. It may improve performance on some CPUs,
+      // when there is a (v)mulss depending on the result.
+      __ movaps(i.OutputDoubleRegister(), i.OutputDoubleRegister());
+      break;
+    case kSSEFloat32Max:
+      __ maxss(i.InputDoubleRegister(0), i.InputOperand(1));
+      break;
+    case kSSEFloat32Min:
+      __ minss(i.InputDoubleRegister(0), i.InputOperand(1));
+      break;
+    case kSSEFloat32Sqrt:
+      __ sqrtss(i.OutputDoubleRegister(), i.InputOperand(0));
+      break;
+    case kSSEFloat32Abs: {
+      // TODO(bmeurer): Use 128-bit constants.
+      __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
+      __ psrlq(kScratchDoubleReg, 33);
+      __ andps(i.OutputDoubleRegister(), kScratchDoubleReg);
+      break;
+    }
+    case kSSEFloat32Neg: {
+      // TODO(bmeurer): Use 128-bit constants.
+      __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
+      __ psllq(kScratchDoubleReg, 31);
+      __ xorps(i.OutputDoubleRegister(), kScratchDoubleReg);
+      break;
+    }
+    case kSSEFloat32Round: {
+      CpuFeatureScope sse_scope(masm(), SSE4_1);
+      RoundingMode const mode =
+          static_cast<RoundingMode>(MiscField::decode(instr->opcode()));
+      __ roundss(i.OutputDoubleRegister(), i.InputDoubleRegister(0), mode);
+      break;
+    }
     case kSSEFloat64Cmp:
       __ ucomisd(i.InputDoubleRegister(0), i.InputOperand(1));
       break;
@@ -448,6 +674,15 @@
       break;
     case kSSEFloat64Div:
       __ divsd(i.InputDoubleRegister(0), i.InputOperand(1));
+      // Don't delete this mov. It may improve performance on some CPUs,
+      // when there is a (v)mulsd depending on the result.
+      __ movaps(i.OutputDoubleRegister(), i.OutputDoubleRegister());
+      break;
+    case kSSEFloat64Max:
+      __ maxsd(i.InputDoubleRegister(0), i.InputOperand(1));
+      break;
+    case kSSEFloat64Min:
+      __ minsd(i.InputDoubleRegister(0), i.InputOperand(1));
       break;
     case kSSEFloat64Mod: {
       // TODO(dcarney): alignment is wrong.
@@ -474,41 +709,43 @@
       __ add(esp, Immediate(kDoubleSize));
       break;
     }
+    case kSSEFloat64Abs: {
+      // TODO(bmeurer): Use 128-bit constants.
+      __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
+      __ psrlq(kScratchDoubleReg, 1);
+      __ andpd(i.OutputDoubleRegister(), kScratchDoubleReg);
+      break;
+    }
+    case kSSEFloat64Neg: {
+      // TODO(bmeurer): Use 128-bit constants.
+      __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
+      __ psllq(kScratchDoubleReg, 63);
+      __ xorpd(i.OutputDoubleRegister(), kScratchDoubleReg);
+      break;
+    }
     case kSSEFloat64Sqrt:
       __ sqrtsd(i.OutputDoubleRegister(), i.InputOperand(0));
       break;
-    case kSSEFloat64Floor: {
+    case kSSEFloat64Round: {
       CpuFeatureScope sse_scope(masm(), SSE4_1);
-      __ roundsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
-                 v8::internal::Assembler::kRoundDown);
+      RoundingMode const mode =
+          static_cast<RoundingMode>(MiscField::decode(instr->opcode()));
+      __ roundsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0), mode);
       break;
     }
-    case kSSEFloat64Ceil: {
-      CpuFeatureScope sse_scope(masm(), SSE4_1);
-      __ roundsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
-                 v8::internal::Assembler::kRoundUp);
-      break;
-    }
-    case kSSEFloat64RoundTruncate: {
-      CpuFeatureScope sse_scope(masm(), SSE4_1);
-      __ roundsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
-                 v8::internal::Assembler::kRoundToZero);
-      break;
-    }
-    case kSSECvtss2sd:
+    case kSSEFloat32ToFloat64:
       __ cvtss2sd(i.OutputDoubleRegister(), i.InputOperand(0));
       break;
-    case kSSECvtsd2ss:
+    case kSSEFloat64ToFloat32:
       __ cvtsd2ss(i.OutputDoubleRegister(), i.InputOperand(0));
       break;
     case kSSEFloat64ToInt32:
       __ cvttsd2si(i.OutputRegister(), i.InputOperand(0));
       break;
     case kSSEFloat64ToUint32: {
-      XMMRegister scratch = xmm0;
-      __ Move(scratch, -2147483648.0);
-      __ addsd(scratch, i.InputOperand(0));
-      __ cvttsd2si(i.OutputRegister(), scratch);
+      __ Move(kScratchDoubleReg, -2147483648.0);
+      __ addsd(kScratchDoubleReg, i.InputOperand(0));
+      __ cvttsd2si(i.OutputRegister(), kScratchDoubleReg);
       __ add(i.OutputRegister(), Immediate(0x80000000));
       break;
     }
@@ -518,6 +755,68 @@
     case kSSEUint32ToFloat64:
       __ LoadUint32(i.OutputDoubleRegister(), i.InputOperand(0));
       break;
+    case kSSEFloat64ExtractLowWord32:
+      if (instr->InputAt(0)->IsDoubleStackSlot()) {
+        __ mov(i.OutputRegister(), i.InputOperand(0));
+      } else {
+        __ movd(i.OutputRegister(), i.InputDoubleRegister(0));
+      }
+      break;
+    case kSSEFloat64ExtractHighWord32:
+      if (instr->InputAt(0)->IsDoubleStackSlot()) {
+        __ mov(i.OutputRegister(), i.InputOperand(0, kDoubleSize / 2));
+      } else {
+        __ Pextrd(i.OutputRegister(), i.InputDoubleRegister(0), 1);
+      }
+      break;
+    case kSSEFloat64InsertLowWord32:
+      __ Pinsrd(i.OutputDoubleRegister(), i.InputOperand(1), 0);
+      break;
+    case kSSEFloat64InsertHighWord32:
+      __ Pinsrd(i.OutputDoubleRegister(), i.InputOperand(1), 1);
+      break;
+    case kSSEFloat64LoadLowWord32:
+      __ movd(i.OutputDoubleRegister(), i.InputOperand(0));
+      break;
+    case kAVXFloat32Add: {
+      CpuFeatureScope avx_scope(masm(), AVX);
+      __ vaddss(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+                i.InputOperand(1));
+      break;
+    }
+    case kAVXFloat32Sub: {
+      CpuFeatureScope avx_scope(masm(), AVX);
+      __ vsubss(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+                i.InputOperand(1));
+      break;
+    }
+    case kAVXFloat32Mul: {
+      CpuFeatureScope avx_scope(masm(), AVX);
+      __ vmulss(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+                i.InputOperand(1));
+      break;
+    }
+    case kAVXFloat32Div: {
+      CpuFeatureScope avx_scope(masm(), AVX);
+      __ vdivss(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+                i.InputOperand(1));
+      // Don't delete this mov. It may improve performance on some CPUs,
+      // when there is a (v)mulss depending on the result.
+      __ movaps(i.OutputDoubleRegister(), i.OutputDoubleRegister());
+      break;
+    }
+    case kAVXFloat32Max: {
+      CpuFeatureScope avx_scope(masm(), AVX);
+      __ vmaxss(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+                i.InputOperand(1));
+      break;
+    }
+    case kAVXFloat32Min: {
+      CpuFeatureScope avx_scope(masm(), AVX);
+      __ vminss(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+                i.InputOperand(1));
+      break;
+    }
     case kAVXFloat64Add: {
       CpuFeatureScope avx_scope(masm(), AVX);
       __ vaddsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
@@ -540,6 +839,53 @@
       CpuFeatureScope avx_scope(masm(), AVX);
       __ vdivsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
                 i.InputOperand(1));
+      // Don't delete this mov. It may improve performance on some CPUs,
+      // when there is a (v)mulsd depending on the result.
+      __ movaps(i.OutputDoubleRegister(), i.OutputDoubleRegister());
+      break;
+    }
+    case kAVXFloat64Max: {
+      CpuFeatureScope avx_scope(masm(), AVX);
+      __ vmaxsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+                i.InputOperand(1));
+      break;
+    }
+    case kAVXFloat64Min: {
+      CpuFeatureScope avx_scope(masm(), AVX);
+      __ vminsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+                i.InputOperand(1));
+      break;
+    }
+    case kAVXFloat32Abs: {
+      // TODO(bmeurer): Use RIP relative 128-bit constants.
+      __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
+      __ psrlq(kScratchDoubleReg, 33);
+      CpuFeatureScope avx_scope(masm(), AVX);
+      __ vandps(i.OutputDoubleRegister(), kScratchDoubleReg, i.InputOperand(0));
+      break;
+    }
+    case kAVXFloat32Neg: {
+      // TODO(bmeurer): Use RIP relative 128-bit constants.
+      __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
+      __ psllq(kScratchDoubleReg, 31);
+      CpuFeatureScope avx_scope(masm(), AVX);
+      __ vxorps(i.OutputDoubleRegister(), kScratchDoubleReg, i.InputOperand(0));
+      break;
+    }
+    case kAVXFloat64Abs: {
+      // TODO(bmeurer): Use RIP relative 128-bit constants.
+      __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
+      __ psrlq(kScratchDoubleReg, 1);
+      CpuFeatureScope avx_scope(masm(), AVX);
+      __ vandpd(i.OutputDoubleRegister(), kScratchDoubleReg, i.InputOperand(0));
+      break;
+    }
+    case kAVXFloat64Neg: {
+      // TODO(bmeurer): Use RIP relative 128-bit constants.
+      __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
+      __ psllq(kScratchDoubleReg, 63);
+      CpuFeatureScope avx_scope(masm(), AVX);
+      __ vxorpd(i.OutputDoubleRegister(), kScratchDoubleReg, i.InputOperand(0));
       break;
     }
     case kIA32Movsxbl:
@@ -549,7 +895,7 @@
       __ movzx_b(i.OutputRegister(), i.MemoryOperand());
       break;
     case kIA32Movb: {
-      int index = 0;
+      size_t index = 0;
       Operand operand = i.MemoryOperand(&index);
       if (HasImmediateInput(instr, index)) {
         __ mov_b(operand, i.InputInt8(index));
@@ -565,7 +911,7 @@
       __ movzx_w(i.OutputRegister(), i.MemoryOperand());
       break;
     case kIA32Movw: {
-      int index = 0;
+      size_t index = 0;
       Operand operand = i.MemoryOperand(&index);
       if (HasImmediateInput(instr, index)) {
         __ mov_w(operand, i.InputInt16(index));
@@ -578,7 +924,7 @@
       if (instr->HasOutput()) {
         __ mov(i.OutputRegister(), i.MemoryOperand());
       } else {
-        int index = 0;
+        size_t index = 0;
         Operand operand = i.MemoryOperand(&index);
         if (HasImmediateInput(instr, index)) {
           __ mov(operand, i.InputImmediate(index));
@@ -591,7 +937,7 @@
       if (instr->HasOutput()) {
         __ movsd(i.OutputDoubleRegister(), i.MemoryOperand());
       } else {
-        int index = 0;
+        size_t index = 0;
         Operand operand = i.MemoryOperand(&index);
         __ movsd(operand, i.InputDoubleRegister(index));
       }
@@ -600,11 +946,25 @@
       if (instr->HasOutput()) {
         __ movss(i.OutputDoubleRegister(), i.MemoryOperand());
       } else {
-        int index = 0;
+        size_t index = 0;
         Operand operand = i.MemoryOperand(&index);
         __ movss(operand, i.InputDoubleRegister(index));
       }
       break;
+    case kIA32BitcastFI:
+      if (instr->InputAt(0)->IsDoubleStackSlot()) {
+        __ mov(i.OutputRegister(), i.InputOperand(0));
+      } else {
+        __ movd(i.OutputRegister(), i.InputDoubleRegister(0));
+      }
+      break;
+    case kIA32BitcastIF:
+      if (instr->InputAt(0)->IsRegister()) {
+        __ movd(i.OutputDoubleRegister(), i.InputRegister(0));
+      } else {
+        __ movss(i.OutputDoubleRegister(), i.InputOperand(0));
+      }
+      break;
     case kIA32Lea: {
       AddressingMode mode = AddressingModeField::decode(instr->opcode());
       // Shorten "leal" to "addl", "subl" or "shll" if the register allocation
@@ -640,22 +1000,60 @@
       }
       break;
     }
-    case kIA32Push:
-      if (HasImmediateInput(instr, 0)) {
-        __ push(i.InputImmediate(0));
+    case kIA32PushFloat32:
+      if (instr->InputAt(0)->IsDoubleRegister()) {
+        __ sub(esp, Immediate(kDoubleSize));
+        __ movss(Operand(esp, 0), i.InputDoubleRegister(0));
+        frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize);
+      } else if (HasImmediateInput(instr, 0)) {
+        __ Move(kScratchDoubleReg, i.InputDouble(0));
+        __ sub(esp, Immediate(kDoubleSize));
+        __ movss(Operand(esp, 0), kScratchDoubleReg);
+        frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize);
       } else {
-        __ push(i.InputOperand(0));
+        __ movsd(kScratchDoubleReg, i.InputOperand(0));
+        __ sub(esp, Immediate(kDoubleSize));
+        __ movss(Operand(esp, 0), kScratchDoubleReg);
+        frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize);
       }
       break;
-    case kIA32StoreWriteBarrier: {
-      Register object = i.InputRegister(0);
-      Register index = i.InputRegister(1);
-      Register value = i.InputRegister(2);
-      __ mov(Operand(object, index, times_1, 0), value);
-      __ lea(index, Operand(object, index, times_1, 0));
-      SaveFPRegsMode mode =
-          frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs;
-      __ RecordWrite(object, index, value, mode);
+    case kIA32PushFloat64:
+      if (instr->InputAt(0)->IsDoubleRegister()) {
+        __ sub(esp, Immediate(kDoubleSize));
+        __ movsd(Operand(esp, 0), i.InputDoubleRegister(0));
+        frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize);
+      } else if (HasImmediateInput(instr, 0)) {
+        __ Move(kScratchDoubleReg, i.InputDouble(0));
+        __ sub(esp, Immediate(kDoubleSize));
+        __ movsd(Operand(esp, 0), kScratchDoubleReg);
+        frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize);
+      } else {
+        __ movsd(kScratchDoubleReg, i.InputOperand(0));
+        __ sub(esp, Immediate(kDoubleSize));
+        __ movsd(Operand(esp, 0), kScratchDoubleReg);
+        frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize);
+      }
+      break;
+    case kIA32Push:
+      if (instr->InputAt(0)->IsDoubleRegister()) {
+        __ sub(esp, Immediate(kDoubleSize));
+        __ movsd(Operand(esp, 0), i.InputDoubleRegister(0));
+        frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize);
+      } else if (HasImmediateInput(instr, 0)) {
+        __ push(i.InputImmediate(0));
+        frame_access_state()->IncreaseSPDelta(1);
+      } else {
+        __ push(i.InputOperand(0));
+        frame_access_state()->IncreaseSPDelta(1);
+      }
+      break;
+    case kIA32Poke: {
+      int const slot = MiscField::decode(instr->opcode());
+      if (HasImmediateInput(instr, 0)) {
+        __ mov(Operand(esp, slot * kPointerSize), i.InputImmediate(0));
+      } else {
+        __ mov(Operand(esp, slot * kPointerSize), i.InputRegister(0));
+      }
       break;
     }
     case kCheckedLoadInt8:
@@ -694,8 +1092,18 @@
     case kCheckedStoreFloat64:
       ASSEMBLE_CHECKED_STORE_FLOAT(movsd);
       break;
+    case kIA32StackCheck: {
+      ExternalReference const stack_limit =
+          ExternalReference::address_of_stack_limit(isolate());
+      __ cmp(esp, Operand::StaticVariable(stack_limit));
+      break;
+    }
+    case kCheckedLoadWord64:
+    case kCheckedStoreWord64:
+      UNREACHABLE();  // currently unsupported checked int64 load/store.
+      break;
   }
-}
+}  // NOLINT(readability/fn_size)
 
 
 // Assembles a branch after an instruction.
@@ -730,27 +1138,15 @@
     case kSignedGreaterThan:
       __ j(greater, tlabel);
       break;
-    case kUnorderedLessThan:
-      __ j(parity_even, flabel, flabel_distance);
-    // Fall through.
     case kUnsignedLessThan:
       __ j(below, tlabel);
       break;
-    case kUnorderedGreaterThanOrEqual:
-      __ j(parity_even, tlabel);
-    // Fall through.
     case kUnsignedGreaterThanOrEqual:
       __ j(above_equal, tlabel);
       break;
-    case kUnorderedLessThanOrEqual:
-      __ j(parity_even, flabel, flabel_distance);
-    // Fall through.
     case kUnsignedLessThanOrEqual:
       __ j(below_equal, tlabel);
       break;
-    case kUnorderedGreaterThan:
-      __ j(parity_even, tlabel);
-    // Fall through.
     case kUnsignedGreaterThan:
       __ j(above, tlabel);
       break;
@@ -760,13 +1156,16 @@
     case kNotOverflow:
       __ j(no_overflow, tlabel);
       break;
+    default:
+      UNREACHABLE();
+      break;
   }
   // Add a jump if not falling through to the next block.
   if (!branch->fallthru) __ jmp(flabel);
 }
 
 
-void CodeGenerator::AssembleArchJump(BasicBlock::RpoNumber target) {
+void CodeGenerator::AssembleArchJump(RpoNumber target) {
   if (!IsNextInAssemblyOrder(target)) __ jmp(GetLabel(target));
 }
 
@@ -780,7 +1179,7 @@
   // Materialize a full 32-bit 1 or 0 value. The result register is always the
   // last output of the instruction.
   Label check;
-  DCHECK_NE(0, instr->OutputCount());
+  DCHECK_NE(0u, instr->OutputCount());
   Register reg = i.OutputRegister(instr->OutputCount() - 1);
   Condition cc = no_condition;
   switch (condition) {
@@ -812,35 +1211,15 @@
     case kSignedGreaterThan:
       cc = greater;
       break;
-    case kUnorderedLessThan:
-      __ j(parity_odd, &check, Label::kNear);
-      __ Move(reg, Immediate(0));
-      __ jmp(&done, Label::kNear);
-    // Fall through.
     case kUnsignedLessThan:
       cc = below;
       break;
-    case kUnorderedGreaterThanOrEqual:
-      __ j(parity_odd, &check, Label::kNear);
-      __ mov(reg, Immediate(1));
-      __ jmp(&done, Label::kNear);
-    // Fall through.
     case kUnsignedGreaterThanOrEqual:
       cc = above_equal;
       break;
-    case kUnorderedLessThanOrEqual:
-      __ j(parity_odd, &check, Label::kNear);
-      __ Move(reg, Immediate(0));
-      __ jmp(&done, Label::kNear);
-    // Fall through.
     case kUnsignedLessThanOrEqual:
       cc = below_equal;
       break;
-    case kUnorderedGreaterThan:
-      __ j(parity_odd, &check, Label::kNear);
-      __ mov(reg, Immediate(1));
-      __ jmp(&done, Label::kNear);
-    // Fall through.
     case kUnsignedGreaterThan:
       cc = above;
       break;
@@ -850,6 +1229,9 @@
     case kNotOverflow:
       cc = no_overflow;
       break;
+    default:
+      UNREACHABLE();
+      break;
   }
   __ bind(&check);
   if (reg.is_byte_register()) {
@@ -869,9 +1251,36 @@
 }
 
 
-void CodeGenerator::AssembleDeoptimizerCall(int deoptimization_id) {
+void CodeGenerator::AssembleArchLookupSwitch(Instruction* instr) {
+  IA32OperandConverter i(this, instr);
+  Register input = i.InputRegister(0);
+  for (size_t index = 2; index < instr->InputCount(); index += 2) {
+    __ cmp(input, Immediate(i.InputInt32(index + 0)));
+    __ j(equal, GetLabel(i.InputRpo(index + 1)));
+  }
+  AssembleArchJump(i.InputRpo(1));
+}
+
+
+void CodeGenerator::AssembleArchTableSwitch(Instruction* instr) {
+  IA32OperandConverter i(this, instr);
+  Register input = i.InputRegister(0);
+  size_t const case_count = instr->InputCount() - 2;
+  Label** cases = zone()->NewArray<Label*>(case_count);
+  for (size_t index = 0; index < case_count; ++index) {
+    cases[index] = GetLabel(i.InputRpo(index + 2));
+  }
+  Label* const table = AddJumpTable(cases, case_count);
+  __ cmp(input, Immediate(case_count));
+  __ j(above_equal, GetLabel(i.InputRpo(1)));
+  __ jmp(Operand::JumpTable(input, times_4, table));
+}
+
+
+void CodeGenerator::AssembleDeoptimizerCall(
+    int deoptimization_id, Deoptimizer::BailoutType bailout_type) {
   Address deopt_entry = Deoptimizer::GetDeoptimizationEntry(
-      isolate(), deoptimization_id, Deoptimizer::LAZY);
+      isolate(), deoptimization_id, bailout_type);
   __ call(deopt_entry, RelocInfo::RUNTIME_ENTRY);
 }
 
@@ -1006,77 +1415,91 @@
 
 void CodeGenerator::AssemblePrologue() {
   CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
-  Frame* frame = this->frame();
-  int stack_slots = frame->GetSpillSlotCount();
-  if (descriptor->kind() == CallDescriptor::kCallAddress) {
+  if (descriptor->IsCFunctionCall()) {
     // Assemble a prologue similar the to cdecl calling convention.
     __ push(ebp);
     __ mov(ebp, esp);
-    const RegList saves = descriptor->CalleeSavedRegisters();
-    if (saves != 0) {  // Save callee-saved registers.
-      int register_save_area_size = 0;
-      for (int i = Register::kNumRegisters - 1; i >= 0; i--) {
-        if (!((1 << i) & saves)) continue;
-        __ push(Register::from_code(i));
-        register_save_area_size += kPointerSize;
-      }
-      frame->SetRegisterSaveAreaSize(register_save_area_size);
-    }
   } else if (descriptor->IsJSFunctionCall()) {
-    CompilationInfo* info = this->info();
-    __ Prologue(info->IsCodePreAgingActive());
-    frame->SetRegisterSaveAreaSize(
-        StandardFrameConstants::kFixedFrameSizeFromFp);
-  } else {
+    // TODO(turbofan): this prologue is redundant with OSR, but still needed for
+    // code aging.
+    __ Prologue(this->info()->GeneratePreagedPrologue());
+  } else if (frame()->needs_frame()) {
     __ StubPrologue();
-    frame->SetRegisterSaveAreaSize(
-        StandardFrameConstants::kFixedFrameSizeFromFp);
+  } else {
+    frame()->SetElidedFrameSizeInSlots(kPCOnStackSize / kPointerSize);
   }
-  if (stack_slots > 0) {
-    __ sub(esp, Immediate(stack_slots * kPointerSize));
+  frame_access_state()->SetFrameAccessToDefault();
+
+  int stack_shrink_slots = frame()->GetSpillSlotCount();
+  if (info()->is_osr()) {
+    // TurboFan OSR-compiled functions cannot be entered directly.
+    __ Abort(kShouldNotDirectlyEnterOsrFunction);
+
+    // Unoptimized code jumps directly to this entrypoint while the unoptimized
+    // frame is still on the stack. Optimized code uses OSR values directly from
+    // the unoptimized frame. Thus, all that needs to be done is to allocate the
+    // remaining stack slots.
+    if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --");
+    osr_pc_offset_ = __ pc_offset();
+    // TODO(titzer): cannot address target function == local #-1
+    __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
+    stack_shrink_slots -= OsrHelper(info()).UnoptimizedFrameSlots();
+  }
+
+  const RegList saves = descriptor->CalleeSavedRegisters();
+  if (stack_shrink_slots > 0) {
+    __ sub(esp, Immediate(stack_shrink_slots * kPointerSize));
+  }
+
+  if (saves != 0) {  // Save callee-saved registers.
+    DCHECK(!info()->is_osr());
+    int pushed = 0;
+    for (int i = Register::kNumRegisters - 1; i >= 0; i--) {
+      if (!((1 << i) & saves)) continue;
+      __ push(Register::from_code(i));
+      ++pushed;
+    }
+    frame()->AllocateSavedCalleeRegisterSlots(pushed);
   }
 }
 
 
 void CodeGenerator::AssembleReturn() {
   CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
-  if (descriptor->kind() == CallDescriptor::kCallAddress) {
-    const RegList saves = descriptor->CalleeSavedRegisters();
-    if (frame()->GetRegisterSaveAreaSize() > 0) {
-      // Remove this frame's spill slots first.
-      int stack_slots = frame()->GetSpillSlotCount();
-      if (stack_slots > 0) {
-        __ add(esp, Immediate(stack_slots * kPointerSize));
-      }
-      // Restore registers.
-      if (saves != 0) {
-        for (int i = 0; i < Register::kNumRegisters; i++) {
-          if (!((1 << i) & saves)) continue;
-          __ pop(Register::from_code(i));
-        }
-      }
-      __ pop(ebp);  // Pop caller's frame pointer.
-      __ ret(0);
-    } else {
-      // No saved registers.
-      __ mov(esp, ebp);  // Move stack pointer back to frame pointer.
-      __ pop(ebp);       // Pop caller's frame pointer.
-      __ ret(0);
+
+  const RegList saves = descriptor->CalleeSavedRegisters();
+  // Restore registers.
+  if (saves != 0) {
+    for (int i = 0; i < Register::kNumRegisters; i++) {
+      if (!((1 << i) & saves)) continue;
+      __ pop(Register::from_code(i));
     }
-  } else {
+  }
+
+  if (descriptor->IsCFunctionCall()) {
     __ mov(esp, ebp);  // Move stack pointer back to frame pointer.
     __ pop(ebp);       // Pop caller's frame pointer.
-    int pop_count = descriptor->IsJSFunctionCall()
-                        ? static_cast<int>(descriptor->JSParameterCount())
-                        : 0;
-    __ ret(pop_count * kPointerSize);
+  } else if (frame()->needs_frame()) {
+    // Canonicalize JSFunction return sites for now.
+    if (return_label_.is_bound()) {
+      __ jmp(&return_label_);
+      return;
+    } else {
+      __ bind(&return_label_);
+      __ mov(esp, ebp);  // Move stack pointer back to frame pointer.
+      __ pop(ebp);       // Pop caller's frame pointer.
+    }
   }
+  size_t pop_size = descriptor->StackParameterCount() * kPointerSize;
+  // Might need ecx for scratch if pop_size is too big.
+  DCHECK_EQ(0u, descriptor->CalleeSavedRegisters() & ecx.bit());
+  __ Ret(static_cast<int>(pop_size), ecx);
 }
 
 
 void CodeGenerator::AssembleMove(InstructionOperand* source,
                                  InstructionOperand* destination) {
-  IA32OperandConverter g(this, NULL);
+  IA32OperandConverter g(this, nullptr);
   // Dispatch on the source and destination operand kinds.  Not all
   // combinations are possible.
   if (source->IsRegister()) {
@@ -1099,7 +1522,18 @@
     Constant src_constant = g.ToConstant(source);
     if (src_constant.type() == Constant::kHeapObject) {
       Handle<HeapObject> src = src_constant.ToHeapObject();
-      if (destination->IsRegister()) {
+      int offset;
+      if (IsMaterializableFromFrame(src, &offset)) {
+        if (destination->IsRegister()) {
+          Register dst = g.ToRegister(destination);
+          __ mov(dst, g.ToMaterializableOperand(offset));
+        } else {
+          DCHECK(destination->IsStackSlot());
+          Operand dst = g.ToOperand(destination);
+          __ push(g.ToMaterializableOperand(offset));
+          __ pop(dst);
+        }
+      } else if (destination->IsRegister()) {
         Register dst = g.ToRegister(destination);
         __ LoadHeapObject(dst, src);
       } else {
@@ -1163,10 +1597,9 @@
       XMMRegister dst = g.ToDoubleRegister(destination);
       __ movsd(dst, src);
     } else {
-      // We rely on having xmm0 available as a fixed scratch register.
       Operand dst = g.ToOperand(destination);
-      __ movsd(xmm0, src);
-      __ movsd(dst, xmm0);
+      __ movsd(kScratchDoubleReg, src);
+      __ movsd(dst, kScratchDoubleReg);
     }
   } else {
     UNREACHABLE();
@@ -1176,53 +1609,64 @@
 
 void CodeGenerator::AssembleSwap(InstructionOperand* source,
                                  InstructionOperand* destination) {
-  IA32OperandConverter g(this, NULL);
+  IA32OperandConverter g(this, nullptr);
   // Dispatch on the source and destination operand kinds.  Not all
   // combinations are possible.
   if (source->IsRegister() && destination->IsRegister()) {
     // Register-register.
     Register src = g.ToRegister(source);
     Register dst = g.ToRegister(destination);
-    __ xchg(dst, src);
+    __ push(src);
+    __ mov(src, dst);
+    __ pop(dst);
   } else if (source->IsRegister() && destination->IsStackSlot()) {
     // Register-memory.
-    __ xchg(g.ToRegister(source), g.ToOperand(destination));
+    Register src = g.ToRegister(source);
+    __ push(src);
+    frame_access_state()->IncreaseSPDelta(1);
+    Operand dst = g.ToOperand(destination);
+    __ mov(src, dst);
+    frame_access_state()->IncreaseSPDelta(-1);
+    dst = g.ToOperand(destination);
+    __ pop(dst);
   } else if (source->IsStackSlot() && destination->IsStackSlot()) {
     // Memory-memory.
-    Operand src = g.ToOperand(source);
-    Operand dst = g.ToOperand(destination);
-    __ push(dst);
-    __ push(src);
-    __ pop(dst);
-    __ pop(src);
+    Operand dst1 = g.ToOperand(destination);
+    __ push(dst1);
+    frame_access_state()->IncreaseSPDelta(1);
+    Operand src1 = g.ToOperand(source);
+    __ push(src1);
+    Operand dst2 = g.ToOperand(destination);
+    __ pop(dst2);
+    frame_access_state()->IncreaseSPDelta(-1);
+    Operand src2 = g.ToOperand(source);
+    __ pop(src2);
   } else if (source->IsDoubleRegister() && destination->IsDoubleRegister()) {
-    // XMM register-register swap. We rely on having xmm0
-    // available as a fixed scratch register.
+    // XMM register-register swap.
     XMMRegister src = g.ToDoubleRegister(source);
     XMMRegister dst = g.ToDoubleRegister(destination);
-    __ movaps(xmm0, src);
+    __ movaps(kScratchDoubleReg, src);
     __ movaps(src, dst);
-    __ movaps(dst, xmm0);
+    __ movaps(dst, kScratchDoubleReg);
   } else if (source->IsDoubleRegister() && destination->IsDoubleStackSlot()) {
-    // XMM register-memory swap.  We rely on having xmm0
-    // available as a fixed scratch register.
+    // XMM register-memory swap.
     XMMRegister reg = g.ToDoubleRegister(source);
     Operand other = g.ToOperand(destination);
-    __ movsd(xmm0, other);
+    __ movsd(kScratchDoubleReg, other);
     __ movsd(other, reg);
-    __ movaps(reg, xmm0);
+    __ movaps(reg, kScratchDoubleReg);
   } else if (source->IsDoubleStackSlot() && destination->IsDoubleStackSlot()) {
     // Double-width memory-to-memory.
     Operand src0 = g.ToOperand(source);
     Operand src1 = g.HighOperand(source);
     Operand dst0 = g.ToOperand(destination);
     Operand dst1 = g.HighOperand(destination);
-    __ movsd(xmm0, dst0);  // Save destination in xmm0.
-    __ push(src0);         // Then use stack to copy source to destination.
+    __ movsd(kScratchDoubleReg, dst0);  // Save destination in scratch register.
+    __ push(src0);  // Then use stack to copy source to destination.
     __ pop(dst0);
     __ push(src1);
     __ pop(dst1);
-    __ movsd(src0, xmm0);
+    __ movsd(src0, kScratchDoubleReg);
   } else {
     // No other combinations are possible.
     UNREACHABLE();
@@ -1230,21 +1674,29 @@
 }
 
 
+void CodeGenerator::AssembleJumpTable(Label** targets, size_t target_count) {
+  for (size_t index = 0; index < target_count; ++index) {
+    __ dd(targets[index]);
+  }
+}
+
+
 void CodeGenerator::AddNopForSmiCodeInlining() { __ nop(); }
 
 
 void CodeGenerator::EnsureSpaceForLazyDeopt() {
-  int space_needed = Deoptimizer::patch_size();
-  if (!info()->IsStub()) {
-    // Ensure that we have enough space after the previous lazy-bailout
-    // instruction for patching the code here.
-    int current_pc = masm()->pc_offset();
-    if (current_pc < last_lazy_deopt_pc_ + space_needed) {
-      int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc;
-      __ Nop(padding_size);
-    }
+  if (!info()->ShouldEnsureSpaceForLazyDeopt()) {
+    return;
   }
-  MarkLazyDeoptSite();
+
+  int space_needed = Deoptimizer::patch_size();
+  // Ensure that we have enough space after the previous lazy-bailout
+  // instruction for patching the code here.
+  int current_pc = masm()->pc_offset();
+  if (current_pc < last_lazy_deopt_pc_ + space_needed) {
+    int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc;
+    __ Nop(padding_size);
+  }
 }
 
 #undef __
diff --git a/src/compiler/ia32/instruction-codes-ia32.h b/src/compiler/ia32/instruction-codes-ia32.h
index ec9fd18..816487d 100644
--- a/src/compiler/ia32/instruction-codes-ia32.h
+++ b/src/compiler/ia32/instruction-codes-ia32.h
@@ -30,26 +30,59 @@
   V(IA32Shr)                       \
   V(IA32Sar)                       \
   V(IA32Ror)                       \
+  V(IA32Lzcnt)                     \
+  V(IA32Tzcnt)                     \
+  V(IA32Popcnt)                    \
+  V(SSEFloat32Cmp)                 \
+  V(SSEFloat32Add)                 \
+  V(SSEFloat32Sub)                 \
+  V(SSEFloat32Mul)                 \
+  V(SSEFloat32Div)                 \
+  V(SSEFloat32Max)                 \
+  V(SSEFloat32Min)                 \
+  V(SSEFloat32Abs)                 \
+  V(SSEFloat32Neg)                 \
+  V(SSEFloat32Sqrt)                \
+  V(SSEFloat32Round)               \
   V(SSEFloat64Cmp)                 \
   V(SSEFloat64Add)                 \
   V(SSEFloat64Sub)                 \
   V(SSEFloat64Mul)                 \
   V(SSEFloat64Div)                 \
   V(SSEFloat64Mod)                 \
+  V(SSEFloat64Max)                 \
+  V(SSEFloat64Min)                 \
+  V(SSEFloat64Abs)                 \
+  V(SSEFloat64Neg)                 \
   V(SSEFloat64Sqrt)                \
-  V(SSEFloat64Floor)               \
-  V(SSEFloat64Ceil)                \
-  V(SSEFloat64RoundTruncate)       \
-  V(SSECvtss2sd)                   \
-  V(SSECvtsd2ss)                   \
+  V(SSEFloat64Round)               \
+  V(SSEFloat32ToFloat64)           \
+  V(SSEFloat64ToFloat32)           \
   V(SSEFloat64ToInt32)             \
   V(SSEFloat64ToUint32)            \
   V(SSEInt32ToFloat64)             \
   V(SSEUint32ToFloat64)            \
+  V(SSEFloat64ExtractLowWord32)    \
+  V(SSEFloat64ExtractHighWord32)   \
+  V(SSEFloat64InsertLowWord32)     \
+  V(SSEFloat64InsertHighWord32)    \
+  V(SSEFloat64LoadLowWord32)       \
+  V(AVXFloat32Add)                 \
+  V(AVXFloat32Sub)                 \
+  V(AVXFloat32Mul)                 \
+  V(AVXFloat32Div)                 \
+  V(AVXFloat32Max)                 \
+  V(AVXFloat32Min)                 \
   V(AVXFloat64Add)                 \
   V(AVXFloat64Sub)                 \
   V(AVXFloat64Mul)                 \
   V(AVXFloat64Div)                 \
+  V(AVXFloat64Max)                 \
+  V(AVXFloat64Min)                 \
+  V(AVXFloat64Abs)                 \
+  V(AVXFloat64Neg)                 \
+  V(AVXFloat32Abs)                 \
+  V(AVXFloat32Neg)                 \
   V(IA32Movsxbl)                   \
   V(IA32Movzxbl)                   \
   V(IA32Movb)                      \
@@ -59,9 +92,14 @@
   V(IA32Movl)                      \
   V(IA32Movss)                     \
   V(IA32Movsd)                     \
+  V(IA32BitcastFI)                 \
+  V(IA32BitcastIF)                 \
   V(IA32Lea)                       \
   V(IA32Push)                      \
-  V(IA32StoreWriteBarrier)
+  V(IA32PushFloat32)               \
+  V(IA32PushFloat64)               \
+  V(IA32Poke)                      \
+  V(IA32StackCheck)
 
 
 // Addressing modes represent the "shape" of inputs to an instruction.
diff --git a/src/compiler/ia32/instruction-scheduler-ia32.cc b/src/compiler/ia32/instruction-scheduler-ia32.cc
new file mode 100644
index 0000000..0a8fcac
--- /dev/null
+++ b/src/compiler/ia32/instruction-scheduler-ia32.cc
@@ -0,0 +1,135 @@
+// Copyright 2015 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/instruction-scheduler.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+bool InstructionScheduler::SchedulerSupported() { return true; }
+
+
+int InstructionScheduler::GetTargetInstructionFlags(
+    const Instruction* instr) const {
+  switch (instr->arch_opcode()) {
+    case kIA32Add:
+    case kIA32And:
+    case kIA32Cmp:
+    case kIA32Test:
+    case kIA32Or:
+    case kIA32Xor:
+    case kIA32Sub:
+    case kIA32Imul:
+    case kIA32ImulHigh:
+    case kIA32UmulHigh:
+    case kIA32Idiv:
+    case kIA32Udiv:
+    case kIA32Not:
+    case kIA32Neg:
+    case kIA32Shl:
+    case kIA32Shr:
+    case kIA32Sar:
+    case kIA32Ror:
+    case kIA32Lzcnt:
+    case kIA32Tzcnt:
+    case kIA32Popcnt:
+    case kIA32Lea:
+    case kSSEFloat32Cmp:
+    case kSSEFloat32Add:
+    case kSSEFloat32Sub:
+    case kSSEFloat32Mul:
+    case kSSEFloat32Div:
+    case kSSEFloat32Max:
+    case kSSEFloat32Min:
+    case kSSEFloat32Abs:
+    case kSSEFloat32Neg:
+    case kSSEFloat32Sqrt:
+    case kSSEFloat32Round:
+    case kSSEFloat64Cmp:
+    case kSSEFloat64Add:
+    case kSSEFloat64Sub:
+    case kSSEFloat64Mul:
+    case kSSEFloat64Div:
+    case kSSEFloat64Mod:
+    case kSSEFloat64Max:
+    case kSSEFloat64Min:
+    case kSSEFloat64Abs:
+    case kSSEFloat64Neg:
+    case kSSEFloat64Sqrt:
+    case kSSEFloat64Round:
+    case kSSEFloat32ToFloat64:
+    case kSSEFloat64ToFloat32:
+    case kSSEFloat64ToInt32:
+    case kSSEFloat64ToUint32:
+    case kSSEInt32ToFloat64:
+    case kSSEUint32ToFloat64:
+    case kSSEFloat64ExtractLowWord32:
+    case kSSEFloat64ExtractHighWord32:
+    case kSSEFloat64InsertLowWord32:
+    case kSSEFloat64InsertHighWord32:
+    case kSSEFloat64LoadLowWord32:
+    case kAVXFloat32Add:
+    case kAVXFloat32Sub:
+    case kAVXFloat32Mul:
+    case kAVXFloat32Div:
+    case kAVXFloat32Max:
+    case kAVXFloat32Min:
+    case kAVXFloat64Add:
+    case kAVXFloat64Sub:
+    case kAVXFloat64Mul:
+    case kAVXFloat64Div:
+    case kAVXFloat64Max:
+    case kAVXFloat64Min:
+    case kAVXFloat64Abs:
+    case kAVXFloat64Neg:
+    case kAVXFloat32Abs:
+    case kAVXFloat32Neg:
+    case kIA32BitcastFI:
+    case kIA32BitcastIF:
+      return (instr->addressing_mode() == kMode_None)
+          ? kNoOpcodeFlags
+          : kIsLoadOperation | kHasSideEffect;
+
+    case kIA32Movsxbl:
+    case kIA32Movzxbl:
+    case kIA32Movb:
+    case kIA32Movsxwl:
+    case kIA32Movzxwl:
+    case kIA32Movw:
+    case kIA32Movl:
+    case kIA32Movss:
+    case kIA32Movsd:
+      // Moves are used for memory load/store operations.
+      return instr->HasOutput() ? kIsLoadOperation : kHasSideEffect;
+
+    case kIA32StackCheck:
+      return kIsLoadOperation;
+
+    case kIA32Push:
+    case kIA32PushFloat32:
+    case kIA32PushFloat64:
+    case kIA32Poke:
+      return kHasSideEffect;
+
+#define CASE(Name) case k##Name:
+    COMMON_ARCH_OPCODE_LIST(CASE)
+#undef CASE
+      // Already covered in architecture independent code.
+      UNREACHABLE();
+  }
+
+  UNREACHABLE();
+  return kNoOpcodeFlags;
+}
+
+
+int InstructionScheduler::GetInstructionLatency(const Instruction* instr) {
+  // TODO(all): Add instruction cost modeling.
+  return 1;
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/ia32/instruction-selector-ia32.cc b/src/compiler/ia32/instruction-selector-ia32.cc
index 16063ab..0906452 100644
--- a/src/compiler/ia32/instruction-selector-ia32.cc
+++ b/src/compiler/ia32/instruction-selector-ia32.cc
@@ -2,25 +2,31 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "src/base/adapters.h"
 #include "src/compiler/instruction-selector-impl.h"
 #include "src/compiler/node-matchers.h"
-#include "src/compiler/node-properties-inl.h"
+#include "src/compiler/node-properties.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
 // Adds IA32-specific methods for generating operands.
-class IA32OperandGenerator FINAL : public OperandGenerator {
+class IA32OperandGenerator final : public OperandGenerator {
  public:
   explicit IA32OperandGenerator(InstructionSelector* selector)
       : OperandGenerator(selector) {}
 
-  InstructionOperand* UseByteRegister(Node* node) {
-    // TODO(dcarney): relax constraint.
+  InstructionOperand UseByteRegister(Node* node) {
+    // TODO(titzer): encode byte register use constraints.
     return UseFixed(node, edx);
   }
 
+  InstructionOperand DefineAsByteRegister(Node* node) {
+    // TODO(titzer): encode byte register def constraints.
+    return DefineAsRegister(node);
+  }
+
   bool CanBeImmediate(Node* node) {
     switch (node->opcode()) {
       case IrOpcode::kInt32Constant:
@@ -30,8 +36,9 @@
       case IrOpcode::kHeapConstant: {
         // Constants in new space cannot be used as immediates in V8 because
         // the GC does not scan code objects when collecting the new generation.
-        Unique<HeapObject> value = OpParameter<Unique<HeapObject> >(node);
-        return !isolate()->heap()->InNewSpace(*value.handle());
+        Handle<HeapObject> value = OpParameter<Handle<HeapObject>>(node);
+        Isolate* isolate = value->GetIsolate();
+        return !isolate->heap()->InNewSpace(*value);
       }
       default:
         return false;
@@ -40,21 +47,21 @@
 
   AddressingMode GenerateMemoryOperandInputs(Node* index, int scale, Node* base,
                                              Node* displacement_node,
-                                             InstructionOperand* inputs[],
+                                             InstructionOperand inputs[],
                                              size_t* input_count) {
     AddressingMode mode = kMode_MRI;
-    int32_t displacement = (displacement_node == NULL)
+    int32_t displacement = (displacement_node == nullptr)
                                ? 0
                                : OpParameter<int32_t>(displacement_node);
-    if (base != NULL) {
+    if (base != nullptr) {
       if (base->opcode() == IrOpcode::kInt32Constant) {
         displacement += OpParameter<int32_t>(base);
-        base = NULL;
+        base = nullptr;
       }
     }
-    if (base != NULL) {
+    if (base != nullptr) {
       inputs[(*input_count)++] = UseRegister(base);
-      if (index != NULL) {
+      if (index != nullptr) {
         DCHECK(scale >= 0 && scale <= 3);
         inputs[(*input_count)++] = UseRegister(index);
         if (displacement != 0) {
@@ -77,7 +84,7 @@
       }
     } else {
       DCHECK(scale >= 0 && scale <= 3);
-      if (index != NULL) {
+      if (index != nullptr) {
         inputs[(*input_count)++] = UseRegister(index);
         if (displacement != 0) {
           inputs[(*input_count)++] = TempImmediate(displacement);
@@ -98,11 +105,11 @@
   }
 
   AddressingMode GetEffectiveAddressMemoryOperand(Node* node,
-                                                  InstructionOperand* inputs[],
+                                                  InstructionOperand inputs[],
                                                   size_t* input_count) {
     BaseWithIndexAndDisplacement32Matcher m(node, true);
     DCHECK(m.matches());
-    if ((m.displacement() == NULL || CanBeImmediate(m.displacement()))) {
+    if ((m.displacement() == nullptr || CanBeImmediate(m.displacement()))) {
       return GenerateMemoryOperandInputs(m.index(), m.scale(), m.base(),
                                          m.displacement(), inputs, input_count);
     } else {
@@ -118,47 +125,81 @@
 };
 
 
-static void VisitRRFloat64(InstructionSelector* selector, ArchOpcode opcode,
-                           Node* node) {
+namespace {
+
+void VisitRO(InstructionSelector* selector, Node* node, ArchOpcode opcode) {
+  IA32OperandGenerator g(selector);
+  selector->Emit(opcode, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
+}
+
+
+void VisitRR(InstructionSelector* selector, Node* node,
+             InstructionCode opcode) {
   IA32OperandGenerator g(selector);
   selector->Emit(opcode, g.DefineAsRegister(node),
                  g.UseRegister(node->InputAt(0)));
 }
 
 
-void InstructionSelector::VisitLoad(Node* node) {
-  MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node));
-  MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node));
+void VisitRROFloat(InstructionSelector* selector, Node* node,
+                   ArchOpcode avx_opcode, ArchOpcode sse_opcode) {
+  IA32OperandGenerator g(selector);
+  InstructionOperand operand0 = g.UseRegister(node->InputAt(0));
+  InstructionOperand operand1 = g.Use(node->InputAt(1));
+  if (selector->IsSupported(AVX)) {
+    selector->Emit(avx_opcode, g.DefineAsRegister(node), operand0, operand1);
+  } else {
+    selector->Emit(sse_opcode, g.DefineSameAsFirst(node), operand0, operand1);
+  }
+}
 
-  ArchOpcode opcode;
-  // TODO(titzer): signed/unsigned small loads
-  switch (rep) {
-    case kRepFloat32:
+
+void VisitFloatUnop(InstructionSelector* selector, Node* node, Node* input,
+                    ArchOpcode avx_opcode, ArchOpcode sse_opcode) {
+  IA32OperandGenerator g(selector);
+  if (selector->IsSupported(AVX)) {
+    selector->Emit(avx_opcode, g.DefineAsRegister(node), g.Use(input));
+  } else {
+    selector->Emit(sse_opcode, g.DefineSameAsFirst(node), g.UseRegister(input));
+  }
+}
+
+
+}  // namespace
+
+
+void InstructionSelector::VisitLoad(Node* node) {
+  LoadRepresentation load_rep = LoadRepresentationOf(node->op());
+
+  ArchOpcode opcode = kArchNop;
+  switch (load_rep.representation()) {
+    case MachineRepresentation::kFloat32:
       opcode = kIA32Movss;
       break;
-    case kRepFloat64:
+    case MachineRepresentation::kFloat64:
       opcode = kIA32Movsd;
       break;
-    case kRepBit:  // Fall through.
-    case kRepWord8:
-      opcode = typ == kTypeInt32 ? kIA32Movsxbl : kIA32Movzxbl;
+    case MachineRepresentation::kBit:  // Fall through.
+    case MachineRepresentation::kWord8:
+      opcode = load_rep.IsSigned() ? kIA32Movsxbl : kIA32Movzxbl;
       break;
-    case kRepWord16:
-      opcode = typ == kTypeInt32 ? kIA32Movsxwl : kIA32Movzxwl;
+    case MachineRepresentation::kWord16:
+      opcode = load_rep.IsSigned() ? kIA32Movsxwl : kIA32Movzxwl;
       break;
-    case kRepTagged:  // Fall through.
-    case kRepWord32:
+    case MachineRepresentation::kTagged:  // Fall through.
+    case MachineRepresentation::kWord32:
       opcode = kIA32Movl;
       break;
-    default:
+    case MachineRepresentation::kWord64:  // Fall through.
+    case MachineRepresentation::kNone:
       UNREACHABLE();
       return;
   }
 
   IA32OperandGenerator g(this);
-  InstructionOperand* outputs[1];
+  InstructionOperand outputs[1];
   outputs[0] = g.DefineAsRegister(node);
-  InstructionOperand* inputs[3];
+  InstructionOperand inputs[3];
   size_t input_count = 0;
   AddressingMode mode =
       g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count);
@@ -173,94 +214,128 @@
   Node* index = node->InputAt(1);
   Node* value = node->InputAt(2);
 
-  StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node);
-  MachineType rep = RepresentationOf(store_rep.machine_type());
-  if (store_rep.write_barrier_kind() == kFullWriteBarrier) {
-    DCHECK_EQ(kRepTagged, rep);
-    // TODO(dcarney): refactor RecordWrite function to take temp registers
-    //                and pass them here instead of using fixed regs
-    // TODO(dcarney): handle immediate indices.
-    InstructionOperand* temps[] = {g.TempRegister(ecx), g.TempRegister(edx)};
-    Emit(kIA32StoreWriteBarrier, NULL, g.UseFixed(base, ebx),
-         g.UseFixed(index, ecx), g.UseFixed(value, edx), arraysize(temps),
-         temps);
-    return;
-  }
-  DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind());
+  StoreRepresentation store_rep = StoreRepresentationOf(node->op());
+  WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind();
+  MachineRepresentation rep = store_rep.representation();
 
-  ArchOpcode opcode;
-  switch (rep) {
-    case kRepFloat32:
-      opcode = kIA32Movss;
-      break;
-    case kRepFloat64:
-      opcode = kIA32Movsd;
-      break;
-    case kRepBit:  // Fall through.
-    case kRepWord8:
-      opcode = kIA32Movb;
-      break;
-    case kRepWord16:
-      opcode = kIA32Movw;
-      break;
-    case kRepTagged:  // Fall through.
-    case kRepWord32:
-      opcode = kIA32Movl;
-      break;
-    default:
-      UNREACHABLE();
-      return;
-  }
-
-  InstructionOperand* val;
-  if (g.CanBeImmediate(value)) {
-    val = g.UseImmediate(value);
-  } else if (rep == kRepWord8 || rep == kRepBit) {
-    val = g.UseByteRegister(value);
+  if (write_barrier_kind != kNoWriteBarrier) {
+    DCHECK_EQ(MachineRepresentation::kTagged, rep);
+    AddressingMode addressing_mode;
+    InstructionOperand inputs[3];
+    size_t input_count = 0;
+    inputs[input_count++] = g.UseUniqueRegister(base);
+    if (g.CanBeImmediate(index)) {
+      inputs[input_count++] = g.UseImmediate(index);
+      addressing_mode = kMode_MRI;
+    } else {
+      inputs[input_count++] = g.UseUniqueRegister(index);
+      addressing_mode = kMode_MR1;
+    }
+    inputs[input_count++] = (write_barrier_kind == kMapWriteBarrier)
+                                ? g.UseRegister(value)
+                                : g.UseUniqueRegister(value);
+    RecordWriteMode record_write_mode = RecordWriteMode::kValueIsAny;
+    switch (write_barrier_kind) {
+      case kNoWriteBarrier:
+        UNREACHABLE();
+        break;
+      case kMapWriteBarrier:
+        record_write_mode = RecordWriteMode::kValueIsMap;
+        break;
+      case kPointerWriteBarrier:
+        record_write_mode = RecordWriteMode::kValueIsPointer;
+        break;
+      case kFullWriteBarrier:
+        record_write_mode = RecordWriteMode::kValueIsAny;
+        break;
+    }
+    InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()};
+    size_t const temp_count = arraysize(temps);
+    InstructionCode code = kArchStoreWithWriteBarrier;
+    code |= AddressingModeField::encode(addressing_mode);
+    code |= MiscField::encode(static_cast<int>(record_write_mode));
+    Emit(code, 0, nullptr, input_count, inputs, temp_count, temps);
   } else {
-    val = g.UseRegister(value);
-  }
+    ArchOpcode opcode = kArchNop;
+    switch (rep) {
+      case MachineRepresentation::kFloat32:
+        opcode = kIA32Movss;
+        break;
+      case MachineRepresentation::kFloat64:
+        opcode = kIA32Movsd;
+        break;
+      case MachineRepresentation::kBit:  // Fall through.
+      case MachineRepresentation::kWord8:
+        opcode = kIA32Movb;
+        break;
+      case MachineRepresentation::kWord16:
+        opcode = kIA32Movw;
+        break;
+      case MachineRepresentation::kTagged:  // Fall through.
+      case MachineRepresentation::kWord32:
+        opcode = kIA32Movl;
+        break;
+      case MachineRepresentation::kWord64:  // Fall through.
+      case MachineRepresentation::kNone:
+        UNREACHABLE();
+        return;
+    }
 
-  InstructionOperand* inputs[4];
-  size_t input_count = 0;
-  AddressingMode mode =
-      g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count);
-  InstructionCode code = opcode | AddressingModeField::encode(mode);
-  inputs[input_count++] = val;
-  Emit(code, 0, static_cast<InstructionOperand**>(NULL), input_count, inputs);
+    InstructionOperand val;
+    if (g.CanBeImmediate(value)) {
+      val = g.UseImmediate(value);
+    } else if (rep == MachineRepresentation::kWord8 ||
+               rep == MachineRepresentation::kBit) {
+      val = g.UseByteRegister(value);
+    } else {
+      val = g.UseRegister(value);
+    }
+
+    InstructionOperand inputs[4];
+    size_t input_count = 0;
+    AddressingMode addressing_mode =
+        g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count);
+    InstructionCode code =
+        opcode | AddressingModeField::encode(addressing_mode);
+    inputs[input_count++] = val;
+    Emit(code, 0, static_cast<InstructionOperand*>(nullptr), input_count,
+         inputs);
+  }
 }
 
 
 void InstructionSelector::VisitCheckedLoad(Node* node) {
-  MachineType rep = RepresentationOf(OpParameter<MachineType>(node));
-  MachineType typ = TypeOf(OpParameter<MachineType>(node));
+  CheckedLoadRepresentation load_rep = CheckedLoadRepresentationOf(node->op());
   IA32OperandGenerator g(this);
   Node* const buffer = node->InputAt(0);
   Node* const offset = node->InputAt(1);
   Node* const length = node->InputAt(2);
-  ArchOpcode opcode;
-  switch (rep) {
-    case kRepWord8:
-      opcode = typ == kTypeInt32 ? kCheckedLoadInt8 : kCheckedLoadUint8;
+  ArchOpcode opcode = kArchNop;
+  switch (load_rep.representation()) {
+    case MachineRepresentation::kWord8:
+      opcode = load_rep.IsSigned() ? kCheckedLoadInt8 : kCheckedLoadUint8;
       break;
-    case kRepWord16:
-      opcode = typ == kTypeInt32 ? kCheckedLoadInt16 : kCheckedLoadUint16;
+    case MachineRepresentation::kWord16:
+      opcode = load_rep.IsSigned() ? kCheckedLoadInt16 : kCheckedLoadUint16;
       break;
-    case kRepWord32:
+    case MachineRepresentation::kWord32:
       opcode = kCheckedLoadWord32;
       break;
-    case kRepFloat32:
+    case MachineRepresentation::kFloat32:
       opcode = kCheckedLoadFloat32;
       break;
-    case kRepFloat64:
+    case MachineRepresentation::kFloat64:
       opcode = kCheckedLoadFloat64;
       break;
-    default:
+    case MachineRepresentation::kBit:     // Fall through.
+    case MachineRepresentation::kTagged:  // Fall through.
+    case MachineRepresentation::kWord64:  // Fall through.
+    case MachineRepresentation::kNone:
       UNREACHABLE();
       return;
   }
-  InstructionOperand* offset_operand = g.UseRegister(offset);
-  InstructionOperand* length_operand =
+  InstructionOperand offset_operand = g.UseRegister(offset);
+  InstructionOperand length_operand =
       g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length);
   if (g.CanBeImmediate(buffer)) {
     Emit(opcode | AddressingModeField::encode(kMode_MRI),
@@ -275,47 +350,51 @@
 
 
 void InstructionSelector::VisitCheckedStore(Node* node) {
-  MachineType rep = RepresentationOf(OpParameter<MachineType>(node));
+  MachineRepresentation rep = CheckedStoreRepresentationOf(node->op());
   IA32OperandGenerator g(this);
   Node* const buffer = node->InputAt(0);
   Node* const offset = node->InputAt(1);
   Node* const length = node->InputAt(2);
   Node* const value = node->InputAt(3);
-  ArchOpcode opcode;
+  ArchOpcode opcode = kArchNop;
   switch (rep) {
-    case kRepWord8:
+    case MachineRepresentation::kWord8:
       opcode = kCheckedStoreWord8;
       break;
-    case kRepWord16:
+    case MachineRepresentation::kWord16:
       opcode = kCheckedStoreWord16;
       break;
-    case kRepWord32:
+    case MachineRepresentation::kWord32:
       opcode = kCheckedStoreWord32;
       break;
-    case kRepFloat32:
+    case MachineRepresentation::kFloat32:
       opcode = kCheckedStoreFloat32;
       break;
-    case kRepFloat64:
+    case MachineRepresentation::kFloat64:
       opcode = kCheckedStoreFloat64;
       break;
-    default:
+    case MachineRepresentation::kBit:     // Fall through.
+    case MachineRepresentation::kTagged:  // Fall through.
+    case MachineRepresentation::kWord64:  // Fall through.
+    case MachineRepresentation::kNone:
       UNREACHABLE();
       return;
   }
-  InstructionOperand* value_operand =
-      g.CanBeImmediate(value)
-          ? g.UseImmediate(value)
-          : ((rep == kRepWord8 || rep == kRepBit) ? g.UseByteRegister(value)
-                                                  : g.UseRegister(value));
-  InstructionOperand* offset_operand = g.UseRegister(offset);
-  InstructionOperand* length_operand =
+  InstructionOperand value_operand =
+      g.CanBeImmediate(value) ? g.UseImmediate(value)
+                              : ((rep == MachineRepresentation::kWord8 ||
+                                  rep == MachineRepresentation::kBit)
+                                     ? g.UseByteRegister(value)
+                                     : g.UseRegister(value));
+  InstructionOperand offset_operand = g.UseRegister(offset);
+  InstructionOperand length_operand =
       g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length);
   if (g.CanBeImmediate(buffer)) {
-    Emit(opcode | AddressingModeField::encode(kMode_MRI), nullptr,
+    Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
          offset_operand, length_operand, value_operand, offset_operand,
          g.UseImmediate(buffer));
   } else {
-    Emit(opcode | AddressingModeField::encode(kMode_MR1), nullptr,
+    Emit(opcode | AddressingModeField::encode(kMode_MR1), g.NoOutput(),
          offset_operand, length_operand, value_operand, g.UseRegister(buffer),
          offset_operand);
   }
@@ -329,9 +408,9 @@
   Int32BinopMatcher m(node);
   Node* left = m.left().node();
   Node* right = m.right().node();
-  InstructionOperand* inputs[4];
+  InstructionOperand inputs[4];
   size_t input_count = 0;
-  InstructionOperand* outputs[2];
+  InstructionOperand outputs[2];
   size_t output_count = 0;
 
   // TODO(turbofan): match complex addressing modes.
@@ -343,7 +422,7 @@
     //   mov eax, [ebp-0x10]
     //   add eax, [ebp-0x10]
     //   jo label
-    InstructionOperand* const input = g.UseRegister(left);
+    InstructionOperand const input = g.UseRegister(left);
     inputs[input_count++] = input;
     inputs[input_count++] = input;
   } else if (g.CanBeImmediate(right)) {
@@ -365,18 +444,16 @@
 
   outputs[output_count++] = g.DefineSameAsFirst(node);
   if (cont->IsSet()) {
-    // TODO(turbofan): Use byte register here.
-    outputs[output_count++] = g.DefineAsRegister(cont->result());
+    outputs[output_count++] = g.DefineAsByteRegister(cont->result());
   }
 
-  DCHECK_NE(0, input_count);
-  DCHECK_NE(0, output_count);
+  DCHECK_NE(0u, input_count);
+  DCHECK_NE(0u, output_count);
   DCHECK_GE(arraysize(inputs), input_count);
   DCHECK_GE(arraysize(outputs), output_count);
 
-  Instruction* instr = selector->Emit(cont->Encode(opcode), output_count,
-                                      outputs, input_count, inputs);
-  if (cont->IsBranch()) instr->MarkAsControl();
+  selector->Emit(cont->Encode(opcode), output_count, outputs, input_count,
+                 inputs);
 }
 
 
@@ -439,7 +516,7 @@
 
 void VisitDiv(InstructionSelector* selector, Node* node, ArchOpcode opcode) {
   IA32OperandGenerator g(selector);
-  InstructionOperand* temps[] = {g.TempRegister(edx)};
+  InstructionOperand temps[] = {g.TempRegister(edx)};
   selector->Emit(opcode, g.DefineAsFixed(node, eax),
                  g.UseFixed(node->InputAt(0), eax),
                  g.UseUnique(node->InputAt(1)), arraysize(temps), temps);
@@ -456,15 +533,15 @@
 void EmitLea(InstructionSelector* selector, Node* result, Node* index,
              int scale, Node* base, Node* displacement) {
   IA32OperandGenerator g(selector);
-  InstructionOperand* inputs[4];
+  InstructionOperand inputs[4];
   size_t input_count = 0;
   AddressingMode mode = g.GenerateMemoryOperandInputs(
       index, scale, base, displacement, inputs, &input_count);
 
-  DCHECK_NE(0, static_cast<int>(input_count));
+  DCHECK_NE(0u, input_count);
   DCHECK_GE(arraysize(inputs), input_count);
 
-  InstructionOperand* outputs[1];
+  InstructionOperand outputs[1];
   outputs[0] = g.DefineAsRegister(result);
 
   InstructionCode opcode = AddressingModeField::encode(mode) | kIA32Lea;
@@ -479,8 +556,8 @@
   Int32ScaleMatcher m(node, true);
   if (m.matches()) {
     Node* index = node->InputAt(0);
-    Node* base = m.power_of_two_plus_one() ? index : NULL;
-    EmitLea(this, node, index, m.scale(), base, NULL);
+    Node* base = m.power_of_two_plus_one() ? index : nullptr;
+    EmitLea(this, node, index, m.scale(), base, nullptr);
     return;
   }
   VisitShift(this, node, kIA32Shl);
@@ -502,22 +579,40 @@
 }
 
 
+void InstructionSelector::VisitWord32Clz(Node* node) {
+  IA32OperandGenerator g(this);
+  Emit(kIA32Lzcnt, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitWord32Ctz(Node* node) {
+  IA32OperandGenerator g(this);
+  Emit(kIA32Tzcnt, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitWord32Popcnt(Node* node) {
+  IA32OperandGenerator g(this);
+  Emit(kIA32Popcnt, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
+}
+
+
 void InstructionSelector::VisitInt32Add(Node* node) {
   IA32OperandGenerator g(this);
 
   // Try to match the Add to a lea pattern
   BaseWithIndexAndDisplacement32Matcher m(node);
   if (m.matches() &&
-      (m.displacement() == NULL || g.CanBeImmediate(m.displacement()))) {
-    InstructionOperand* inputs[4];
+      (m.displacement() == nullptr || g.CanBeImmediate(m.displacement()))) {
+    InstructionOperand inputs[4];
     size_t input_count = 0;
     AddressingMode mode = g.GenerateMemoryOperandInputs(
         m.index(), m.scale(), m.base(), m.displacement(), inputs, &input_count);
 
-    DCHECK_NE(0, static_cast<int>(input_count));
+    DCHECK_NE(0u, input_count);
     DCHECK_GE(arraysize(inputs), input_count);
 
-    InstructionOperand* outputs[1];
+    InstructionOperand outputs[1];
     outputs[0] = g.DefineAsRegister(node);
 
     InstructionCode opcode = AddressingModeField::encode(mode) | kIA32Lea;
@@ -545,8 +640,8 @@
   Int32ScaleMatcher m(node, true);
   if (m.matches()) {
     Node* index = node->InputAt(0);
-    Node* base = m.power_of_two_plus_one() ? index : NULL;
-    EmitLea(this, node, index, m.scale(), base, NULL);
+    Node* base = m.power_of_two_plus_one() ? index : nullptr;
+    EmitLea(this, node, index, m.scale(), base, nullptr);
     return;
   }
   IA32OperandGenerator g(this);
@@ -596,119 +691,202 @@
 
 
 void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) {
-  IA32OperandGenerator g(this);
-  Emit(kSSECvtss2sd, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
+  VisitRO(this, node, kSSEFloat32ToFloat64);
 }
 
 
 void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) {
-  IA32OperandGenerator g(this);
-  Emit(kSSEInt32ToFloat64, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
+  VisitRO(this, node, kSSEInt32ToFloat64);
 }
 
 
 void InstructionSelector::VisitChangeUint32ToFloat64(Node* node) {
-  IA32OperandGenerator g(this);
-  Emit(kSSEUint32ToFloat64, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
+  VisitRO(this, node, kSSEUint32ToFloat64);
 }
 
 
 void InstructionSelector::VisitChangeFloat64ToInt32(Node* node) {
-  IA32OperandGenerator g(this);
-  Emit(kSSEFloat64ToInt32, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
+  VisitRO(this, node, kSSEFloat64ToInt32);
 }
 
 
 void InstructionSelector::VisitChangeFloat64ToUint32(Node* node) {
-  IA32OperandGenerator g(this);
-  Emit(kSSEFloat64ToUint32, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
+  VisitRO(this, node, kSSEFloat64ToUint32);
 }
 
 
 void InstructionSelector::VisitTruncateFloat64ToFloat32(Node* node) {
+  VisitRO(this, node, kSSEFloat64ToFloat32);
+}
+
+
+void InstructionSelector::VisitTruncateFloat64ToInt32(Node* node) {
+  switch (TruncationModeOf(node->op())) {
+    case TruncationMode::kJavaScript:
+      return VisitRR(this, node, kArchTruncateDoubleToI);
+    case TruncationMode::kRoundToZero:
+      return VisitRO(this, node, kSSEFloat64ToInt32);
+  }
+  UNREACHABLE();
+}
+
+
+void InstructionSelector::VisitBitcastFloat32ToInt32(Node* node) {
   IA32OperandGenerator g(this);
-  Emit(kSSECvtsd2ss, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
+  Emit(kIA32BitcastFI, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitBitcastInt32ToFloat32(Node* node) {
+  IA32OperandGenerator g(this);
+  Emit(kIA32BitcastIF, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitFloat32Add(Node* node) {
+  VisitRROFloat(this, node, kAVXFloat32Add, kSSEFloat32Add);
 }
 
 
 void InstructionSelector::VisitFloat64Add(Node* node) {
+  VisitRROFloat(this, node, kAVXFloat64Add, kSSEFloat64Add);
+}
+
+
+void InstructionSelector::VisitFloat32Sub(Node* node) {
   IA32OperandGenerator g(this);
-  if (IsSupported(AVX)) {
-    Emit(kAVXFloat64Add, g.DefineAsRegister(node),
-         g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
-  } else {
-    Emit(kSSEFloat64Add, g.DefineSameAsFirst(node),
-         g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
+  Float32BinopMatcher m(node);
+  if (m.left().IsMinusZero()) {
+    VisitFloatUnop(this, node, m.right().node(), kAVXFloat32Neg,
+                   kSSEFloat32Neg);
+    return;
   }
+  VisitRROFloat(this, node, kAVXFloat32Sub, kSSEFloat32Sub);
 }
 
 
 void InstructionSelector::VisitFloat64Sub(Node* node) {
   IA32OperandGenerator g(this);
-  if (IsSupported(AVX)) {
-    Emit(kAVXFloat64Sub, g.DefineAsRegister(node),
-         g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
-  } else {
-    Emit(kSSEFloat64Sub, g.DefineSameAsFirst(node),
-         g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
+  Float64BinopMatcher m(node);
+  if (m.left().IsMinusZero()) {
+    if (m.right().IsFloat64RoundDown() &&
+        CanCover(m.node(), m.right().node())) {
+      if (m.right().InputAt(0)->opcode() == IrOpcode::kFloat64Sub &&
+          CanCover(m.right().node(), m.right().InputAt(0))) {
+        Float64BinopMatcher mright0(m.right().InputAt(0));
+        if (mright0.left().IsMinusZero()) {
+          Emit(kSSEFloat64Round | MiscField::encode(kRoundUp),
+               g.DefineAsRegister(node), g.UseRegister(mright0.right().node()));
+          return;
+        }
+      }
+    }
+    VisitFloatUnop(this, node, m.right().node(), kAVXFloat64Neg,
+                   kSSEFloat64Neg);
+    return;
   }
+  VisitRROFloat(this, node, kAVXFloat64Sub, kSSEFloat64Sub);
+}
+
+
+void InstructionSelector::VisitFloat32Mul(Node* node) {
+  VisitRROFloat(this, node, kAVXFloat32Mul, kSSEFloat32Mul);
 }
 
 
 void InstructionSelector::VisitFloat64Mul(Node* node) {
-  IA32OperandGenerator g(this);
-  if (IsSupported(AVX)) {
-    Emit(kAVXFloat64Mul, g.DefineAsRegister(node),
-         g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
-  } else {
-    Emit(kSSEFloat64Mul, g.DefineSameAsFirst(node),
-         g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
-  }
+  VisitRROFloat(this, node, kAVXFloat64Mul, kSSEFloat64Mul);
+}
+
+
+void InstructionSelector::VisitFloat32Div(Node* node) {
+  VisitRROFloat(this, node, kAVXFloat32Div, kSSEFloat32Div);
 }
 
 
 void InstructionSelector::VisitFloat64Div(Node* node) {
-  IA32OperandGenerator g(this);
-  if (IsSupported(AVX)) {
-    Emit(kAVXFloat64Div, g.DefineAsRegister(node),
-         g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
-  } else {
-    Emit(kSSEFloat64Div, g.DefineSameAsFirst(node),
-         g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
-  }
+  VisitRROFloat(this, node, kAVXFloat64Div, kSSEFloat64Div);
 }
 
 
 void InstructionSelector::VisitFloat64Mod(Node* node) {
   IA32OperandGenerator g(this);
-  InstructionOperand* temps[] = {g.TempRegister(eax)};
+  InstructionOperand temps[] = {g.TempRegister(eax)};
   Emit(kSSEFloat64Mod, g.DefineSameAsFirst(node),
        g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)), 1,
        temps);
 }
 
 
-void InstructionSelector::VisitFloat64Sqrt(Node* node) {
+void InstructionSelector::VisitFloat32Max(Node* node) {
+  VisitRROFloat(this, node, kAVXFloat32Max, kSSEFloat32Max);
+}
+
+
+void InstructionSelector::VisitFloat64Max(Node* node) {
+  VisitRROFloat(this, node, kAVXFloat64Max, kSSEFloat64Max);
+}
+
+
+void InstructionSelector::VisitFloat32Min(Node* node) {
+  VisitRROFloat(this, node, kAVXFloat32Min, kSSEFloat32Min);
+}
+
+
+void InstructionSelector::VisitFloat64Min(Node* node) {
+  VisitRROFloat(this, node, kAVXFloat64Min, kSSEFloat64Min);
+}
+
+
+void InstructionSelector::VisitFloat32Abs(Node* node) {
   IA32OperandGenerator g(this);
-  Emit(kSSEFloat64Sqrt, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
+  VisitFloatUnop(this, node, node->InputAt(0), kAVXFloat32Abs, kSSEFloat32Abs);
 }
 
 
-void InstructionSelector::VisitFloat64Floor(Node* node) {
-  DCHECK(CpuFeatures::IsSupported(SSE4_1));
-  VisitRRFloat64(this, kSSEFloat64Floor, node);
+void InstructionSelector::VisitFloat64Abs(Node* node) {
+  IA32OperandGenerator g(this);
+  VisitFloatUnop(this, node, node->InputAt(0), kAVXFloat64Abs, kSSEFloat64Abs);
 }
 
 
-void InstructionSelector::VisitFloat64Ceil(Node* node) {
-  DCHECK(CpuFeatures::IsSupported(SSE4_1));
-  VisitRRFloat64(this, kSSEFloat64Ceil, node);
+void InstructionSelector::VisitFloat32Sqrt(Node* node) {
+  VisitRO(this, node, kSSEFloat32Sqrt);
+}
+
+
+void InstructionSelector::VisitFloat64Sqrt(Node* node) {
+  VisitRO(this, node, kSSEFloat64Sqrt);
+}
+
+
+void InstructionSelector::VisitFloat32RoundDown(Node* node) {
+  VisitRR(this, node, kSSEFloat32Round | MiscField::encode(kRoundDown));
+}
+
+
+void InstructionSelector::VisitFloat64RoundDown(Node* node) {
+  VisitRR(this, node, kSSEFloat64Round | MiscField::encode(kRoundDown));
+}
+
+
+void InstructionSelector::VisitFloat32RoundUp(Node* node) {
+  VisitRR(this, node, kSSEFloat32Round | MiscField::encode(kRoundUp));
+}
+
+
+void InstructionSelector::VisitFloat64RoundUp(Node* node) {
+  VisitRR(this, node, kSSEFloat64Round | MiscField::encode(kRoundUp));
+}
+
+
+void InstructionSelector::VisitFloat32RoundTruncate(Node* node) {
+  VisitRR(this, node, kSSEFloat32Round | MiscField::encode(kRoundToZero));
 }
 
 
 void InstructionSelector::VisitFloat64RoundTruncate(Node* node) {
-  DCHECK(CpuFeatures::IsSupported(SSE4_1));
-  VisitRRFloat64(this, kSSEFloat64RoundTruncate, node);
+  VisitRR(this, node, kSSEFloat64Round | MiscField::encode(kRoundToZero));
 }
 
 
@@ -717,71 +895,80 @@
 }
 
 
-void InstructionSelector::VisitCall(Node* node) {
-  IA32OperandGenerator g(this);
-  const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(node);
-
-  FrameStateDescriptor* frame_state_descriptor = NULL;
-
-  if (descriptor->NeedsFrameState()) {
-    frame_state_descriptor =
-        GetFrameStateDescriptor(node->InputAt(descriptor->InputCount()));
-  }
-
-  CallBuffer buffer(zone(), descriptor, frame_state_descriptor);
-
-  // Compute InstructionOperands for inputs and outputs.
-  InitializeCallBuffer(node, &buffer, true, true);
-
-  // Push any stack arguments.
-  for (NodeVectorRIter input = buffer.pushed_nodes.rbegin();
-       input != buffer.pushed_nodes.rend(); input++) {
-    // TODO(titzer): handle pushing double parameters.
-    Emit(kIA32Push, NULL,
-         g.CanBeImmediate(*input) ? g.UseImmediate(*input) : g.Use(*input));
-  }
-
-  // Select the appropriate opcode based on the call type.
-  InstructionCode opcode;
-  switch (descriptor->kind()) {
-    case CallDescriptor::kCallCodeObject: {
-      opcode = kArchCallCodeObject;
-      break;
-    }
-    case CallDescriptor::kCallJSFunction:
-      opcode = kArchCallJSFunction;
-      break;
-    default:
-      UNREACHABLE();
-      return;
-  }
-  opcode |= MiscField::encode(descriptor->flags());
-
-  // Emit the call instruction.
-  InstructionOperand** first_output =
-      buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL;
-  Instruction* call_instr =
-      Emit(opcode, buffer.outputs.size(), first_output,
-           buffer.instruction_args.size(), &buffer.instruction_args.front());
-  call_instr->MarkAsCall();
+void InstructionSelector::VisitFloat32RoundTiesEven(Node* node) {
+  VisitRR(this, node, kSSEFloat32Round | MiscField::encode(kRoundToNearest));
 }
 
 
+void InstructionSelector::VisitFloat64RoundTiesEven(Node* node) {
+  VisitRR(this, node, kSSEFloat64Round | MiscField::encode(kRoundToNearest));
+}
+
+
+void InstructionSelector::EmitPrepareArguments(
+    ZoneVector<PushParameter>* arguments, const CallDescriptor* descriptor,
+    Node* node) {
+  IA32OperandGenerator g(this);
+
+  // Prepare for C function call.
+  if (descriptor->IsCFunctionCall()) {
+    InstructionOperand temps[] = {g.TempRegister()};
+    size_t const temp_count = arraysize(temps);
+    Emit(kArchPrepareCallCFunction |
+             MiscField::encode(static_cast<int>(descriptor->CParameterCount())),
+         0, nullptr, 0, nullptr, temp_count, temps);
+
+    // Poke any stack arguments.
+    for (size_t n = 0; n < arguments->size(); ++n) {
+      PushParameter input = (*arguments)[n];
+      if (input.node()) {
+        int const slot = static_cast<int>(n);
+        InstructionOperand value = g.CanBeImmediate(node)
+                                       ? g.UseImmediate(input.node())
+                                       : g.UseRegister(input.node());
+        Emit(kIA32Poke | MiscField::encode(slot), g.NoOutput(), value);
+      }
+    }
+  } else {
+    // Push any stack arguments.
+    for (PushParameter input : base::Reversed(*arguments)) {
+      // Skip any alignment holes in pushed nodes.
+      if (input.node() == nullptr) continue;
+      InstructionOperand value =
+          g.CanBeImmediate(input.node())
+              ? g.UseImmediate(input.node())
+              : IsSupported(ATOM) ||
+                        sequence()->IsFloat(GetVirtualRegister(input.node()))
+                    ? g.UseRegister(input.node())
+                    : g.Use(input.node());
+      if (input.type() == MachineType::Float32()) {
+        Emit(kIA32PushFloat32, g.NoOutput(), value);
+      } else if (input.type() == MachineType::Float64()) {
+        Emit(kIA32PushFloat64, g.NoOutput(), value);
+      } else {
+        Emit(kIA32Push, g.NoOutput(), value);
+      }
+    }
+  }
+}
+
+
+bool InstructionSelector::IsTailCallAddressImmediate() { return true; }
+
+
 namespace {
 
 // Shared routine for multiple compare operations.
 void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
-                  InstructionOperand* left, InstructionOperand* right,
+                  InstructionOperand left, InstructionOperand right,
                   FlagsContinuation* cont) {
   IA32OperandGenerator g(selector);
   if (cont->IsBranch()) {
-    selector->Emit(cont->Encode(opcode), NULL, left, right,
-                   g.Label(cont->true_block()),
-                   g.Label(cont->false_block()))->MarkAsControl();
+    selector->Emit(cont->Encode(opcode), g.NoOutput(), left, right,
+                   g.Label(cont->true_block()), g.Label(cont->false_block()));
   } else {
     DCHECK(cont->IsSet());
-    // TODO(titzer): Needs byte register.
-    selector->Emit(cont->Encode(opcode), g.DefineAsRegister(cont->result()),
+    selector->Emit(cont->Encode(opcode), g.DefineAsByteRegister(cont->result()),
                    left, right);
   }
 }
@@ -799,11 +986,21 @@
 }
 
 
-// Shared routine for multiple float compare operations.
+// Shared routine for multiple float32 compare operations (inputs commuted).
+void VisitFloat32Compare(InstructionSelector* selector, Node* node,
+                         FlagsContinuation* cont) {
+  Node* const left = node->InputAt(0);
+  Node* const right = node->InputAt(1);
+  VisitCompare(selector, kSSEFloat32Cmp, right, left, cont, false);
+}
+
+
+// Shared routine for multiple float64 compare operations (inputs commuted).
 void VisitFloat64Compare(InstructionSelector* selector, Node* node,
                          FlagsContinuation* cont) {
-  VisitCompare(selector, kSSEFloat64Cmp, node->InputAt(0), node->InputAt(1),
-               cont, node->op()->HasProperty(Operator::kCommutative));
+  Node* const left = node->InputAt(0);
+  Node* const right = node->InputAt(1);
+  VisitCompare(selector, kSSEFloat64Cmp, right, left, cont, false);
 }
 
 
@@ -829,6 +1026,26 @@
 
 void VisitWordCompare(InstructionSelector* selector, Node* node,
                       FlagsContinuation* cont) {
+  IA32OperandGenerator g(selector);
+  Int32BinopMatcher m(node);
+  if (m.left().IsLoad() && m.right().IsLoadStackPointer()) {
+    LoadMatcher<ExternalReferenceMatcher> mleft(m.left().node());
+    ExternalReference js_stack_limit =
+        ExternalReference::address_of_stack_limit(selector->isolate());
+    if (mleft.object().Is(js_stack_limit) && mleft.index().Is(0)) {
+      // Compare(Load(js_stack_limit), LoadStackPointer)
+      if (!node->op()->HasProperty(Operator::kCommutative)) cont->Commute();
+      InstructionCode opcode = cont->Encode(kIA32StackCheck);
+      if (cont->IsBranch()) {
+        selector->Emit(opcode, g.NoOutput(), g.Label(cont->true_block()),
+                       g.Label(cont->false_block()));
+      } else {
+        DCHECK(cont->IsSet());
+        selector->Emit(opcode, g.DefineAsRegister(cont->result()));
+      }
+      return;
+    }
+  }
   VisitWordCompare(selector, node, kIA32Cmp, cont);
 }
 
@@ -864,27 +1081,36 @@
       case IrOpcode::kUint32LessThanOrEqual:
         cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
         return VisitWordCompare(selector, value, cont);
+      case IrOpcode::kFloat32Equal:
+        cont->OverwriteAndNegateIfEqual(kUnorderedEqual);
+        return VisitFloat32Compare(selector, value, cont);
+      case IrOpcode::kFloat32LessThan:
+        cont->OverwriteAndNegateIfEqual(kUnsignedGreaterThan);
+        return VisitFloat32Compare(selector, value, cont);
+      case IrOpcode::kFloat32LessThanOrEqual:
+        cont->OverwriteAndNegateIfEqual(kUnsignedGreaterThanOrEqual);
+        return VisitFloat32Compare(selector, value, cont);
       case IrOpcode::kFloat64Equal:
         cont->OverwriteAndNegateIfEqual(kUnorderedEqual);
         return VisitFloat64Compare(selector, value, cont);
       case IrOpcode::kFloat64LessThan:
-        cont->OverwriteAndNegateIfEqual(kUnorderedLessThan);
+        cont->OverwriteAndNegateIfEqual(kUnsignedGreaterThan);
         return VisitFloat64Compare(selector, value, cont);
       case IrOpcode::kFloat64LessThanOrEqual:
-        cont->OverwriteAndNegateIfEqual(kUnorderedLessThanOrEqual);
+        cont->OverwriteAndNegateIfEqual(kUnsignedGreaterThanOrEqual);
         return VisitFloat64Compare(selector, value, cont);
       case IrOpcode::kProjection:
         // Check if this is the overflow output projection of an
         // <Operation>WithOverflow node.
-        if (OpParameter<size_t>(value) == 1u) {
+        if (ProjectionIndexOf(value->op()) == 1u) {
           // We cannot combine the <Operation>WithOverflow with this branch
           // unless the 0th projection (the use of the actual value of the
-          // <Operation> is either NULL, which means there's no use of the
+          // <Operation> is either nullptr, which means there's no use of the
           // actual value, or was already defined, which means it is scheduled
           // *AFTER* this branch).
-          Node* node = value->InputAt(0);
-          Node* result = node->FindProjection(0);
-          if (result == NULL || selector->IsDefined(result)) {
+          Node* const node = value->InputAt(0);
+          Node* const result = NodeProperties::FindProjection(node, 0);
+          if (result == nullptr || selector->IsDefined(result)) {
             switch (node->opcode()) {
               case IrOpcode::kInt32AddWithOverflow:
                 cont->OverwriteAndNegateIfEqual(kOverflow);
@@ -923,6 +1149,34 @@
 }
 
 
+void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) {
+  IA32OperandGenerator g(this);
+  InstructionOperand value_operand = g.UseRegister(node->InputAt(0));
+
+  // Emit either ArchTableSwitch or ArchLookupSwitch.
+  size_t table_space_cost = 4 + sw.value_range;
+  size_t table_time_cost = 3;
+  size_t lookup_space_cost = 3 + 2 * sw.case_count;
+  size_t lookup_time_cost = sw.case_count;
+  if (sw.case_count > 4 &&
+      table_space_cost + 3 * table_time_cost <=
+          lookup_space_cost + 3 * lookup_time_cost &&
+      sw.min_value > std::numeric_limits<int32_t>::min()) {
+    InstructionOperand index_operand = value_operand;
+    if (sw.min_value) {
+      index_operand = g.TempRegister();
+      Emit(kIA32Lea | AddressingModeField::encode(kMode_MRI), index_operand,
+           value_operand, g.TempImmediate(-sw.min_value));
+    }
+    // Generate a table lookup.
+    return EmitTableSwitch(sw, index_operand);
+  }
+
+  // Generate a sequence of conditional jumps.
+  return EmitLookupSwitch(sw, value_operand);
+}
+
+
 void InstructionSelector::VisitWord32Equal(Node* const node) {
   FlagsContinuation cont(kEqual, node);
   Int32BinopMatcher m(node);
@@ -958,7 +1212,7 @@
 
 
 void InstructionSelector::VisitInt32AddWithOverflow(Node* node) {
-  if (Node* ovf = node->FindProjection(1)) {
+  if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
     FlagsContinuation cont(kOverflow, ovf);
     return VisitBinop(this, node, kIA32Add, &cont);
   }
@@ -968,7 +1222,7 @@
 
 
 void InstructionSelector::VisitInt32SubWithOverflow(Node* node) {
-  if (Node* ovf = node->FindProjection(1)) {
+  if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
     FlagsContinuation cont(kOverflow, ovf);
     return VisitBinop(this, node, kIA32Sub, &cont);
   }
@@ -977,6 +1231,24 @@
 }
 
 
+void InstructionSelector::VisitFloat32Equal(Node* node) {
+  FlagsContinuation cont(kUnorderedEqual, node);
+  VisitFloat32Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitFloat32LessThan(Node* node) {
+  FlagsContinuation cont(kUnsignedGreaterThan, node);
+  VisitFloat32Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitFloat32LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kUnsignedGreaterThanOrEqual, node);
+  VisitFloat32Compare(this, node, &cont);
+}
+
+
 void InstructionSelector::VisitFloat64Equal(Node* node) {
   FlagsContinuation cont(kUnorderedEqual, node);
   VisitFloat64Compare(this, node, &cont);
@@ -984,28 +1256,80 @@
 
 
 void InstructionSelector::VisitFloat64LessThan(Node* node) {
-  FlagsContinuation cont(kUnorderedLessThan, node);
+  FlagsContinuation cont(kUnsignedGreaterThan, node);
   VisitFloat64Compare(this, node, &cont);
 }
 
 
 void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
-  FlagsContinuation cont(kUnorderedLessThanOrEqual, node);
+  FlagsContinuation cont(kUnsignedGreaterThanOrEqual, node);
   VisitFloat64Compare(this, node, &cont);
 }
 
 
+void InstructionSelector::VisitFloat64ExtractLowWord32(Node* node) {
+  IA32OperandGenerator g(this);
+  Emit(kSSEFloat64ExtractLowWord32, g.DefineAsRegister(node),
+       g.Use(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitFloat64ExtractHighWord32(Node* node) {
+  IA32OperandGenerator g(this);
+  Emit(kSSEFloat64ExtractHighWord32, g.DefineAsRegister(node),
+       g.Use(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitFloat64InsertLowWord32(Node* node) {
+  IA32OperandGenerator g(this);
+  Node* left = node->InputAt(0);
+  Node* right = node->InputAt(1);
+  Float64Matcher mleft(left);
+  if (mleft.HasValue() && (bit_cast<uint64_t>(mleft.Value()) >> 32) == 0u) {
+    Emit(kSSEFloat64LoadLowWord32, g.DefineAsRegister(node), g.Use(right));
+    return;
+  }
+  Emit(kSSEFloat64InsertLowWord32, g.DefineSameAsFirst(node),
+       g.UseRegister(left), g.Use(right));
+}
+
+
+void InstructionSelector::VisitFloat64InsertHighWord32(Node* node) {
+  IA32OperandGenerator g(this);
+  Node* left = node->InputAt(0);
+  Node* right = node->InputAt(1);
+  Emit(kSSEFloat64InsertHighWord32, g.DefineSameAsFirst(node),
+       g.UseRegister(left), g.Use(right));
+}
+
+
 // static
 MachineOperatorBuilder::Flags
 InstructionSelector::SupportedMachineOperatorFlags() {
-  if (CpuFeatures::IsSupported(SSE4_1)) {
-    return MachineOperatorBuilder::kFloat64Floor |
-           MachineOperatorBuilder::kFloat64Ceil |
-           MachineOperatorBuilder::kFloat64RoundTruncate |
-           MachineOperatorBuilder::kWord32ShiftIsSafe;
+  MachineOperatorBuilder::Flags flags =
+      MachineOperatorBuilder::kFloat32Max |
+      MachineOperatorBuilder::kFloat32Min |
+      MachineOperatorBuilder::kFloat64Max |
+      MachineOperatorBuilder::kFloat64Min |
+      MachineOperatorBuilder::kWord32ShiftIsSafe |
+      MachineOperatorBuilder::kWord32Ctz;
+  if (CpuFeatures::IsSupported(POPCNT)) {
+    flags |= MachineOperatorBuilder::kWord32Popcnt;
   }
-  return MachineOperatorBuilder::Flag::kNoFlags;
+  if (CpuFeatures::IsSupported(SSE4_1)) {
+    flags |= MachineOperatorBuilder::kFloat32RoundDown |
+             MachineOperatorBuilder::kFloat64RoundDown |
+             MachineOperatorBuilder::kFloat32RoundUp |
+             MachineOperatorBuilder::kFloat64RoundUp |
+             MachineOperatorBuilder::kFloat32RoundTruncate |
+             MachineOperatorBuilder::kFloat64RoundTruncate |
+             MachineOperatorBuilder::kFloat32RoundTiesEven |
+             MachineOperatorBuilder::kFloat64RoundTiesEven;
+  }
+  return flags;
 }
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/src/compiler/ia32/linkage-ia32.cc b/src/compiler/ia32/linkage-ia32.cc
deleted file mode 100644
index 12cc34f..0000000
--- a/src/compiler/ia32/linkage-ia32.cc
+++ /dev/null
@@ -1,62 +0,0 @@
-// 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/v8.h"
-
-#include "src/assembler.h"
-#include "src/code-stubs.h"
-#include "src/compiler/linkage.h"
-#include "src/compiler/linkage-impl.h"
-#include "src/zone.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-struct IA32LinkageHelperTraits {
-  static Register ReturnValueReg() { return eax; }
-  static Register ReturnValue2Reg() { return edx; }
-  static Register JSCallFunctionReg() { return edi; }
-  static Register ContextReg() { return esi; }
-  static Register RuntimeCallFunctionReg() { return ebx; }
-  static Register RuntimeCallArgCountReg() { return eax; }
-  static RegList CCalleeSaveRegisters() {
-    return esi.bit() | edi.bit() | ebx.bit();
-  }
-  static Register CRegisterParameter(int i) { return no_reg; }
-  static int CRegisterParametersLength() { return 0; }
-};
-
-typedef LinkageHelper<IA32LinkageHelperTraits> LH;
-
-CallDescriptor* Linkage::GetJSCallDescriptor(int parameter_count, Zone* zone,
-                                             CallDescriptor::Flags flags) {
-  return LH::GetJSCallDescriptor(zone, parameter_count, flags);
-}
-
-
-CallDescriptor* Linkage::GetRuntimeCallDescriptor(
-    Runtime::FunctionId function, int parameter_count,
-    Operator::Properties properties, Zone* zone) {
-  return LH::GetRuntimeCallDescriptor(zone, function, parameter_count,
-                                      properties);
-}
-
-
-CallDescriptor* Linkage::GetStubCallDescriptor(
-    const CallInterfaceDescriptor& descriptor, int stack_parameter_count,
-    CallDescriptor::Flags flags, Operator::Properties properties, Zone* zone) {
-  return LH::GetStubCallDescriptor(zone, descriptor, stack_parameter_count,
-                                   flags, properties);
-}
-
-
-CallDescriptor* Linkage::GetSimplifiedCDescriptor(Zone* zone,
-                                                  MachineSignature* sig) {
-  return LH::GetSimplifiedCDescriptor(zone, sig);
-}
-
-}  // namespace compiler
-}  // namespace internal
-}  // namespace v8
diff --git a/src/compiler/instruction-codes.h b/src/compiler/instruction-codes.h
index ea17854..6c31ac8 100644
--- a/src/compiler/instruction-codes.h
+++ b/src/compiler/instruction-codes.h
@@ -19,6 +19,10 @@
 #include "src/compiler/mips64/instruction-codes-mips64.h"
 #elif V8_TARGET_ARCH_X64
 #include "src/compiler/x64/instruction-codes-x64.h"
+#elif V8_TARGET_ARCH_PPC
+#include "src/compiler/ppc/instruction-codes-ppc.h"
+#elif V8_TARGET_ARCH_X87
+#include "src/compiler/x87/instruction-codes-x87.h"
 #else
 #define TARGET_ARCH_OPCODE_LIST(V)
 #define TARGET_ADDRESSING_MODE_LIST(V)
@@ -29,28 +33,49 @@
 namespace internal {
 namespace compiler {
 
+// Modes for ArchStoreWithWriteBarrier below.
+enum class RecordWriteMode { kValueIsMap, kValueIsPointer, kValueIsAny };
+
+
 // Target-specific opcodes that specify which assembly sequence to emit.
 // Most opcodes specify a single instruction.
-#define ARCH_OPCODE_LIST(V) \
-  V(ArchCallCodeObject)     \
-  V(ArchCallJSFunction)     \
-  V(ArchJmp)                \
-  V(ArchNop)                \
-  V(ArchRet)                \
-  V(ArchStackPointer)       \
-  V(ArchTruncateDoubleToI)  \
-  V(CheckedLoadInt8)        \
-  V(CheckedLoadUint8)       \
-  V(CheckedLoadInt16)       \
-  V(CheckedLoadUint16)      \
-  V(CheckedLoadWord32)      \
-  V(CheckedLoadFloat32)     \
-  V(CheckedLoadFloat64)     \
-  V(CheckedStoreWord8)      \
-  V(CheckedStoreWord16)     \
-  V(CheckedStoreWord32)     \
-  V(CheckedStoreFloat32)    \
-  V(CheckedStoreFloat64)    \
+#define COMMON_ARCH_OPCODE_LIST(V) \
+  V(ArchCallCodeObject)            \
+  V(ArchTailCallCodeObject)        \
+  V(ArchCallJSFunction)            \
+  V(ArchTailCallJSFunction)        \
+  V(ArchPrepareCallCFunction)      \
+  V(ArchCallCFunction)             \
+  V(ArchPrepareTailCall)           \
+  V(ArchLazyBailout)               \
+  V(ArchJmp)                       \
+  V(ArchLookupSwitch)              \
+  V(ArchTableSwitch)               \
+  V(ArchNop)                       \
+  V(ArchThrowTerminator)           \
+  V(ArchDeoptimize)                \
+  V(ArchRet)                       \
+  V(ArchStackPointer)              \
+  V(ArchFramePointer)              \
+  V(ArchTruncateDoubleToI)         \
+  V(ArchStoreWithWriteBarrier)     \
+  V(CheckedLoadInt8)               \
+  V(CheckedLoadUint8)              \
+  V(CheckedLoadInt16)              \
+  V(CheckedLoadUint16)             \
+  V(CheckedLoadWord32)             \
+  V(CheckedLoadWord64)             \
+  V(CheckedLoadFloat32)            \
+  V(CheckedLoadFloat64)            \
+  V(CheckedStoreWord8)             \
+  V(CheckedStoreWord16)            \
+  V(CheckedStoreWord32)            \
+  V(CheckedStoreWord64)            \
+  V(CheckedStoreFloat32)           \
+  V(CheckedStoreFloat64)
+
+#define ARCH_OPCODE_LIST(V)  \
+  COMMON_ARCH_OPCODE_LIST(V) \
   TARGET_ARCH_OPCODE_LIST(V)
 
 enum ArchOpcode {
@@ -100,12 +125,16 @@
   kUnsignedGreaterThanOrEqual,
   kUnsignedLessThanOrEqual,
   kUnsignedGreaterThan,
+  kFloatLessThanOrUnordered,
+  kFloatGreaterThanOrEqual,
+  kFloatLessThanOrEqual,
+  kFloatGreaterThanOrUnordered,
+  kFloatLessThan,
+  kFloatGreaterThanOrEqualOrUnordered,
+  kFloatLessThanOrEqualOrUnordered,
+  kFloatGreaterThan,
   kUnorderedEqual,
   kUnorderedNotEqual,
-  kUnorderedLessThan,
-  kUnorderedGreaterThanOrEqual,
-  kUnorderedLessThanOrEqual,
-  kUnorderedGreaterThan,
   kOverflow,
   kNotOverflow
 };
@@ -114,6 +143,8 @@
   return static_cast<FlagsCondition>(condition ^ 1);
 }
 
+FlagsCondition CommuteFlagsCondition(FlagsCondition condition);
+
 std::ostream& operator<<(std::ostream& os, const FlagsCondition& fc);
 
 // The InstructionCode is an opaque, target-specific integer that encodes
@@ -126,11 +157,11 @@
 // for code generation. We encode the instruction, addressing mode, and flags
 // continuation into a single InstructionCode which is stored as part of
 // the instruction.
-typedef BitField<ArchOpcode, 0, 7> ArchOpcodeField;
-typedef BitField<AddressingMode, 7, 5> AddressingModeField;
-typedef BitField<FlagsMode, 12, 2> FlagsModeField;
-typedef BitField<FlagsCondition, 14, 5> FlagsConditionField;
-typedef BitField<int, 14, 18> MiscField;
+typedef BitField<ArchOpcode, 0, 8> ArchOpcodeField;
+typedef BitField<AddressingMode, 8, 5> AddressingModeField;
+typedef BitField<FlagsMode, 13, 2> FlagsModeField;
+typedef BitField<FlagsCondition, 15, 5> FlagsConditionField;
+typedef BitField<int, 20, 12> MiscField;
 
 }  // namespace compiler
 }  // namespace internal
diff --git a/src/compiler/instruction-scheduler.cc b/src/compiler/instruction-scheduler.cc
new file mode 100644
index 0000000..2f329ea
--- /dev/null
+++ b/src/compiler/instruction-scheduler.cc
@@ -0,0 +1,280 @@
+// Copyright 2015 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/instruction-scheduler.h"
+
+#include "src/base/adapters.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+InstructionScheduler::ScheduleGraphNode::ScheduleGraphNode(
+    Zone* zone,
+    Instruction* instr)
+    : instr_(instr),
+      successors_(zone),
+      unscheduled_predecessors_count_(0),
+      latency_(GetInstructionLatency(instr)),
+      total_latency_(-1),
+      start_cycle_(-1) {
+}
+
+
+void InstructionScheduler::ScheduleGraphNode::AddSuccessor(
+    ScheduleGraphNode* node) {
+  successors_.push_back(node);
+  node->unscheduled_predecessors_count_++;
+}
+
+
+InstructionScheduler::InstructionScheduler(Zone* zone,
+                                           InstructionSequence* sequence)
+    : zone_(zone),
+      sequence_(sequence),
+      graph_(zone),
+      last_side_effect_instr_(nullptr),
+      pending_loads_(zone),
+      last_live_in_reg_marker_(nullptr) {
+}
+
+
+void InstructionScheduler::StartBlock(RpoNumber rpo) {
+  DCHECK(graph_.empty());
+  DCHECK(last_side_effect_instr_ == nullptr);
+  DCHECK(pending_loads_.empty());
+  DCHECK(last_live_in_reg_marker_ == nullptr);
+  sequence()->StartBlock(rpo);
+}
+
+
+void InstructionScheduler::EndBlock(RpoNumber rpo) {
+  ScheduleBlock();
+  sequence()->EndBlock(rpo);
+  graph_.clear();
+  last_side_effect_instr_ = nullptr;
+  pending_loads_.clear();
+  last_live_in_reg_marker_ = nullptr;
+}
+
+
+void InstructionScheduler::AddInstruction(Instruction* instr) {
+  ScheduleGraphNode* new_node = new (zone()) ScheduleGraphNode(zone(), instr);
+
+  if (IsBlockTerminator(instr)) {
+    // Make sure that basic block terminators are not moved by adding them
+    // as successor of every instruction.
+    for (auto node : graph_) {
+      node->AddSuccessor(new_node);
+    }
+  } else if (IsFixedRegisterParameter(instr)) {
+    if (last_live_in_reg_marker_ != nullptr) {
+      last_live_in_reg_marker_->AddSuccessor(new_node);
+    }
+    last_live_in_reg_marker_ = new_node;
+  } else {
+    if (last_live_in_reg_marker_ != nullptr) {
+      last_live_in_reg_marker_->AddSuccessor(new_node);
+    }
+
+    // Instructions with side effects and memory operations can't be
+    // reordered with respect to each other.
+    if (HasSideEffect(instr)) {
+      if (last_side_effect_instr_ != nullptr) {
+        last_side_effect_instr_->AddSuccessor(new_node);
+      }
+      for (auto load : pending_loads_) {
+        load->AddSuccessor(new_node);
+      }
+      pending_loads_.clear();
+      last_side_effect_instr_ = new_node;
+    } else if (IsLoadOperation(instr)) {
+      // Load operations can't be reordered with side effects instructions but
+      // independent loads can be reordered with respect to each other.
+      if (last_side_effect_instr_ != nullptr) {
+        last_side_effect_instr_->AddSuccessor(new_node);
+      }
+      pending_loads_.push_back(new_node);
+    }
+
+    // Look for operand dependencies.
+    for (auto node : graph_) {
+      if (HasOperandDependency(node->instruction(), instr)) {
+        node->AddSuccessor(new_node);
+      }
+    }
+  }
+
+  graph_.push_back(new_node);
+}
+
+
+bool InstructionScheduler::CompareNodes(ScheduleGraphNode *node1,
+                                        ScheduleGraphNode *node2) const {
+  return node1->total_latency() > node2->total_latency();
+}
+
+
+void InstructionScheduler::ScheduleBlock() {
+  ZoneLinkedList<ScheduleGraphNode*> ready_list(zone());
+
+  // Compute total latencies so that we can schedule the critical path first.
+  ComputeTotalLatencies();
+
+  // Add nodes which don't have dependencies to the ready list.
+  for (auto node : graph_) {
+    if (!node->HasUnscheduledPredecessor()) {
+      ready_list.push_back(node);
+    }
+  }
+
+  // Go through the ready list and schedule the instructions.
+  int cycle = 0;
+  while (!ready_list.empty()) {
+    auto candidate = ready_list.end();
+    for (auto iterator = ready_list.begin(); iterator != ready_list.end();
+         ++iterator) {
+      // Look for the best candidate to schedule.
+      // We only consider instructions that have all their operands ready and
+      // we try to schedule the critical path first (we look for the instruction
+      // with the highest latency on the path to reach the end of the graph).
+      if (cycle >= (*iterator)->start_cycle()) {
+        if ((candidate == ready_list.end()) ||
+            CompareNodes(*iterator, *candidate)) {
+          candidate = iterator;
+        }
+      }
+    }
+
+    if (candidate != ready_list.end()) {
+      sequence()->AddInstruction((*candidate)->instruction());
+
+      for (auto successor : (*candidate)->successors()) {
+        successor->DropUnscheduledPredecessor();
+        successor->set_start_cycle(
+            std::max(successor->start_cycle(),
+                     cycle + (*candidate)->latency()));
+
+        if (!successor->HasUnscheduledPredecessor()) {
+          ready_list.push_back(successor);
+        }
+      }
+
+      ready_list.erase(candidate);
+    }
+
+    cycle++;
+  }
+}
+
+
+int InstructionScheduler::GetInstructionFlags(const Instruction* instr) const {
+  switch (instr->arch_opcode()) {
+    case kArchNop:
+    case kArchStackPointer:
+    case kArchFramePointer:
+    case kArchTruncateDoubleToI:
+      return kNoOpcodeFlags;
+
+    case kArchPrepareCallCFunction:
+    case kArchPrepareTailCall:
+    case kArchCallCFunction:
+    case kArchCallCodeObject:
+    case kArchCallJSFunction:
+    case kArchLazyBailout:
+      return kHasSideEffect;
+
+    case kArchTailCallCodeObject:
+    case kArchTailCallJSFunction:
+      return kHasSideEffect | kIsBlockTerminator;
+
+    case kArchDeoptimize:
+    case kArchJmp:
+    case kArchLookupSwitch:
+    case kArchTableSwitch:
+    case kArchRet:
+    case kArchThrowTerminator:
+      return kIsBlockTerminator;
+
+    case kCheckedLoadInt8:
+    case kCheckedLoadUint8:
+    case kCheckedLoadInt16:
+    case kCheckedLoadUint16:
+    case kCheckedLoadWord32:
+    case kCheckedLoadWord64:
+    case kCheckedLoadFloat32:
+    case kCheckedLoadFloat64:
+      return kIsLoadOperation;
+
+    case kCheckedStoreWord8:
+    case kCheckedStoreWord16:
+    case kCheckedStoreWord32:
+    case kCheckedStoreWord64:
+    case kCheckedStoreFloat32:
+    case kCheckedStoreFloat64:
+    case kArchStoreWithWriteBarrier:
+      return kHasSideEffect;
+
+#define CASE(Name) case k##Name:
+    TARGET_ARCH_OPCODE_LIST(CASE)
+#undef CASE
+      return GetTargetInstructionFlags(instr);
+  }
+
+  UNREACHABLE();
+  return kNoOpcodeFlags;
+}
+
+
+bool InstructionScheduler::HasOperandDependency(
+    const Instruction* instr1, const Instruction* instr2) const {
+  for (size_t i = 0; i < instr1->OutputCount(); ++i) {
+    for (size_t j = 0; j < instr2->InputCount(); ++j) {
+      const InstructionOperand* output = instr1->OutputAt(i);
+      const InstructionOperand* input = instr2->InputAt(j);
+
+      if (output->IsUnallocated() && input->IsUnallocated() &&
+          (UnallocatedOperand::cast(output)->virtual_register() ==
+           UnallocatedOperand::cast(input)->virtual_register())) {
+        return true;
+      }
+
+      if (output->IsConstant() && input->IsUnallocated() &&
+          (ConstantOperand::cast(output)->virtual_register() ==
+           UnallocatedOperand::cast(input)->virtual_register())) {
+        return true;
+      }
+    }
+  }
+
+  // TODO(bafsa): Do we need to look for anti-dependencies/output-dependencies?
+
+  return false;
+}
+
+
+bool InstructionScheduler::IsBlockTerminator(const Instruction* instr) const {
+  return ((GetInstructionFlags(instr) & kIsBlockTerminator) ||
+          (instr->flags_mode() == kFlags_branch));
+}
+
+
+void InstructionScheduler::ComputeTotalLatencies() {
+  for (auto node : base::Reversed(graph_)) {
+    int max_latency = 0;
+
+    for (auto successor : node->successors()) {
+      DCHECK(successor->total_latency() != -1);
+      if (successor->total_latency() > max_latency) {
+        max_latency = successor->total_latency();
+      }
+    }
+
+    node->set_total_latency(max_latency + node->latency());
+  }
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/instruction-scheduler.h b/src/compiler/instruction-scheduler.h
new file mode 100644
index 0000000..fafbe47
--- /dev/null
+++ b/src/compiler/instruction-scheduler.h
@@ -0,0 +1,162 @@
+// Copyright 2015 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.
+
+#ifndef V8_COMPILER_INSTRUCTION_SCHEDULER_H_
+#define V8_COMPILER_INSTRUCTION_SCHEDULER_H_
+
+#include "src/compiler/instruction.h"
+#include "src/zone-containers.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+// A set of flags describing properties of the instructions so that the
+// scheduler is aware of dependencies between instructions.
+enum ArchOpcodeFlags {
+  kNoOpcodeFlags = 0,
+  kIsBlockTerminator = 1,  // The instruction marks the end of a basic block
+                           // e.g.: jump and return instructions.
+  kHasSideEffect = 2,      // The instruction has some side effects (memory
+                           // store, function call...)
+  kIsLoadOperation = 4,    // The instruction is a memory load.
+};
+
+
+class InstructionScheduler final : public ZoneObject {
+ public:
+  InstructionScheduler(Zone* zone, InstructionSequence* sequence);
+
+  void StartBlock(RpoNumber rpo);
+  void EndBlock(RpoNumber rpo);
+
+  void AddInstruction(Instruction* instr);
+
+  static bool SchedulerSupported();
+
+ private:
+  // A scheduling graph node.
+  // Represent an instruction and their dependencies.
+  class ScheduleGraphNode: public ZoneObject {
+   public:
+    ScheduleGraphNode(Zone* zone, Instruction* instr);
+
+    // Mark the instruction represented by 'node' as a dependecy of this one.
+    // The current instruction will be registered as an unscheduled predecessor
+    // of 'node' (i.e. it must be scheduled before 'node').
+    void AddSuccessor(ScheduleGraphNode* node);
+
+    // Check if all the predecessors of this instruction have been scheduled.
+    bool HasUnscheduledPredecessor() {
+      return unscheduled_predecessors_count_ != 0;
+    }
+
+    // Record that we have scheduled one of the predecessors of this node.
+    void DropUnscheduledPredecessor() {
+      DCHECK(unscheduled_predecessors_count_ > 0);
+      unscheduled_predecessors_count_--;
+    }
+
+    Instruction* instruction() { return instr_; }
+    ZoneDeque<ScheduleGraphNode*>& successors() { return successors_; }
+    int latency() const { return latency_; }
+
+    int total_latency() const { return total_latency_; }
+    void set_total_latency(int latency) { total_latency_ = latency; }
+
+    int start_cycle() const { return start_cycle_; }
+    void set_start_cycle(int start_cycle) { start_cycle_ = start_cycle; }
+
+   private:
+    Instruction* instr_;
+    ZoneDeque<ScheduleGraphNode*> successors_;
+
+    // Number of unscheduled predecessors for this node.
+    int unscheduled_predecessors_count_;
+
+    // Estimate of the instruction latency (the number of cycles it takes for
+    // instruction to complete).
+    int latency_;
+
+    // The sum of all the latencies on the path from this node to the end of
+    // the graph (i.e. a node with no successor).
+    int total_latency_;
+
+    // The scheduler keeps a nominal cycle count to keep track of when the
+    // result of an instruction is available. This field is updated by the
+    // scheduler to indicate when the value of all the operands of this
+    // instruction will be available.
+    int start_cycle_;
+  };
+
+  // Compare the two nodes and return true if node1 is a better candidate than
+  // node2 (i.e. node1 should be scheduled before node2).
+  bool CompareNodes(ScheduleGraphNode *node1, ScheduleGraphNode *node2) const;
+
+  // Perform scheduling for the current block.
+  void ScheduleBlock();
+
+  // Return the scheduling properties of the given instruction.
+  int GetInstructionFlags(const Instruction* instr) const;
+  int GetTargetInstructionFlags(const Instruction* instr) const;
+
+  // Return true if instr2 uses any value defined by instr1.
+  bool HasOperandDependency(const Instruction* instr1,
+                            const Instruction* instr2) const;
+
+  // Return true if the instruction is a basic block terminator.
+  bool IsBlockTerminator(const Instruction* instr) const;
+
+  // Check whether the given instruction has side effects (e.g. function call,
+  // memory store).
+  bool HasSideEffect(const Instruction* instr) const {
+    return GetInstructionFlags(instr) & kHasSideEffect;
+  }
+
+  // Return true if the instruction is a memory load.
+  bool IsLoadOperation(const Instruction* instr) const {
+    return GetInstructionFlags(instr) & kIsLoadOperation;
+  }
+
+  // Identify nops used as a definition point for live-in registers at
+  // function entry.
+  bool IsFixedRegisterParameter(const Instruction* instr) const {
+    return (instr->arch_opcode() == kArchNop) &&
+      (instr->OutputCount() == 1) &&
+      (instr->OutputAt(0)->IsUnallocated()) &&
+      UnallocatedOperand::cast(instr->OutputAt(0))->HasFixedRegisterPolicy();
+  }
+
+  void ComputeTotalLatencies();
+
+  static int GetInstructionLatency(const Instruction* instr);
+
+  Zone* zone() { return zone_; }
+  InstructionSequence* sequence() { return sequence_; }
+
+  Zone* zone_;
+  InstructionSequence* sequence_;
+  ZoneVector<ScheduleGraphNode*> graph_;
+
+  // Last side effect instruction encountered while building the graph.
+  ScheduleGraphNode* last_side_effect_instr_;
+
+  // Set of load instructions encountered since the last side effect instruction
+  // which will be added as predecessors of the next instruction with side
+  // effects.
+  ZoneVector<ScheduleGraphNode*> pending_loads_;
+
+  // Live-in register markers are nop instructions which are emitted at the
+  // beginning of a basic block so that the register allocator will find a
+  // defining instruction for live-in values. They must not be moved.
+  // All these nops are chained together and added as a predecessor of every
+  // other instructions in the basic block.
+  ScheduleGraphNode* last_live_in_reg_marker_;
+};
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_INSTRUCTION_SCHEDULER_H_
diff --git a/src/compiler/instruction-selector-impl.h b/src/compiler/instruction-selector-impl.h
index bdcd952..5cca888 100644
--- a/src/compiler/instruction-selector-impl.h
+++ b/src/compiler/instruction-selector-impl.h
@@ -8,12 +8,24 @@
 #include "src/compiler/instruction.h"
 #include "src/compiler/instruction-selector.h"
 #include "src/compiler/linkage.h"
+#include "src/compiler/schedule.h"
 #include "src/macro-assembler.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
+// Helper struct containing data about a table or lookup switch.
+struct SwitchInfo {
+  int32_t min_value;           // minimum value of {case_values}
+  int32_t max_value;           // maximum value of {case_values}
+  size_t value_range;          // |max_value - min_value| + 1
+  size_t case_count;           // number of cases
+  int32_t* case_values;        // actual case values, unsorted
+  BasicBlock** case_branches;  // basic blocks corresponding to case values
+  BasicBlock* default_branch;  // default branch target
+};
+
 // A helper class for the instruction selector that simplifies construction of
 // Operands. This class implements a base for architecture-specific helpers.
 class OperandGenerator {
@@ -21,132 +33,176 @@
   explicit OperandGenerator(InstructionSelector* selector)
       : selector_(selector) {}
 
-  InstructionOperand* DefineAsRegister(Node* node) {
-    return Define(node, new (zone())
-                  UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER));
+  InstructionOperand NoOutput() {
+    return InstructionOperand();  // Generates an invalid operand.
   }
 
-  InstructionOperand* DefineSameAsFirst(Node* result) {
-    return Define(result, new (zone())
-                  UnallocatedOperand(UnallocatedOperand::SAME_AS_FIRST_INPUT));
+  InstructionOperand DefineAsRegister(Node* node) {
+    return Define(node,
+                  UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER,
+                                     GetVReg(node)));
   }
 
-  InstructionOperand* DefineAsFixed(Node* node, Register reg) {
-    return Define(node, new (zone())
-                  UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER,
-                                     Register::ToAllocationIndex(reg)));
+  InstructionOperand DefineSameAsFirst(Node* node) {
+    return Define(node,
+                  UnallocatedOperand(UnallocatedOperand::SAME_AS_FIRST_INPUT,
+                                     GetVReg(node)));
   }
 
-  InstructionOperand* DefineAsFixed(Node* node, DoubleRegister reg) {
-    return Define(node, new (zone())
+  InstructionOperand DefineAsFixed(Node* node, Register reg) {
+    return Define(node, UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER,
+                                           reg.code(), GetVReg(node)));
+  }
+
+  InstructionOperand DefineAsFixed(Node* node, DoubleRegister reg) {
+    return Define(node,
                   UnallocatedOperand(UnallocatedOperand::FIXED_DOUBLE_REGISTER,
-                                     DoubleRegister::ToAllocationIndex(reg)));
+                                     reg.code(), GetVReg(node)));
   }
 
-  InstructionOperand* DefineAsConstant(Node* node) {
+  InstructionOperand DefineAsConstant(Node* node) {
     selector()->MarkAsDefined(node);
-    int virtual_register = selector_->GetVirtualRegister(node);
+    int virtual_register = GetVReg(node);
     sequence()->AddConstant(virtual_register, ToConstant(node));
-    return ConstantOperand::Create(virtual_register, zone());
+    return ConstantOperand(virtual_register);
   }
 
-  InstructionOperand* DefineAsLocation(Node* node, LinkageLocation location,
-                                       MachineType type) {
-    return Define(node, ToUnallocatedOperand(location, type));
+  InstructionOperand DefineAsLocation(Node* node, LinkageLocation location,
+                                      MachineRepresentation rep) {
+    return Define(node, ToUnallocatedOperand(location, rep, GetVReg(node)));
   }
 
-  InstructionOperand* Use(Node* node) {
-    return Use(
-        node, new (zone()) UnallocatedOperand(
-                  UnallocatedOperand::NONE, UnallocatedOperand::USED_AT_START));
+  InstructionOperand DefineAsDualLocation(Node* node,
+                                          LinkageLocation primary_location,
+                                          LinkageLocation secondary_location) {
+    return Define(node,
+                  ToDualLocationUnallocatedOperand(
+                      primary_location, secondary_location, GetVReg(node)));
   }
 
-  InstructionOperand* UseRegister(Node* node) {
-    return Use(node, new (zone())
-               UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER,
-                                  UnallocatedOperand::USED_AT_START));
+  InstructionOperand Use(Node* node) {
+    return Use(node, UnallocatedOperand(UnallocatedOperand::NONE,
+                                        UnallocatedOperand::USED_AT_START,
+                                        GetVReg(node)));
+  }
+
+  InstructionOperand UseAny(Node* node) {
+    return Use(node, UnallocatedOperand(UnallocatedOperand::ANY,
+                                        UnallocatedOperand::USED_AT_START,
+                                        GetVReg(node)));
+  }
+
+  InstructionOperand UseRegister(Node* node) {
+    return Use(node, UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER,
+                                        UnallocatedOperand::USED_AT_START,
+                                        GetVReg(node)));
+  }
+
+  InstructionOperand UseUniqueSlot(Node* node) {
+    return Use(node, UnallocatedOperand(UnallocatedOperand::MUST_HAVE_SLOT,
+                                        GetVReg(node)));
   }
 
   // Use register or operand for the node. If a register is chosen, it won't
   // alias any temporary or output registers.
-  InstructionOperand* UseUnique(Node* node) {
-    return Use(node, new (zone()) UnallocatedOperand(UnallocatedOperand::NONE));
+  InstructionOperand UseUnique(Node* node) {
+    return Use(node,
+               UnallocatedOperand(UnallocatedOperand::NONE, GetVReg(node)));
   }
 
   // Use a unique register for the node that does not alias any temporary or
   // output registers.
-  InstructionOperand* UseUniqueRegister(Node* node) {
-    return Use(node, new (zone())
-               UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER));
+  InstructionOperand UseUniqueRegister(Node* node) {
+    return Use(node, UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER,
+                                        GetVReg(node)));
   }
 
-  InstructionOperand* UseFixed(Node* node, Register reg) {
-    return Use(node, new (zone())
-               UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER,
-                                  Register::ToAllocationIndex(reg)));
+  InstructionOperand UseFixed(Node* node, Register reg) {
+    return Use(node, UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER,
+                                        reg.code(), GetVReg(node)));
   }
 
-  InstructionOperand* UseFixed(Node* node, DoubleRegister reg) {
-    return Use(node, new (zone())
+  InstructionOperand UseFixed(Node* node, DoubleRegister reg) {
+    return Use(node,
                UnallocatedOperand(UnallocatedOperand::FIXED_DOUBLE_REGISTER,
-                                  DoubleRegister::ToAllocationIndex(reg)));
+                                  reg.code(), GetVReg(node)));
   }
 
-  InstructionOperand* UseImmediate(Node* node) {
-    int index = sequence()->AddImmediate(ToConstant(node));
-    return ImmediateOperand::Create(index, zone());
+  InstructionOperand UseExplicit(LinkageLocation location) {
+    MachineRepresentation rep = InstructionSequence::DefaultRepresentation();
+    if (location.IsRegister()) {
+      return ExplicitOperand(LocationOperand::REGISTER, rep,
+                             location.AsRegister());
+    } else {
+      return ExplicitOperand(LocationOperand::STACK_SLOT, rep,
+                             location.GetLocation());
+    }
   }
 
-  InstructionOperand* UseLocation(Node* node, LinkageLocation location,
-                                  MachineType type) {
-    return Use(node, ToUnallocatedOperand(location, type));
+  InstructionOperand UseImmediate(Node* node) {
+    return sequence()->AddImmediate(ToConstant(node));
   }
 
-  InstructionOperand* TempRegister() {
-    UnallocatedOperand* op =
-        new (zone()) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER,
-                                        UnallocatedOperand::USED_AT_START);
-    op->set_virtual_register(sequence()->NextVirtualRegister());
+  InstructionOperand UseLocation(Node* node, LinkageLocation location,
+                                 MachineRepresentation rep) {
+    return Use(node, ToUnallocatedOperand(location, rep, GetVReg(node)));
+  }
+
+  // Used to force gap moves from the from_location to the to_location
+  // immediately before an instruction.
+  InstructionOperand UsePointerLocation(LinkageLocation to_location,
+                                        LinkageLocation from_location) {
+    MachineRepresentation rep = MachineType::PointerRepresentation();
+    UnallocatedOperand casted_from_operand =
+        UnallocatedOperand::cast(TempLocation(from_location, rep));
+    selector_->Emit(kArchNop, casted_from_operand);
+    return ToUnallocatedOperand(to_location, rep,
+                                casted_from_operand.virtual_register());
+  }
+
+  InstructionOperand TempRegister() {
+    return UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER,
+                              UnallocatedOperand::USED_AT_START,
+                              sequence()->NextVirtualRegister());
+  }
+
+  InstructionOperand TempDoubleRegister() {
+    UnallocatedOperand op = UnallocatedOperand(
+        UnallocatedOperand::MUST_HAVE_REGISTER,
+        UnallocatedOperand::USED_AT_START, sequence()->NextVirtualRegister());
+    sequence()->MarkAsRepresentation(MachineRepresentation::kFloat64,
+                                     op.virtual_register());
     return op;
   }
 
-  InstructionOperand* TempDoubleRegister() {
-    UnallocatedOperand* op =
-        new (zone()) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER,
-                                        UnallocatedOperand::USED_AT_START);
-    op->set_virtual_register(sequence()->NextVirtualRegister());
-    sequence()->MarkAsDouble(op->virtual_register());
-    return op;
+  InstructionOperand TempRegister(Register reg) {
+    return UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER, reg.code(),
+                              InstructionOperand::kInvalidVirtualRegister);
   }
 
-  InstructionOperand* TempRegister(Register reg) {
-    return new (zone()) UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER,
-                                           Register::ToAllocationIndex(reg));
+  InstructionOperand TempImmediate(int32_t imm) {
+    return sequence()->AddImmediate(Constant(imm));
   }
 
-  InstructionOperand* TempImmediate(int32_t imm) {
-    int index = sequence()->AddImmediate(Constant(imm));
-    return ImmediateOperand::Create(index, zone());
+  InstructionOperand TempLocation(LinkageLocation location,
+                                  MachineRepresentation rep) {
+    return ToUnallocatedOperand(location, rep,
+                                sequence()->NextVirtualRegister());
   }
 
-  InstructionOperand* TempLocation(LinkageLocation location, MachineType type) {
-    UnallocatedOperand* op = ToUnallocatedOperand(location, type);
-    op->set_virtual_register(sequence()->NextVirtualRegister());
-    return op;
-  }
-
-  InstructionOperand* Label(BasicBlock* block) {
-    int index = sequence()->AddImmediate(Constant(block->GetRpoNumber()));
-    return ImmediateOperand::Create(index, zone());
+  InstructionOperand Label(BasicBlock* block) {
+    return sequence()->AddImmediate(
+        Constant(RpoNumber::FromInt(block->rpo_number())));
   }
 
  protected:
   InstructionSelector* selector() const { return selector_; }
   InstructionSequence* sequence() const { return selector()->sequence(); }
-  Isolate* isolate() const { return zone()->isolate(); }
   Zone* zone() const { return selector()->instruction_zone(); }
 
  private:
+  int GetVReg(Node* node) const { return selector_->GetVirtualRegister(node); }
+
   static Constant ToConstant(const Node* node) {
     switch (node->opcode()) {
       case IrOpcode::kInt32Constant:
@@ -161,7 +217,7 @@
       case IrOpcode::kExternalConstant:
         return Constant(OpParameter<ExternalReference>(node));
       case IrOpcode::kHeapConstant:
-        return Constant(OpParameter<Unique<HeapObject> >(node).handle());
+        return Constant(OpParameter<Handle<HeapObject>>(node));
       default:
         break;
     }
@@ -169,38 +225,57 @@
     return Constant(static_cast<int32_t>(0));
   }
 
-  UnallocatedOperand* Define(Node* node, UnallocatedOperand* operand) {
+  UnallocatedOperand Define(Node* node, UnallocatedOperand operand) {
     DCHECK_NOT_NULL(node);
-    DCHECK_NOT_NULL(operand);
-    operand->set_virtual_register(selector_->GetVirtualRegister(node));
+    DCHECK_EQ(operand.virtual_register(), GetVReg(node));
     selector()->MarkAsDefined(node);
     return operand;
   }
 
-  UnallocatedOperand* Use(Node* node, UnallocatedOperand* operand) {
+  UnallocatedOperand Use(Node* node, UnallocatedOperand operand) {
     DCHECK_NOT_NULL(node);
-    DCHECK_NOT_NULL(operand);
-    operand->set_virtual_register(selector_->GetVirtualRegister(node));
+    DCHECK_EQ(operand.virtual_register(), GetVReg(node));
     selector()->MarkAsUsed(node);
     return operand;
   }
 
-  UnallocatedOperand* ToUnallocatedOperand(LinkageLocation location,
-                                           MachineType type) {
-    if (location.location_ == LinkageLocation::ANY_REGISTER) {
-      return new (zone())
-          UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER);
+  UnallocatedOperand ToDualLocationUnallocatedOperand(
+      LinkageLocation primary_location, LinkageLocation secondary_location,
+      int virtual_register) {
+    // We only support the primary location being a register and the secondary
+    // one a slot.
+    DCHECK(primary_location.IsRegister() &&
+           secondary_location.IsCalleeFrameSlot());
+    int reg_id = primary_location.AsRegister();
+    int slot_id = secondary_location.AsCalleeFrameSlot();
+    return UnallocatedOperand(reg_id, slot_id, virtual_register);
+  }
+
+  UnallocatedOperand ToUnallocatedOperand(LinkageLocation location,
+                                          MachineRepresentation rep,
+                                          int virtual_register) {
+    if (location.IsAnyRegister()) {
+      // any machine register.
+      return UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER,
+                                virtual_register);
     }
-    if (location.location_ < 0) {
-      return new (zone()) UnallocatedOperand(UnallocatedOperand::FIXED_SLOT,
-                                             location.location_);
+    if (location.IsCallerFrameSlot()) {
+      // a location on the caller frame.
+      return UnallocatedOperand(UnallocatedOperand::FIXED_SLOT,
+                                location.AsCallerFrameSlot(), virtual_register);
     }
-    if (RepresentationOf(type) == kRepFloat64) {
-      return new (zone()) UnallocatedOperand(
-          UnallocatedOperand::FIXED_DOUBLE_REGISTER, location.location_);
+    if (location.IsCalleeFrameSlot()) {
+      // a spill location on this (callee) frame.
+      return UnallocatedOperand(UnallocatedOperand::FIXED_SLOT,
+                                location.AsCalleeFrameSlot(), virtual_register);
     }
-    return new (zone()) UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER,
-                                           location.location_);
+    // a fixed register.
+    if (IsFloatingPoint(rep)) {
+      return UnallocatedOperand(UnallocatedOperand::FIXED_DOUBLE_REGISTER,
+                                location.AsRegister(), virtual_register);
+    }
+    return UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER,
+                              location.AsRegister(), virtual_register);
   }
 
   InstructionSelector* selector_;
@@ -212,7 +287,7 @@
 // The whole instruction is treated as a unit by the register allocator, and
 // thus no spills or moves can be introduced between the flags-setting
 // instruction and the branch or set it should be combined with.
-class FlagsContinuation FINAL {
+class FlagsContinuation final {
  public:
   FlagsContinuation() : mode_(kFlags_none) {}
 
@@ -261,53 +336,7 @@
 
   void Commute() {
     DCHECK(!IsNone());
-    switch (condition_) {
-      case kEqual:
-      case kNotEqual:
-      case kOverflow:
-      case kNotOverflow:
-        return;
-      case kSignedLessThan:
-        condition_ = kSignedGreaterThan;
-        return;
-      case kSignedGreaterThanOrEqual:
-        condition_ = kSignedLessThanOrEqual;
-        return;
-      case kSignedLessThanOrEqual:
-        condition_ = kSignedGreaterThanOrEqual;
-        return;
-      case kSignedGreaterThan:
-        condition_ = kSignedLessThan;
-        return;
-      case kUnsignedLessThan:
-        condition_ = kUnsignedGreaterThan;
-        return;
-      case kUnsignedGreaterThanOrEqual:
-        condition_ = kUnsignedLessThanOrEqual;
-        return;
-      case kUnsignedLessThanOrEqual:
-        condition_ = kUnsignedGreaterThanOrEqual;
-        return;
-      case kUnsignedGreaterThan:
-        condition_ = kUnsignedLessThan;
-        return;
-      case kUnorderedEqual:
-      case kUnorderedNotEqual:
-        return;
-      case kUnorderedLessThan:
-        condition_ = kUnorderedGreaterThan;
-        return;
-      case kUnorderedGreaterThanOrEqual:
-        condition_ = kUnorderedLessThanOrEqual;
-        return;
-      case kUnorderedLessThanOrEqual:
-        condition_ = kUnorderedGreaterThanOrEqual;
-        return;
-      case kUnorderedGreaterThan:
-        condition_ = kUnorderedLessThan;
-        return;
-    }
-    UNREACHABLE();
+    condition_ = CommuteFlagsCondition(condition_);
   }
 
   void OverwriteAndNegateIfEqual(FlagsCondition condition) {
@@ -333,33 +362,6 @@
   BasicBlock* false_block_;  // Only valid if mode_ == kFlags_branch.
 };
 
-
-// An internal helper class for generating the operands to calls.
-// TODO(bmeurer): Get rid of the CallBuffer business and make
-// InstructionSelector::VisitCall platform independent instead.
-struct CallBuffer {
-  CallBuffer(Zone* zone, const CallDescriptor* descriptor,
-             FrameStateDescriptor* frame_state);
-
-  const CallDescriptor* descriptor;
-  FrameStateDescriptor* frame_state_descriptor;
-  NodeVector output_nodes;
-  InstructionOperandVector outputs;
-  InstructionOperandVector instruction_args;
-  NodeVector pushed_nodes;
-
-  size_t input_count() const { return descriptor->InputCount(); }
-
-  size_t frame_state_count() const { return descriptor->FrameStateCount(); }
-
-  size_t frame_state_value_count() const {
-    return (frame_state_descriptor == NULL)
-               ? 0
-               : (frame_state_descriptor->GetTotalSize() +
-                  1);  // Include deopt id.
-  }
-};
-
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/src/compiler/instruction-selector.cc b/src/compiler/instruction-selector.cc
index ffb8f9f..86868e5 100644
--- a/src/compiler/instruction-selector.cc
+++ b/src/compiler/instruction-selector.cc
@@ -4,101 +4,143 @@
 
 #include "src/compiler/instruction-selector.h"
 
-#include "src/compiler/graph.h"
+#include <limits>
+
+#include "src/base/adapters.h"
 #include "src/compiler/instruction-selector-impl.h"
 #include "src/compiler/node-matchers.h"
-#include "src/compiler/node-properties-inl.h"
 #include "src/compiler/pipeline.h"
+#include "src/compiler/schedule.h"
+#include "src/compiler/state-values-utils.h"
+#include "src/deoptimizer.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
-InstructionSelector::InstructionSelector(Zone* local_zone, Graph* graph,
-                                         Linkage* linkage,
-                                         InstructionSequence* sequence,
-                                         Schedule* schedule,
-                                         SourcePositionTable* source_positions,
-                                         Features features)
-    : zone_(local_zone),
+InstructionSelector::InstructionSelector(
+    Zone* zone, size_t node_count, Linkage* linkage,
+    InstructionSequence* sequence, Schedule* schedule,
+    SourcePositionTable* source_positions,
+    SourcePositionMode source_position_mode, Features features)
+    : zone_(zone),
       linkage_(linkage),
       sequence_(sequence),
       source_positions_(source_positions),
+      source_position_mode_(source_position_mode),
       features_(features),
       schedule_(schedule),
-      node_map_(graph->NodeCount(), kNodeUnmapped, zone()),
-      current_block_(NULL),
-      instructions_(zone()),
-      defined_(graph->NodeCount(), false, zone()),
-      used_(graph->NodeCount(), false, zone()) {}
+      current_block_(nullptr),
+      instructions_(zone),
+      defined_(node_count, false, zone),
+      used_(node_count, false, zone),
+      virtual_registers_(node_count,
+                         InstructionOperand::kInvalidVirtualRegister, zone),
+      scheduler_(nullptr) {
+  instructions_.reserve(node_count);
+}
 
 
 void InstructionSelector::SelectInstructions() {
   // Mark the inputs of all phis in loop headers as used.
   BasicBlockVector* blocks = schedule()->rpo_order();
-  for (BasicBlockVectorIter i = blocks->begin(); i != blocks->end(); ++i) {
-    BasicBlock* block = *i;
+  for (auto const block : *blocks) {
     if (!block->IsLoopHeader()) continue;
-    DCHECK_NE(0, static_cast<int>(block->PredecessorCount()));
-    DCHECK_NE(1, static_cast<int>(block->PredecessorCount()));
-    for (BasicBlock::const_iterator j = block->begin(); j != block->end();
-         ++j) {
-      Node* phi = *j;
+    DCHECK_LE(2u, block->PredecessorCount());
+    for (Node* const phi : *block) {
       if (phi->opcode() != IrOpcode::kPhi) continue;
 
       // Mark all inputs as used.
-      for (Node* const k : phi->inputs()) {
-        MarkAsUsed(k);
+      for (Node* const input : phi->inputs()) {
+        MarkAsUsed(input);
       }
     }
   }
 
   // Visit each basic block in post order.
-  for (BasicBlockVectorRIter i = blocks->rbegin(); i != blocks->rend(); ++i) {
+  for (auto i = blocks->rbegin(); i != blocks->rend(); ++i) {
     VisitBlock(*i);
   }
 
   // Schedule the selected instructions.
-  for (BasicBlockVectorIter i = blocks->begin(); i != blocks->end(); ++i) {
-    BasicBlock* block = *i;
+  if (FLAG_turbo_instruction_scheduling &&
+      InstructionScheduler::SchedulerSupported()) {
+    scheduler_ = new (zone()) InstructionScheduler(zone(), sequence());
+  }
+
+  for (auto const block : *blocks) {
     InstructionBlock* instruction_block =
-        sequence()->InstructionBlockAt(block->GetRpoNumber());
+        sequence()->InstructionBlockAt(RpoNumber::FromInt(block->rpo_number()));
     size_t end = instruction_block->code_end();
     size_t start = instruction_block->code_start();
-    sequence()->StartBlock(block->GetRpoNumber());
+    DCHECK_LE(end, start);
+    StartBlock(RpoNumber::FromInt(block->rpo_number()));
     while (start-- > end) {
-      sequence()->AddInstruction(instructions_[start]);
+      AddInstruction(instructions_[start]);
     }
-    sequence()->EndBlock(block->GetRpoNumber());
+    EndBlock(RpoNumber::FromInt(block->rpo_number()));
+  }
+}
+
+
+void InstructionSelector::StartBlock(RpoNumber rpo) {
+  if (FLAG_turbo_instruction_scheduling &&
+      InstructionScheduler::SchedulerSupported()) {
+    DCHECK_NOT_NULL(scheduler_);
+    scheduler_->StartBlock(rpo);
+  } else {
+    sequence()->StartBlock(rpo);
+  }
+}
+
+
+void InstructionSelector::EndBlock(RpoNumber rpo) {
+  if (FLAG_turbo_instruction_scheduling &&
+      InstructionScheduler::SchedulerSupported()) {
+    DCHECK_NOT_NULL(scheduler_);
+    scheduler_->EndBlock(rpo);
+  } else {
+    sequence()->EndBlock(rpo);
+  }
+}
+
+
+void InstructionSelector::AddInstruction(Instruction* instr) {
+  if (FLAG_turbo_instruction_scheduling &&
+      InstructionScheduler::SchedulerSupported()) {
+    DCHECK_NOT_NULL(scheduler_);
+    scheduler_->AddInstruction(instr);
+  } else {
+    sequence()->AddInstruction(instr);
   }
 }
 
 
 Instruction* InstructionSelector::Emit(InstructionCode opcode,
-                                       InstructionOperand* output,
+                                       InstructionOperand output,
                                        size_t temp_count,
-                                       InstructionOperand** temps) {
-  size_t output_count = output == NULL ? 0 : 1;
-  return Emit(opcode, output_count, &output, 0, NULL, temp_count, temps);
+                                       InstructionOperand* temps) {
+  size_t output_count = output.IsInvalid() ? 0 : 1;
+  return Emit(opcode, output_count, &output, 0, nullptr, temp_count, temps);
 }
 
 
 Instruction* InstructionSelector::Emit(InstructionCode opcode,
-                                       InstructionOperand* output,
-                                       InstructionOperand* a, size_t temp_count,
-                                       InstructionOperand** temps) {
-  size_t output_count = output == NULL ? 0 : 1;
+                                       InstructionOperand output,
+                                       InstructionOperand a, size_t temp_count,
+                                       InstructionOperand* temps) {
+  size_t output_count = output.IsInvalid() ? 0 : 1;
   return Emit(opcode, output_count, &output, 1, &a, temp_count, temps);
 }
 
 
 Instruction* InstructionSelector::Emit(InstructionCode opcode,
-                                       InstructionOperand* output,
-                                       InstructionOperand* a,
-                                       InstructionOperand* b, size_t temp_count,
-                                       InstructionOperand** temps) {
-  size_t output_count = output == NULL ? 0 : 1;
-  InstructionOperand* inputs[] = {a, b};
+                                       InstructionOperand output,
+                                       InstructionOperand a,
+                                       InstructionOperand b, size_t temp_count,
+                                       InstructionOperand* temps) {
+  size_t output_count = output.IsInvalid() ? 0 : 1;
+  InstructionOperand inputs[] = {a, b};
   size_t input_count = arraysize(inputs);
   return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
               temps);
@@ -106,13 +148,13 @@
 
 
 Instruction* InstructionSelector::Emit(InstructionCode opcode,
-                                       InstructionOperand* output,
-                                       InstructionOperand* a,
-                                       InstructionOperand* b,
-                                       InstructionOperand* c, size_t temp_count,
-                                       InstructionOperand** temps) {
-  size_t output_count = output == NULL ? 0 : 1;
-  InstructionOperand* inputs[] = {a, b, c};
+                                       InstructionOperand output,
+                                       InstructionOperand a,
+                                       InstructionOperand b,
+                                       InstructionOperand c, size_t temp_count,
+                                       InstructionOperand* temps) {
+  size_t output_count = output.IsInvalid() ? 0 : 1;
+  InstructionOperand inputs[] = {a, b, c};
   size_t input_count = arraysize(inputs);
   return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
               temps);
@@ -120,11 +162,11 @@
 
 
 Instruction* InstructionSelector::Emit(
-    InstructionCode opcode, InstructionOperand* output, InstructionOperand* a,
-    InstructionOperand* b, InstructionOperand* c, InstructionOperand* d,
-    size_t temp_count, InstructionOperand** temps) {
-  size_t output_count = output == NULL ? 0 : 1;
-  InstructionOperand* inputs[] = {a, b, c, d};
+    InstructionCode opcode, InstructionOperand output, InstructionOperand a,
+    InstructionOperand b, InstructionOperand c, InstructionOperand d,
+    size_t temp_count, InstructionOperand* temps) {
+  size_t output_count = output.IsInvalid() ? 0 : 1;
+  InstructionOperand inputs[] = {a, b, c, d};
   size_t input_count = arraysize(inputs);
   return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
               temps);
@@ -132,11 +174,11 @@
 
 
 Instruction* InstructionSelector::Emit(
-    InstructionCode opcode, InstructionOperand* output, InstructionOperand* a,
-    InstructionOperand* b, InstructionOperand* c, InstructionOperand* d,
-    InstructionOperand* e, size_t temp_count, InstructionOperand** temps) {
-  size_t output_count = output == NULL ? 0 : 1;
-  InstructionOperand* inputs[] = {a, b, c, d, e};
+    InstructionCode opcode, InstructionOperand output, InstructionOperand a,
+    InstructionOperand b, InstructionOperand c, InstructionOperand d,
+    InstructionOperand e, size_t temp_count, InstructionOperand* temps) {
+  size_t output_count = output.IsInvalid() ? 0 : 1;
+  InstructionOperand inputs[] = {a, b, c, d, e};
   size_t input_count = arraysize(inputs);
   return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
               temps);
@@ -144,12 +186,12 @@
 
 
 Instruction* InstructionSelector::Emit(
-    InstructionCode opcode, InstructionOperand* output, InstructionOperand* a,
-    InstructionOperand* b, InstructionOperand* c, InstructionOperand* d,
-    InstructionOperand* e, InstructionOperand* f, size_t temp_count,
-    InstructionOperand** temps) {
-  size_t output_count = output == NULL ? 0 : 1;
-  InstructionOperand* inputs[] = {a, b, c, d, e, f};
+    InstructionCode opcode, InstructionOperand output, InstructionOperand a,
+    InstructionOperand b, InstructionOperand c, InstructionOperand d,
+    InstructionOperand e, InstructionOperand f, size_t temp_count,
+    InstructionOperand* temps) {
+  size_t output_count = output.IsInvalid() ? 0 : 1;
+  InstructionOperand inputs[] = {a, b, c, d, e, f};
   size_t input_count = arraysize(inputs);
   return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
               temps);
@@ -157,9 +199,9 @@
 
 
 Instruction* InstructionSelector::Emit(
-    InstructionCode opcode, size_t output_count, InstructionOperand** outputs,
-    size_t input_count, InstructionOperand** inputs, size_t temp_count,
-    InstructionOperand** temps) {
+    InstructionCode opcode, size_t output_count, InstructionOperand* outputs,
+    size_t input_count, InstructionOperand* inputs, size_t temp_count,
+    InstructionOperand* temps) {
   Instruction* instr =
       Instruction::New(instruction_zone(), opcode, output_count, outputs,
                        input_count, inputs, temp_count, temps);
@@ -180,141 +222,281 @@
 
 
 int InstructionSelector::GetVirtualRegister(const Node* node) {
-  if (node_map_[node->id()] == kNodeUnmapped) {
-    node_map_[node->id()] = sequence()->NextVirtualRegister();
+  DCHECK_NOT_NULL(node);
+  size_t const id = node->id();
+  DCHECK_LT(id, virtual_registers_.size());
+  int virtual_register = virtual_registers_[id];
+  if (virtual_register == InstructionOperand::kInvalidVirtualRegister) {
+    virtual_register = sequence()->NextVirtualRegister();
+    virtual_registers_[id] = virtual_register;
   }
-  return node_map_[node->id()];
+  return virtual_register;
 }
 
 
-int InstructionSelector::GetMappedVirtualRegister(const Node* node) const {
-  return node_map_[node->id()];
+const std::map<NodeId, int> InstructionSelector::GetVirtualRegistersForTesting()
+    const {
+  std::map<NodeId, int> virtual_registers;
+  for (size_t n = 0; n < virtual_registers_.size(); ++n) {
+    if (virtual_registers_[n] != InstructionOperand::kInvalidVirtualRegister) {
+      NodeId const id = static_cast<NodeId>(n);
+      virtual_registers.insert(std::make_pair(id, virtual_registers_[n]));
+    }
+  }
+  return virtual_registers;
 }
 
 
 bool InstructionSelector::IsDefined(Node* node) const {
   DCHECK_NOT_NULL(node);
-  NodeId id = node->id();
-  DCHECK(id >= 0);
-  DCHECK(id < static_cast<NodeId>(defined_.size()));
+  size_t const id = node->id();
+  DCHECK_LT(id, defined_.size());
   return defined_[id];
 }
 
 
 void InstructionSelector::MarkAsDefined(Node* node) {
   DCHECK_NOT_NULL(node);
-  NodeId id = node->id();
-  DCHECK(id >= 0);
-  DCHECK(id < static_cast<NodeId>(defined_.size()));
+  size_t const id = node->id();
+  DCHECK_LT(id, defined_.size());
   defined_[id] = true;
 }
 
 
 bool InstructionSelector::IsUsed(Node* node) const {
+  DCHECK_NOT_NULL(node);
   if (!node->op()->HasProperty(Operator::kEliminatable)) return true;
-  NodeId id = node->id();
-  DCHECK(id >= 0);
-  DCHECK(id < static_cast<NodeId>(used_.size()));
+  size_t const id = node->id();
+  DCHECK_LT(id, used_.size());
   return used_[id];
 }
 
 
 void InstructionSelector::MarkAsUsed(Node* node) {
   DCHECK_NOT_NULL(node);
-  NodeId id = node->id();
-  DCHECK(id >= 0);
-  DCHECK(id < static_cast<NodeId>(used_.size()));
+  size_t const id = node->id();
+  DCHECK_LT(id, used_.size());
   used_[id] = true;
 }
 
 
-bool InstructionSelector::IsDouble(const Node* node) const {
-  DCHECK_NOT_NULL(node);
-  int virtual_register = GetMappedVirtualRegister(node);
-  if (virtual_register == kNodeUnmapped) return false;
-  return sequence()->IsDouble(virtual_register);
+void InstructionSelector::MarkAsRepresentation(MachineRepresentation rep,
+                                               const InstructionOperand& op) {
+  UnallocatedOperand unalloc = UnallocatedOperand::cast(op);
+  sequence()->MarkAsRepresentation(rep, unalloc.virtual_register());
 }
 
 
-void InstructionSelector::MarkAsDouble(Node* node) {
-  DCHECK_NOT_NULL(node);
-  DCHECK(!IsReference(node));
-  sequence()->MarkAsDouble(GetVirtualRegister(node));
+void InstructionSelector::MarkAsRepresentation(MachineRepresentation rep,
+                                               Node* node) {
+  sequence()->MarkAsRepresentation(rep, GetVirtualRegister(node));
 }
 
 
-bool InstructionSelector::IsReference(const Node* node) const {
-  DCHECK_NOT_NULL(node);
-  int virtual_register = GetMappedVirtualRegister(node);
-  if (virtual_register == kNodeUnmapped) return false;
-  return sequence()->IsReference(virtual_register);
-}
+namespace {
+
+enum class FrameStateInputKind { kAny, kStackSlot };
 
 
-void InstructionSelector::MarkAsReference(Node* node) {
-  DCHECK_NOT_NULL(node);
-  DCHECK(!IsDouble(node));
-  sequence()->MarkAsReference(GetVirtualRegister(node));
-}
-
-
-void InstructionSelector::MarkAsRepresentation(MachineType rep,
-                                               InstructionOperand* op) {
-  UnallocatedOperand* unalloc = UnallocatedOperand::cast(op);
-  switch (RepresentationOf(rep)) {
-    case kRepFloat32:
-    case kRepFloat64:
-      sequence()->MarkAsDouble(unalloc->virtual_register());
-      break;
-    case kRepTagged:
-      sequence()->MarkAsReference(unalloc->virtual_register());
+InstructionOperand OperandForDeopt(OperandGenerator* g, Node* input,
+                                   FrameStateInputKind kind) {
+  switch (input->opcode()) {
+    case IrOpcode::kInt32Constant:
+    case IrOpcode::kNumberConstant:
+    case IrOpcode::kFloat32Constant:
+    case IrOpcode::kFloat64Constant:
+    case IrOpcode::kHeapConstant:
+      return g->UseImmediate(input);
+    case IrOpcode::kObjectState:
+      UNREACHABLE();
       break;
     default:
+      switch (kind) {
+        case FrameStateInputKind::kStackSlot:
+          return g->UseUniqueSlot(input);
+        case FrameStateInputKind::kAny:
+          return g->UseAny(input);
+      }
+  }
+  UNREACHABLE();
+  return InstructionOperand();
+}
+
+
+class StateObjectDeduplicator {
+ public:
+  explicit StateObjectDeduplicator(Zone* zone) : objects_(zone) {}
+  static const size_t kNotDuplicated = SIZE_MAX;
+
+  size_t GetObjectId(Node* node) {
+    for (size_t i = 0; i < objects_.size(); ++i) {
+      if (objects_[i] == node) {
+        return i;
+      }
+    }
+    return kNotDuplicated;
+  }
+
+  size_t InsertObject(Node* node) {
+    size_t id = objects_.size();
+    objects_.push_back(node);
+    return id;
+  }
+
+ private:
+  ZoneVector<Node*> objects_;
+};
+
+
+// Returns the number of instruction operands added to inputs.
+size_t AddOperandToStateValueDescriptor(StateValueDescriptor* descriptor,
+                                        InstructionOperandVector* inputs,
+                                        OperandGenerator* g,
+                                        StateObjectDeduplicator* deduplicator,
+                                        Node* input, MachineType type,
+                                        FrameStateInputKind kind, Zone* zone) {
+  switch (input->opcode()) {
+    case IrOpcode::kObjectState: {
+      size_t id = deduplicator->GetObjectId(input);
+      if (id == StateObjectDeduplicator::kNotDuplicated) {
+        size_t entries = 0;
+        id = deduplicator->InsertObject(input);
+        descriptor->fields().push_back(
+            StateValueDescriptor::Recursive(zone, id));
+        StateValueDescriptor* new_desc = &descriptor->fields().back();
+        for (Edge edge : input->input_edges()) {
+          entries += AddOperandToStateValueDescriptor(
+              new_desc, inputs, g, deduplicator, edge.to(),
+              MachineType::AnyTagged(), kind, zone);
+        }
+        return entries;
+      } else {
+        // Crankshaft counts duplicate objects for the running id, so we have
+        // to push the input again.
+        deduplicator->InsertObject(input);
+        descriptor->fields().push_back(
+            StateValueDescriptor::Duplicate(zone, id));
+        return 0;
+      }
       break;
+    }
+    default: {
+      inputs->push_back(OperandForDeopt(g, input, kind));
+      descriptor->fields().push_back(StateValueDescriptor::Plain(zone, type));
+      return 1;
+    }
   }
 }
 
 
-void InstructionSelector::MarkAsRepresentation(MachineType rep, Node* node) {
-  DCHECK_NOT_NULL(node);
-  switch (RepresentationOf(rep)) {
-    case kRepFloat32:
-    case kRepFloat64:
-      MarkAsDouble(node);
-      break;
-    case kRepTagged:
-      MarkAsReference(node);
-      break;
-    default:
-      break;
+// Returns the number of instruction operands added to inputs.
+size_t AddInputsToFrameStateDescriptor(FrameStateDescriptor* descriptor,
+                                       Node* state, OperandGenerator* g,
+                                       StateObjectDeduplicator* deduplicator,
+                                       InstructionOperandVector* inputs,
+                                       FrameStateInputKind kind, Zone* zone) {
+  DCHECK_EQ(IrOpcode::kFrameState, state->op()->opcode());
+
+  size_t entries = 0;
+  size_t initial_size = inputs->size();
+  USE(initial_size);  // initial_size is only used for debug.
+
+  if (descriptor->outer_state()) {
+    entries += AddInputsToFrameStateDescriptor(
+        descriptor->outer_state(), state->InputAt(kFrameStateOuterStateInput),
+        g, deduplicator, inputs, kind, zone);
   }
+
+  Node* parameters = state->InputAt(kFrameStateParametersInput);
+  Node* locals = state->InputAt(kFrameStateLocalsInput);
+  Node* stack = state->InputAt(kFrameStateStackInput);
+  Node* context = state->InputAt(kFrameStateContextInput);
+  Node* function = state->InputAt(kFrameStateFunctionInput);
+
+  DCHECK_EQ(descriptor->parameters_count(),
+            StateValuesAccess(parameters).size());
+  DCHECK_EQ(descriptor->locals_count(), StateValuesAccess(locals).size());
+  DCHECK_EQ(descriptor->stack_count(), StateValuesAccess(stack).size());
+
+  StateValueDescriptor* values_descriptor =
+      descriptor->GetStateValueDescriptor();
+  entries += AddOperandToStateValueDescriptor(
+      values_descriptor, inputs, g, deduplicator, function,
+      MachineType::AnyTagged(), FrameStateInputKind::kStackSlot, zone);
+  for (StateValuesAccess::TypedNode input_node :
+       StateValuesAccess(parameters)) {
+    entries += AddOperandToStateValueDescriptor(values_descriptor, inputs, g,
+                                                deduplicator, input_node.node,
+                                                input_node.type, kind, zone);
+  }
+  if (descriptor->HasContext()) {
+    entries += AddOperandToStateValueDescriptor(
+        values_descriptor, inputs, g, deduplicator, context,
+        MachineType::AnyTagged(), FrameStateInputKind::kStackSlot, zone);
+  }
+  for (StateValuesAccess::TypedNode input_node : StateValuesAccess(locals)) {
+    entries += AddOperandToStateValueDescriptor(values_descriptor, inputs, g,
+                                                deduplicator, input_node.node,
+                                                input_node.type, kind, zone);
+  }
+  for (StateValuesAccess::TypedNode input_node : StateValuesAccess(stack)) {
+    entries += AddOperandToStateValueDescriptor(values_descriptor, inputs, g,
+                                                deduplicator, input_node.node,
+                                                input_node.type, kind, zone);
+  }
+  DCHECK_EQ(initial_size + entries, inputs->size());
+  return entries;
 }
 
+}  // namespace
 
+
+// An internal helper class for generating the operands to calls.
 // TODO(bmeurer): Get rid of the CallBuffer business and make
 // InstructionSelector::VisitCall platform independent instead.
-CallBuffer::CallBuffer(Zone* zone, const CallDescriptor* d,
-                       FrameStateDescriptor* frame_desc)
-    : descriptor(d),
-      frame_state_descriptor(frame_desc),
-      output_nodes(zone),
-      outputs(zone),
-      instruction_args(zone),
-      pushed_nodes(zone) {
-  output_nodes.reserve(d->ReturnCount());
-  outputs.reserve(d->ReturnCount());
-  pushed_nodes.reserve(input_count());
-  instruction_args.reserve(input_count() + frame_state_value_count());
-}
+struct CallBuffer {
+  CallBuffer(Zone* zone, const CallDescriptor* descriptor,
+             FrameStateDescriptor* frame_state)
+      : descriptor(descriptor),
+        frame_state_descriptor(frame_state),
+        output_nodes(zone),
+        outputs(zone),
+        instruction_args(zone),
+        pushed_nodes(zone) {
+    output_nodes.reserve(descriptor->ReturnCount());
+    outputs.reserve(descriptor->ReturnCount());
+    pushed_nodes.reserve(input_count());
+    instruction_args.reserve(input_count() + frame_state_value_count());
+  }
+
+
+  const CallDescriptor* descriptor;
+  FrameStateDescriptor* frame_state_descriptor;
+  NodeVector output_nodes;
+  InstructionOperandVector outputs;
+  InstructionOperandVector instruction_args;
+  ZoneVector<PushParameter> pushed_nodes;
+
+  size_t input_count() const { return descriptor->InputCount(); }
+
+  size_t frame_state_count() const { return descriptor->FrameStateCount(); }
+
+  size_t frame_state_value_count() const {
+    return (frame_state_descriptor == nullptr)
+               ? 0
+               : (frame_state_descriptor->GetTotalSize() +
+                  1);  // Include deopt id.
+  }
+};
 
 
 // TODO(bmeurer): Get rid of the CallBuffer business and make
 // InstructionSelector::VisitCall platform independent instead.
 void InstructionSelector::InitializeCallBuffer(Node* call, CallBuffer* buffer,
-                                               bool call_code_immediate,
-                                               bool call_address_immediate) {
+                                               CallBufferFlags flags,
+                                               int stack_param_delta) {
   OperandGenerator g(this);
-  DCHECK_EQ(call->op()->ValueOutputCount(),
+  DCHECK_LE(call->op()->ValueOutputCount(),
             static_cast<int>(buffer->descriptor->ReturnCount()));
   DCHECK_EQ(
       call->op()->ValueInputCount(),
@@ -325,19 +507,25 @@
     if (buffer->descriptor->ReturnCount() == 1) {
       buffer->output_nodes.push_back(call);
     } else {
-      buffer->output_nodes.resize(buffer->descriptor->ReturnCount(), NULL);
-      call->CollectProjections(&buffer->output_nodes);
+      buffer->output_nodes.resize(buffer->descriptor->ReturnCount(), nullptr);
+      for (auto use : call->uses()) {
+        if (use->opcode() != IrOpcode::kProjection) continue;
+        size_t const index = ProjectionIndexOf(use->op());
+        DCHECK_LT(index, buffer->output_nodes.size());
+        DCHECK(!buffer->output_nodes[index]);
+        buffer->output_nodes[index] = use;
+      }
     }
 
     // Filter out the outputs that aren't live because no projection uses them.
     size_t outputs_needed_by_framestate =
-        buffer->frame_state_descriptor == NULL
+        buffer->frame_state_descriptor == nullptr
             ? 0
             : buffer->frame_state_descriptor->state_combine()
                   .ConsumedOutputCount();
     for (size_t i = 0; i < buffer->output_nodes.size(); i++) {
-      bool output_is_live =
-          buffer->output_nodes[i] != NULL || i < outputs_needed_by_framestate;
+      bool output_is_live = buffer->output_nodes[i] != nullptr ||
+                            i < outputs_needed_by_framestate;
       if (output_is_live) {
         MachineType type =
             buffer->descriptor->GetReturnType(static_cast<int>(i));
@@ -345,10 +533,11 @@
             buffer->descriptor->GetReturnLocation(static_cast<int>(i));
 
         Node* output = buffer->output_nodes[i];
-        InstructionOperand* op =
-            output == NULL ? g.TempLocation(location, type)
-                           : g.DefineAsLocation(output, location, type);
-        MarkAsRepresentation(type, op);
+        InstructionOperand op =
+            output == nullptr
+                ? g.TempLocation(location, type.representation())
+                : g.DefineAsLocation(output, location, type.representation());
+        MarkAsRepresentation(type.representation(), op);
 
         buffer->outputs.push_back(op);
       }
@@ -357,6 +546,8 @@
 
   // The first argument is always the callee code.
   Node* callee = call->InputAt(0);
+  bool call_code_immediate = (flags & kCallCodeImmediate) != 0;
+  bool call_address_immediate = (flags & kCallAddressImmediate) != 0;
   switch (buffer->descriptor->kind()) {
     case CallDescriptor::kCallCodeObject:
       buffer->instruction_args.push_back(
@@ -367,35 +558,46 @@
     case CallDescriptor::kCallAddress:
       buffer->instruction_args.push_back(
           (call_address_immediate &&
-           (callee->opcode() == IrOpcode::kInt32Constant ||
-            callee->opcode() == IrOpcode::kInt64Constant))
+           callee->opcode() == IrOpcode::kExternalConstant)
               ? g.UseImmediate(callee)
               : g.UseRegister(callee));
       break;
     case CallDescriptor::kCallJSFunction:
       buffer->instruction_args.push_back(
           g.UseLocation(callee, buffer->descriptor->GetInputLocation(0),
-                        buffer->descriptor->GetInputType(0)));
+                        buffer->descriptor->GetInputType(0).representation()));
+      break;
+    case CallDescriptor::kLazyBailout:
+      // The target is ignored, but we still need to pass a value here.
+      buffer->instruction_args.push_back(g.UseImmediate(callee));
       break;
   }
-  DCHECK_EQ(1, static_cast<int>(buffer->instruction_args.size()));
+  DCHECK_EQ(1u, buffer->instruction_args.size());
 
   // If the call needs a frame state, we insert the state information as
   // follows (n is the number of value inputs to the frame state):
   // arg 1               : deoptimization id.
   // arg 2 - arg (n + 1) : value inputs to the frame state.
-  if (buffer->frame_state_descriptor != NULL) {
+  size_t frame_state_entries = 0;
+  USE(frame_state_entries);  // frame_state_entries is only used for debug.
+  if (buffer->frame_state_descriptor != nullptr) {
     InstructionSequence::StateId state_id =
         sequence()->AddFrameStateDescriptor(buffer->frame_state_descriptor);
     buffer->instruction_args.push_back(g.TempImmediate(state_id.ToInt()));
 
     Node* frame_state =
         call->InputAt(static_cast<int>(buffer->descriptor->InputCount()));
-    AddFrameStateInputs(frame_state, &buffer->instruction_args,
-                        buffer->frame_state_descriptor);
+
+    StateObjectDeduplicator deduplicator(instruction_zone());
+
+    frame_state_entries =
+        1 + AddInputsToFrameStateDescriptor(
+                buffer->frame_state_descriptor, frame_state, &g, &deduplicator,
+                &buffer->instruction_args, FrameStateInputKind::kStackSlot,
+                instruction_zone());
+
+    DCHECK_EQ(1 + frame_state_entries, buffer->instruction_args.size());
   }
-  DCHECK(1 + buffer->frame_state_value_count() ==
-         buffer->instruction_args.size());
 
   size_t input_count = static_cast<size_t>(buffer->input_count());
 
@@ -404,35 +606,53 @@
   // not appear as arguments to the call. Everything else ends up
   // as an InstructionOperand argument to the call.
   auto iter(call->inputs().begin());
-  int pushed_count = 0;
+  size_t pushed_count = 0;
+  bool call_tail = (flags & kCallTail) != 0;
   for (size_t index = 0; index < input_count; ++iter, ++index) {
     DCHECK(iter != call->inputs().end());
     DCHECK((*iter)->op()->opcode() != IrOpcode::kFrameState);
     if (index == 0) continue;  // The first argument (callee) is already done.
-    InstructionOperand* op =
-        g.UseLocation(*iter, buffer->descriptor->GetInputLocation(index),
-                      buffer->descriptor->GetInputType(index));
-    if (UnallocatedOperand::cast(op)->HasFixedSlotPolicy()) {
-      int stack_index = -UnallocatedOperand::cast(op)->fixed_slot_index() - 1;
+
+    LinkageLocation location = buffer->descriptor->GetInputLocation(index);
+    if (call_tail) {
+      location = LinkageLocation::ConvertToTailCallerLocation(
+          location, stack_param_delta);
+    }
+    InstructionOperand op =
+        g.UseLocation(*iter, location,
+                      buffer->descriptor->GetInputType(index).representation());
+    if (UnallocatedOperand::cast(op).HasFixedSlotPolicy() && !call_tail) {
+      int stack_index = -UnallocatedOperand::cast(op).fixed_slot_index() - 1;
       if (static_cast<size_t>(stack_index) >= buffer->pushed_nodes.size()) {
-        buffer->pushed_nodes.resize(stack_index + 1, NULL);
+        buffer->pushed_nodes.resize(stack_index + 1);
       }
-      DCHECK_EQ(NULL, buffer->pushed_nodes[stack_index]);
-      buffer->pushed_nodes[stack_index] = *iter;
+      PushParameter parameter(*iter, buffer->descriptor->GetInputType(index));
+      buffer->pushed_nodes[stack_index] = parameter;
       pushed_count++;
     } else {
       buffer->instruction_args.push_back(op);
     }
   }
-  CHECK_EQ(pushed_count, static_cast<int>(buffer->pushed_nodes.size()));
-  DCHECK(static_cast<size_t>(input_count) ==
-         (buffer->instruction_args.size() + buffer->pushed_nodes.size() -
-          buffer->frame_state_value_count()));
+  DCHECK_EQ(input_count, buffer->instruction_args.size() + pushed_count -
+                             frame_state_entries);
+  if (V8_TARGET_ARCH_STORES_RETURN_ADDRESS_ON_STACK && call_tail &&
+      stack_param_delta != 0) {
+    // For tail calls that change the size of their parameter list and keep
+    // their return address on the stack, move the return address to just above
+    // the parameters.
+    LinkageLocation saved_return_location =
+        LinkageLocation::ForSavedCallerReturnAddress();
+    InstructionOperand return_address =
+        g.UsePointerLocation(LinkageLocation::ConvertToTailCallerLocation(
+                                 saved_return_location, stack_param_delta),
+                             saved_return_location);
+    buffer->instruction_args.push_back(return_address);
+  }
 }
 
 
 void InstructionSelector::VisitBlock(BasicBlock* block) {
-  DCHECK_EQ(NULL, current_block_);
+  DCHECK(!current_block_);
   current_block_ = block;
   int current_block_end = static_cast<int>(instructions_.size());
 
@@ -443,9 +663,7 @@
 
   // Visit code in reverse control flow order, because architecture-specific
   // matching may cover more than one node at a time.
-  for (BasicBlock::reverse_iterator i = block->rbegin(); i != block->rend();
-       ++i) {
-    Node* node = *i;
+  for (auto node : base::Reversed(*block)) {
     // Skip nodes that are unused or already defined.
     if (!IsUsed(node) || IsDefined(node)) continue;
     // Generate code for this node "top down", but schedule the code "bottom
@@ -453,57 +671,104 @@
     size_t current_node_end = instructions_.size();
     VisitNode(node);
     std::reverse(instructions_.begin() + current_node_end, instructions_.end());
+    if (instructions_.size() == current_node_end) continue;
+    // Mark source position on first instruction emitted.
+    SourcePosition source_position = source_positions_->GetSourcePosition(node);
+    if (source_position.IsKnown() &&
+        (source_position_mode_ == kAllSourcePositions ||
+         node->opcode() == IrOpcode::kCall)) {
+      sequence()->SetSourcePosition(instructions_[current_node_end],
+                                    source_position);
+    }
   }
 
   // We're done with the block.
   InstructionBlock* instruction_block =
-      sequence()->InstructionBlockAt(block->GetRpoNumber());
+      sequence()->InstructionBlockAt(RpoNumber::FromInt(block->rpo_number()));
   instruction_block->set_code_start(static_cast<int>(instructions_.size()));
   instruction_block->set_code_end(current_block_end);
 
-  current_block_ = NULL;
-}
-
-
-static inline void CheckNoPhis(const BasicBlock* block) {
-#ifdef DEBUG
-  // Branch targets should not have phis.
-  for (BasicBlock::const_iterator i = block->begin(); i != block->end(); ++i) {
-    const Node* node = *i;
-    CHECK_NE(IrOpcode::kPhi, node->opcode());
-  }
-#endif
+  current_block_ = nullptr;
 }
 
 
 void InstructionSelector::VisitControl(BasicBlock* block) {
+#ifdef DEBUG
+  // SSA deconstruction requires targets of branches not to have phis.
+  // Edge split form guarantees this property, but is more strict.
+  if (block->SuccessorCount() > 1) {
+    for (BasicBlock* const successor : block->successors()) {
+      for (Node* const node : *successor) {
+        CHECK(!IrOpcode::IsPhiOpcode(node->opcode()));
+      }
+    }
+  }
+#endif
+
   Node* input = block->control_input();
   switch (block->control()) {
     case BasicBlock::kGoto:
       return VisitGoto(block->SuccessorAt(0));
+    case BasicBlock::kCall: {
+      DCHECK_EQ(IrOpcode::kCall, input->opcode());
+      BasicBlock* success = block->SuccessorAt(0);
+      BasicBlock* exception = block->SuccessorAt(1);
+      return VisitCall(input, exception), VisitGoto(success);
+    }
+    case BasicBlock::kTailCall: {
+      DCHECK_EQ(IrOpcode::kTailCall, input->opcode());
+      return VisitTailCall(input);
+    }
     case BasicBlock::kBranch: {
       DCHECK_EQ(IrOpcode::kBranch, input->opcode());
       BasicBlock* tbranch = block->SuccessorAt(0);
       BasicBlock* fbranch = block->SuccessorAt(1);
-      // SSA deconstruction requires targets of branches not to have phis.
-      // Edge split form guarantees this property, but is more strict.
-      CheckNoPhis(tbranch);
-      CheckNoPhis(fbranch);
       if (tbranch == fbranch) return VisitGoto(tbranch);
       return VisitBranch(input, tbranch, fbranch);
     }
+    case BasicBlock::kSwitch: {
+      DCHECK_EQ(IrOpcode::kSwitch, input->opcode());
+      SwitchInfo sw;
+      // Last successor must be Default.
+      sw.default_branch = block->successors().back();
+      DCHECK_EQ(IrOpcode::kIfDefault, sw.default_branch->front()->opcode());
+      // All other successors must be cases.
+      sw.case_count = block->SuccessorCount() - 1;
+      sw.case_branches = &block->successors().front();
+      // Determine case values and their min/max.
+      sw.case_values = zone()->NewArray<int32_t>(sw.case_count);
+      sw.min_value = std::numeric_limits<int32_t>::max();
+      sw.max_value = std::numeric_limits<int32_t>::min();
+      for (size_t index = 0; index < sw.case_count; ++index) {
+        BasicBlock* branch = sw.case_branches[index];
+        int32_t value = OpParameter<int32_t>(branch->front()->op());
+        sw.case_values[index] = value;
+        if (sw.min_value > value) sw.min_value = value;
+        if (sw.max_value < value) sw.max_value = value;
+      }
+      DCHECK_LE(sw.min_value, sw.max_value);
+      // Note that {value_range} can be 0 if {min_value} is -2^31 and
+      // {max_value}
+      // is 2^31-1, so don't assume that it's non-zero below.
+      sw.value_range = 1u + bit_cast<uint32_t>(sw.max_value) -
+                       bit_cast<uint32_t>(sw.min_value);
+      return VisitSwitch(input, sw);
+    }
     case BasicBlock::kReturn: {
-      // If the result itself is a return, return its input.
-      Node* value = (input != NULL && input->opcode() == IrOpcode::kReturn)
-                        ? input->InputAt(0)
-                        : input;
-      return VisitReturn(value);
+      DCHECK_EQ(IrOpcode::kReturn, input->opcode());
+      return VisitReturn(input);
+    }
+    case BasicBlock::kDeoptimize: {
+      DeoptimizeKind kind = DeoptimizeKindOf(input->op());
+      Node* value = input->InputAt(0);
+      return VisitDeoptimize(kind, value);
     }
     case BasicBlock::kThrow:
-      return VisitThrow(input);
+      DCHECK_EQ(IrOpcode::kThrow, input->opcode());
+      return VisitThrow(input->InputAt(0));
     case BasicBlock::kNone: {
       // TODO(titzer): exit block doesn't have control.
-      DCHECK(input == NULL);
+      DCHECK_NULL(input);
       break;
     }
     default:
@@ -513,7 +778,7 @@
 }
 
 
-MachineType InstructionSelector::GetMachineType(Node* node) {
+void InstructionSelector::VisitNode(Node* node) {
   DCHECK_NOT_NULL(schedule()->block(node));  // should only use scheduled nodes.
   switch (node->opcode()) {
     case IrOpcode::kStart:
@@ -522,156 +787,33 @@
     case IrOpcode::kBranch:
     case IrOpcode::kIfTrue:
     case IrOpcode::kIfFalse:
+    case IrOpcode::kIfSuccess:
+    case IrOpcode::kSwitch:
+    case IrOpcode::kIfValue:
+    case IrOpcode::kIfDefault:
     case IrOpcode::kEffectPhi:
     case IrOpcode::kMerge:
     case IrOpcode::kTerminate:
-      // No code needed for these graph artifacts.
-      return kMachNone;
-    case IrOpcode::kFinish:
-      return kMachAnyTagged;
-    case IrOpcode::kParameter:
-      return linkage()->GetParameterType(OpParameter<int>(node));
-    case IrOpcode::kPhi:
-      return OpParameter<MachineType>(node);
-    case IrOpcode::kProjection:
-      // TODO(jarin) Really project from outputs.
-      return kMachAnyTagged;
-    case IrOpcode::kInt32Constant:
-      return kMachInt32;
-    case IrOpcode::kInt64Constant:
-      return kMachInt64;
-    case IrOpcode::kExternalConstant:
-      return kMachPtr;
-    case IrOpcode::kFloat64Constant:
-      return kMachFloat64;
-    case IrOpcode::kHeapConstant:
-    case IrOpcode::kNumberConstant:
-      return kMachAnyTagged;
-    case IrOpcode::kCall:
-      return kMachAnyTagged;
-    case IrOpcode::kFrameState:
-    case IrOpcode::kStateValues:
-      return kMachNone;
-    case IrOpcode::kLoad:
-      return OpParameter<LoadRepresentation>(node);
-    case IrOpcode::kStore:
-      return kMachNone;
-    case IrOpcode::kCheckedLoad:
-      return OpParameter<MachineType>(node);
-    case IrOpcode::kCheckedStore:
-      return kMachNone;
-    case IrOpcode::kWord32And:
-    case IrOpcode::kWord32Or:
-    case IrOpcode::kWord32Xor:
-    case IrOpcode::kWord32Shl:
-    case IrOpcode::kWord32Shr:
-    case IrOpcode::kWord32Sar:
-    case IrOpcode::kWord32Ror:
-      return kMachInt32;
-    case IrOpcode::kWord32Equal:
-      return kMachBool;
-    case IrOpcode::kWord64And:
-    case IrOpcode::kWord64Or:
-    case IrOpcode::kWord64Xor:
-    case IrOpcode::kWord64Shl:
-    case IrOpcode::kWord64Shr:
-    case IrOpcode::kWord64Sar:
-    case IrOpcode::kWord64Ror:
-      return kMachInt64;
-    case IrOpcode::kWord64Equal:
-      return kMachBool;
-    case IrOpcode::kInt32Add:
-    case IrOpcode::kInt32AddWithOverflow:
-    case IrOpcode::kInt32Sub:
-    case IrOpcode::kInt32SubWithOverflow:
-    case IrOpcode::kInt32Mul:
-    case IrOpcode::kInt32Div:
-    case IrOpcode::kInt32Mod:
-      return kMachInt32;
-    case IrOpcode::kInt32LessThan:
-    case IrOpcode::kInt32LessThanOrEqual:
-    case IrOpcode::kUint32LessThan:
-    case IrOpcode::kUint32LessThanOrEqual:
-      return kMachBool;
-    case IrOpcode::kInt64Add:
-    case IrOpcode::kInt64Sub:
-    case IrOpcode::kInt64Mul:
-    case IrOpcode::kInt64Div:
-    case IrOpcode::kInt64Mod:
-      return kMachInt64;
-    case IrOpcode::kInt64LessThan:
-    case IrOpcode::kInt64LessThanOrEqual:
-      return kMachBool;
-    case IrOpcode::kChangeFloat32ToFloat64:
-    case IrOpcode::kChangeInt32ToFloat64:
-    case IrOpcode::kChangeUint32ToFloat64:
-      return kMachFloat64;
-    case IrOpcode::kChangeFloat64ToInt32:
-      return kMachInt32;
-    case IrOpcode::kChangeFloat64ToUint32:
-      return kMachUint32;
-    case IrOpcode::kChangeInt32ToInt64:
-      return kMachInt64;
-    case IrOpcode::kChangeUint32ToUint64:
-      return kMachUint64;
-    case IrOpcode::kTruncateFloat64ToFloat32:
-      return kMachFloat32;
-    case IrOpcode::kTruncateFloat64ToInt32:
-    case IrOpcode::kTruncateInt64ToInt32:
-      return kMachInt32;
-    case IrOpcode::kFloat64Add:
-    case IrOpcode::kFloat64Sub:
-    case IrOpcode::kFloat64Mul:
-    case IrOpcode::kFloat64Div:
-    case IrOpcode::kFloat64Mod:
-    case IrOpcode::kFloat64Sqrt:
-    case IrOpcode::kFloat64Floor:
-    case IrOpcode::kFloat64Ceil:
-    case IrOpcode::kFloat64RoundTruncate:
-    case IrOpcode::kFloat64RoundTiesAway:
-      return kMachFloat64;
-    case IrOpcode::kFloat64Equal:
-    case IrOpcode::kFloat64LessThan:
-    case IrOpcode::kFloat64LessThanOrEqual:
-      return kMachBool;
-    default:
-      V8_Fatal(__FILE__, __LINE__, "Unexpected operator #%d:%s @ node #%d",
-               node->opcode(), node->op()->mnemonic(), node->id());
-  }
-  return kMachNone;
-}
-
-
-void InstructionSelector::VisitNode(Node* node) {
-  DCHECK_NOT_NULL(schedule()->block(node));  // should only use scheduled nodes.
-  SourcePosition source_position = source_positions_->GetSourcePosition(node);
-  if (!source_position.IsUnknown()) {
-    DCHECK(!source_position.IsInvalid());
-    if (FLAG_turbo_source_positions || node->opcode() == IrOpcode::kCall) {
-      Emit(SourcePositionInstruction::New(instruction_zone(), source_position));
-    }
-  }
-  switch (node->opcode()) {
-    case IrOpcode::kStart:
-    case IrOpcode::kLoop:
-    case IrOpcode::kEnd:
-    case IrOpcode::kBranch:
-    case IrOpcode::kIfTrue:
-    case IrOpcode::kIfFalse:
-    case IrOpcode::kEffectPhi:
-    case IrOpcode::kMerge:
+    case IrOpcode::kBeginRegion:
       // No code needed for these graph artifacts.
       return;
-    case IrOpcode::kFinish:
-      return MarkAsReference(node), VisitFinish(node);
+    case IrOpcode::kIfException:
+      return MarkAsReference(node), VisitIfException(node);
+    case IrOpcode::kFinishRegion:
+      return MarkAsReference(node), VisitFinishRegion(node);
+    case IrOpcode::kGuard:
+      return MarkAsReference(node), VisitGuard(node);
     case IrOpcode::kParameter: {
-      MachineType type = linkage()->GetParameterType(OpParameter<int>(node));
-      MarkAsRepresentation(type, node);
+      MachineType type =
+          linkage()->GetParameterType(ParameterIndexOf(node->op()));
+      MarkAsRepresentation(type.representation(), node);
       return VisitParameter(node);
     }
+    case IrOpcode::kOsrValue:
+      return MarkAsReference(node), VisitOsrValue(node);
     case IrOpcode::kPhi: {
-      MachineType type = OpParameter<MachineType>(node);
-      MarkAsRepresentation(type, node);
+      MachineRepresentation rep = PhiRepresentationOf(node->op());
+      MarkAsRepresentation(rep, node);
       return VisitPhi(node);
     }
     case IrOpcode::kProjection:
@@ -681,157 +823,252 @@
     case IrOpcode::kExternalConstant:
       return VisitConstant(node);
     case IrOpcode::kFloat32Constant:
-      return MarkAsDouble(node), VisitConstant(node);
+      return MarkAsFloat32(node), VisitConstant(node);
     case IrOpcode::kFloat64Constant:
-      return MarkAsDouble(node), VisitConstant(node);
+      return MarkAsFloat64(node), VisitConstant(node);
     case IrOpcode::kHeapConstant:
-    case IrOpcode::kNumberConstant:
-      // TODO(turbofan): only mark non-smis as references.
       return MarkAsReference(node), VisitConstant(node);
+    case IrOpcode::kNumberConstant: {
+      double value = OpParameter<double>(node);
+      if (!IsSmiDouble(value)) MarkAsReference(node);
+      return VisitConstant(node);
+    }
     case IrOpcode::kCall:
       return VisitCall(node);
     case IrOpcode::kFrameState:
     case IrOpcode::kStateValues:
+    case IrOpcode::kObjectState:
       return;
     case IrOpcode::kLoad: {
-      LoadRepresentation rep = OpParameter<LoadRepresentation>(node);
-      MarkAsRepresentation(rep, node);
+      LoadRepresentation type = LoadRepresentationOf(node->op());
+      MarkAsRepresentation(type.representation(), node);
       return VisitLoad(node);
     }
     case IrOpcode::kStore:
       return VisitStore(node);
     case IrOpcode::kWord32And:
-      return VisitWord32And(node);
+      return MarkAsWord32(node), VisitWord32And(node);
     case IrOpcode::kWord32Or:
-      return VisitWord32Or(node);
+      return MarkAsWord32(node), VisitWord32Or(node);
     case IrOpcode::kWord32Xor:
-      return VisitWord32Xor(node);
+      return MarkAsWord32(node), VisitWord32Xor(node);
     case IrOpcode::kWord32Shl:
-      return VisitWord32Shl(node);
+      return MarkAsWord32(node), VisitWord32Shl(node);
     case IrOpcode::kWord32Shr:
-      return VisitWord32Shr(node);
+      return MarkAsWord32(node), VisitWord32Shr(node);
     case IrOpcode::kWord32Sar:
-      return VisitWord32Sar(node);
+      return MarkAsWord32(node), VisitWord32Sar(node);
     case IrOpcode::kWord32Ror:
-      return VisitWord32Ror(node);
+      return MarkAsWord32(node), VisitWord32Ror(node);
     case IrOpcode::kWord32Equal:
       return VisitWord32Equal(node);
+    case IrOpcode::kWord32Clz:
+      return MarkAsWord32(node), VisitWord32Clz(node);
+    case IrOpcode::kWord32Ctz:
+      return MarkAsWord32(node), VisitWord32Ctz(node);
+    case IrOpcode::kWord32Popcnt:
+      return MarkAsWord32(node), VisitWord32Popcnt(node);
+    case IrOpcode::kWord64Popcnt:
+      return MarkAsWord32(node), VisitWord64Popcnt(node);
     case IrOpcode::kWord64And:
-      return VisitWord64And(node);
+      return MarkAsWord64(node), VisitWord64And(node);
     case IrOpcode::kWord64Or:
-      return VisitWord64Or(node);
+      return MarkAsWord64(node), VisitWord64Or(node);
     case IrOpcode::kWord64Xor:
-      return VisitWord64Xor(node);
+      return MarkAsWord64(node), VisitWord64Xor(node);
     case IrOpcode::kWord64Shl:
-      return VisitWord64Shl(node);
+      return MarkAsWord64(node), VisitWord64Shl(node);
     case IrOpcode::kWord64Shr:
-      return VisitWord64Shr(node);
+      return MarkAsWord64(node), VisitWord64Shr(node);
     case IrOpcode::kWord64Sar:
-      return VisitWord64Sar(node);
+      return MarkAsWord64(node), VisitWord64Sar(node);
     case IrOpcode::kWord64Ror:
-      return VisitWord64Ror(node);
+      return MarkAsWord64(node), VisitWord64Ror(node);
+    case IrOpcode::kWord64Clz:
+      return MarkAsWord64(node), VisitWord64Clz(node);
+    case IrOpcode::kWord64Ctz:
+      return MarkAsWord64(node), VisitWord64Ctz(node);
     case IrOpcode::kWord64Equal:
       return VisitWord64Equal(node);
     case IrOpcode::kInt32Add:
-      return VisitInt32Add(node);
+      return MarkAsWord32(node), VisitInt32Add(node);
     case IrOpcode::kInt32AddWithOverflow:
-      return VisitInt32AddWithOverflow(node);
+      return MarkAsWord32(node), VisitInt32AddWithOverflow(node);
     case IrOpcode::kInt32Sub:
-      return VisitInt32Sub(node);
+      return MarkAsWord32(node), VisitInt32Sub(node);
     case IrOpcode::kInt32SubWithOverflow:
       return VisitInt32SubWithOverflow(node);
     case IrOpcode::kInt32Mul:
-      return VisitInt32Mul(node);
+      return MarkAsWord32(node), VisitInt32Mul(node);
     case IrOpcode::kInt32MulHigh:
       return VisitInt32MulHigh(node);
     case IrOpcode::kInt32Div:
-      return VisitInt32Div(node);
+      return MarkAsWord32(node), VisitInt32Div(node);
     case IrOpcode::kInt32Mod:
-      return VisitInt32Mod(node);
+      return MarkAsWord32(node), VisitInt32Mod(node);
     case IrOpcode::kInt32LessThan:
       return VisitInt32LessThan(node);
     case IrOpcode::kInt32LessThanOrEqual:
       return VisitInt32LessThanOrEqual(node);
     case IrOpcode::kUint32Div:
-      return VisitUint32Div(node);
+      return MarkAsWord32(node), VisitUint32Div(node);
     case IrOpcode::kUint32LessThan:
       return VisitUint32LessThan(node);
     case IrOpcode::kUint32LessThanOrEqual:
       return VisitUint32LessThanOrEqual(node);
     case IrOpcode::kUint32Mod:
-      return VisitUint32Mod(node);
+      return MarkAsWord32(node), VisitUint32Mod(node);
     case IrOpcode::kUint32MulHigh:
       return VisitUint32MulHigh(node);
     case IrOpcode::kInt64Add:
-      return VisitInt64Add(node);
+      return MarkAsWord64(node), VisitInt64Add(node);
+    case IrOpcode::kInt64AddWithOverflow:
+      return MarkAsWord64(node), VisitInt64AddWithOverflow(node);
     case IrOpcode::kInt64Sub:
-      return VisitInt64Sub(node);
+      return MarkAsWord64(node), VisitInt64Sub(node);
+    case IrOpcode::kInt64SubWithOverflow:
+      return MarkAsWord64(node), VisitInt64SubWithOverflow(node);
     case IrOpcode::kInt64Mul:
-      return VisitInt64Mul(node);
+      return MarkAsWord64(node), VisitInt64Mul(node);
     case IrOpcode::kInt64Div:
-      return VisitInt64Div(node);
+      return MarkAsWord64(node), VisitInt64Div(node);
     case IrOpcode::kInt64Mod:
-      return VisitInt64Mod(node);
+      return MarkAsWord64(node), VisitInt64Mod(node);
     case IrOpcode::kInt64LessThan:
       return VisitInt64LessThan(node);
     case IrOpcode::kInt64LessThanOrEqual:
       return VisitInt64LessThanOrEqual(node);
     case IrOpcode::kUint64Div:
-      return VisitUint64Div(node);
+      return MarkAsWord64(node), VisitUint64Div(node);
     case IrOpcode::kUint64LessThan:
       return VisitUint64LessThan(node);
+    case IrOpcode::kUint64LessThanOrEqual:
+      return VisitUint64LessThanOrEqual(node);
     case IrOpcode::kUint64Mod:
-      return VisitUint64Mod(node);
+      return MarkAsWord64(node), VisitUint64Mod(node);
     case IrOpcode::kChangeFloat32ToFloat64:
-      return MarkAsDouble(node), VisitChangeFloat32ToFloat64(node);
+      return MarkAsFloat64(node), VisitChangeFloat32ToFloat64(node);
     case IrOpcode::kChangeInt32ToFloat64:
-      return MarkAsDouble(node), VisitChangeInt32ToFloat64(node);
+      return MarkAsFloat64(node), VisitChangeInt32ToFloat64(node);
     case IrOpcode::kChangeUint32ToFloat64:
-      return MarkAsDouble(node), VisitChangeUint32ToFloat64(node);
+      return MarkAsFloat64(node), VisitChangeUint32ToFloat64(node);
     case IrOpcode::kChangeFloat64ToInt32:
-      return VisitChangeFloat64ToInt32(node);
+      return MarkAsWord32(node), VisitChangeFloat64ToInt32(node);
     case IrOpcode::kChangeFloat64ToUint32:
-      return VisitChangeFloat64ToUint32(node);
+      return MarkAsWord32(node), VisitChangeFloat64ToUint32(node);
+    case IrOpcode::kTryTruncateFloat32ToInt64:
+      return MarkAsWord64(node), VisitTryTruncateFloat32ToInt64(node);
+    case IrOpcode::kTryTruncateFloat64ToInt64:
+      return MarkAsWord64(node), VisitTryTruncateFloat64ToInt64(node);
+    case IrOpcode::kTryTruncateFloat32ToUint64:
+      return MarkAsWord64(node), VisitTryTruncateFloat32ToUint64(node);
+    case IrOpcode::kTryTruncateFloat64ToUint64:
+      return MarkAsWord64(node), VisitTryTruncateFloat64ToUint64(node);
     case IrOpcode::kChangeInt32ToInt64:
-      return VisitChangeInt32ToInt64(node);
+      return MarkAsWord64(node), VisitChangeInt32ToInt64(node);
     case IrOpcode::kChangeUint32ToUint64:
-      return VisitChangeUint32ToUint64(node);
+      return MarkAsWord64(node), VisitChangeUint32ToUint64(node);
     case IrOpcode::kTruncateFloat64ToFloat32:
-      return MarkAsDouble(node), VisitTruncateFloat64ToFloat32(node);
+      return MarkAsFloat32(node), VisitTruncateFloat64ToFloat32(node);
     case IrOpcode::kTruncateFloat64ToInt32:
-      return VisitTruncateFloat64ToInt32(node);
+      return MarkAsWord32(node), VisitTruncateFloat64ToInt32(node);
     case IrOpcode::kTruncateInt64ToInt32:
-      return VisitTruncateInt64ToInt32(node);
+      return MarkAsWord32(node), VisitTruncateInt64ToInt32(node);
+    case IrOpcode::kRoundInt64ToFloat32:
+      return MarkAsFloat32(node), VisitRoundInt64ToFloat32(node);
+    case IrOpcode::kRoundInt64ToFloat64:
+      return MarkAsFloat64(node), VisitRoundInt64ToFloat64(node);
+    case IrOpcode::kBitcastFloat32ToInt32:
+      return MarkAsWord32(node), VisitBitcastFloat32ToInt32(node);
+    case IrOpcode::kRoundUint64ToFloat32:
+      return MarkAsFloat64(node), VisitRoundUint64ToFloat32(node);
+    case IrOpcode::kRoundUint64ToFloat64:
+      return MarkAsFloat64(node), VisitRoundUint64ToFloat64(node);
+    case IrOpcode::kBitcastFloat64ToInt64:
+      return MarkAsWord64(node), VisitBitcastFloat64ToInt64(node);
+    case IrOpcode::kBitcastInt32ToFloat32:
+      return MarkAsFloat32(node), VisitBitcastInt32ToFloat32(node);
+    case IrOpcode::kBitcastInt64ToFloat64:
+      return MarkAsFloat64(node), VisitBitcastInt64ToFloat64(node);
+    case IrOpcode::kFloat32Add:
+      return MarkAsFloat32(node), VisitFloat32Add(node);
+    case IrOpcode::kFloat32Sub:
+      return MarkAsFloat32(node), VisitFloat32Sub(node);
+    case IrOpcode::kFloat32Mul:
+      return MarkAsFloat32(node), VisitFloat32Mul(node);
+    case IrOpcode::kFloat32Div:
+      return MarkAsFloat32(node), VisitFloat32Div(node);
+    case IrOpcode::kFloat32Min:
+      return MarkAsFloat32(node), VisitFloat32Min(node);
+    case IrOpcode::kFloat32Max:
+      return MarkAsFloat32(node), VisitFloat32Max(node);
+    case IrOpcode::kFloat32Abs:
+      return MarkAsFloat32(node), VisitFloat32Abs(node);
+    case IrOpcode::kFloat32Sqrt:
+      return MarkAsFloat32(node), VisitFloat32Sqrt(node);
+    case IrOpcode::kFloat32Equal:
+      return VisitFloat32Equal(node);
+    case IrOpcode::kFloat32LessThan:
+      return VisitFloat32LessThan(node);
+    case IrOpcode::kFloat32LessThanOrEqual:
+      return VisitFloat32LessThanOrEqual(node);
     case IrOpcode::kFloat64Add:
-      return MarkAsDouble(node), VisitFloat64Add(node);
+      return MarkAsFloat64(node), VisitFloat64Add(node);
     case IrOpcode::kFloat64Sub:
-      return MarkAsDouble(node), VisitFloat64Sub(node);
+      return MarkAsFloat64(node), VisitFloat64Sub(node);
     case IrOpcode::kFloat64Mul:
-      return MarkAsDouble(node), VisitFloat64Mul(node);
+      return MarkAsFloat64(node), VisitFloat64Mul(node);
     case IrOpcode::kFloat64Div:
-      return MarkAsDouble(node), VisitFloat64Div(node);
+      return MarkAsFloat64(node), VisitFloat64Div(node);
     case IrOpcode::kFloat64Mod:
-      return MarkAsDouble(node), VisitFloat64Mod(node);
+      return MarkAsFloat64(node), VisitFloat64Mod(node);
+    case IrOpcode::kFloat64Min:
+      return MarkAsFloat64(node), VisitFloat64Min(node);
+    case IrOpcode::kFloat64Max:
+      return MarkAsFloat64(node), VisitFloat64Max(node);
+    case IrOpcode::kFloat64Abs:
+      return MarkAsFloat64(node), VisitFloat64Abs(node);
     case IrOpcode::kFloat64Sqrt:
-      return MarkAsDouble(node), VisitFloat64Sqrt(node);
+      return MarkAsFloat64(node), VisitFloat64Sqrt(node);
     case IrOpcode::kFloat64Equal:
       return VisitFloat64Equal(node);
     case IrOpcode::kFloat64LessThan:
       return VisitFloat64LessThan(node);
     case IrOpcode::kFloat64LessThanOrEqual:
       return VisitFloat64LessThanOrEqual(node);
-    case IrOpcode::kFloat64Floor:
-      return MarkAsDouble(node), VisitFloat64Floor(node);
-    case IrOpcode::kFloat64Ceil:
-      return MarkAsDouble(node), VisitFloat64Ceil(node);
+    case IrOpcode::kFloat32RoundDown:
+      return MarkAsFloat32(node), VisitFloat32RoundDown(node);
+    case IrOpcode::kFloat64RoundDown:
+      return MarkAsFloat64(node), VisitFloat64RoundDown(node);
+    case IrOpcode::kFloat32RoundUp:
+      return MarkAsFloat32(node), VisitFloat32RoundUp(node);
+    case IrOpcode::kFloat64RoundUp:
+      return MarkAsFloat64(node), VisitFloat64RoundUp(node);
+    case IrOpcode::kFloat32RoundTruncate:
+      return MarkAsFloat32(node), VisitFloat32RoundTruncate(node);
     case IrOpcode::kFloat64RoundTruncate:
-      return MarkAsDouble(node), VisitFloat64RoundTruncate(node);
+      return MarkAsFloat64(node), VisitFloat64RoundTruncate(node);
     case IrOpcode::kFloat64RoundTiesAway:
-      return MarkAsDouble(node), VisitFloat64RoundTiesAway(node);
+      return MarkAsFloat64(node), VisitFloat64RoundTiesAway(node);
+    case IrOpcode::kFloat32RoundTiesEven:
+      return MarkAsFloat32(node), VisitFloat32RoundTiesEven(node);
+    case IrOpcode::kFloat64RoundTiesEven:
+      return MarkAsFloat64(node), VisitFloat64RoundTiesEven(node);
+    case IrOpcode::kFloat64ExtractLowWord32:
+      return MarkAsWord32(node), VisitFloat64ExtractLowWord32(node);
+    case IrOpcode::kFloat64ExtractHighWord32:
+      return MarkAsWord32(node), VisitFloat64ExtractHighWord32(node);
+    case IrOpcode::kFloat64InsertLowWord32:
+      return MarkAsFloat64(node), VisitFloat64InsertLowWord32(node);
+    case IrOpcode::kFloat64InsertHighWord32:
+      return MarkAsFloat64(node), VisitFloat64InsertHighWord32(node);
     case IrOpcode::kLoadStackPointer:
       return VisitLoadStackPointer(node);
+    case IrOpcode::kLoadFramePointer:
+      return VisitLoadFramePointer(node);
     case IrOpcode::kCheckedLoad: {
-      MachineType rep = OpParameter<MachineType>(node);
+      MachineRepresentation rep =
+          CheckedLoadRepresentationOf(node->op()).representation();
       MarkAsRepresentation(rep, node);
       return VisitCheckedLoad(node);
     }
@@ -845,24 +1082,56 @@
 }
 
 
-#if V8_TURBOFAN_BACKEND
-
-void InstructionSelector::VisitTruncateFloat64ToInt32(Node* node) {
-  OperandGenerator g(this);
-  Emit(kArchTruncateDoubleToI, g.DefineAsRegister(node),
-       g.UseRegister(node->InputAt(0)));
-}
-
-
 void InstructionSelector::VisitLoadStackPointer(Node* node) {
   OperandGenerator g(this);
   Emit(kArchStackPointer, g.DefineAsRegister(node));
 }
 
-#endif  // V8_TURBOFAN_BACKEND
+
+void InstructionSelector::VisitLoadFramePointer(Node* node) {
+  OperandGenerator g(this);
+  Emit(kArchFramePointer, g.DefineAsRegister(node));
+}
+
+
+void InstructionSelector::EmitTableSwitch(const SwitchInfo& sw,
+                                          InstructionOperand& index_operand) {
+  OperandGenerator g(this);
+  size_t input_count = 2 + sw.value_range;
+  auto* inputs = zone()->NewArray<InstructionOperand>(input_count);
+  inputs[0] = index_operand;
+  InstructionOperand default_operand = g.Label(sw.default_branch);
+  std::fill(&inputs[1], &inputs[input_count], default_operand);
+  for (size_t index = 0; index < sw.case_count; ++index) {
+    size_t value = sw.case_values[index] - sw.min_value;
+    BasicBlock* branch = sw.case_branches[index];
+    DCHECK_LE(0u, value);
+    DCHECK_LT(value + 2, input_count);
+    inputs[value + 2] = g.Label(branch);
+  }
+  Emit(kArchTableSwitch, 0, nullptr, input_count, inputs, 0, nullptr);
+}
+
+
+void InstructionSelector::EmitLookupSwitch(const SwitchInfo& sw,
+                                           InstructionOperand& value_operand) {
+  OperandGenerator g(this);
+  size_t input_count = 2 + sw.case_count * 2;
+  auto* inputs = zone()->NewArray<InstructionOperand>(input_count);
+  inputs[0] = value_operand;
+  inputs[1] = g.Label(sw.default_branch);
+  for (size_t index = 0; index < sw.case_count; ++index) {
+    int32_t value = sw.case_values[index];
+    BasicBlock* branch = sw.case_branches[index];
+    inputs[index * 2 + 2 + 0] = g.TempImmediate(value);
+    inputs[index * 2 + 2 + 1] = g.Label(branch);
+  }
+  Emit(kArchLookupSwitch, 0, nullptr, input_count, inputs, 0, nullptr);
+}
+
 
 // 32 bit targets do not implement the following instructions.
-#if V8_TARGET_ARCH_32_BIT && !V8_TARGET_ARCH_X64 && V8_TURBOFAN_BACKEND
+#if V8_TARGET_ARCH_32_BIT
 
 void InstructionSelector::VisitWord64And(Node* node) { UNIMPLEMENTED(); }
 
@@ -885,15 +1154,34 @@
 void InstructionSelector::VisitWord64Ror(Node* node) { UNIMPLEMENTED(); }
 
 
+void InstructionSelector::VisitWord64Clz(Node* node) { UNIMPLEMENTED(); }
+
+
+void InstructionSelector::VisitWord64Ctz(Node* node) { UNIMPLEMENTED(); }
+
+
+void InstructionSelector::VisitWord64Popcnt(Node* node) { UNIMPLEMENTED(); }
+
+
 void InstructionSelector::VisitWord64Equal(Node* node) { UNIMPLEMENTED(); }
 
 
 void InstructionSelector::VisitInt64Add(Node* node) { UNIMPLEMENTED(); }
 
 
+void InstructionSelector::VisitInt64AddWithOverflow(Node* node) {
+  UNIMPLEMENTED();
+}
+
+
 void InstructionSelector::VisitInt64Sub(Node* node) { UNIMPLEMENTED(); }
 
 
+void InstructionSelector::VisitInt64SubWithOverflow(Node* node) {
+  UNIMPLEMENTED();
+}
+
+
 void InstructionSelector::VisitInt64Mul(Node* node) { UNIMPLEMENTED(); }
 
 
@@ -917,6 +1205,11 @@
 void InstructionSelector::VisitUint64LessThan(Node* node) { UNIMPLEMENTED(); }
 
 
+void InstructionSelector::VisitUint64LessThanOrEqual(Node* node) {
+  UNIMPLEMENTED();
+}
+
+
 void InstructionSelector::VisitUint64Mod(Node* node) { UNIMPLEMENTED(); }
 
 
@@ -930,14 +1223,71 @@
 }
 
 
+void InstructionSelector::VisitTryTruncateFloat32ToInt64(Node* node) {
+  UNIMPLEMENTED();
+}
+
+
+void InstructionSelector::VisitTryTruncateFloat64ToInt64(Node* node) {
+  UNIMPLEMENTED();
+}
+
+
+void InstructionSelector::VisitTryTruncateFloat32ToUint64(Node* node) {
+  UNIMPLEMENTED();
+}
+
+
+void InstructionSelector::VisitTryTruncateFloat64ToUint64(Node* node) {
+  UNIMPLEMENTED();
+}
+
+
 void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) {
   UNIMPLEMENTED();
 }
 
-#endif  // V8_TARGET_ARCH_32_BIT && !V8_TARGET_ARCH_X64 && V8_TURBOFAN_BACKEND
+
+void InstructionSelector::VisitRoundInt64ToFloat32(Node* node) {
+  UNIMPLEMENTED();
+}
 
 
-void InstructionSelector::VisitFinish(Node* node) {
+void InstructionSelector::VisitRoundInt64ToFloat64(Node* node) {
+  UNIMPLEMENTED();
+}
+
+
+void InstructionSelector::VisitRoundUint64ToFloat32(Node* node) {
+  UNIMPLEMENTED();
+}
+
+
+void InstructionSelector::VisitRoundUint64ToFloat64(Node* node) {
+  UNIMPLEMENTED();
+}
+
+
+void InstructionSelector::VisitBitcastFloat64ToInt64(Node* node) {
+  UNIMPLEMENTED();
+}
+
+
+void InstructionSelector::VisitBitcastInt64ToFloat64(Node* node) {
+  UNIMPLEMENTED();
+}
+
+#endif  // V8_TARGET_ARCH_32_BIT
+
+
+void InstructionSelector::VisitFinishRegion(Node* node) {
+  OperandGenerator g(this);
+  Node* value = node->InputAt(0);
+  Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value));
+}
+
+
+void InstructionSelector::VisitGuard(Node* node) {
   OperandGenerator g(this);
   Node* value = node->InputAt(0);
   Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value));
@@ -946,10 +1296,36 @@
 
 void InstructionSelector::VisitParameter(Node* node) {
   OperandGenerator g(this);
-  int index = OpParameter<int>(node);
+  int index = ParameterIndexOf(node->op());
+  InstructionOperand op =
+      linkage()->ParameterHasSecondaryLocation(index)
+          ? g.DefineAsDualLocation(
+                node, linkage()->GetParameterLocation(index),
+                linkage()->GetParameterSecondaryLocation(index))
+          : g.DefineAsLocation(
+                node, linkage()->GetParameterLocation(index),
+                linkage()->GetParameterType(index).representation());
+
+  Emit(kArchNop, op);
+}
+
+
+void InstructionSelector::VisitIfException(Node* node) {
+  OperandGenerator g(this);
+  Node* call = node->InputAt(1);
+  DCHECK_EQ(IrOpcode::kCall, call->opcode());
+  const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(call);
   Emit(kArchNop,
-       g.DefineAsLocation(node, linkage()->GetParameterLocation(index),
-                          linkage()->GetParameterType(index)));
+       g.DefineAsLocation(node, descriptor->GetReturnLocation(0),
+                          descriptor->GetReturnType(0).representation()));
+}
+
+
+void InstructionSelector::VisitOsrValue(Node* node) {
+  OperandGenerator g(this);
+  int index = OpParameter<int>(node);
+  Emit(kArchNop, g.DefineAsLocation(node, linkage()->GetOsrValueLocation(index),
+                                    MachineRepresentation::kTagged));
 }
 
 
@@ -958,11 +1334,13 @@
   PhiInstruction* phi = new (instruction_zone())
       PhiInstruction(instruction_zone(), GetVirtualRegister(node),
                      static_cast<size_t>(input_count));
-  sequence()->InstructionBlockAt(current_block_->GetRpoNumber())->AddPhi(phi);
+  sequence()
+      ->InstructionBlockAt(RpoNumber::FromInt(current_block_->rpo_number()))
+      ->AddPhi(phi);
   for (int i = 0; i < input_count; ++i) {
     Node* const input = node->InputAt(i);
     MarkAsUsed(input);
-    phi->Extend(instruction_zone(), GetVirtualRegister(input));
+    phi->SetInput(static_cast<size_t>(i), GetVirtualRegister(input));
   }
 }
 
@@ -973,10 +1351,16 @@
   switch (value->opcode()) {
     case IrOpcode::kInt32AddWithOverflow:
     case IrOpcode::kInt32SubWithOverflow:
-      if (OpParameter<size_t>(node) == 0) {
+    case IrOpcode::kInt64AddWithOverflow:
+    case IrOpcode::kInt64SubWithOverflow:
+    case IrOpcode::kTryTruncateFloat32ToInt64:
+    case IrOpcode::kTryTruncateFloat64ToInt64:
+    case IrOpcode::kTryTruncateFloat32ToUint64:
+    case IrOpcode::kTryTruncateFloat64ToUint64:
+      if (ProjectionIndexOf(node->op()) == 0u) {
         Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value));
       } else {
-        DCHECK(OpParameter<size_t>(node) == 1u);
+        DCHECK(ProjectionIndexOf(node->op()) == 1u);
         MarkAsUsed(value);
       }
       break;
@@ -994,153 +1378,246 @@
 }
 
 
-void InstructionSelector::VisitGoto(BasicBlock* target) {
-  // jump to the next block.
+void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) {
   OperandGenerator g(this);
-  Emit(kArchJmp, NULL, g.Label(target))->MarkAsControl();
+  const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(node);
+
+  FrameStateDescriptor* frame_state_descriptor = nullptr;
+  if (descriptor->NeedsFrameState()) {
+    frame_state_descriptor = GetFrameStateDescriptor(
+        node->InputAt(static_cast<int>(descriptor->InputCount())));
+  }
+
+  CallBuffer buffer(zone(), descriptor, frame_state_descriptor);
+
+  // Compute InstructionOperands for inputs and outputs.
+  // TODO(turbofan): on some architectures it's probably better to use
+  // the code object in a register if there are multiple uses of it.
+  // Improve constant pool and the heuristics in the register allocator
+  // for where to emit constants.
+  CallBufferFlags call_buffer_flags(kCallCodeImmediate | kCallAddressImmediate);
+  InitializeCallBuffer(node, &buffer, call_buffer_flags);
+
+  EmitPrepareArguments(&(buffer.pushed_nodes), descriptor, node);
+
+  // Pass label of exception handler block.
+  CallDescriptor::Flags flags = descriptor->flags();
+  if (handler) {
+    DCHECK_EQ(IrOpcode::kIfException, handler->front()->opcode());
+    IfExceptionHint hint = OpParameter<IfExceptionHint>(handler->front());
+    if (hint == IfExceptionHint::kLocallyCaught) {
+      flags |= CallDescriptor::kHasLocalCatchHandler;
+    }
+    flags |= CallDescriptor::kHasExceptionHandler;
+    buffer.instruction_args.push_back(g.Label(handler));
+  }
+
+  // Select the appropriate opcode based on the call type.
+  InstructionCode opcode = kArchNop;
+  switch (descriptor->kind()) {
+    case CallDescriptor::kCallAddress:
+      opcode =
+          kArchCallCFunction |
+          MiscField::encode(static_cast<int>(descriptor->CParameterCount()));
+      break;
+    case CallDescriptor::kCallCodeObject:
+      opcode = kArchCallCodeObject | MiscField::encode(flags);
+      break;
+    case CallDescriptor::kCallJSFunction:
+      opcode = kArchCallJSFunction | MiscField::encode(flags);
+      break;
+    case CallDescriptor::kLazyBailout:
+      opcode = kArchLazyBailout | MiscField::encode(flags);
+      break;
+  }
+
+  // Emit the call instruction.
+  size_t const output_count = buffer.outputs.size();
+  auto* outputs = output_count ? &buffer.outputs.front() : nullptr;
+  Emit(opcode, output_count, outputs, buffer.instruction_args.size(),
+       &buffer.instruction_args.front())
+      ->MarkAsCall();
 }
 
 
-void InstructionSelector::VisitReturn(Node* value) {
+void InstructionSelector::VisitTailCall(Node* node) {
   OperandGenerator g(this);
-  if (value != NULL) {
-    Emit(kArchRet, NULL, g.UseLocation(value, linkage()->GetReturnLocation(),
-                                       linkage()->GetReturnType()));
+  CallDescriptor const* descriptor = OpParameter<CallDescriptor const*>(node);
+  DCHECK_NE(0, descriptor->flags() & CallDescriptor::kSupportsTailCalls);
+  DCHECK_EQ(0, descriptor->flags() & CallDescriptor::kPatchableCallSite);
+  DCHECK_EQ(0, descriptor->flags() & CallDescriptor::kNeedsNopAfterCall);
+
+  // TODO(turbofan): Relax restriction for stack parameters.
+
+  int stack_param_delta = 0;
+  if (linkage()->GetIncomingDescriptor()->CanTailCall(node,
+                                                      &stack_param_delta)) {
+    CallBuffer buffer(zone(), descriptor, nullptr);
+
+    // Compute InstructionOperands for inputs and outputs.
+    CallBufferFlags flags(kCallCodeImmediate | kCallTail);
+    if (IsTailCallAddressImmediate()) {
+      flags |= kCallAddressImmediate;
+    }
+    InitializeCallBuffer(node, &buffer, flags, stack_param_delta);
+
+    // Select the appropriate opcode based on the call type.
+    InstructionCode opcode;
+    switch (descriptor->kind()) {
+      case CallDescriptor::kCallCodeObject:
+        opcode = kArchTailCallCodeObject;
+        break;
+      case CallDescriptor::kCallJSFunction:
+        opcode = kArchTailCallJSFunction;
+        break;
+      default:
+        UNREACHABLE();
+        return;
+    }
+    opcode |= MiscField::encode(descriptor->flags());
+
+    buffer.instruction_args.push_back(g.TempImmediate(stack_param_delta));
+
+    Emit(kArchPrepareTailCall, g.NoOutput(),
+         g.TempImmediate(stack_param_delta));
+
+    // Emit the tailcall instruction.
+    Emit(opcode, 0, nullptr, buffer.instruction_args.size(),
+         &buffer.instruction_args.front());
   } else {
-    Emit(kArchRet, NULL);
+    FrameStateDescriptor* frame_state_descriptor =
+        descriptor->NeedsFrameState()
+            ? GetFrameStateDescriptor(
+                  node->InputAt(static_cast<int>(descriptor->InputCount())))
+            : nullptr;
+
+    CallBuffer buffer(zone(), descriptor, frame_state_descriptor);
+
+    // Compute InstructionOperands for inputs and outputs.
+    CallBufferFlags flags = kCallCodeImmediate;
+    if (IsTailCallAddressImmediate()) {
+      flags |= kCallAddressImmediate;
+    }
+    InitializeCallBuffer(node, &buffer, flags);
+
+    EmitPrepareArguments(&(buffer.pushed_nodes), descriptor, node);
+
+    // Select the appropriate opcode based on the call type.
+    InstructionCode opcode;
+    switch (descriptor->kind()) {
+      case CallDescriptor::kCallCodeObject:
+        opcode = kArchCallCodeObject;
+        break;
+      case CallDescriptor::kCallJSFunction:
+        opcode = kArchCallJSFunction;
+        break;
+      default:
+        UNREACHABLE();
+        return;
+    }
+    opcode |= MiscField::encode(descriptor->flags());
+
+    // Emit the call instruction.
+    size_t output_count = buffer.outputs.size();
+    auto* outputs = &buffer.outputs.front();
+    Emit(opcode, output_count, outputs, buffer.instruction_args.size(),
+         &buffer.instruction_args.front())
+        ->MarkAsCall();
+    Emit(kArchRet, 0, nullptr, output_count, outputs);
   }
 }
 
 
+void InstructionSelector::VisitGoto(BasicBlock* target) {
+  // jump to the next block.
+  OperandGenerator g(this);
+  Emit(kArchJmp, g.NoOutput(), g.Label(target));
+}
+
+
+void InstructionSelector::VisitReturn(Node* ret) {
+  OperandGenerator g(this);
+  if (linkage()->GetIncomingDescriptor()->ReturnCount() == 0) {
+    Emit(kArchRet, g.NoOutput());
+  } else {
+    const int ret_count = ret->op()->ValueInputCount();
+    auto value_locations = zone()->NewArray<InstructionOperand>(ret_count);
+    for (int i = 0; i < ret_count; ++i) {
+      value_locations[i] =
+          g.UseLocation(ret->InputAt(i), linkage()->GetReturnLocation(i),
+                        linkage()->GetReturnType(i).representation());
+    }
+    Emit(kArchRet, 0, nullptr, ret_count, value_locations);
+  }
+}
+
+
+void InstructionSelector::VisitDeoptimize(DeoptimizeKind kind, Node* value) {
+  OperandGenerator g(this);
+
+  FrameStateDescriptor* desc = GetFrameStateDescriptor(value);
+
+  InstructionOperandVector args(instruction_zone());
+  args.reserve(desc->GetTotalSize() + 1);  // Include deopt id.
+
+  InstructionSequence::StateId state_id =
+      sequence()->AddFrameStateDescriptor(desc);
+  args.push_back(g.TempImmediate(state_id.ToInt()));
+
+  StateObjectDeduplicator deduplicator(instruction_zone());
+
+  AddInputsToFrameStateDescriptor(desc, value, &g, &deduplicator, &args,
+                                  FrameStateInputKind::kAny,
+                                  instruction_zone());
+
+  InstructionCode opcode = kArchDeoptimize;
+  switch (kind) {
+    case DeoptimizeKind::kEager:
+      opcode |= MiscField::encode(Deoptimizer::EAGER);
+      break;
+    case DeoptimizeKind::kSoft:
+      opcode |= MiscField::encode(Deoptimizer::SOFT);
+      break;
+  }
+  Emit(opcode, 0, nullptr, args.size(), &args.front(), 0, nullptr);
+}
+
+
 void InstructionSelector::VisitThrow(Node* value) {
-  UNIMPLEMENTED();  // TODO(titzer)
-}
-
-
-void InstructionSelector::FillTypeVectorFromStateValues(
-    ZoneVector<MachineType>* types, Node* state_values) {
-  DCHECK(state_values->opcode() == IrOpcode::kStateValues);
-  int count = state_values->InputCount();
-  types->reserve(static_cast<size_t>(count));
-  for (int i = 0; i < count; i++) {
-    types->push_back(GetMachineType(state_values->InputAt(i)));
-  }
+  OperandGenerator g(this);
+  Emit(kArchThrowTerminator, g.NoOutput());  // TODO(titzer)
 }
 
 
 FrameStateDescriptor* InstructionSelector::GetFrameStateDescriptor(
     Node* state) {
   DCHECK(state->opcode() == IrOpcode::kFrameState);
-  DCHECK_EQ(5, state->InputCount());
-  DCHECK_EQ(IrOpcode::kStateValues, state->InputAt(0)->opcode());
-  DCHECK_EQ(IrOpcode::kStateValues, state->InputAt(1)->opcode());
-  DCHECK_EQ(IrOpcode::kStateValues, state->InputAt(2)->opcode());
-  FrameStateCallInfo state_info = OpParameter<FrameStateCallInfo>(state);
+  DCHECK_EQ(kFrameStateInputCount, state->InputCount());
+  FrameStateInfo state_info = OpParameter<FrameStateInfo>(state);
 
-  int parameters = state->InputAt(0)->InputCount();
-  int locals = state->InputAt(1)->InputCount();
-  int stack = state->InputAt(2)->InputCount();
+  int parameters = static_cast<int>(
+      StateValuesAccess(state->InputAt(kFrameStateParametersInput)).size());
+  int locals = static_cast<int>(
+      StateValuesAccess(state->InputAt(kFrameStateLocalsInput)).size());
+  int stack = static_cast<int>(
+      StateValuesAccess(state->InputAt(kFrameStateStackInput)).size());
 
-  FrameStateDescriptor* outer_state = NULL;
-  Node* outer_node = state->InputAt(4);
+  DCHECK_EQ(parameters, state_info.parameter_count());
+  DCHECK_EQ(locals, state_info.local_count());
+
+  FrameStateDescriptor* outer_state = nullptr;
+  Node* outer_node = state->InputAt(kFrameStateOuterStateInput);
   if (outer_node->opcode() == IrOpcode::kFrameState) {
     outer_state = GetFrameStateDescriptor(outer_node);
   }
 
   return new (instruction_zone()) FrameStateDescriptor(
-      instruction_zone(), state_info, parameters, locals, stack, outer_state);
+      instruction_zone(), state_info.type(), state_info.bailout_id(),
+      state_info.state_combine(), parameters, locals, stack,
+      state_info.shared_info(), outer_state);
 }
 
 
-static InstructionOperand* UseOrImmediate(OperandGenerator* g, Node* input) {
-  switch (input->opcode()) {
-    case IrOpcode::kInt32Constant:
-    case IrOpcode::kNumberConstant:
-    case IrOpcode::kFloat64Constant:
-    case IrOpcode::kHeapConstant:
-      return g->UseImmediate(input);
-    default:
-      return g->UseUnique(input);
-  }
-}
-
-
-void InstructionSelector::AddFrameStateInputs(
-    Node* state, InstructionOperandVector* inputs,
-    FrameStateDescriptor* descriptor) {
-  DCHECK_EQ(IrOpcode::kFrameState, state->op()->opcode());
-
-  if (descriptor->outer_state() != NULL) {
-    AddFrameStateInputs(state->InputAt(4), inputs, descriptor->outer_state());
-  }
-
-  Node* parameters = state->InputAt(0);
-  Node* locals = state->InputAt(1);
-  Node* stack = state->InputAt(2);
-  Node* context = state->InputAt(3);
-
-  DCHECK_EQ(IrOpcode::kStateValues, parameters->op()->opcode());
-  DCHECK_EQ(IrOpcode::kStateValues, locals->op()->opcode());
-  DCHECK_EQ(IrOpcode::kStateValues, stack->op()->opcode());
-
-  DCHECK_EQ(static_cast<int>(descriptor->parameters_count()),
-            parameters->InputCount());
-  DCHECK_EQ(static_cast<int>(descriptor->locals_count()), locals->InputCount());
-  DCHECK_EQ(static_cast<int>(descriptor->stack_count()), stack->InputCount());
-
-  ZoneVector<MachineType> types(instruction_zone());
-  types.reserve(descriptor->GetSize());
-
-  OperandGenerator g(this);
-  size_t value_index = 0;
-  for (int i = 0; i < static_cast<int>(descriptor->parameters_count()); i++) {
-    Node* input_node = parameters->InputAt(i);
-    inputs->push_back(UseOrImmediate(&g, input_node));
-    descriptor->SetType(value_index++, GetMachineType(input_node));
-  }
-  if (descriptor->HasContext()) {
-    inputs->push_back(UseOrImmediate(&g, context));
-    descriptor->SetType(value_index++, kMachAnyTagged);
-  }
-  for (int i = 0; i < static_cast<int>(descriptor->locals_count()); i++) {
-    Node* input_node = locals->InputAt(i);
-    inputs->push_back(UseOrImmediate(&g, input_node));
-    descriptor->SetType(value_index++, GetMachineType(input_node));
-  }
-  for (int i = 0; i < static_cast<int>(descriptor->stack_count()); i++) {
-    Node* input_node = stack->InputAt(i);
-    inputs->push_back(UseOrImmediate(&g, input_node));
-    descriptor->SetType(value_index++, GetMachineType(input_node));
-  }
-  DCHECK(value_index == descriptor->GetSize());
-}
-
-
-#if !V8_TURBOFAN_BACKEND
-
-#define DECLARE_UNIMPLEMENTED_SELECTOR(x) \
-  void InstructionSelector::Visit##x(Node* node) { UNIMPLEMENTED(); }
-MACHINE_OP_LIST(DECLARE_UNIMPLEMENTED_SELECTOR)
-#undef DECLARE_UNIMPLEMENTED_SELECTOR
-
-
-void InstructionSelector::VisitCall(Node* node) { UNIMPLEMENTED(); }
-
-
-void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
-                                      BasicBlock* fbranch) {
-  UNIMPLEMENTED();
-}
-
-
-// static
-MachineOperatorBuilder::Flags
-InstructionSelector::SupportedMachineOperatorFlags() {
-  return MachineOperatorBuilder::Flag::kNoFlags;
-}
-
-#endif  // !V8_TURBOFAN_BACKEND
-
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/src/compiler/instruction-selector.h b/src/compiler/instruction-selector.h
index 5e3c52f..52aea70 100644
--- a/src/compiler/instruction-selector.h
+++ b/src/compiler/instruction-selector.h
@@ -5,11 +5,13 @@
 #ifndef V8_COMPILER_INSTRUCTION_SELECTOR_H_
 #define V8_COMPILER_INSTRUCTION_SELECTOR_H_
 
-#include <deque>
+#include <map>
 
 #include "src/compiler/common-operator.h"
 #include "src/compiler/instruction.h"
+#include "src/compiler/instruction-scheduler.h"
 #include "src/compiler/machine-operator.h"
+#include "src/compiler/node.h"
 #include "src/zone-containers.h"
 
 namespace v8 {
@@ -17,69 +19,91 @@
 namespace compiler {
 
 // Forward declarations.
+class BasicBlock;
 struct CallBuffer;  // TODO(bmeurer): Remove this.
 class FlagsContinuation;
 class Linkage;
+class OperandGenerator;
+struct SwitchInfo;
 
-typedef IntVector NodeToVregMap;
-
-class InstructionSelector FINAL {
+// This struct connects nodes of parameters which are going to be pushed on the
+// call stack with their parameter index in the call descriptor of the callee.
+class PushParameter {
  public:
-  static const int kNodeUnmapped = -1;
+  PushParameter() : node_(nullptr), type_(MachineType::None()) {}
+  PushParameter(Node* node, MachineType type) : node_(node), type_(type) {}
 
+  Node* node() const { return node_; }
+  MachineType type() const { return type_; }
+
+ private:
+  Node* node_;
+  MachineType type_;
+};
+
+// Instruction selection generates an InstructionSequence for a given Schedule.
+class InstructionSelector final {
+ public:
   // Forward declarations.
   class Features;
 
-  // TODO(dcarney): pass in vreg mapping instead of graph.
-  InstructionSelector(Zone* local_zone, Graph* graph, Linkage* linkage,
-                      InstructionSequence* sequence, Schedule* schedule,
-                      SourcePositionTable* source_positions,
-                      Features features = SupportedFeatures());
+  enum SourcePositionMode { kCallSourcePositions, kAllSourcePositions };
+
+  InstructionSelector(
+      Zone* zone, size_t node_count, Linkage* linkage,
+      InstructionSequence* sequence, Schedule* schedule,
+      SourcePositionTable* source_positions,
+      SourcePositionMode source_position_mode = kCallSourcePositions,
+      Features features = SupportedFeatures());
 
   // Visit code for the entire graph with the included schedule.
   void SelectInstructions();
 
+  void StartBlock(RpoNumber rpo);
+  void EndBlock(RpoNumber rpo);
+  void AddInstruction(Instruction* instr);
+
   // ===========================================================================
   // ============= Architecture-independent code emission methods. =============
   // ===========================================================================
 
-  Instruction* Emit(InstructionCode opcode, InstructionOperand* output,
-                    size_t temp_count = 0, InstructionOperand* *temps = NULL);
-  Instruction* Emit(InstructionCode opcode, InstructionOperand* output,
-                    InstructionOperand* a, size_t temp_count = 0,
-                    InstructionOperand* *temps = NULL);
-  Instruction* Emit(InstructionCode opcode, InstructionOperand* output,
-                    InstructionOperand* a, InstructionOperand* b,
-                    size_t temp_count = 0, InstructionOperand* *temps = NULL);
-  Instruction* Emit(InstructionCode opcode, InstructionOperand* output,
-                    InstructionOperand* a, InstructionOperand* b,
-                    InstructionOperand* c, size_t temp_count = 0,
-                    InstructionOperand* *temps = NULL);
-  Instruction* Emit(InstructionCode opcode, InstructionOperand* output,
-                    InstructionOperand* a, InstructionOperand* b,
-                    InstructionOperand* c, InstructionOperand* d,
-                    size_t temp_count = 0, InstructionOperand* *temps = NULL);
-  Instruction* Emit(InstructionCode opcode, InstructionOperand* output,
-                    InstructionOperand* a, InstructionOperand* b,
-                    InstructionOperand* c, InstructionOperand* d,
-                    InstructionOperand* e, size_t temp_count = 0,
-                    InstructionOperand* *temps = NULL);
-  Instruction* Emit(InstructionCode opcode, InstructionOperand* output,
-                    InstructionOperand* a, InstructionOperand* b,
-                    InstructionOperand* c, InstructionOperand* d,
-                    InstructionOperand* e, InstructionOperand* f,
-                    size_t temp_count = 0, InstructionOperand* *temps = NULL);
+  Instruction* Emit(InstructionCode opcode, InstructionOperand output,
+                    size_t temp_count = 0, InstructionOperand* temps = nullptr);
+  Instruction* Emit(InstructionCode opcode, InstructionOperand output,
+                    InstructionOperand a, size_t temp_count = 0,
+                    InstructionOperand* temps = nullptr);
+  Instruction* Emit(InstructionCode opcode, InstructionOperand output,
+                    InstructionOperand a, InstructionOperand b,
+                    size_t temp_count = 0, InstructionOperand* temps = nullptr);
+  Instruction* Emit(InstructionCode opcode, InstructionOperand output,
+                    InstructionOperand a, InstructionOperand b,
+                    InstructionOperand c, size_t temp_count = 0,
+                    InstructionOperand* temps = nullptr);
+  Instruction* Emit(InstructionCode opcode, InstructionOperand output,
+                    InstructionOperand a, InstructionOperand b,
+                    InstructionOperand c, InstructionOperand d,
+                    size_t temp_count = 0, InstructionOperand* temps = nullptr);
+  Instruction* Emit(InstructionCode opcode, InstructionOperand output,
+                    InstructionOperand a, InstructionOperand b,
+                    InstructionOperand c, InstructionOperand d,
+                    InstructionOperand e, size_t temp_count = 0,
+                    InstructionOperand* temps = nullptr);
+  Instruction* Emit(InstructionCode opcode, InstructionOperand output,
+                    InstructionOperand a, InstructionOperand b,
+                    InstructionOperand c, InstructionOperand d,
+                    InstructionOperand e, InstructionOperand f,
+                    size_t temp_count = 0, InstructionOperand* temps = nullptr);
   Instruction* Emit(InstructionCode opcode, size_t output_count,
-                    InstructionOperand** outputs, size_t input_count,
-                    InstructionOperand** inputs, size_t temp_count = 0,
-                    InstructionOperand* *temps = NULL);
+                    InstructionOperand* outputs, size_t input_count,
+                    InstructionOperand* inputs, size_t temp_count = 0,
+                    InstructionOperand* temps = nullptr);
   Instruction* Emit(Instruction* instr);
 
   // ===========================================================================
   // ============== Architecture-independent CPU feature methods. ==============
   // ===========================================================================
 
-  class Features FINAL {
+  class Features final {
    public:
     Features() : bits_(0) {}
     explicit Features(unsigned bits) : bits_(bits) {}
@@ -126,13 +150,17 @@
   bool IsLive(Node* node) const { return !IsDefined(node) && IsUsed(node); }
 
   int GetVirtualRegister(const Node* node);
-  // Gets the current mapping if it exists, kNodeUnmapped otherwise.
-  int GetMappedVirtualRegister(const Node* node) const;
-  const NodeToVregMap& GetNodeMapForTesting() const { return node_map_; }
+  const std::map<NodeId, int> GetVirtualRegistersForTesting() const;
+
+  Isolate* isolate() const { return sequence()->isolate(); }
 
  private:
   friend class OperandGenerator;
 
+  void EmitTableSwitch(const SwitchInfo& sw, InstructionOperand& index_operand);
+  void EmitLookupSwitch(const SwitchInfo& sw,
+                        InstructionOperand& value_operand);
+
   // Inform the instruction selection that {node} was just defined.
   void MarkAsDefined(Node* node);
 
@@ -140,25 +168,36 @@
   // will need to generate code for it.
   void MarkAsUsed(Node* node);
 
-  // Checks if {node} is marked as double.
-  bool IsDouble(const Node* node) const;
-
-  // Inform the register allocator of a double result.
-  void MarkAsDouble(Node* node);
-
-  // Checks if {node} is marked as reference.
-  bool IsReference(const Node* node) const;
-
-  // Inform the register allocator of a reference result.
-  void MarkAsReference(Node* node);
-
   // Inform the register allocation of the representation of the value produced
   // by {node}.
-  void MarkAsRepresentation(MachineType rep, Node* node);
+  void MarkAsRepresentation(MachineRepresentation rep, Node* node);
+  void MarkAsWord32(Node* node) {
+    MarkAsRepresentation(MachineRepresentation::kWord32, node);
+  }
+  void MarkAsWord64(Node* node) {
+    MarkAsRepresentation(MachineRepresentation::kWord64, node);
+  }
+  void MarkAsFloat32(Node* node) {
+    MarkAsRepresentation(MachineRepresentation::kFloat32, node);
+  }
+  void MarkAsFloat64(Node* node) {
+    MarkAsRepresentation(MachineRepresentation::kFloat64, node);
+  }
+  void MarkAsReference(Node* node) {
+    MarkAsRepresentation(MachineRepresentation::kTagged, node);
+  }
 
   // Inform the register allocation of the representation of the unallocated
   // operand {op}.
-  void MarkAsRepresentation(MachineType rep, InstructionOperand* op);
+  void MarkAsRepresentation(MachineRepresentation rep,
+                            const InstructionOperand& op);
+
+  enum CallBufferFlag {
+    kCallCodeImmediate = 1u << 0,
+    kCallAddressImmediate = 1u << 1,
+    kCallTail = 1u << 2
+  };
+  typedef base::Flags<CallBufferFlag> CallBufferFlags;
 
   // Initialize the call buffer with the InstructionOperands, nodes, etc,
   // corresponding
@@ -166,15 +205,10 @@
   // {call_code_immediate} to generate immediate operands to calls of code.
   // {call_address_immediate} to generate immediate operands to address calls.
   void InitializeCallBuffer(Node* call, CallBuffer* buffer,
-                            bool call_code_immediate,
-                            bool call_address_immediate);
+                            CallBufferFlags flags, int stack_param_delta = 0);
+  bool IsTailCallAddressImmediate();
 
   FrameStateDescriptor* GetFrameStateDescriptor(Node* node);
-  void FillTypeVectorFromStateValues(ZoneVector<MachineType>* parameters,
-                                     Node* state_values);
-  void AddFrameStateInputs(Node* state, InstructionOperandVector* inputs,
-                           FrameStateDescriptor* descriptor);
-  MachineType GetMachineType(Node* node);
 
   // ===========================================================================
   // ============= Architecture-specific graph covering methods. ===============
@@ -194,17 +228,25 @@
   MACHINE_OP_LIST(DECLARE_GENERATOR)
 #undef DECLARE_GENERATOR
 
-  void VisitFinish(Node* node);
+  void VisitFinishRegion(Node* node);
+  void VisitGuard(Node* node);
   void VisitParameter(Node* node);
+  void VisitIfException(Node* node);
+  void VisitOsrValue(Node* node);
   void VisitPhi(Node* node);
   void VisitProjection(Node* node);
   void VisitConstant(Node* node);
-  void VisitCall(Node* call);
+  void VisitCall(Node* call, BasicBlock* handler = nullptr);
+  void VisitTailCall(Node* call);
   void VisitGoto(BasicBlock* target);
   void VisitBranch(Node* input, BasicBlock* tbranch, BasicBlock* fbranch);
-  void VisitReturn(Node* value);
+  void VisitSwitch(Node* node, const SwitchInfo& sw);
+  void VisitDeoptimize(DeoptimizeKind kind, Node* value);
+  void VisitReturn(Node* ret);
   void VisitThrow(Node* value);
-  void VisitDeoptimize(Node* deopt);
+
+  void EmitPrepareArguments(ZoneVector<compiler::PushParameter>* arguments,
+                            const CallDescriptor* descriptor, Node* node);
 
   // ===========================================================================
 
@@ -220,13 +262,15 @@
   Linkage* const linkage_;
   InstructionSequence* const sequence_;
   SourcePositionTable* const source_positions_;
+  SourcePositionMode const source_position_mode_;
   Features features_;
   Schedule* const schedule_;
-  NodeToVregMap node_map_;
   BasicBlock* current_block_;
-  ZoneDeque<Instruction*> instructions_;
+  ZoneVector<Instruction*> instructions_;
   BoolVector defined_;
   BoolVector used_;
+  IntVector virtual_registers_;
+  InstructionScheduler* scheduler_;
 };
 
 }  // namespace compiler
diff --git a/src/compiler/instruction.cc b/src/compiler/instruction.cc
index f83cdeb..383e27d 100644
--- a/src/compiler/instruction.cc
+++ b/src/compiler/instruction.cc
@@ -5,14 +5,80 @@
 #include "src/compiler/common-operator.h"
 #include "src/compiler/graph.h"
 #include "src/compiler/instruction.h"
+#include "src/compiler/schedule.h"
+#include "src/compiler/state-values-utils.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
+
+FlagsCondition CommuteFlagsCondition(FlagsCondition condition) {
+  switch (condition) {
+    case kSignedLessThan:
+      return kSignedGreaterThan;
+    case kSignedGreaterThanOrEqual:
+      return kSignedLessThanOrEqual;
+    case kSignedLessThanOrEqual:
+      return kSignedGreaterThanOrEqual;
+    case kSignedGreaterThan:
+      return kSignedLessThan;
+    case kUnsignedLessThan:
+      return kUnsignedGreaterThan;
+    case kUnsignedGreaterThanOrEqual:
+      return kUnsignedLessThanOrEqual;
+    case kUnsignedLessThanOrEqual:
+      return kUnsignedGreaterThanOrEqual;
+    case kUnsignedGreaterThan:
+      return kUnsignedLessThan;
+    case kFloatLessThanOrUnordered:
+      return kFloatGreaterThanOrUnordered;
+    case kFloatGreaterThanOrEqual:
+      return kFloatLessThanOrEqual;
+    case kFloatLessThanOrEqual:
+      return kFloatGreaterThanOrEqual;
+    case kFloatGreaterThanOrUnordered:
+      return kFloatLessThanOrUnordered;
+    case kFloatLessThan:
+      return kFloatGreaterThan;
+    case kFloatGreaterThanOrEqualOrUnordered:
+      return kFloatLessThanOrEqualOrUnordered;
+    case kFloatLessThanOrEqualOrUnordered:
+      return kFloatGreaterThanOrEqualOrUnordered;
+    case kFloatGreaterThan:
+      return kFloatLessThan;
+    case kEqual:
+    case kNotEqual:
+    case kOverflow:
+    case kNotOverflow:
+    case kUnorderedEqual:
+    case kUnorderedNotEqual:
+      return condition;
+  }
+  UNREACHABLE();
+  return condition;
+}
+
+
+void InstructionOperand::Print(const RegisterConfiguration* config) const {
+  OFStream os(stdout);
+  PrintableInstructionOperand wrapper;
+  wrapper.register_configuration_ = config;
+  wrapper.op_ = *this;
+  os << wrapper << std::endl;
+}
+
+
+void InstructionOperand::Print() const {
+  const RegisterConfiguration* config =
+      RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN);
+  Print(config);
+}
+
+
 std::ostream& operator<<(std::ostream& os,
                          const PrintableInstructionOperand& printable) {
-  const InstructionOperand& op = *printable.op_;
+  const InstructionOperand& op = printable.op_;
   const RegisterConfiguration* conf = printable.register_configuration_;
   switch (op.kind()) {
     case InstructionOperand::UNALLOCATED: {
@@ -25,13 +91,19 @@
         case UnallocatedOperand::NONE:
           return os;
         case UnallocatedOperand::FIXED_REGISTER:
-          return os << "(=" << conf->general_register_name(
-                                   unalloc->fixed_register_index()) << ")";
+          return os << "(="
+                    << conf->GetGeneralRegisterName(
+                           unalloc->fixed_register_index())
+                    << ")";
         case UnallocatedOperand::FIXED_DOUBLE_REGISTER:
-          return os << "(=" << conf->double_register_name(
-                                   unalloc->fixed_register_index()) << ")";
+          return os << "(="
+                    << conf->GetDoubleRegisterName(
+                           unalloc->fixed_register_index())
+                    << ")";
         case UnallocatedOperand::MUST_HAVE_REGISTER:
           return os << "(R)";
+        case UnallocatedOperand::MUST_HAVE_SLOT:
+          return os << "(S)";
         case UnallocatedOperand::SAME_AS_FIRST_INPUT:
           return os << "(1)";
         case UnallocatedOperand::ANY:
@@ -39,58 +111,88 @@
       }
     }
     case InstructionOperand::CONSTANT:
-      return os << "[constant:" << op.index() << "]";
-    case InstructionOperand::IMMEDIATE:
-      return os << "[immediate:" << op.index() << "]";
-    case InstructionOperand::STACK_SLOT:
-      return os << "[stack:" << op.index() << "]";
-    case InstructionOperand::DOUBLE_STACK_SLOT:
-      return os << "[double_stack:" << op.index() << "]";
-    case InstructionOperand::REGISTER:
-      return os << "[" << conf->general_register_name(op.index()) << "|R]";
-    case InstructionOperand::DOUBLE_REGISTER:
-      return os << "[" << conf->double_register_name(op.index()) << "|R]";
+      return os << "[constant:" << ConstantOperand::cast(op).virtual_register()
+                << "]";
+    case InstructionOperand::IMMEDIATE: {
+      auto imm = ImmediateOperand::cast(op);
+      switch (imm.type()) {
+        case ImmediateOperand::INLINE:
+          return os << "#" << imm.inline_value();
+        case ImmediateOperand::INDEXED:
+          return os << "[immediate:" << imm.indexed_value() << "]";
+      }
+    }
+    case InstructionOperand::EXPLICIT:
+    case InstructionOperand::ALLOCATED: {
+      auto allocated = LocationOperand::cast(op);
+      if (op.IsStackSlot()) {
+        os << "[stack:" << LocationOperand::cast(op).index();
+      } else if (op.IsDoubleStackSlot()) {
+        os << "[double_stack:" << LocationOperand::cast(op).index();
+      } else if (op.IsRegister()) {
+        os << "[" << LocationOperand::cast(op).GetRegister().ToString() << "|R";
+      } else {
+        DCHECK(op.IsDoubleRegister());
+        os << "[" << LocationOperand::cast(op).GetDoubleRegister().ToString()
+           << "|R";
+      }
+      if (allocated.IsExplicit()) {
+        os << "|E";
+      }
+      switch (allocated.representation()) {
+        case MachineRepresentation::kNone:
+          os << "|-";
+          break;
+        case MachineRepresentation::kBit:
+          os << "|b";
+          break;
+        case MachineRepresentation::kWord8:
+          os << "|w8";
+          break;
+        case MachineRepresentation::kWord16:
+          os << "|w16";
+          break;
+        case MachineRepresentation::kWord32:
+          os << "|w32";
+          break;
+        case MachineRepresentation::kWord64:
+          os << "|w64";
+          break;
+        case MachineRepresentation::kFloat32:
+          os << "|f32";
+          break;
+        case MachineRepresentation::kFloat64:
+          os << "|f64";
+          break;
+        case MachineRepresentation::kTagged:
+          os << "|t";
+          break;
+      }
+      return os << "]";
+    }
+    case InstructionOperand::INVALID:
+      return os << "(x)";
   }
   UNREACHABLE();
   return os;
 }
 
 
-template <InstructionOperand::Kind kOperandKind, int kNumCachedOperands>
-SubKindOperand<kOperandKind, kNumCachedOperands>*
-    SubKindOperand<kOperandKind, kNumCachedOperands>::cache = NULL;
-
-
-template <InstructionOperand::Kind kOperandKind, int kNumCachedOperands>
-void SubKindOperand<kOperandKind, kNumCachedOperands>::SetUpCache() {
-  if (cache) return;
-  cache = new SubKindOperand[kNumCachedOperands];
-  for (int i = 0; i < kNumCachedOperands; i++) {
-    cache[i].ConvertTo(kOperandKind, i);
-  }
+void MoveOperands::Print(const RegisterConfiguration* config) const {
+  OFStream os(stdout);
+  PrintableInstructionOperand wrapper;
+  wrapper.register_configuration_ = config;
+  wrapper.op_ = destination();
+  os << wrapper << " = ";
+  wrapper.op_ = source();
+  os << wrapper << std::endl;
 }
 
 
-template <InstructionOperand::Kind kOperandKind, int kNumCachedOperands>
-void SubKindOperand<kOperandKind, kNumCachedOperands>::TearDownCache() {
-  delete[] cache;
-  cache = NULL;
-}
-
-
-void InstructionOperand::SetUpCaches() {
-#define INSTRUCTION_OPERAND_SETUP(name, type, number) \
-  name##Operand::SetUpCache();
-  INSTRUCTION_OPERAND_LIST(INSTRUCTION_OPERAND_SETUP)
-#undef INSTRUCTION_OPERAND_SETUP
-}
-
-
-void InstructionOperand::TearDownCaches() {
-#define INSTRUCTION_OPERAND_TEARDOWN(name, type, number) \
-  name##Operand::TearDownCache();
-  INSTRUCTION_OPERAND_LIST(INSTRUCTION_OPERAND_TEARDOWN)
-#undef INSTRUCTION_OPERAND_TEARDOWN
+void MoveOperands::Print() const {
+  const RegisterConfiguration* config =
+      RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN);
+  Print(config);
 }
 
 
@@ -99,9 +201,8 @@
   const MoveOperands& mo = *printable.move_operands_;
   PrintableInstructionOperand printable_op = {printable.register_configuration_,
                                               mo.destination()};
-
   os << printable_op;
-  if (!mo.source()->Equals(mo.destination())) {
+  if (!mo.source().Equals(mo.destination())) {
     printable_op.op_ = mo.source();
     os << " = " << printable_op;
   }
@@ -110,29 +211,114 @@
 
 
 bool ParallelMove::IsRedundant() const {
-  for (int i = 0; i < move_operands_.length(); ++i) {
-    if (!move_operands_[i].IsRedundant()) return false;
+  for (auto move : *this) {
+    if (!move->IsRedundant()) return false;
   }
   return true;
 }
 
 
-bool GapInstruction::IsRedundant() const {
-  for (int i = GapInstruction::FIRST_INNER_POSITION;
-       i <= GapInstruction::LAST_INNER_POSITION; i++) {
-    if (parallel_moves_[i] != NULL && !parallel_moves_[i]->IsRedundant())
+MoveOperands* ParallelMove::PrepareInsertAfter(MoveOperands* move) const {
+  MoveOperands* replacement = nullptr;
+  MoveOperands* to_eliminate = nullptr;
+  for (auto curr : *this) {
+    if (curr->IsEliminated()) continue;
+    if (curr->destination().EqualsCanonicalized(move->source())) {
+      DCHECK(!replacement);
+      replacement = curr;
+      if (to_eliminate != nullptr) break;
+    } else if (curr->destination().EqualsCanonicalized(move->destination())) {
+      DCHECK(!to_eliminate);
+      to_eliminate = curr;
+      if (replacement != nullptr) break;
+    }
+  }
+  DCHECK_IMPLIES(replacement == to_eliminate, replacement == nullptr);
+  if (replacement != nullptr) move->set_source(replacement->source());
+  return to_eliminate;
+}
+
+
+ExplicitOperand::ExplicitOperand(LocationKind kind, MachineRepresentation rep,
+                                 int index)
+    : LocationOperand(EXPLICIT, kind, rep, index) {
+  DCHECK_IMPLIES(kind == REGISTER && !IsFloatingPoint(rep),
+                 Register::from_code(index).IsAllocatable());
+  DCHECK_IMPLIES(kind == REGISTER && IsFloatingPoint(rep),
+                 DoubleRegister::from_code(index).IsAllocatable());
+}
+
+
+Instruction::Instruction(InstructionCode opcode)
+    : opcode_(opcode),
+      bit_field_(OutputCountField::encode(0) | InputCountField::encode(0) |
+                 TempCountField::encode(0) | IsCallField::encode(false)),
+      reference_map_(nullptr) {
+  parallel_moves_[0] = nullptr;
+  parallel_moves_[1] = nullptr;
+}
+
+
+Instruction::Instruction(InstructionCode opcode, size_t output_count,
+                         InstructionOperand* outputs, size_t input_count,
+                         InstructionOperand* inputs, size_t temp_count,
+                         InstructionOperand* temps)
+    : opcode_(opcode),
+      bit_field_(OutputCountField::encode(output_count) |
+                 InputCountField::encode(input_count) |
+                 TempCountField::encode(temp_count) |
+                 IsCallField::encode(false)),
+      reference_map_(nullptr) {
+  parallel_moves_[0] = nullptr;
+  parallel_moves_[1] = nullptr;
+  size_t offset = 0;
+  for (size_t i = 0; i < output_count; ++i) {
+    DCHECK(!outputs[i].IsInvalid());
+    operands_[offset++] = outputs[i];
+  }
+  for (size_t i = 0; i < input_count; ++i) {
+    DCHECK(!inputs[i].IsInvalid());
+    operands_[offset++] = inputs[i];
+  }
+  for (size_t i = 0; i < temp_count; ++i) {
+    DCHECK(!temps[i].IsInvalid());
+    operands_[offset++] = temps[i];
+  }
+}
+
+
+bool Instruction::AreMovesRedundant() const {
+  for (int i = Instruction::FIRST_GAP_POSITION;
+       i <= Instruction::LAST_GAP_POSITION; i++) {
+    if (parallel_moves_[i] != nullptr && !parallel_moves_[i]->IsRedundant()) {
       return false;
+    }
   }
   return true;
 }
 
 
+void Instruction::Print(const RegisterConfiguration* config) const {
+  OFStream os(stdout);
+  PrintableInstruction wrapper;
+  wrapper.instr_ = this;
+  wrapper.register_configuration_ = config;
+  os << wrapper << std::endl;
+}
+
+
+void Instruction::Print() const {
+  const RegisterConfiguration* config =
+      RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN);
+  Print(config);
+}
+
+
 std::ostream& operator<<(std::ostream& os,
                          const PrintableParallelMove& printable) {
   const ParallelMove& pm = *printable.parallel_move_;
   bool first = true;
-  for (ZoneList<MoveOperands>::iterator move = pm.move_operands()->begin();
-       move != pm.move_operands()->end(); ++move) {
+  for (auto move : pm) {
     if (move->IsEliminated()) continue;
     if (!first) os << " ";
     first = false;
@@ -143,42 +329,28 @@
 }
 
 
-void PointerMap::RecordPointer(InstructionOperand* op, Zone* zone) {
+void ReferenceMap::RecordReference(const AllocatedOperand& op) {
   // Do not record arguments as pointers.
-  if (op->IsStackSlot() && op->index() < 0) return;
-  DCHECK(!op->IsDoubleRegister() && !op->IsDoubleStackSlot());
-  pointer_operands_.Add(op, zone);
+  if (op.IsStackSlot() && LocationOperand::cast(op).index() < 0) return;
+  DCHECK(!op.IsDoubleRegister() && !op.IsDoubleStackSlot());
+  reference_operands_.push_back(op);
 }
 
 
-void PointerMap::RemovePointer(InstructionOperand* op) {
-  // Do not record arguments as pointers.
-  if (op->IsStackSlot() && op->index() < 0) return;
-  DCHECK(!op->IsDoubleRegister() && !op->IsDoubleStackSlot());
-  for (int i = 0; i < pointer_operands_.length(); ++i) {
-    if (pointer_operands_[i]->Equals(op)) {
-      pointer_operands_.Remove(i);
-      --i;
-    }
-  }
-}
-
-
-void PointerMap::RecordUntagged(InstructionOperand* op, Zone* zone) {
-  // Do not record arguments as pointers.
-  if (op->IsStackSlot() && op->index() < 0) return;
-  DCHECK(!op->IsDoubleRegister() && !op->IsDoubleStackSlot());
-  untagged_operands_.Add(op, zone);
-}
-
-
-std::ostream& operator<<(std::ostream& os, const PointerMap& pm) {
+std::ostream& operator<<(std::ostream& os, const ReferenceMap& pm) {
   os << "{";
-  for (ZoneList<InstructionOperand*>::iterator op =
-           pm.pointer_operands_.begin();
-       op != pm.pointer_operands_.end(); ++op) {
-    if (op != pm.pointer_operands_.begin()) os << ";";
-    os << *op;
+  bool first = true;
+  PrintableInstructionOperand poi = {
+      RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN),
+      InstructionOperand()};
+  for (auto& op : pm.reference_operands_) {
+    if (!first) {
+      os << ";";
+    } else {
+      first = false;
+    }
+    poi.op_ = op;
+    os << poi;
   }
   return os << "}";
 }
@@ -248,18 +420,26 @@
       return os << "unsigned less than or equal";
     case kUnsignedGreaterThan:
       return os << "unsigned greater than";
+    case kFloatLessThanOrUnordered:
+      return os << "less than or unordered (FP)";
+    case kFloatGreaterThanOrEqual:
+      return os << "greater than or equal (FP)";
+    case kFloatLessThanOrEqual:
+      return os << "less than or equal (FP)";
+    case kFloatGreaterThanOrUnordered:
+      return os << "greater than or unordered (FP)";
+    case kFloatLessThan:
+      return os << "less than (FP)";
+    case kFloatGreaterThanOrEqualOrUnordered:
+      return os << "greater than, equal or unordered (FP)";
+    case kFloatLessThanOrEqualOrUnordered:
+      return os << "less than, equal or unordered (FP)";
+    case kFloatGreaterThan:
+      return os << "greater than (FP)";
     case kUnorderedEqual:
       return os << "unordered equal";
     case kUnorderedNotEqual:
       return os << "unordered not equal";
-    case kUnorderedLessThan:
-      return os << "unordered less than";
-    case kUnorderedGreaterThanOrEqual:
-      return os << "unordered greater than or equal";
-    case kUnorderedLessThanOrEqual:
-      return os << "unordered less than or equal";
-    case kUnorderedGreaterThan:
-      return os << "unordered greater than";
     case kOverflow:
       return os << "overflow";
     case kNotOverflow:
@@ -274,49 +454,42 @@
                          const PrintableInstruction& printable) {
   const Instruction& instr = *printable.instr_;
   PrintableInstructionOperand printable_op = {printable.register_configuration_,
-                                              NULL};
+                                              InstructionOperand()};
+  os << "gap ";
+  for (int i = Instruction::FIRST_GAP_POSITION;
+       i <= Instruction::LAST_GAP_POSITION; i++) {
+    os << "(";
+    if (instr.parallel_moves()[i] != nullptr) {
+      PrintableParallelMove ppm = {printable.register_configuration_,
+                                   instr.parallel_moves()[i]};
+      os << ppm;
+    }
+    os << ") ";
+  }
+  os << "\n          ";
+
   if (instr.OutputCount() > 1) os << "(";
   for (size_t i = 0; i < instr.OutputCount(); i++) {
     if (i > 0) os << ", ";
-    printable_op.op_ = instr.OutputAt(i);
+    printable_op.op_ = *instr.OutputAt(i);
     os << printable_op;
   }
 
   if (instr.OutputCount() > 1) os << ") = ";
   if (instr.OutputCount() == 1) os << " = ";
 
-  if (instr.IsGapMoves()) {
-    const GapInstruction* gap = GapInstruction::cast(&instr);
-    os << (instr.IsBlockStart() ? " block-start" : "gap ");
-    for (int i = GapInstruction::FIRST_INNER_POSITION;
-         i <= GapInstruction::LAST_INNER_POSITION; i++) {
-      os << "(";
-      if (gap->parallel_moves_[i] != NULL) {
-        PrintableParallelMove ppm = {printable.register_configuration_,
-                                     gap->parallel_moves_[i]};
-        os << ppm;
-      }
-      os << ") ";
-    }
-  } else if (instr.IsSourcePosition()) {
-    const SourcePositionInstruction* pos =
-        SourcePositionInstruction::cast(&instr);
-    os << "position (" << pos->source_position().raw() << ")";
-  } else {
-    os << ArchOpcodeField::decode(instr.opcode());
-    AddressingMode am = AddressingModeField::decode(instr.opcode());
-    if (am != kMode_None) {
-      os << " : " << AddressingModeField::decode(instr.opcode());
-    }
-    FlagsMode fm = FlagsModeField::decode(instr.opcode());
-    if (fm != kFlags_none) {
-      os << " && " << fm << " if "
-         << FlagsConditionField::decode(instr.opcode());
-    }
+  os << ArchOpcodeField::decode(instr.opcode());
+  AddressingMode am = AddressingModeField::decode(instr.opcode());
+  if (am != kMode_None) {
+    os << " : " << AddressingModeField::decode(instr.opcode());
+  }
+  FlagsMode fm = FlagsModeField::decode(instr.opcode());
+  if (fm != kFlags_none) {
+    os << " && " << fm << " if " << FlagsConditionField::decode(instr.opcode());
   }
   if (instr.InputCount() > 0) {
     for (size_t i = 0; i < instr.InputCount(); i++) {
-      printable_op.op_ = instr.InputAt(i);
+      printable_op.op_ = *instr.InputAt(i);
       os << " " << printable_op;
     }
   }
@@ -324,6 +497,9 @@
 }
 
 
+Constant::Constant(int32_t v) : type_(kInt32), value_(v) {}
+
+
 std::ostream& operator<<(std::ostream& os, const Constant& constant) {
   switch (constant.type()) {
     case Constant::kInt32:
@@ -347,26 +523,41 @@
 }
 
 
-InstructionBlock::InstructionBlock(Zone* zone, BasicBlock::Id id,
-                                   BasicBlock::RpoNumber rpo_number,
-                                   BasicBlock::RpoNumber loop_header,
-                                   BasicBlock::RpoNumber loop_end,
-                                   bool deferred)
+PhiInstruction::PhiInstruction(Zone* zone, int virtual_register,
+                               size_t input_count)
+    : virtual_register_(virtual_register),
+      output_(UnallocatedOperand(UnallocatedOperand::NONE, virtual_register)),
+      operands_(input_count, InstructionOperand::kInvalidVirtualRegister,
+                zone) {}
+
+
+void PhiInstruction::SetInput(size_t offset, int virtual_register) {
+  DCHECK_EQ(InstructionOperand::kInvalidVirtualRegister, operands_[offset]);
+  operands_[offset] = virtual_register;
+}
+
+
+InstructionBlock::InstructionBlock(Zone* zone, RpoNumber rpo_number,
+                                   RpoNumber loop_header, RpoNumber loop_end,
+                                   bool deferred, bool handler)
     : successors_(zone),
       predecessors_(zone),
       phis_(zone),
-      id_(id),
       ao_number_(rpo_number),
       rpo_number_(rpo_number),
       loop_header_(loop_header),
       loop_end_(loop_end),
       code_start_(-1),
       code_end_(-1),
-      deferred_(deferred) {}
+      deferred_(deferred),
+      handler_(handler),
+      needs_frame_(false),
+      must_construct_frame_(false),
+      must_deconstruct_frame_(false),
+      last_deferred_(RpoNumber::Invalid()) {}
 
 
-size_t InstructionBlock::PredecessorIndexOf(
-    BasicBlock::RpoNumber rpo_number) const {
+size_t InstructionBlock::PredecessorIndexOf(RpoNumber rpo_number) const {
   size_t j = 0;
   for (InstructionBlock::Predecessors::const_iterator i = predecessors_.begin();
        i != predecessors_.end(); ++i, ++j) {
@@ -376,33 +567,33 @@
 }
 
 
-static BasicBlock::RpoNumber GetRpo(BasicBlock* block) {
-  if (block == NULL) return BasicBlock::RpoNumber::Invalid();
-  return block->GetRpoNumber();
+static RpoNumber GetRpo(const BasicBlock* block) {
+  if (block == nullptr) return RpoNumber::Invalid();
+  return RpoNumber::FromInt(block->rpo_number());
 }
 
 
-static BasicBlock::RpoNumber GetLoopEndRpo(const BasicBlock* block) {
-  if (!block->IsLoopHeader()) return BasicBlock::RpoNumber::Invalid();
-  return block->loop_end()->GetRpoNumber();
+static RpoNumber GetLoopEndRpo(const BasicBlock* block) {
+  if (!block->IsLoopHeader()) return RpoNumber::Invalid();
+  return RpoNumber::FromInt(block->loop_end()->rpo_number());
 }
 
 
 static InstructionBlock* InstructionBlockFor(Zone* zone,
                                              const BasicBlock* block) {
-  InstructionBlock* instr_block = new (zone) InstructionBlock(
-      zone, block->id(), block->GetRpoNumber(), GetRpo(block->loop_header()),
-      GetLoopEndRpo(block), block->deferred());
+  bool is_handler =
+      !block->empty() && block->front()->opcode() == IrOpcode::kIfException;
+  InstructionBlock* instr_block = new (zone)
+      InstructionBlock(zone, GetRpo(block), GetRpo(block->loop_header()),
+                       GetLoopEndRpo(block), block->deferred(), is_handler);
   // Map successors and precessors
   instr_block->successors().reserve(block->SuccessorCount());
-  for (auto it = block->successors_begin(); it != block->successors_end();
-       ++it) {
-    instr_block->successors().push_back((*it)->GetRpoNumber());
+  for (BasicBlock* successor : block->successors()) {
+    instr_block->successors().push_back(GetRpo(successor));
   }
   instr_block->predecessors().reserve(block->PredecessorCount());
-  for (auto it = block->predecessors_begin(); it != block->predecessors_end();
-       ++it) {
-    instr_block->predecessors().push_back((*it)->GetRpoNumber());
+  for (BasicBlock* predecessor : block->predecessors()) {
+    instr_block->predecessors().push_back(GetRpo(predecessor));
   }
   return instr_block;
 }
@@ -412,12 +603,12 @@
     Zone* zone, const Schedule* schedule) {
   InstructionBlocks* blocks = zone->NewArray<InstructionBlocks>(1);
   new (blocks) InstructionBlocks(
-      static_cast<int>(schedule->rpo_order()->size()), NULL, zone);
+      static_cast<int>(schedule->rpo_order()->size()), nullptr, zone);
   size_t rpo_number = 0;
   for (BasicBlockVector::const_iterator it = schedule->rpo_order()->begin();
        it != schedule->rpo_order()->end(); ++it, ++rpo_number) {
-    DCHECK_EQ(NULL, (*blocks)[rpo_number]);
-    DCHECK((*it)->GetRpoNumber().ToSize() == rpo_number);
+    DCHECK(!(*blocks)[rpo_number]);
+    DCHECK(GetRpo(*it).ToSize() == rpo_number);
     (*blocks)[rpo_number] = InstructionBlockFor(zone, *it);
   }
   ComputeAssemblyOrder(blocks);
@@ -429,86 +620,95 @@
   int ao = 0;
   for (auto const block : *blocks) {
     if (!block->IsDeferred()) {
-      block->set_ao_number(BasicBlock::RpoNumber::FromInt(ao++));
+      block->set_ao_number(RpoNumber::FromInt(ao++));
     }
   }
   for (auto const block : *blocks) {
     if (block->IsDeferred()) {
-      block->set_ao_number(BasicBlock::RpoNumber::FromInt(ao++));
+      block->set_ao_number(RpoNumber::FromInt(ao++));
     }
   }
 }
 
 
-InstructionSequence::InstructionSequence(Zone* instruction_zone,
+InstructionSequence::InstructionSequence(Isolate* isolate,
+                                         Zone* instruction_zone,
                                          InstructionBlocks* instruction_blocks)
-    : zone_(instruction_zone),
+    : isolate_(isolate),
+      zone_(instruction_zone),
       instruction_blocks_(instruction_blocks),
+      source_positions_(zone()),
       block_starts_(zone()),
       constants_(ConstantMap::key_compare(),
                  ConstantMap::allocator_type(zone())),
       immediates_(zone()),
       instructions_(zone()),
       next_virtual_register_(0),
-      pointer_maps_(zone()),
-      doubles_(std::less<int>(), VirtualRegisterSet::allocator_type(zone())),
-      references_(std::less<int>(), VirtualRegisterSet::allocator_type(zone())),
+      reference_maps_(zone()),
+      representations_(zone()),
       deoptimization_entries_(zone()) {
   block_starts_.reserve(instruction_blocks_->size());
 }
 
 
-BlockStartInstruction* InstructionSequence::GetBlockStart(
-    BasicBlock::RpoNumber rpo) const {
-  const InstructionBlock* block = InstructionBlockAt(rpo);
-  return BlockStartInstruction::cast(InstructionAt(block->code_start()));
+int InstructionSequence::NextVirtualRegister() {
+  int virtual_register = next_virtual_register_++;
+  CHECK_NE(virtual_register, InstructionOperand::kInvalidVirtualRegister);
+  return virtual_register;
 }
 
 
-void InstructionSequence::StartBlock(BasicBlock::RpoNumber rpo) {
+Instruction* InstructionSequence::GetBlockStart(RpoNumber rpo) const {
+  const InstructionBlock* block = InstructionBlockAt(rpo);
+  return InstructionAt(block->code_start());
+}
+
+
+void InstructionSequence::StartBlock(RpoNumber rpo) {
   DCHECK(block_starts_.size() == rpo.ToSize());
   InstructionBlock* block = InstructionBlockAt(rpo);
   int code_start = static_cast<int>(instructions_.size());
   block->set_code_start(code_start);
   block_starts_.push_back(code_start);
-  BlockStartInstruction* block_start = BlockStartInstruction::New(zone());
-  AddInstruction(block_start);
 }
 
 
-void InstructionSequence::EndBlock(BasicBlock::RpoNumber rpo) {
+void InstructionSequence::EndBlock(RpoNumber rpo) {
   int end = static_cast<int>(instructions_.size());
   InstructionBlock* block = InstructionBlockAt(rpo);
+  if (block->code_start() == end) {  // Empty block.  Insert a nop.
+    AddInstruction(Instruction::New(zone(), kArchNop));
+    end = static_cast<int>(instructions_.size());
+  }
   DCHECK(block->code_start() >= 0 && block->code_start() < end);
   block->set_code_end(end);
 }
 
 
 int InstructionSequence::AddInstruction(Instruction* instr) {
-  // TODO(titzer): the order of these gaps is a holdover from Lithium.
-  GapInstruction* gap = GapInstruction::New(zone());
-  if (instr->IsControl()) instructions_.push_back(gap);
   int index = static_cast<int>(instructions_.size());
   instructions_.push_back(instr);
-  if (!instr->IsControl()) instructions_.push_back(gap);
-  if (instr->NeedsPointerMap()) {
-    DCHECK(instr->pointer_map() == NULL);
-    PointerMap* pointer_map = new (zone()) PointerMap(zone());
-    pointer_map->set_instruction_position(index);
-    instr->set_pointer_map(pointer_map);
-    pointer_maps_.push_back(pointer_map);
+  if (instr->NeedsReferenceMap()) {
+    DCHECK(instr->reference_map() == nullptr);
+    ReferenceMap* reference_map = new (zone()) ReferenceMap(zone());
+    reference_map->set_instruction_position(index);
+    instr->set_reference_map(reference_map);
+    reference_maps_.push_back(reference_map);
   }
   return index;
 }
 
 
-const InstructionBlock* InstructionSequence::GetInstructionBlock(
+InstructionBlock* InstructionSequence::GetInstructionBlock(
     int instruction_index) const {
   DCHECK(instruction_blocks_->size() == block_starts_.size());
   auto begin = block_starts_.begin();
-  auto end = std::lower_bound(begin, block_starts_.end(), instruction_index,
-                              std::less_equal<int>());
-  size_t index = std::distance(begin, end) - 1;
+  auto end = std::lower_bound(begin, block_starts_.end(), instruction_index);
+  // Post condition of std::lower_bound:
+  DCHECK(end == block_starts_.end() || *end >= instruction_index);
+  if (end == block_starts_.end() || *end > instruction_index) --end;
+  DCHECK(*end <= instruction_index);
+  size_t index = std::distance(begin, end);
   auto block = instruction_blocks_->at(index);
   DCHECK(block->code_start() <= instruction_index &&
          instruction_index < block->code_end());
@@ -516,30 +716,48 @@
 }
 
 
-bool InstructionSequence::IsReference(int virtual_register) const {
-  return references_.find(virtual_register) != references_.end();
+static MachineRepresentation FilterRepresentation(MachineRepresentation rep) {
+  switch (rep) {
+    case MachineRepresentation::kBit:
+    case MachineRepresentation::kWord8:
+    case MachineRepresentation::kWord16:
+      return InstructionSequence::DefaultRepresentation();
+    case MachineRepresentation::kWord32:
+    case MachineRepresentation::kWord64:
+    case MachineRepresentation::kFloat32:
+    case MachineRepresentation::kFloat64:
+    case MachineRepresentation::kTagged:
+      return rep;
+    case MachineRepresentation::kNone:
+      break;
+  }
+  UNREACHABLE();
+  return MachineRepresentation::kNone;
 }
 
 
-bool InstructionSequence::IsDouble(int virtual_register) const {
-  return doubles_.find(virtual_register) != doubles_.end();
+MachineRepresentation InstructionSequence::GetRepresentation(
+    int virtual_register) const {
+  DCHECK_LE(0, virtual_register);
+  DCHECK_LT(virtual_register, VirtualRegisterCount());
+  if (virtual_register >= static_cast<int>(representations_.size())) {
+    return DefaultRepresentation();
+  }
+  return representations_[virtual_register];
 }
 
 
-void InstructionSequence::MarkAsReference(int virtual_register) {
-  references_.insert(virtual_register);
-}
-
-
-void InstructionSequence::MarkAsDouble(int virtual_register) {
-  doubles_.insert(virtual_register);
-}
-
-
-void InstructionSequence::AddGapMove(int index, InstructionOperand* from,
-                                     InstructionOperand* to) {
-  GapAt(index)->GetOrCreateParallelMove(GapInstruction::START, zone())->AddMove(
-      from, to, zone());
+void InstructionSequence::MarkAsRepresentation(MachineRepresentation rep,
+                                               int virtual_register) {
+  DCHECK_LE(0, virtual_register);
+  DCHECK_LT(virtual_register, VirtualRegisterCount());
+  if (virtual_register >= static_cast<int>(representations_.size())) {
+    representations_.resize(VirtualRegisterCount(), DefaultRepresentation());
+  }
+  rep = FilterRepresentation(rep);
+  DCHECK_IMPLIES(representations_[virtual_register] != rep,
+                 representations_[virtual_register] == DefaultRepresentation());
+  representations_[virtual_register] = rep;
 }
 
 
@@ -561,23 +779,66 @@
 }
 
 
+RpoNumber InstructionSequence::InputRpo(Instruction* instr, size_t index) {
+  InstructionOperand* operand = instr->InputAt(index);
+  Constant constant =
+      operand->IsImmediate()
+          ? GetImmediate(ImmediateOperand::cast(operand))
+          : GetConstant(ConstantOperand::cast(operand)->virtual_register());
+  return constant.ToRpoNumber();
+}
+
+
+bool InstructionSequence::GetSourcePosition(const Instruction* instr,
+                                            SourcePosition* result) const {
+  auto it = source_positions_.find(instr);
+  if (it == source_positions_.end()) return false;
+  *result = it->second;
+  return true;
+}
+
+
+void InstructionSequence::SetSourcePosition(const Instruction* instr,
+                                            SourcePosition value) {
+  source_positions_.insert(std::make_pair(instr, value));
+}
+
+
+void InstructionSequence::Print(const RegisterConfiguration* config) const {
+  OFStream os(stdout);
+  PrintableInstructionSequence wrapper;
+  wrapper.register_configuration_ = config;
+  wrapper.sequence_ = this;
+  os << wrapper << std::endl;
+}
+
+
+void InstructionSequence::Print() const {
+  const RegisterConfiguration* config =
+      RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN);
+  Print(config);
+}
+
+
 FrameStateDescriptor::FrameStateDescriptor(
-    Zone* zone, const FrameStateCallInfo& state_info, size_t parameters_count,
-    size_t locals_count, size_t stack_count, FrameStateDescriptor* outer_state)
-    : type_(state_info.type()),
-      bailout_id_(state_info.bailout_id()),
-      frame_state_combine_(state_info.state_combine()),
+    Zone* zone, FrameStateType type, BailoutId bailout_id,
+    OutputFrameStateCombine state_combine, size_t parameters_count,
+    size_t locals_count, size_t stack_count,
+    MaybeHandle<SharedFunctionInfo> shared_info,
+    FrameStateDescriptor* outer_state)
+    : type_(type),
+      bailout_id_(bailout_id),
+      frame_state_combine_(state_combine),
       parameters_count_(parameters_count),
       locals_count_(locals_count),
       stack_count_(stack_count),
-      types_(zone),
-      outer_state_(outer_state),
-      jsfunction_(state_info.jsfunction()) {
-  types_.resize(GetSize(), kMachNone);
-}
+      values_(zone),
+      shared_info_(shared_info),
+      outer_state_(outer_state) {}
+
 
 size_t FrameStateDescriptor::GetSize(OutputFrameStateCombine combine) const {
-  size_t size = parameters_count() + locals_count() + stack_count() +
+  size_t size = 1 + parameters_count() + locals_count() + stack_count() +
                 (HasContext() ? 1 : 0);
   switch (combine.kind()) {
     case OutputFrameStateCombine::kPushOutput:
@@ -592,7 +853,7 @@
 
 size_t FrameStateDescriptor::GetTotalSize() const {
   size_t total_size = 0;
-  for (const FrameStateDescriptor* iter = this; iter != NULL;
+  for (const FrameStateDescriptor* iter = this; iter != nullptr;
        iter = iter->outer_state_) {
     total_size += iter->GetSize();
   }
@@ -602,7 +863,7 @@
 
 size_t FrameStateDescriptor::GetFrameCount() const {
   size_t count = 0;
-  for (const FrameStateDescriptor* iter = this; iter != NULL;
+  for (const FrameStateDescriptor* iter = this; iter != nullptr;
        iter = iter->outer_state_) {
     ++count;
   }
@@ -612,9 +873,9 @@
 
 size_t FrameStateDescriptor::GetJSFrameCount() const {
   size_t count = 0;
-  for (const FrameStateDescriptor* iter = this; iter != NULL;
+  for (const FrameStateDescriptor* iter = this; iter != nullptr;
        iter = iter->outer_state_) {
-    if (iter->type_ == JS_FRAME) {
+    if (FrameStateFunctionInfo::IsJSFunctionType(iter->type_)) {
       ++count;
     }
   }
@@ -622,14 +883,8 @@
 }
 
 
-MachineType FrameStateDescriptor::GetType(size_t index) const {
-  return types_[index];
-}
-
-
-void FrameStateDescriptor::SetType(size_t index, MachineType type) {
-  DCHECK(index < GetSize());
-  types_[index] = type;
+std::ostream& operator<<(std::ostream& os, const RpoNumber& rpo) {
+  return os << rpo.ToSize();
 }
 
 
@@ -646,14 +901,16 @@
     os << "CST#" << i << ": v" << it->first << " = " << it->second << "\n";
   }
   for (int i = 0; i < code.InstructionBlockCount(); i++) {
-    BasicBlock::RpoNumber rpo = BasicBlock::RpoNumber::FromInt(i);
+    RpoNumber rpo = RpoNumber::FromInt(i);
     const InstructionBlock* block = code.InstructionBlockAt(rpo);
     CHECK(block->rpo_number() == rpo);
 
-    os << "RPO#" << block->rpo_number();
+    os << "B" << block->rpo_number();
     os << ": AO#" << block->ao_number();
-    os << ": B" << block->id();
     if (block->IsDeferred()) os << " (deferred)";
+    if (!block->needs_frame()) os << " (no frame)";
+    if (block->must_construct_frame()) os << " (construct frame)";
+    if (block->must_deconstruct_frame()) os << " (deconstruct frame)";
     if (block->IsLoopHeader()) {
       os << " loop blocks: [" << block->rpo_number() << ", "
          << block->loop_end() << ")";
@@ -662,8 +919,7 @@
        << block->code_end() << ")\n  predecessors:";
 
     for (auto pred : block->predecessors()) {
-      const InstructionBlock* pred_block = code.InstructionBlockAt(pred);
-      os << " B" << pred_block->id();
+      os << " B" << pred.ToInt();
     }
     os << "\n";
 
@@ -671,9 +927,8 @@
       PrintableInstructionOperand printable_op = {
           printable.register_configuration_, phi->output()};
       os << "     phi: " << printable_op << " =";
-      for (auto input : phi->inputs()) {
-        printable_op.op_ = input;
-        os << " " << printable_op;
+      for (auto input : phi->operands()) {
+        os << " v" << input;
       }
       os << "\n";
     }
@@ -690,8 +945,7 @@
     }
 
     for (auto succ : block->successors()) {
-      const InstructionBlock* succ_block = code.InstructionBlockAt(succ);
-      os << " B" << succ_block->id();
+      os << " B" << succ.ToInt();
     }
     os << "\n";
   }
diff --git a/src/compiler/instruction.h b/src/compiler/instruction.h
index daa83f2..8a6a0ae 100644
--- a/src/compiler/instruction.h
+++ b/src/compiler/instruction.h
@@ -14,80 +14,133 @@
 #include "src/compiler/frame.h"
 #include "src/compiler/instruction-codes.h"
 #include "src/compiler/opcodes.h"
-#include "src/compiler/register-configuration.h"
-#include "src/compiler/schedule.h"
 #include "src/compiler/source-position.h"
+#include "src/macro-assembler.h"
+#include "src/register-configuration.h"
 #include "src/zone-allocator.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
-// A couple of reserved opcodes are used for internal use.
-const InstructionCode kGapInstruction = -1;
-const InstructionCode kBlockStartInstruction = -2;
-const InstructionCode kSourcePositionInstruction = -3;
+// Forward declarations.
+class Schedule;
 
-#define INSTRUCTION_OPERAND_LIST(V)                                  \
-  V(Constant, CONSTANT, 0)                                           \
-  V(Immediate, IMMEDIATE, 0)                                         \
-  V(StackSlot, STACK_SLOT, 128)                                      \
-  V(DoubleStackSlot, DOUBLE_STACK_SLOT, 128)                         \
-  V(Register, REGISTER, RegisterConfiguration::kMaxGeneralRegisters) \
-  V(DoubleRegister, DOUBLE_REGISTER, RegisterConfiguration::kMaxDoubleRegisters)
 
-class InstructionOperand : public ZoneObject {
+class InstructionOperand {
  public:
-  enum Kind {
-    UNALLOCATED,
-    CONSTANT,
-    IMMEDIATE,
-    STACK_SLOT,
-    DOUBLE_STACK_SLOT,
-    REGISTER,
-    DOUBLE_REGISTER
-  };
+  static const int kInvalidVirtualRegister = -1;
 
-  InstructionOperand(Kind kind, int index) { ConvertTo(kind, index); }
+  // TODO(dcarney): recover bit. INVALID can be represented as UNALLOCATED with
+  // kInvalidVirtualRegister and some DCHECKS.
+  enum Kind { INVALID, UNALLOCATED, CONSTANT, IMMEDIATE, EXPLICIT, ALLOCATED };
+
+  InstructionOperand() : InstructionOperand(INVALID) {}
 
   Kind kind() const { return KindField::decode(value_); }
-  int index() const { return static_cast<int>(value_) >> KindField::kSize; }
-#define INSTRUCTION_OPERAND_PREDICATE(name, type, number) \
+
+#define INSTRUCTION_OPERAND_PREDICATE(name, type) \
   bool Is##name() const { return kind() == type; }
-  INSTRUCTION_OPERAND_LIST(INSTRUCTION_OPERAND_PREDICATE)
-  INSTRUCTION_OPERAND_PREDICATE(Unallocated, UNALLOCATED, 0)
+  INSTRUCTION_OPERAND_PREDICATE(Invalid, INVALID)
+  // UnallocatedOperands are place-holder operands created before register
+  // allocation. They later are assigned registers and become AllocatedOperands.
+  INSTRUCTION_OPERAND_PREDICATE(Unallocated, UNALLOCATED)
+  // Constant operands participate in register allocation. They are allocated to
+  // registers but have a special "spilling" behavior. When a ConstantOperand
+  // value must be rematerialized, it is loaded from an immediate constant
+  // rather from an unspilled slot.
+  INSTRUCTION_OPERAND_PREDICATE(Constant, CONSTANT)
+  // ImmediateOperands do not participate in register allocation and are only
+  // embedded directly in instructions, e.g. small integers and on some
+  // platforms Objects.
+  INSTRUCTION_OPERAND_PREDICATE(Immediate, IMMEDIATE)
+  // ExplicitOperands do not participate in register allocation. They are
+  // created by the instruction selector for direct access to registers and
+  // stack slots, completely bypassing the register allocator. They are never
+  // associated with a virtual register
+  INSTRUCTION_OPERAND_PREDICATE(Explicit, EXPLICIT)
+  // AllocatedOperands are registers or stack slots that are assigned by the
+  // register allocator and are always associated with a virtual register.
+  INSTRUCTION_OPERAND_PREDICATE(Allocated, ALLOCATED)
 #undef INSTRUCTION_OPERAND_PREDICATE
-  bool Equals(const InstructionOperand* other) const {
-    return value_ == other->value_;
+
+  inline bool IsAnyRegister() const;
+  inline bool IsRegister() const;
+  inline bool IsDoubleRegister() const;
+  inline bool IsStackSlot() const;
+  inline bool IsDoubleStackSlot() const;
+
+  template <typename SubKindOperand>
+  static SubKindOperand* New(Zone* zone, const SubKindOperand& op) {
+    void* buffer = zone->New(sizeof(op));
+    return new (buffer) SubKindOperand(op);
   }
 
-  void ConvertTo(Kind kind, int index) {
-    if (kind == REGISTER || kind == DOUBLE_REGISTER) DCHECK(index >= 0);
-    value_ = KindField::encode(kind);
-    value_ |= bit_cast<unsigned>(index << KindField::kSize);
-    DCHECK(this->index() == index);
+  static void ReplaceWith(InstructionOperand* dest,
+                          const InstructionOperand* src) {
+    *dest = *src;
   }
 
-  // Calls SetUpCache()/TearDownCache() for each subclass.
-  static void SetUpCaches();
-  static void TearDownCaches();
+  bool Equals(const InstructionOperand& that) const {
+    return this->value_ == that.value_;
+  }
+
+  bool Compare(const InstructionOperand& that) const {
+    return this->value_ < that.value_;
+  }
+
+  bool EqualsCanonicalized(const InstructionOperand& that) const {
+    return this->GetCanonicalizedValue() == that.GetCanonicalizedValue();
+  }
+
+  bool CompareCanonicalized(const InstructionOperand& that) const {
+    return this->GetCanonicalizedValue() < that.GetCanonicalizedValue();
+  }
+
+  void Print(const RegisterConfiguration* config) const;
+  void Print() const;
 
  protected:
-  typedef BitField64<Kind, 0, 3> KindField;
+  explicit InstructionOperand(Kind kind) : value_(KindField::encode(kind)) {}
+
+  inline uint64_t GetCanonicalizedValue() const;
+
+  class KindField : public BitField64<Kind, 0, 3> {};
 
   uint64_t value_;
 };
 
-typedef ZoneVector<InstructionOperand*> InstructionOperandVector;
+
+typedef ZoneVector<InstructionOperand> InstructionOperandVector;
+
 
 struct PrintableInstructionOperand {
   const RegisterConfiguration* register_configuration_;
-  const InstructionOperand* op_;
+  InstructionOperand op_;
 };
 
+
 std::ostream& operator<<(std::ostream& os,
                          const PrintableInstructionOperand& op);
 
+
+#define INSTRUCTION_OPERAND_CASTS(OperandType, OperandKind)      \
+                                                                 \
+  static OperandType* cast(InstructionOperand* op) {             \
+    DCHECK_EQ(OperandKind, op->kind());                          \
+    return static_cast<OperandType*>(op);                        \
+  }                                                              \
+                                                                 \
+  static const OperandType* cast(const InstructionOperand* op) { \
+    DCHECK_EQ(OperandKind, op->kind());                          \
+    return static_cast<const OperandType*>(op);                  \
+  }                                                              \
+                                                                 \
+  static OperandType cast(const InstructionOperand& op) {        \
+    DCHECK_EQ(OperandKind, op.kind());                           \
+    return *static_cast<const OperandType*>(&op);                \
+  }
+
 class UnallocatedOperand : public InstructionOperand {
  public:
   enum BasicPolicy { FIXED_SLOT, EXTENDED_POLICY };
@@ -98,6 +151,7 @@
     FIXED_REGISTER,
     FIXED_DOUBLE_REGISTER,
     MUST_HAVE_REGISTER,
+    MUST_HAVE_SLOT,
     SAME_AS_FIRST_INPUT
   };
 
@@ -115,96 +169,44 @@
     USED_AT_END
   };
 
-  explicit UnallocatedOperand(ExtendedPolicy policy)
-      : InstructionOperand(UNALLOCATED, 0) {
-    value_ |= VirtualRegisterField::encode(kInvalidVirtualRegister);
+  UnallocatedOperand(ExtendedPolicy policy, int virtual_register)
+      : UnallocatedOperand(virtual_register) {
     value_ |= BasicPolicyField::encode(EXTENDED_POLICY);
     value_ |= ExtendedPolicyField::encode(policy);
     value_ |= LifetimeField::encode(USED_AT_END);
   }
 
-  UnallocatedOperand(BasicPolicy policy, int index)
-      : InstructionOperand(UNALLOCATED, 0) {
+  UnallocatedOperand(BasicPolicy policy, int index, int virtual_register)
+      : UnallocatedOperand(virtual_register) {
     DCHECK(policy == FIXED_SLOT);
-    value_ |= VirtualRegisterField::encode(kInvalidVirtualRegister);
     value_ |= BasicPolicyField::encode(policy);
     value_ |= static_cast<int64_t>(index) << FixedSlotIndexField::kShift;
     DCHECK(this->fixed_slot_index() == index);
   }
 
-  UnallocatedOperand(ExtendedPolicy policy, int index)
-      : InstructionOperand(UNALLOCATED, 0) {
+  UnallocatedOperand(ExtendedPolicy policy, int index, int virtual_register)
+      : UnallocatedOperand(virtual_register) {
     DCHECK(policy == FIXED_REGISTER || policy == FIXED_DOUBLE_REGISTER);
-    value_ |= VirtualRegisterField::encode(kInvalidVirtualRegister);
     value_ |= BasicPolicyField::encode(EXTENDED_POLICY);
     value_ |= ExtendedPolicyField::encode(policy);
     value_ |= LifetimeField::encode(USED_AT_END);
     value_ |= FixedRegisterField::encode(index);
   }
 
-  UnallocatedOperand(ExtendedPolicy policy, Lifetime lifetime)
-      : InstructionOperand(UNALLOCATED, 0) {
-    value_ |= VirtualRegisterField::encode(kInvalidVirtualRegister);
+  UnallocatedOperand(ExtendedPolicy policy, Lifetime lifetime,
+                     int virtual_register)
+      : UnallocatedOperand(virtual_register) {
     value_ |= BasicPolicyField::encode(EXTENDED_POLICY);
     value_ |= ExtendedPolicyField::encode(policy);
     value_ |= LifetimeField::encode(lifetime);
   }
 
-  UnallocatedOperand* CopyUnconstrained(Zone* zone) {
-    UnallocatedOperand* result = new (zone) UnallocatedOperand(ANY);
-    result->set_virtual_register(virtual_register());
-    return result;
+  UnallocatedOperand(int reg_id, int slot_id, int virtual_register)
+      : UnallocatedOperand(FIXED_REGISTER, reg_id, virtual_register) {
+    value_ |= HasSecondaryStorageField::encode(true);
+    value_ |= SecondaryStorageField::encode(slot_id);
   }
 
-  static const UnallocatedOperand* cast(const InstructionOperand* op) {
-    DCHECK(op->IsUnallocated());
-    return static_cast<const UnallocatedOperand*>(op);
-  }
-
-  static UnallocatedOperand* cast(InstructionOperand* op) {
-    DCHECK(op->IsUnallocated());
-    return static_cast<UnallocatedOperand*>(op);
-  }
-
-  // The encoding used for UnallocatedOperand operands depends on the policy
-  // that is
-  // stored within the operand. The FIXED_SLOT policy uses a compact encoding
-  // because it accommodates a larger pay-load.
-  //
-  // For FIXED_SLOT policy:
-  //     +------------------------------------------+
-  //     |       slot_index      |  vreg  | 0 | 001 |
-  //     +------------------------------------------+
-  //
-  // For all other (extended) policies:
-  //     +------------------------------------------+
-  //     |  reg_index  | L | PPP |  vreg  | 1 | 001 |    L ... Lifetime
-  //     +------------------------------------------+    P ... Policy
-  //
-  // The slot index is a signed value which requires us to decode it manually
-  // instead of using the BitField64 utility class.
-
-  // The superclass has a KindField.
-  STATIC_ASSERT(KindField::kSize == 3);
-
-  // BitFields for all unallocated operands.
-  class BasicPolicyField : public BitField64<BasicPolicy, 3, 1> {};
-  class VirtualRegisterField : public BitField64<unsigned, 4, 30> {};
-
-  // BitFields specific to BasicPolicy::FIXED_SLOT.
-  class FixedSlotIndexField : public BitField64<int, 34, 30> {};
-
-  // BitFields specific to BasicPolicy::EXTENDED_POLICY.
-  class ExtendedPolicyField : public BitField64<ExtendedPolicy, 34, 3> {};
-  class LifetimeField : public BitField64<Lifetime, 37, 1> {};
-  class FixedRegisterField : public BitField64<int, 38, 6> {};
-
-  static const int kInvalidVirtualRegister = VirtualRegisterField::kMax;
-  static const int kMaxVirtualRegisters = VirtualRegisterField::kMax;
-  static const int kFixedSlotIndexWidth = FixedSlotIndexField::kSize;
-  static const int kMaxFixedSlotIndex = (1 << (kFixedSlotIndexWidth - 1)) - 1;
-  static const int kMinFixedSlotIndex = -(1 << (kFixedSlotIndexWidth - 1));
-
   // Predicates for the operand policy.
   bool HasAnyPolicy() const {
     return basic_policy() == EXTENDED_POLICY && extended_policy() == ANY;
@@ -218,6 +220,10 @@
     return basic_policy() == EXTENDED_POLICY &&
            extended_policy() == MUST_HAVE_REGISTER;
   }
+  bool HasSlotPolicy() const {
+    return basic_policy() == EXTENDED_POLICY &&
+           extended_policy() == MUST_HAVE_SLOT;
+  }
   bool HasSameAsInputPolicy() const {
     return basic_policy() == EXTENDED_POLICY &&
            extended_policy() == SAME_AS_FIRST_INPUT;
@@ -231,9 +237,21 @@
     return basic_policy() == EXTENDED_POLICY &&
            extended_policy() == FIXED_DOUBLE_REGISTER;
   }
+  bool HasSecondaryStorage() const {
+    return basic_policy() == EXTENDED_POLICY &&
+           extended_policy() == FIXED_REGISTER &&
+           HasSecondaryStorageField::decode(value_);
+  }
+  int GetSecondaryStorage() const {
+    DCHECK(HasSecondaryStorage());
+    return SecondaryStorageField::decode(value_);
+  }
 
   // [basic_policy]: Distinguish between FIXED_SLOT and all other policies.
-  BasicPolicy basic_policy() const { return BasicPolicyField::decode(value_); }
+  BasicPolicy basic_policy() const {
+    DCHECK_EQ(UNALLOCATED, kind());
+    return BasicPolicyField::decode(value_);
+  }
 
   // [extended_policy]: Only for non-FIXED_SLOT. The finer-grained policy.
   ExtendedPolicy extended_policy() const {
@@ -244,7 +262,7 @@
   // [fixed_slot_index]: Only for FIXED_SLOT.
   int fixed_slot_index() const {
     DCHECK(HasFixedSlotPolicy());
-    return static_cast<int>(bit_cast<int64_t>(value_) >>
+    return static_cast<int>(static_cast<int64_t>(value_) >>
                             FixedSlotIndexField::kShift);
   }
 
@@ -255,9 +273,15 @@
   }
 
   // [virtual_register]: The virtual register ID for this operand.
-  int virtual_register() const { return VirtualRegisterField::decode(value_); }
-  void set_virtual_register(unsigned id) {
-    value_ = VirtualRegisterField::update(value_, id);
+  int32_t virtual_register() const {
+    DCHECK_EQ(UNALLOCATED, kind());
+    return static_cast<int32_t>(VirtualRegisterField::decode(value_));
+  }
+
+  // TODO(dcarney): remove this.
+  void set_virtual_register(int32_t id) {
+    DCHECK_EQ(UNALLOCATED, kind());
+    value_ = VirtualRegisterField::update(value_, static_cast<uint32_t>(id));
   }
 
   // [lifetime]: Only for non-FIXED_SLOT.
@@ -265,46 +289,330 @@
     DCHECK(basic_policy() == EXTENDED_POLICY);
     return LifetimeField::decode(value_) == USED_AT_START;
   }
+
+  INSTRUCTION_OPERAND_CASTS(UnallocatedOperand, UNALLOCATED);
+
+  // The encoding used for UnallocatedOperand operands depends on the policy
+  // that is
+  // stored within the operand. The FIXED_SLOT policy uses a compact encoding
+  // because it accommodates a larger pay-load.
+  //
+  // For FIXED_SLOT policy:
+  //     +------------------------------------------------+
+  //     |      slot_index   | 0 | virtual_register | 001 |
+  //     +------------------------------------------------+
+  //
+  // For all other (extended) policies:
+  //     +-----------------------------------------------------+
+  //     |  reg_index  | L | PPP |  1 | virtual_register | 001 |
+  //     +-----------------------------------------------------+
+  //     L ... Lifetime
+  //     P ... Policy
+  //
+  // The slot index is a signed value which requires us to decode it manually
+  // instead of using the BitField utility class.
+
+  STATIC_ASSERT(KindField::kSize == 3);
+
+  class VirtualRegisterField : public BitField64<uint32_t, 3, 32> {};
+
+  // BitFields for all unallocated operands.
+  class BasicPolicyField : public BitField64<BasicPolicy, 35, 1> {};
+
+  // BitFields specific to BasicPolicy::FIXED_SLOT.
+  class FixedSlotIndexField : public BitField64<int, 36, 28> {};
+
+  // BitFields specific to BasicPolicy::EXTENDED_POLICY.
+  class ExtendedPolicyField : public BitField64<ExtendedPolicy, 36, 3> {};
+  class LifetimeField : public BitField64<Lifetime, 39, 1> {};
+  class HasSecondaryStorageField : public BitField64<bool, 40, 1> {};
+  class FixedRegisterField : public BitField64<int, 41, 6> {};
+  class SecondaryStorageField : public BitField64<int, 47, 3> {};
+
+ private:
+  explicit UnallocatedOperand(int virtual_register)
+      : InstructionOperand(UNALLOCATED) {
+    value_ |=
+        VirtualRegisterField::encode(static_cast<uint32_t>(virtual_register));
+  }
 };
 
 
-class MoveOperands FINAL {
+class ConstantOperand : public InstructionOperand {
  public:
-  MoveOperands(InstructionOperand* source, InstructionOperand* destination)
-      : source_(source), destination_(destination) {}
+  explicit ConstantOperand(int virtual_register)
+      : InstructionOperand(CONSTANT) {
+    value_ |=
+        VirtualRegisterField::encode(static_cast<uint32_t>(virtual_register));
+  }
 
-  InstructionOperand* source() const { return source_; }
-  void set_source(InstructionOperand* operand) { source_ = operand; }
+  int32_t virtual_register() const {
+    return static_cast<int32_t>(VirtualRegisterField::decode(value_));
+  }
 
-  InstructionOperand* destination() const { return destination_; }
-  void set_destination(InstructionOperand* operand) { destination_ = operand; }
+  static ConstantOperand* New(Zone* zone, int virtual_register) {
+    return InstructionOperand::New(zone, ConstantOperand(virtual_register));
+  }
+
+  INSTRUCTION_OPERAND_CASTS(ConstantOperand, CONSTANT);
+
+  STATIC_ASSERT(KindField::kSize == 3);
+  class VirtualRegisterField : public BitField64<uint32_t, 3, 32> {};
+};
+
+
+class ImmediateOperand : public InstructionOperand {
+ public:
+  enum ImmediateType { INLINE, INDEXED };
+
+  explicit ImmediateOperand(ImmediateType type, int32_t value)
+      : InstructionOperand(IMMEDIATE) {
+    value_ |= TypeField::encode(type);
+    value_ |= static_cast<int64_t>(value) << ValueField::kShift;
+  }
+
+  ImmediateType type() const { return TypeField::decode(value_); }
+
+  int32_t inline_value() const {
+    DCHECK_EQ(INLINE, type());
+    return static_cast<int64_t>(value_) >> ValueField::kShift;
+  }
+
+  int32_t indexed_value() const {
+    DCHECK_EQ(INDEXED, type());
+    return static_cast<int64_t>(value_) >> ValueField::kShift;
+  }
+
+  static ImmediateOperand* New(Zone* zone, ImmediateType type, int32_t value) {
+    return InstructionOperand::New(zone, ImmediateOperand(type, value));
+  }
+
+  INSTRUCTION_OPERAND_CASTS(ImmediateOperand, IMMEDIATE);
+
+  STATIC_ASSERT(KindField::kSize == 3);
+  class TypeField : public BitField64<ImmediateType, 3, 1> {};
+  class ValueField : public BitField64<int32_t, 32, 32> {};
+};
+
+
+class LocationOperand : public InstructionOperand {
+ public:
+  enum LocationKind { REGISTER, STACK_SLOT };
+
+  LocationOperand(InstructionOperand::Kind operand_kind,
+                  LocationOperand::LocationKind location_kind,
+                  MachineRepresentation rep, int index)
+      : InstructionOperand(operand_kind) {
+    DCHECK_IMPLIES(location_kind == REGISTER, index >= 0);
+    DCHECK(IsSupportedRepresentation(rep));
+    value_ |= LocationKindField::encode(location_kind);
+    value_ |= RepresentationField::encode(rep);
+    value_ |= static_cast<int64_t>(index) << IndexField::kShift;
+  }
+
+  int index() const {
+    DCHECK(IsStackSlot() || IsDoubleStackSlot());
+    return static_cast<int64_t>(value_) >> IndexField::kShift;
+  }
+
+  Register GetRegister() const {
+    DCHECK(IsRegister());
+    return Register::from_code(static_cast<int64_t>(value_) >>
+                               IndexField::kShift);
+  }
+
+  DoubleRegister GetDoubleRegister() const {
+    DCHECK(IsDoubleRegister());
+    return DoubleRegister::from_code(static_cast<int64_t>(value_) >>
+                                     IndexField::kShift);
+  }
+
+  LocationKind location_kind() const {
+    return LocationKindField::decode(value_);
+  }
+
+  MachineRepresentation representation() const {
+    return RepresentationField::decode(value_);
+  }
+
+  static bool IsSupportedRepresentation(MachineRepresentation rep) {
+    switch (rep) {
+      case MachineRepresentation::kWord32:
+      case MachineRepresentation::kWord64:
+      case MachineRepresentation::kFloat32:
+      case MachineRepresentation::kFloat64:
+      case MachineRepresentation::kTagged:
+        return true;
+      case MachineRepresentation::kBit:
+      case MachineRepresentation::kWord8:
+      case MachineRepresentation::kWord16:
+      case MachineRepresentation::kNone:
+        return false;
+    }
+    UNREACHABLE();
+    return false;
+  }
+
+  static LocationOperand* cast(InstructionOperand* op) {
+    DCHECK(ALLOCATED == op->kind() || EXPLICIT == op->kind());
+    return static_cast<LocationOperand*>(op);
+  }
+
+  static const LocationOperand* cast(const InstructionOperand* op) {
+    DCHECK(ALLOCATED == op->kind() || EXPLICIT == op->kind());
+    return static_cast<const LocationOperand*>(op);
+  }
+
+  static LocationOperand cast(const InstructionOperand& op) {
+    DCHECK(ALLOCATED == op.kind() || EXPLICIT == op.kind());
+    return *static_cast<const LocationOperand*>(&op);
+  }
+
+  STATIC_ASSERT(KindField::kSize == 3);
+  class LocationKindField : public BitField64<LocationKind, 3, 2> {};
+  class RepresentationField : public BitField64<MachineRepresentation, 5, 8> {};
+  class IndexField : public BitField64<int32_t, 35, 29> {};
+};
+
+
+class ExplicitOperand : public LocationOperand {
+ public:
+  ExplicitOperand(LocationKind kind, MachineRepresentation rep, int index);
+
+  static ExplicitOperand* New(Zone* zone, LocationKind kind,
+                              MachineRepresentation rep, int index) {
+    return InstructionOperand::New(zone, ExplicitOperand(kind, rep, index));
+  }
+
+  INSTRUCTION_OPERAND_CASTS(ExplicitOperand, EXPLICIT);
+};
+
+
+class AllocatedOperand : public LocationOperand {
+ public:
+  AllocatedOperand(LocationKind kind, MachineRepresentation rep, int index)
+      : LocationOperand(ALLOCATED, kind, rep, index) {}
+
+  static AllocatedOperand* New(Zone* zone, LocationKind kind,
+                               MachineRepresentation rep, int index) {
+    return InstructionOperand::New(zone, AllocatedOperand(kind, rep, index));
+  }
+
+  INSTRUCTION_OPERAND_CASTS(AllocatedOperand, ALLOCATED);
+};
+
+
+#undef INSTRUCTION_OPERAND_CASTS
+
+
+bool InstructionOperand::IsAnyRegister() const {
+  return (IsAllocated() || IsExplicit()) &&
+         LocationOperand::cast(this)->location_kind() ==
+             LocationOperand::REGISTER;
+}
+
+
+bool InstructionOperand::IsRegister() const {
+  return IsAnyRegister() &&
+         !IsFloatingPoint(LocationOperand::cast(this)->representation());
+}
+
+bool InstructionOperand::IsDoubleRegister() const {
+  return IsAnyRegister() &&
+         IsFloatingPoint(LocationOperand::cast(this)->representation());
+}
+
+bool InstructionOperand::IsStackSlot() const {
+  return (IsAllocated() || IsExplicit()) &&
+         LocationOperand::cast(this)->location_kind() ==
+             LocationOperand::STACK_SLOT &&
+         !IsFloatingPoint(LocationOperand::cast(this)->representation());
+}
+
+bool InstructionOperand::IsDoubleStackSlot() const {
+  return (IsAllocated() || IsExplicit()) &&
+         LocationOperand::cast(this)->location_kind() ==
+             LocationOperand::STACK_SLOT &&
+         IsFloatingPoint(LocationOperand::cast(this)->representation());
+}
+
+uint64_t InstructionOperand::GetCanonicalizedValue() const {
+  if (IsAllocated() || IsExplicit()) {
+    // TODO(dcarney): put machine type last and mask.
+    MachineRepresentation canonicalized_representation =
+        IsFloatingPoint(LocationOperand::cast(this)->representation())
+            ? MachineRepresentation::kFloat64
+            : MachineRepresentation::kNone;
+    return InstructionOperand::KindField::update(
+        LocationOperand::RepresentationField::update(
+            this->value_, canonicalized_representation),
+        LocationOperand::EXPLICIT);
+  }
+  return this->value_;
+}
+
+
+// Required for maps that don't care about machine type.
+struct CompareOperandModuloType {
+  bool operator()(const InstructionOperand& a,
+                  const InstructionOperand& b) const {
+    return a.CompareCanonicalized(b);
+  }
+};
+
+
+class MoveOperands final : public ZoneObject {
+ public:
+  MoveOperands(const InstructionOperand& source,
+               const InstructionOperand& destination)
+      : source_(source), destination_(destination) {
+    DCHECK(!source.IsInvalid() && !destination.IsInvalid());
+  }
+
+  const InstructionOperand& source() const { return source_; }
+  InstructionOperand& source() { return source_; }
+  void set_source(const InstructionOperand& operand) { source_ = operand; }
+
+  const InstructionOperand& destination() const { return destination_; }
+  InstructionOperand& destination() { return destination_; }
+  void set_destination(const InstructionOperand& operand) {
+    destination_ = operand;
+  }
 
   // The gap resolver marks moves as "in-progress" by clearing the
   // destination (but not the source).
-  bool IsPending() const { return destination_ == NULL && source_ != NULL; }
+  bool IsPending() const {
+    return destination_.IsInvalid() && !source_.IsInvalid();
+  }
+  void SetPending() { destination_ = InstructionOperand(); }
 
   // True if this move a move into the given destination operand.
-  bool Blocks(InstructionOperand* operand) const {
-    return !IsEliminated() && source()->Equals(operand);
+  bool Blocks(const InstructionOperand& operand) const {
+    return !IsEliminated() && source().EqualsCanonicalized(operand);
   }
 
-  // A move is redundant if it's been eliminated, if its source and
-  // destination are the same, or if its destination is  constant.
+  // A move is redundant if it's been eliminated or if its source and
+  // destination are the same.
   bool IsRedundant() const {
-    return IsEliminated() || source_->Equals(destination_) ||
-           (destination_ != NULL && destination_->IsConstant());
+    DCHECK_IMPLIES(!destination_.IsInvalid(), !destination_.IsConstant());
+    return IsEliminated() || source_.EqualsCanonicalized(destination_);
   }
 
   // We clear both operands to indicate move that's been eliminated.
-  void Eliminate() { source_ = destination_ = NULL; }
+  void Eliminate() { source_ = destination_ = InstructionOperand(); }
   bool IsEliminated() const {
-    DCHECK(source_ != NULL || destination_ == NULL);
-    return source_ == NULL;
+    DCHECK_IMPLIES(source_.IsInvalid(), destination_.IsInvalid());
+    return source_.IsInvalid();
   }
 
+  void Print(const RegisterConfiguration* config) const;
+  void Print() const;
+
  private:
-  InstructionOperand* source_;
-  InstructionOperand* destination_;
+  InstructionOperand source_;
+  InstructionOperand destination_;
+
+  DISALLOW_COPY_AND_ASSIGN(MoveOperands);
 };
 
 
@@ -317,60 +625,29 @@
 std::ostream& operator<<(std::ostream& os, const PrintableMoveOperands& mo);
 
 
-template <InstructionOperand::Kind kOperandKind, int kNumCachedOperands>
-class SubKindOperand FINAL : public InstructionOperand {
+class ParallelMove final : public ZoneVector<MoveOperands*>, public ZoneObject {
  public:
-  static SubKindOperand* Create(int index, Zone* zone) {
-    DCHECK(index >= 0);
-    if (index < kNumCachedOperands) return &cache[index];
-    return new (zone) SubKindOperand(index);
+  explicit ParallelMove(Zone* zone) : ZoneVector<MoveOperands*>(zone) {
+    reserve(4);
   }
 
-  static SubKindOperand* cast(InstructionOperand* op) {
-    DCHECK(op->kind() == kOperandKind);
-    return reinterpret_cast<SubKindOperand*>(op);
-  }
-
-  static const SubKindOperand* cast(const InstructionOperand* op) {
-    DCHECK(op->kind() == kOperandKind);
-    return reinterpret_cast<const SubKindOperand*>(op);
-  }
-
-  static void SetUpCache();
-  static void TearDownCache();
-
- private:
-  static SubKindOperand* cache;
-
-  SubKindOperand() : InstructionOperand(kOperandKind, 0) {}  // For the caches.
-  explicit SubKindOperand(int index)
-      : InstructionOperand(kOperandKind, index) {}
-};
-
-
-#define INSTRUCTION_TYPEDEF_SUBKIND_OPERAND_CLASS(name, type, number) \
-  typedef SubKindOperand<InstructionOperand::type, number> name##Operand;
-INSTRUCTION_OPERAND_LIST(INSTRUCTION_TYPEDEF_SUBKIND_OPERAND_CLASS)
-#undef INSTRUCTION_TYPEDEF_SUBKIND_OPERAND_CLASS
-
-
-class ParallelMove FINAL : public ZoneObject {
- public:
-  explicit ParallelMove(Zone* zone) : move_operands_(4, zone) {}
-
-  void AddMove(InstructionOperand* from, InstructionOperand* to, Zone* zone) {
-    move_operands_.Add(MoveOperands(from, to), zone);
+  MoveOperands* AddMove(const InstructionOperand& from,
+                        const InstructionOperand& to) {
+    auto zone = get_allocator().zone();
+    auto move = new (zone) MoveOperands(from, to);
+    push_back(move);
+    return move;
   }
 
   bool IsRedundant() const;
 
-  ZoneList<MoveOperands>* move_operands() { return &move_operands_; }
-  const ZoneList<MoveOperands>* move_operands() const {
-    return &move_operands_;
-  }
+  // Prepare this ParallelMove to insert move as if it happened in a subsequent
+  // ParallelMove.  move->source() may be changed.  The MoveOperand returned
+  // must be Eliminated.
+  MoveOperands* PrepareInsertAfter(MoveOperands* move) const;
 
  private:
-  ZoneList<MoveOperands> move_operands_;
+  DISALLOW_COPY_AND_ASSIGN(ParallelMove);
 };
 
 
@@ -383,19 +660,13 @@
 std::ostream& operator<<(std::ostream& os, const PrintableParallelMove& pm);
 
 
-class PointerMap FINAL : public ZoneObject {
+class ReferenceMap final : public ZoneObject {
  public:
-  explicit PointerMap(Zone* zone)
-      : pointer_operands_(8, zone),
-        untagged_operands_(0, zone),
-        instruction_position_(-1) {}
+  explicit ReferenceMap(Zone* zone)
+      : reference_operands_(8, zone), instruction_position_(-1) {}
 
-  const ZoneList<InstructionOperand*>* GetNormalizedOperands() {
-    for (int i = 0; i < untagged_operands_.length(); ++i) {
-      RemovePointer(untagged_operands_[i]);
-    }
-    untagged_operands_.Clear();
-    return &pointer_operands_;
+  const ZoneVector<InstructionOperand>& reference_operands() const {
+    return reference_operands_;
   }
   int instruction_position() const { return instruction_position_; }
 
@@ -404,46 +675,51 @@
     instruction_position_ = pos;
   }
 
-  void RecordPointer(InstructionOperand* op, Zone* zone);
-  void RemovePointer(InstructionOperand* op);
-  void RecordUntagged(InstructionOperand* op, Zone* zone);
+  void RecordReference(const AllocatedOperand& op);
 
  private:
-  friend std::ostream& operator<<(std::ostream& os, const PointerMap& pm);
+  friend std::ostream& operator<<(std::ostream& os, const ReferenceMap& pm);
 
-  ZoneList<InstructionOperand*> pointer_operands_;
-  ZoneList<InstructionOperand*> untagged_operands_;
+  ZoneVector<InstructionOperand> reference_operands_;
   int instruction_position_;
 };
 
-std::ostream& operator<<(std::ostream& os, const PointerMap& pm);
+std::ostream& operator<<(std::ostream& os, const ReferenceMap& pm);
 
-// TODO(titzer): s/PointerMap/ReferenceMap/
-class Instruction : public ZoneObject {
+class Instruction final {
  public:
   size_t OutputCount() const { return OutputCountField::decode(bit_field_); }
-  InstructionOperand* OutputAt(size_t i) const {
+  const InstructionOperand* OutputAt(size_t i) const {
     DCHECK(i < OutputCount());
-    return operands_[i];
+    return &operands_[i];
+  }
+  InstructionOperand* OutputAt(size_t i) {
+    DCHECK(i < OutputCount());
+    return &operands_[i];
   }
 
   bool HasOutput() const { return OutputCount() == 1; }
-  InstructionOperand* Output() const { return OutputAt(0); }
+  const InstructionOperand* Output() const { return OutputAt(0); }
+  InstructionOperand* Output() { return OutputAt(0); }
 
   size_t InputCount() const { return InputCountField::decode(bit_field_); }
-  InstructionOperand* InputAt(size_t i) const {
+  const InstructionOperand* InputAt(size_t i) const {
     DCHECK(i < InputCount());
-    return operands_[OutputCount() + i];
+    return &operands_[OutputCount() + i];
   }
-  void SetInputAt(size_t i, InstructionOperand* operand) {
+  InstructionOperand* InputAt(size_t i) {
     DCHECK(i < InputCount());
-    operands_[OutputCount() + i] = operand;
+    return &operands_[OutputCount() + i];
   }
 
   size_t TempCount() const { return TempCountField::decode(bit_field_); }
-  InstructionOperand* TempAt(size_t i) const {
+  const InstructionOperand* TempAt(size_t i) const {
     DCHECK(i < TempCount());
-    return operands_[OutputCount() + InputCount() + i];
+    return &operands_[OutputCount() + InputCount() + i];
+  }
+  InstructionOperand* TempAt(size_t i) {
+    DCHECK(i < TempCount());
+    return &operands_[OutputCount() + InputCount() + i];
   }
 
   InstructionCode opcode() const { return opcode_; }
@@ -456,72 +732,51 @@
     return FlagsConditionField::decode(opcode());
   }
 
-  // TODO(titzer): make control and call into flags.
+  // TODO(titzer): make call into a flags.
   static Instruction* New(Zone* zone, InstructionCode opcode) {
-    return New(zone, opcode, 0, NULL, 0, NULL, 0, NULL);
+    return New(zone, opcode, 0, nullptr, 0, nullptr, 0, nullptr);
   }
 
   static Instruction* New(Zone* zone, InstructionCode opcode,
-                          size_t output_count, InstructionOperand** outputs,
-                          size_t input_count, InstructionOperand** inputs,
-                          size_t temp_count, InstructionOperand** temps) {
+                          size_t output_count, InstructionOperand* outputs,
+                          size_t input_count, InstructionOperand* inputs,
+                          size_t temp_count, InstructionOperand* temps) {
     DCHECK(opcode >= 0);
-    DCHECK(output_count == 0 || outputs != NULL);
-    DCHECK(input_count == 0 || inputs != NULL);
-    DCHECK(temp_count == 0 || temps != NULL);
-    InstructionOperand* none = NULL;
-    USE(none);
-    int size = static_cast<int>(RoundUp(sizeof(Instruction), kPointerSize) +
-                                (output_count + input_count + temp_count - 1) *
-                                    sizeof(none));
+    DCHECK(output_count == 0 || outputs != nullptr);
+    DCHECK(input_count == 0 || inputs != nullptr);
+    DCHECK(temp_count == 0 || temps != nullptr);
+    size_t total_extra_ops = output_count + input_count + temp_count;
+    if (total_extra_ops != 0) total_extra_ops--;
+    int size = static_cast<int>(
+        RoundUp(sizeof(Instruction), sizeof(InstructionOperand)) +
+        total_extra_ops * sizeof(InstructionOperand));
     return new (zone->New(size)) Instruction(
         opcode, output_count, outputs, input_count, inputs, temp_count, temps);
   }
 
-  // TODO(titzer): another holdover from lithium days; register allocator
-  // should not need to know about control instructions.
-  Instruction* MarkAsControl() {
-    bit_field_ = IsControlField::update(bit_field_, true);
-    return this;
-  }
   Instruction* MarkAsCall() {
     bit_field_ = IsCallField::update(bit_field_, true);
     return this;
   }
-  bool IsControl() const { return IsControlField::decode(bit_field_); }
   bool IsCall() const { return IsCallField::decode(bit_field_); }
-  bool NeedsPointerMap() const { return IsCall(); }
-  bool HasPointerMap() const { return pointer_map_ != NULL; }
-
-  bool IsGapMoves() const {
-    return opcode() == kGapInstruction || opcode() == kBlockStartInstruction;
-  }
-  bool IsBlockStart() const { return opcode() == kBlockStartInstruction; }
-  bool IsSourcePosition() const {
-    return opcode() == kSourcePositionInstruction;
-  }
+  bool NeedsReferenceMap() const { return IsCall(); }
+  bool HasReferenceMap() const { return reference_map_ != nullptr; }
 
   bool ClobbersRegisters() const { return IsCall(); }
   bool ClobbersTemps() const { return IsCall(); }
   bool ClobbersDoubleRegisters() const { return IsCall(); }
-  PointerMap* pointer_map() const { return pointer_map_; }
+  ReferenceMap* reference_map() const { return reference_map_; }
 
-  void set_pointer_map(PointerMap* map) {
-    DCHECK(NeedsPointerMap());
-    DCHECK_EQ(NULL, pointer_map_);
-    pointer_map_ = map;
+  void set_reference_map(ReferenceMap* map) {
+    DCHECK(NeedsReferenceMap());
+    DCHECK(!reference_map_);
+    reference_map_ = map;
   }
 
-  // Placement new operator so that we can smash instructions into
-  // zone-allocated memory.
-  void* operator new(size_t, void* location) { return location; }
-
-  void operator delete(void* pointer, void* location) { UNREACHABLE(); }
-
   void OverwriteWithNop() {
     opcode_ = ArchOpcodeField::encode(kArchNop);
     bit_field_ = 0;
-    pointer_map_ = NULL;
+    reference_map_ = nullptr;
   }
 
   bool IsNop() const {
@@ -529,46 +784,56 @@
            OutputCount() == 0 && TempCount() == 0;
   }
 
- protected:
-  explicit Instruction(InstructionCode opcode)
-      : opcode_(opcode),
-        bit_field_(OutputCountField::encode(0) | InputCountField::encode(0) |
-                   TempCountField::encode(0) | IsCallField::encode(false) |
-                   IsControlField::encode(false)),
-        pointer_map_(NULL) {}
+  enum GapPosition {
+    START,
+    END,
+    FIRST_GAP_POSITION = START,
+    LAST_GAP_POSITION = END
+  };
 
-  Instruction(InstructionCode opcode, size_t output_count,
-              InstructionOperand** outputs, size_t input_count,
-              InstructionOperand** inputs, size_t temp_count,
-              InstructionOperand** temps)
-      : opcode_(opcode),
-        bit_field_(OutputCountField::encode(output_count) |
-                   InputCountField::encode(input_count) |
-                   TempCountField::encode(temp_count) |
-                   IsCallField::encode(false) | IsControlField::encode(false)),
-        pointer_map_(NULL) {
-    for (size_t i = 0; i < output_count; ++i) {
-      operands_[i] = outputs[i];
+  ParallelMove* GetOrCreateParallelMove(GapPosition pos, Zone* zone) {
+    if (parallel_moves_[pos] == nullptr) {
+      parallel_moves_[pos] = new (zone) ParallelMove(zone);
     }
-    for (size_t i = 0; i < input_count; ++i) {
-      operands_[output_count + i] = inputs[i];
-    }
-    for (size_t i = 0; i < temp_count; ++i) {
-      operands_[output_count + input_count + i] = temps[i];
-    }
+    return parallel_moves_[pos];
   }
 
- protected:
+  ParallelMove* GetParallelMove(GapPosition pos) {
+    return parallel_moves_[pos];
+  }
+
+  const ParallelMove* GetParallelMove(GapPosition pos) const {
+    return parallel_moves_[pos];
+  }
+
+  bool AreMovesRedundant() const;
+
+  ParallelMove* const* parallel_moves() const { return &parallel_moves_[0]; }
+  ParallelMove** parallel_moves() { return &parallel_moves_[0]; }
+
+  void Print(const RegisterConfiguration* config) const;
+  void Print() const;
+
+ private:
+  explicit Instruction(InstructionCode opcode);
+
+  Instruction(InstructionCode opcode, size_t output_count,
+              InstructionOperand* outputs, size_t input_count,
+              InstructionOperand* inputs, size_t temp_count,
+              InstructionOperand* temps);
+
   typedef BitField<size_t, 0, 8> OutputCountField;
   typedef BitField<size_t, 8, 16> InputCountField;
   typedef BitField<size_t, 24, 6> TempCountField;
   typedef BitField<bool, 30, 1> IsCallField;
-  typedef BitField<bool, 31, 1> IsControlField;
 
   InstructionCode opcode_;
   uint32_t bit_field_;
-  PointerMap* pointer_map_;
-  InstructionOperand* operands_[1];
+  ParallelMove* parallel_moves_[2];
+  ReferenceMap* reference_map_;
+  InstructionOperand operands_[1];
+
+  DISALLOW_COPY_AND_ASSIGN(Instruction);
 };
 
 
@@ -579,125 +844,44 @@
 std::ostream& operator<<(std::ostream& os, const PrintableInstruction& instr);
 
 
-// Represents moves inserted before an instruction due to register allocation.
-// TODO(titzer): squash GapInstruction back into Instruction, since essentially
-// every instruction can possibly have moves inserted before it.
-class GapInstruction : public Instruction {
+class RpoNumber final {
  public:
-  enum InnerPosition {
-    BEFORE,
-    START,
-    END,
-    AFTER,
-    FIRST_INNER_POSITION = BEFORE,
-    LAST_INNER_POSITION = AFTER
-  };
+  static const int kInvalidRpoNumber = -1;
+  int ToInt() const {
+    DCHECK(IsValid());
+    return index_;
+  }
+  size_t ToSize() const {
+    DCHECK(IsValid());
+    return static_cast<size_t>(index_);
+  }
+  bool IsValid() const { return index_ >= 0; }
+  static RpoNumber FromInt(int index) { return RpoNumber(index); }
+  static RpoNumber Invalid() { return RpoNumber(kInvalidRpoNumber); }
 
-  ParallelMove* GetOrCreateParallelMove(InnerPosition pos, Zone* zone) {
-    if (parallel_moves_[pos] == NULL) {
-      parallel_moves_[pos] = new (zone) ParallelMove(zone);
-    }
-    return parallel_moves_[pos];
+  bool IsNext(const RpoNumber other) const {
+    DCHECK(IsValid());
+    return other.index_ == this->index_ + 1;
   }
 
-  ParallelMove* GetParallelMove(InnerPosition pos) {
-    return parallel_moves_[pos];
-  }
-
-  const ParallelMove* GetParallelMove(InnerPosition pos) const {
-    return parallel_moves_[pos];
-  }
-
-  bool IsRedundant() const;
-
-  ParallelMove** parallel_moves() { return parallel_moves_; }
-
-  static GapInstruction* New(Zone* zone) {
-    void* buffer = zone->New(sizeof(GapInstruction));
-    return new (buffer) GapInstruction(kGapInstruction);
-  }
-
-  static GapInstruction* cast(Instruction* instr) {
-    DCHECK(instr->IsGapMoves());
-    return static_cast<GapInstruction*>(instr);
-  }
-
-  static const GapInstruction* cast(const Instruction* instr) {
-    DCHECK(instr->IsGapMoves());
-    return static_cast<const GapInstruction*>(instr);
-  }
-
- protected:
-  explicit GapInstruction(InstructionCode opcode) : Instruction(opcode) {
-    parallel_moves_[BEFORE] = NULL;
-    parallel_moves_[START] = NULL;
-    parallel_moves_[END] = NULL;
-    parallel_moves_[AFTER] = NULL;
-  }
+  // Comparison operators.
+  bool operator==(RpoNumber other) const { return index_ == other.index_; }
+  bool operator!=(RpoNumber other) const { return index_ != other.index_; }
+  bool operator>(RpoNumber other) const { return index_ > other.index_; }
+  bool operator<(RpoNumber other) const { return index_ < other.index_; }
+  bool operator<=(RpoNumber other) const { return index_ <= other.index_; }
+  bool operator>=(RpoNumber other) const { return index_ >= other.index_; }
 
  private:
-  friend std::ostream& operator<<(std::ostream& os,
-                                  const PrintableInstruction& instr);
-  ParallelMove* parallel_moves_[LAST_INNER_POSITION + 1];
+  explicit RpoNumber(int32_t index) : index_(index) {}
+  int32_t index_;
 };
 
 
-// This special kind of gap move instruction represents the beginning of a
-// block of code.
-class BlockStartInstruction FINAL : public GapInstruction {
- public:
-  static BlockStartInstruction* New(Zone* zone) {
-    void* buffer = zone->New(sizeof(BlockStartInstruction));
-    return new (buffer) BlockStartInstruction();
-  }
-
-  static BlockStartInstruction* cast(Instruction* instr) {
-    DCHECK(instr->IsBlockStart());
-    return static_cast<BlockStartInstruction*>(instr);
-  }
-
-  static const BlockStartInstruction* cast(const Instruction* instr) {
-    DCHECK(instr->IsBlockStart());
-    return static_cast<const BlockStartInstruction*>(instr);
-  }
-
- private:
-  BlockStartInstruction() : GapInstruction(kBlockStartInstruction) {}
-};
+std::ostream& operator<<(std::ostream&, const RpoNumber&);
 
 
-class SourcePositionInstruction FINAL : public Instruction {
- public:
-  static SourcePositionInstruction* New(Zone* zone, SourcePosition position) {
-    void* buffer = zone->New(sizeof(SourcePositionInstruction));
-    return new (buffer) SourcePositionInstruction(position);
-  }
-
-  SourcePosition source_position() const { return source_position_; }
-
-  static SourcePositionInstruction* cast(Instruction* instr) {
-    DCHECK(instr->IsSourcePosition());
-    return static_cast<SourcePositionInstruction*>(instr);
-  }
-
-  static const SourcePositionInstruction* cast(const Instruction* instr) {
-    DCHECK(instr->IsSourcePosition());
-    return static_cast<const SourcePositionInstruction*>(instr);
-  }
-
- private:
-  explicit SourcePositionInstruction(SourcePosition source_position)
-      : Instruction(kSourcePositionInstruction),
-        source_position_(source_position) {
-    DCHECK(!source_position_.IsInvalid());
-    DCHECK(!source_position_.IsUnknown());
-  }
-
-  SourcePosition source_position_;
-};
-
-
-class Constant FINAL {
+class Constant final {
  public:
   enum Type {
     kInt32,
@@ -709,7 +893,7 @@
     kRpoNumber
   };
 
-  explicit Constant(int32_t v) : type_(kInt32), value_(v) {}
+  explicit Constant(int32_t v);
   explicit Constant(int64_t v) : type_(kInt64), value_(v) {}
   explicit Constant(float v) : type_(kFloat32), value_(bit_cast<int32_t>(v)) {}
   explicit Constant(double v) : type_(kFloat64), value_(bit_cast<int64_t>(v)) {}
@@ -717,8 +901,7 @@
       : type_(kExternalReference), value_(bit_cast<intptr_t>(ref)) {}
   explicit Constant(Handle<HeapObject> obj)
       : type_(kHeapObject), value_(bit_cast<intptr_t>(obj)) {}
-  explicit Constant(BasicBlock::RpoNumber rpo)
-      : type_(kRpoNumber), value_(rpo.ToInt()) {}
+  explicit Constant(RpoNumber rpo) : type_(kRpoNumber), value_(rpo.ToInt()) {}
 
   Type type() const { return type_; }
 
@@ -751,9 +934,9 @@
     return bit_cast<ExternalReference>(static_cast<intptr_t>(value_));
   }
 
-  BasicBlock::RpoNumber ToRpoNumber() const {
+  RpoNumber ToRpoNumber() const {
     DCHECK_EQ(kRpoNumber, type());
-    return BasicBlock::RpoNumber::FromInt(static_cast<int>(value_));
+    return RpoNumber::FromInt(static_cast<int>(value_));
   }
 
   Handle<HeapObject> ToHeapObject() const {
@@ -767,12 +950,67 @@
 };
 
 
+std::ostream& operator<<(std::ostream& os, const Constant& constant);
+
+
+// Forward declarations.
+class FrameStateDescriptor;
+
+
+enum class StateValueKind { kPlain, kNested, kDuplicate };
+
+
+class StateValueDescriptor {
+ public:
+  explicit StateValueDescriptor(Zone* zone)
+      : kind_(StateValueKind::kPlain),
+        type_(MachineType::AnyTagged()),
+        id_(0),
+        fields_(zone) {}
+
+  static StateValueDescriptor Plain(Zone* zone, MachineType type) {
+    return StateValueDescriptor(StateValueKind::kPlain, zone, type, 0);
+  }
+  static StateValueDescriptor Recursive(Zone* zone, size_t id) {
+    return StateValueDescriptor(StateValueKind::kNested, zone,
+                                MachineType::AnyTagged(), id);
+  }
+  static StateValueDescriptor Duplicate(Zone* zone, size_t id) {
+    return StateValueDescriptor(StateValueKind::kDuplicate, zone,
+                                MachineType::AnyTagged(), id);
+  }
+
+  size_t size() { return fields_.size(); }
+  ZoneVector<StateValueDescriptor>& fields() { return fields_; }
+  int IsPlain() { return kind_ == StateValueKind::kPlain; }
+  int IsNested() { return kind_ == StateValueKind::kNested; }
+  int IsDuplicate() { return kind_ == StateValueKind::kDuplicate; }
+  MachineType type() const { return type_; }
+  MachineType GetOperandType(size_t index) const {
+    return fields_[index].type_;
+  }
+  size_t id() const { return id_; }
+
+ private:
+  StateValueDescriptor(StateValueKind kind, Zone* zone, MachineType type,
+                       size_t id)
+      : kind_(kind), type_(type), id_(id), fields_(zone) {}
+
+  StateValueKind kind_;
+  MachineType type_;
+  size_t id_;
+  ZoneVector<StateValueDescriptor> fields_;
+};
+
+
 class FrameStateDescriptor : public ZoneObject {
  public:
-  FrameStateDescriptor(Zone* zone, const FrameStateCallInfo& state_info,
+  FrameStateDescriptor(Zone* zone, FrameStateType type, BailoutId bailout_id,
+                       OutputFrameStateCombine state_combine,
                        size_t parameters_count, size_t locals_count,
                        size_t stack_count,
-                       FrameStateDescriptor* outer_state = NULL);
+                       MaybeHandle<SharedFunctionInfo> shared_info,
+                       FrameStateDescriptor* outer_state = nullptr);
 
   FrameStateType type() const { return type_; }
   BailoutId bailout_id() const { return bailout_id_; }
@@ -780,9 +1018,11 @@
   size_t parameters_count() const { return parameters_count_; }
   size_t locals_count() const { return locals_count_; }
   size_t stack_count() const { return stack_count_; }
+  MaybeHandle<SharedFunctionInfo> shared_info() const { return shared_info_; }
   FrameStateDescriptor* outer_state() const { return outer_state_; }
-  MaybeHandle<JSFunction> jsfunction() const { return jsfunction_; }
-  bool HasContext() const { return type_ == JS_FRAME; }
+  bool HasContext() const {
+    return FrameStateFunctionInfo::IsJSFunctionType(type_);
+  }
 
   size_t GetSize(OutputFrameStateCombine combine =
                      OutputFrameStateCombine::Ignore()) const;
@@ -790,8 +1030,10 @@
   size_t GetFrameCount() const;
   size_t GetJSFrameCount() const;
 
-  MachineType GetType(size_t index) const;
-  void SetType(size_t index, MachineType type);
+  MachineType GetType(size_t index) const {
+    return values_.GetOperandType(index);
+  }
+  StateValueDescriptor* GetStateValueDescriptor() { return &values_; }
 
  private:
   FrameStateType type_;
@@ -800,63 +1042,43 @@
   size_t parameters_count_;
   size_t locals_count_;
   size_t stack_count_;
-  ZoneVector<MachineType> types_;
+  StateValueDescriptor values_;
+  MaybeHandle<SharedFunctionInfo> const shared_info_;
   FrameStateDescriptor* outer_state_;
-  MaybeHandle<JSFunction> jsfunction_;
 };
 
-std::ostream& operator<<(std::ostream& os, const Constant& constant);
+
+typedef ZoneVector<FrameStateDescriptor*> DeoptimizationVector;
 
 
-class PhiInstruction FINAL : public ZoneObject {
+class PhiInstruction final : public ZoneObject {
  public:
-  typedef ZoneVector<InstructionOperand*> Inputs;
+  typedef ZoneVector<InstructionOperand> Inputs;
 
-  PhiInstruction(Zone* zone, int virtual_register, size_t reserved_input_count)
-      : virtual_register_(virtual_register),
-        operands_(zone),
-        output_(nullptr),
-        inputs_(zone) {
-    UnallocatedOperand* output =
-        new (zone) UnallocatedOperand(UnallocatedOperand::NONE);
-    output->set_virtual_register(virtual_register);
-    output_ = output;
-    inputs_.reserve(reserved_input_count);
-    operands_.reserve(reserved_input_count);
-  }
+  PhiInstruction(Zone* zone, int virtual_register, size_t input_count);
+
+  void SetInput(size_t offset, int virtual_register);
 
   int virtual_register() const { return virtual_register_; }
   const IntVector& operands() const { return operands_; }
 
-  void Extend(Zone* zone, int virtual_register) {
-    UnallocatedOperand* input =
-        new (zone) UnallocatedOperand(UnallocatedOperand::ANY);
-    input->set_virtual_register(virtual_register);
-    operands_.push_back(virtual_register);
-    inputs_.push_back(input);
-  }
-
-  InstructionOperand* output() const { return output_; }
-  const Inputs& inputs() const { return inputs_; }
-  Inputs& inputs() { return inputs_; }
+  // TODO(dcarney): this has no real business being here, since it's internal to
+  // the register allocator, but putting it here was convenient.
+  const InstructionOperand& output() const { return output_; }
+  InstructionOperand& output() { return output_; }
 
  private:
-  // TODO(dcarney): some of these fields are only for verification, move them to
-  // verifier.
   const int virtual_register_;
+  InstructionOperand output_;
   IntVector operands_;
-  InstructionOperand* output_;
-  Inputs inputs_;
 };
 
 
 // Analogue of BasicBlock for Instructions instead of Nodes.
-class InstructionBlock FINAL : public ZoneObject {
+class InstructionBlock final : public ZoneObject {
  public:
-  InstructionBlock(Zone* zone, BasicBlock::Id id,
-                   BasicBlock::RpoNumber rpo_number,
-                   BasicBlock::RpoNumber loop_header,
-                   BasicBlock::RpoNumber loop_end, bool deferred);
+  InstructionBlock(Zone* zone, RpoNumber rpo_number, RpoNumber loop_header,
+                   RpoNumber loop_end, bool deferred, bool handler);
 
   // Instruction indexes (used by the register allocator).
   int first_instruction_index() const {
@@ -879,24 +1101,24 @@
   void set_code_end(int32_t end) { code_end_ = end; }
 
   bool IsDeferred() const { return deferred_; }
+  bool IsHandler() const { return handler_; }
 
-  BasicBlock::Id id() const { return id_; }
-  BasicBlock::RpoNumber ao_number() const { return ao_number_; }
-  BasicBlock::RpoNumber rpo_number() const { return rpo_number_; }
-  BasicBlock::RpoNumber loop_header() const { return loop_header_; }
-  BasicBlock::RpoNumber loop_end() const {
+  RpoNumber ao_number() const { return ao_number_; }
+  RpoNumber rpo_number() const { return rpo_number_; }
+  RpoNumber loop_header() const { return loop_header_; }
+  RpoNumber loop_end() const {
     DCHECK(IsLoopHeader());
     return loop_end_;
   }
   inline bool IsLoopHeader() const { return loop_end_.IsValid(); }
 
-  typedef ZoneVector<BasicBlock::RpoNumber> Predecessors;
+  typedef ZoneVector<RpoNumber> Predecessors;
   Predecessors& predecessors() { return predecessors_; }
   const Predecessors& predecessors() const { return predecessors_; }
   size_t PredecessorCount() const { return predecessors_.size(); }
-  size_t PredecessorIndexOf(BasicBlock::RpoNumber rpo_number) const;
+  size_t PredecessorIndexOf(RpoNumber rpo_number) const;
 
-  typedef ZoneVector<BasicBlock::RpoNumber> Successors;
+  typedef ZoneVector<RpoNumber> Successors;
   Successors& successors() { return successors_; }
   const Successors& successors() const { return successors_; }
   size_t SuccessorCount() const { return successors_.size(); }
@@ -905,49 +1127,64 @@
   const PhiInstructions& phis() const { return phis_; }
   void AddPhi(PhiInstruction* phi) { phis_.push_back(phi); }
 
-  void set_ao_number(BasicBlock::RpoNumber ao_number) {
-    ao_number_ = ao_number;
-  }
+  void set_ao_number(RpoNumber ao_number) { ao_number_ = ao_number; }
+
+  bool needs_frame() const { return needs_frame_; }
+  void mark_needs_frame() { needs_frame_ = true; }
+
+  bool must_construct_frame() const { return must_construct_frame_; }
+  void mark_must_construct_frame() { must_construct_frame_ = true; }
+
+  bool must_deconstruct_frame() const { return must_deconstruct_frame_; }
+  void mark_must_deconstruct_frame() { must_deconstruct_frame_ = true; }
+
+  void set_last_deferred(RpoNumber last) { last_deferred_ = last; }
+  RpoNumber last_deferred() const { return last_deferred_; }
 
  private:
   Successors successors_;
   Predecessors predecessors_;
   PhiInstructions phis_;
-  const BasicBlock::Id id_;
-  BasicBlock::RpoNumber ao_number_;  // Assembly order number.
-  const BasicBlock::RpoNumber rpo_number_;
-  const BasicBlock::RpoNumber loop_header_;
-  const BasicBlock::RpoNumber loop_end_;
+  RpoNumber ao_number_;  // Assembly order number.
+  const RpoNumber rpo_number_;
+  const RpoNumber loop_header_;
+  const RpoNumber loop_end_;
   int32_t code_start_;   // start index of arch-specific code.
   int32_t code_end_;     // end index of arch-specific code.
   const bool deferred_;  // Block contains deferred code.
+  const bool handler_;   // Block is a handler entry point.
+  bool needs_frame_;
+  bool must_construct_frame_;
+  bool must_deconstruct_frame_;
+  RpoNumber last_deferred_;
 };
 
 typedef ZoneDeque<Constant> ConstantDeque;
 typedef std::map<int, Constant, std::less<int>,
-                 zone_allocator<std::pair<int, Constant> > > ConstantMap;
+                 zone_allocator<std::pair<const int, Constant> > > ConstantMap;
 
 typedef ZoneDeque<Instruction*> InstructionDeque;
-typedef ZoneDeque<PointerMap*> PointerMapDeque;
-typedef ZoneVector<FrameStateDescriptor*> DeoptimizationVector;
+typedef ZoneDeque<ReferenceMap*> ReferenceMapDeque;
 typedef ZoneVector<InstructionBlock*> InstructionBlocks;
 
+
+// Forward declarations.
 struct PrintableInstructionSequence;
 
 
 // Represents architecture-specific generated code before, during, and after
 // register allocation.
-// TODO(titzer): s/IsDouble/IsFloat64/
-class InstructionSequence FINAL : public ZoneObject {
+class InstructionSequence final : public ZoneObject {
  public:
   static InstructionBlocks* InstructionBlocksFor(Zone* zone,
                                                  const Schedule* schedule);
   // Puts the deferred blocks last.
   static void ComputeAssemblyOrder(InstructionBlocks* blocks);
 
-  InstructionSequence(Zone* zone, InstructionBlocks* instruction_blocks);
+  InstructionSequence(Isolate* isolate, Zone* zone,
+                      InstructionBlocks* instruction_blocks);
 
-  int NextVirtualRegister() { return next_virtual_register_++; }
+  int NextVirtualRegister();
   int VirtualRegisterCount() const { return next_virtual_register_; }
 
   const InstructionBlocks& instruction_blocks() const {
@@ -958,7 +1195,7 @@
     return static_cast<int>(instruction_blocks_->size());
   }
 
-  InstructionBlock* InstructionBlockAt(BasicBlock::RpoNumber rpo_number) {
+  InstructionBlock* InstructionBlockAt(RpoNumber rpo_number) {
     return instruction_blocks_->at(rpo_number.ToSize());
   }
 
@@ -967,46 +1204,50 @@
         ->last_instruction_index();
   }
 
-  const InstructionBlock* InstructionBlockAt(
-      BasicBlock::RpoNumber rpo_number) const {
+  const InstructionBlock* InstructionBlockAt(RpoNumber rpo_number) const {
     return instruction_blocks_->at(rpo_number.ToSize());
   }
 
-  const InstructionBlock* GetInstructionBlock(int instruction_index) const;
+  InstructionBlock* GetInstructionBlock(int instruction_index) const;
 
-  bool IsReference(int virtual_register) const;
-  bool IsDouble(int virtual_register) const;
+  static MachineRepresentation DefaultRepresentation() {
+    return MachineType::PointerRepresentation();
+  }
+  MachineRepresentation GetRepresentation(int virtual_register) const;
+  void MarkAsRepresentation(MachineRepresentation rep, int virtual_register);
 
-  void MarkAsReference(int virtual_register);
-  void MarkAsDouble(int virtual_register);
+  bool IsReference(int virtual_register) const {
+    return GetRepresentation(virtual_register) ==
+           MachineRepresentation::kTagged;
+  }
+  bool IsFloat(int virtual_register) const {
+    return IsFloatingPoint(GetRepresentation(virtual_register));
+  }
 
-  void AddGapMove(int index, InstructionOperand* from, InstructionOperand* to);
-
-  BlockStartInstruction* GetBlockStart(BasicBlock::RpoNumber rpo) const;
+  Instruction* GetBlockStart(RpoNumber rpo) const;
 
   typedef InstructionDeque::const_iterator const_iterator;
   const_iterator begin() const { return instructions_.begin(); }
   const_iterator end() const { return instructions_.end(); }
   const InstructionDeque& instructions() const { return instructions_; }
-
-  GapInstruction* GapAt(int index) const {
-    return GapInstruction::cast(InstructionAt(index));
+  int LastInstructionIndex() const {
+    return static_cast<int>(instructions().size()) - 1;
   }
-  bool IsGapAt(int index) const { return InstructionAt(index)->IsGapMoves(); }
+
   Instruction* InstructionAt(int index) const {
     DCHECK(index >= 0);
     DCHECK(index < static_cast<int>(instructions_.size()));
     return instructions_[index];
   }
 
-  Isolate* isolate() const { return zone()->isolate(); }
-  const PointerMapDeque* pointer_maps() const { return &pointer_maps_; }
+  Isolate* isolate() const { return isolate_; }
+  const ReferenceMapDeque* reference_maps() const { return &reference_maps_; }
   Zone* zone() const { return zone_; }
 
   // Used by the instruction selector while adding instructions.
   int AddInstruction(Instruction* instr);
-  void StartBlock(BasicBlock::RpoNumber rpo);
-  void EndBlock(BasicBlock::RpoNumber rpo);
+  void StartBlock(RpoNumber rpo);
+  void EndBlock(RpoNumber rpo);
 
   int AddConstant(int virtual_register, Constant constant) {
     // TODO(titzer): allow RPO numbers as constants?
@@ -1026,15 +1267,28 @@
   typedef ZoneVector<Constant> Immediates;
   Immediates& immediates() { return immediates_; }
 
-  int AddImmediate(Constant constant) {
+  ImmediateOperand AddImmediate(const Constant& constant) {
+    if (constant.type() == Constant::kInt32) {
+      return ImmediateOperand(ImmediateOperand::INLINE, constant.ToInt32());
+    }
     int index = static_cast<int>(immediates_.size());
     immediates_.push_back(constant);
-    return index;
+    return ImmediateOperand(ImmediateOperand::INDEXED, index);
   }
-  Constant GetImmediate(int index) const {
-    DCHECK(index >= 0);
-    DCHECK(index < static_cast<int>(immediates_.size()));
-    return immediates_[index];
+
+  Constant GetImmediate(const ImmediateOperand* op) const {
+    switch (op->type()) {
+      case ImmediateOperand::INLINE:
+        return Constant(op->inline_value());
+      case ImmediateOperand::INDEXED: {
+        int index = op->indexed_value();
+        DCHECK(index >= 0);
+        DCHECK(index < static_cast<int>(immediates_.size()));
+        return immediates_[index];
+      }
+    }
+    UNREACHABLE();
+    return Constant(static_cast<int32_t>(0));
   }
 
   class StateId {
@@ -1050,30 +1304,42 @@
   StateId AddFrameStateDescriptor(FrameStateDescriptor* descriptor);
   FrameStateDescriptor* GetFrameStateDescriptor(StateId deoptimization_id);
   int GetFrameStateDescriptorCount();
-
-  BasicBlock::RpoNumber InputRpo(Instruction* instr, size_t index) {
-    InstructionOperand* operand = instr->InputAt(index);
-    Constant constant = operand->IsImmediate() ? GetImmediate(operand->index())
-                                               : GetConstant(operand->index());
-    return constant.ToRpoNumber();
+  DeoptimizationVector const& frame_state_descriptors() const {
+    return deoptimization_entries_;
   }
 
+  RpoNumber InputRpo(Instruction* instr, size_t index);
+
+  bool GetSourcePosition(const Instruction* instr,
+                         SourcePosition* result) const;
+  void SetSourcePosition(const Instruction* instr, SourcePosition value);
+
+  bool ContainsCall() const {
+    for (Instruction* instr : instructions_) {
+      if (instr->IsCall()) return true;
+    }
+    return false;
+  }
+  void Print(const RegisterConfiguration* config) const;
+  void Print() const;
+
  private:
   friend std::ostream& operator<<(std::ostream& os,
                                   const PrintableInstructionSequence& code);
 
-  typedef std::set<int, std::less<int>, ZoneIntAllocator> VirtualRegisterSet;
+  typedef ZoneMap<const Instruction*, SourcePosition> SourcePositionMap;
 
+  Isolate* isolate_;
   Zone* const zone_;
   InstructionBlocks* const instruction_blocks_;
+  SourcePositionMap source_positions_;
   IntVector block_starts_;
   ConstantMap constants_;
   Immediates immediates_;
   InstructionDeque instructions_;
   int next_virtual_register_;
-  PointerMapDeque pointer_maps_;
-  VirtualRegisterSet doubles_;
-  VirtualRegisterSet references_;
+  ReferenceMapDeque reference_maps_;
+  ZoneVector<MachineRepresentation> representations_;
   DeoptimizationVector deoptimization_entries_;
 
   DISALLOW_COPY_AND_ASSIGN(InstructionSequence);
diff --git a/src/compiler/interpreter-assembler.cc b/src/compiler/interpreter-assembler.cc
new file mode 100644
index 0000000..7080d02
--- /dev/null
+++ b/src/compiler/interpreter-assembler.cc
@@ -0,0 +1,751 @@
+// Copyright 2015 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/interpreter-assembler.h"
+
+#include <ostream>
+
+#include "src/code-factory.h"
+#include "src/compiler/graph.h"
+#include "src/compiler/instruction-selector.h"
+#include "src/compiler/linkage.h"
+#include "src/compiler/pipeline.h"
+#include "src/compiler/raw-machine-assembler.h"
+#include "src/compiler/schedule.h"
+#include "src/frames.h"
+#include "src/interface-descriptors.h"
+#include "src/interpreter/bytecodes.h"
+#include "src/machine-type.h"
+#include "src/macro-assembler.h"
+#include "src/zone.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+
+InterpreterAssembler::InterpreterAssembler(Isolate* isolate, Zone* zone,
+                                           interpreter::Bytecode bytecode)
+    : bytecode_(bytecode),
+      raw_assembler_(new RawMachineAssembler(
+          isolate, new (zone) Graph(zone),
+          Linkage::GetInterpreterDispatchDescriptor(zone),
+          MachineType::PointerRepresentation(),
+          InstructionSelector::SupportedMachineOperatorFlags())),
+      accumulator_(
+          raw_assembler_->Parameter(Linkage::kInterpreterAccumulatorParameter)),
+      bytecode_offset_(raw_assembler_->Parameter(
+          Linkage::kInterpreterBytecodeOffsetParameter)),
+      context_(
+          raw_assembler_->Parameter(Linkage::kInterpreterContextParameter)),
+      code_generated_(false) {}
+
+
+InterpreterAssembler::~InterpreterAssembler() {}
+
+
+Handle<Code> InterpreterAssembler::GenerateCode() {
+  DCHECK(!code_generated_);
+
+  // Disallow empty handlers that never return.
+  DCHECK_NE(0, graph()->end()->InputCount());
+
+  const char* bytecode_name = interpreter::Bytecodes::ToString(bytecode_);
+  Schedule* schedule = raw_assembler_->Export();
+  Handle<Code> code = Pipeline::GenerateCodeForCodeStub(
+      isolate(), raw_assembler_->call_descriptor(), graph(), schedule,
+      Code::STUB, bytecode_name);
+
+#ifdef ENABLE_DISASSEMBLER
+  if (FLAG_trace_ignition_codegen) {
+    OFStream os(stdout);
+    code->Disassemble(bytecode_name, os);
+    os << std::flush;
+  }
+#endif
+
+  code_generated_ = true;
+  return code;
+}
+
+
+Node* InterpreterAssembler::GetAccumulator() { return accumulator_; }
+
+
+void InterpreterAssembler::SetAccumulator(Node* value) { accumulator_ = value; }
+
+
+Node* InterpreterAssembler::GetContext() { return context_; }
+
+
+void InterpreterAssembler::SetContext(Node* value) { context_ = value; }
+
+
+Node* InterpreterAssembler::BytecodeOffset() { return bytecode_offset_; }
+
+
+Node* InterpreterAssembler::RegisterFileRawPointer() {
+  return raw_assembler_->Parameter(Linkage::kInterpreterRegisterFileParameter);
+}
+
+
+Node* InterpreterAssembler::BytecodeArrayTaggedPointer() {
+  return raw_assembler_->Parameter(Linkage::kInterpreterBytecodeArrayParameter);
+}
+
+
+Node* InterpreterAssembler::DispatchTableRawPointer() {
+  return raw_assembler_->Parameter(Linkage::kInterpreterDispatchTableParameter);
+}
+
+
+Node* InterpreterAssembler::RegisterLocation(Node* reg_index) {
+  return IntPtrAdd(RegisterFileRawPointer(), RegisterFrameOffset(reg_index));
+}
+
+
+Node* InterpreterAssembler::LoadRegister(int offset) {
+  return raw_assembler_->Load(MachineType::AnyTagged(),
+                              RegisterFileRawPointer(), Int32Constant(offset));
+}
+
+
+Node* InterpreterAssembler::LoadRegister(interpreter::Register reg) {
+  return LoadRegister(reg.ToOperand() << kPointerSizeLog2);
+}
+
+
+Node* InterpreterAssembler::RegisterFrameOffset(Node* index) {
+  return WordShl(index, kPointerSizeLog2);
+}
+
+
+Node* InterpreterAssembler::LoadRegister(Node* reg_index) {
+  return raw_assembler_->Load(MachineType::AnyTagged(),
+                              RegisterFileRawPointer(),
+                              RegisterFrameOffset(reg_index));
+}
+
+
+Node* InterpreterAssembler::StoreRegister(Node* value, int offset) {
+  return raw_assembler_->Store(MachineRepresentation::kTagged,
+                               RegisterFileRawPointer(), Int32Constant(offset),
+                               value, kNoWriteBarrier);
+}
+
+
+Node* InterpreterAssembler::StoreRegister(Node* value,
+                                          interpreter::Register reg) {
+  return StoreRegister(value, reg.ToOperand() << kPointerSizeLog2);
+}
+
+
+Node* InterpreterAssembler::StoreRegister(Node* value, Node* reg_index) {
+  return raw_assembler_->Store(
+      MachineRepresentation::kTagged, RegisterFileRawPointer(),
+      RegisterFrameOffset(reg_index), value, kNoWriteBarrier);
+}
+
+
+Node* InterpreterAssembler::NextRegister(Node* reg_index) {
+  // Register indexes are negative, so the next index is minus one.
+  return IntPtrAdd(reg_index, Int32Constant(-1));
+}
+
+
+Node* InterpreterAssembler::BytecodeOperand(int operand_index) {
+  DCHECK_LT(operand_index, interpreter::Bytecodes::NumberOfOperands(bytecode_));
+  DCHECK_EQ(interpreter::OperandSize::kByte,
+            interpreter::Bytecodes::GetOperandSize(bytecode_, operand_index));
+  return raw_assembler_->Load(
+      MachineType::Uint8(), BytecodeArrayTaggedPointer(),
+      IntPtrAdd(BytecodeOffset(),
+                Int32Constant(interpreter::Bytecodes::GetOperandOffset(
+                    bytecode_, operand_index))));
+}
+
+
+Node* InterpreterAssembler::BytecodeOperandSignExtended(int operand_index) {
+  DCHECK_LT(operand_index, interpreter::Bytecodes::NumberOfOperands(bytecode_));
+  DCHECK_EQ(interpreter::OperandSize::kByte,
+            interpreter::Bytecodes::GetOperandSize(bytecode_, operand_index));
+  Node* load = raw_assembler_->Load(
+      MachineType::Int8(), BytecodeArrayTaggedPointer(),
+      IntPtrAdd(BytecodeOffset(),
+                Int32Constant(interpreter::Bytecodes::GetOperandOffset(
+                    bytecode_, operand_index))));
+  // Ensure that we sign extend to full pointer size
+  if (kPointerSize == 8) {
+    load = raw_assembler_->ChangeInt32ToInt64(load);
+  }
+  return load;
+}
+
+
+Node* InterpreterAssembler::BytecodeOperandShort(int operand_index) {
+  DCHECK_LT(operand_index, interpreter::Bytecodes::NumberOfOperands(bytecode_));
+  DCHECK_EQ(interpreter::OperandSize::kShort,
+            interpreter::Bytecodes::GetOperandSize(bytecode_, operand_index));
+  if (TargetSupportsUnalignedAccess()) {
+    return raw_assembler_->Load(
+        MachineType::Uint16(), BytecodeArrayTaggedPointer(),
+        IntPtrAdd(BytecodeOffset(),
+                  Int32Constant(interpreter::Bytecodes::GetOperandOffset(
+                      bytecode_, operand_index))));
+  } else {
+    int offset =
+        interpreter::Bytecodes::GetOperandOffset(bytecode_, operand_index);
+    Node* first_byte = raw_assembler_->Load(
+        MachineType::Uint8(), BytecodeArrayTaggedPointer(),
+        IntPtrAdd(BytecodeOffset(), Int32Constant(offset)));
+    Node* second_byte = raw_assembler_->Load(
+        MachineType::Uint8(), BytecodeArrayTaggedPointer(),
+        IntPtrAdd(BytecodeOffset(), Int32Constant(offset + 1)));
+#if V8_TARGET_LITTLE_ENDIAN
+    return raw_assembler_->WordOr(WordShl(second_byte, kBitsPerByte),
+                                  first_byte);
+#elif V8_TARGET_BIG_ENDIAN
+    return raw_assembler_->WordOr(WordShl(first_byte, kBitsPerByte),
+                                  second_byte);
+#else
+#error "Unknown Architecture"
+#endif
+  }
+}
+
+
+Node* InterpreterAssembler::BytecodeOperandShortSignExtended(
+    int operand_index) {
+  DCHECK_LT(operand_index, interpreter::Bytecodes::NumberOfOperands(bytecode_));
+  DCHECK_EQ(interpreter::OperandSize::kShort,
+            interpreter::Bytecodes::GetOperandSize(bytecode_, operand_index));
+  int operand_offset =
+      interpreter::Bytecodes::GetOperandOffset(bytecode_, operand_index);
+  Node* load;
+  if (TargetSupportsUnalignedAccess()) {
+    load = raw_assembler_->Load(
+        MachineType::Int16(), BytecodeArrayTaggedPointer(),
+        IntPtrAdd(BytecodeOffset(), Int32Constant(operand_offset)));
+  } else {
+#if V8_TARGET_LITTLE_ENDIAN
+    Node* hi_byte_offset = Int32Constant(operand_offset + 1);
+    Node* lo_byte_offset = Int32Constant(operand_offset);
+#elif V8_TARGET_BIG_ENDIAN
+    Node* hi_byte_offset = Int32Constant(operand_offset);
+    Node* lo_byte_offset = Int32Constant(operand_offset + 1);
+#else
+#error "Unknown Architecture"
+#endif
+    Node* hi_byte =
+        raw_assembler_->Load(MachineType::Int8(), BytecodeArrayTaggedPointer(),
+                             IntPtrAdd(BytecodeOffset(), hi_byte_offset));
+    Node* lo_byte =
+        raw_assembler_->Load(MachineType::Uint8(), BytecodeArrayTaggedPointer(),
+                             IntPtrAdd(BytecodeOffset(), lo_byte_offset));
+    hi_byte = raw_assembler_->Word32Shl(hi_byte, Int32Constant(kBitsPerByte));
+    load = raw_assembler_->Word32Or(hi_byte, lo_byte);
+  }
+
+  // Ensure that we sign extend to full pointer size
+  if (kPointerSize == 8) {
+    load = raw_assembler_->ChangeInt32ToInt64(load);
+  }
+  return load;
+}
+
+
+Node* InterpreterAssembler::BytecodeOperandCount(int operand_index) {
+  switch (interpreter::Bytecodes::GetOperandSize(bytecode_, operand_index)) {
+    case interpreter::OperandSize::kByte:
+      DCHECK_EQ(
+          interpreter::OperandType::kCount8,
+          interpreter::Bytecodes::GetOperandType(bytecode_, operand_index));
+      return BytecodeOperand(operand_index);
+    case interpreter::OperandSize::kShort:
+      DCHECK_EQ(
+          interpreter::OperandType::kCount16,
+          interpreter::Bytecodes::GetOperandType(bytecode_, operand_index));
+      return BytecodeOperandShort(operand_index);
+    default:
+      UNREACHABLE();
+      return nullptr;
+  }
+}
+
+
+Node* InterpreterAssembler::BytecodeOperandImm(int operand_index) {
+  DCHECK_EQ(interpreter::OperandType::kImm8,
+            interpreter::Bytecodes::GetOperandType(bytecode_, operand_index));
+  return BytecodeOperandSignExtended(operand_index);
+}
+
+
+Node* InterpreterAssembler::BytecodeOperandIdx(int operand_index) {
+  switch (interpreter::Bytecodes::GetOperandSize(bytecode_, operand_index)) {
+    case interpreter::OperandSize::kByte:
+      DCHECK_EQ(
+          interpreter::OperandType::kIdx8,
+          interpreter::Bytecodes::GetOperandType(bytecode_, operand_index));
+      return BytecodeOperand(operand_index);
+    case interpreter::OperandSize::kShort:
+      DCHECK_EQ(
+          interpreter::OperandType::kIdx16,
+          interpreter::Bytecodes::GetOperandType(bytecode_, operand_index));
+      return BytecodeOperandShort(operand_index);
+    default:
+      UNREACHABLE();
+      return nullptr;
+  }
+}
+
+
+Node* InterpreterAssembler::BytecodeOperandReg(int operand_index) {
+  switch (interpreter::Bytecodes::GetOperandType(bytecode_, operand_index)) {
+    case interpreter::OperandType::kReg8:
+    case interpreter::OperandType::kRegPair8:
+    case interpreter::OperandType::kMaybeReg8:
+      DCHECK_EQ(
+          interpreter::OperandSize::kByte,
+          interpreter::Bytecodes::GetOperandSize(bytecode_, operand_index));
+      return BytecodeOperandSignExtended(operand_index);
+    case interpreter::OperandType::kReg16:
+      DCHECK_EQ(
+          interpreter::OperandSize::kShort,
+          interpreter::Bytecodes::GetOperandSize(bytecode_, operand_index));
+      return BytecodeOperandShortSignExtended(operand_index);
+    default:
+      UNREACHABLE();
+      return nullptr;
+  }
+}
+
+
+Node* InterpreterAssembler::Int32Constant(int value) {
+  return raw_assembler_->Int32Constant(value);
+}
+
+
+Node* InterpreterAssembler::IntPtrConstant(intptr_t value) {
+  return raw_assembler_->IntPtrConstant(value);
+}
+
+
+Node* InterpreterAssembler::NumberConstant(double value) {
+  return raw_assembler_->NumberConstant(value);
+}
+
+
+Node* InterpreterAssembler::HeapConstant(Handle<HeapObject> object) {
+  return raw_assembler_->HeapConstant(object);
+}
+
+
+Node* InterpreterAssembler::BooleanConstant(bool value) {
+  return raw_assembler_->BooleanConstant(value);
+}
+
+
+Node* InterpreterAssembler::SmiShiftBitsConstant() {
+  return Int32Constant(kSmiShiftSize + kSmiTagSize);
+}
+
+
+Node* InterpreterAssembler::SmiTag(Node* value) {
+  return raw_assembler_->WordShl(value, SmiShiftBitsConstant());
+}
+
+
+Node* InterpreterAssembler::SmiUntag(Node* value) {
+  return raw_assembler_->WordSar(value, SmiShiftBitsConstant());
+}
+
+
+Node* InterpreterAssembler::IntPtrAdd(Node* a, Node* b) {
+  return raw_assembler_->IntPtrAdd(a, b);
+}
+
+
+Node* InterpreterAssembler::IntPtrSub(Node* a, Node* b) {
+  return raw_assembler_->IntPtrSub(a, b);
+}
+
+
+Node* InterpreterAssembler::WordShl(Node* value, int shift) {
+  return raw_assembler_->WordShl(value, Int32Constant(shift));
+}
+
+
+Node* InterpreterAssembler::LoadConstantPoolEntry(Node* index) {
+  Node* constant_pool = LoadObjectField(BytecodeArrayTaggedPointer(),
+                                        BytecodeArray::kConstantPoolOffset);
+  Node* entry_offset =
+      IntPtrAdd(IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag),
+                WordShl(index, kPointerSizeLog2));
+  return raw_assembler_->Load(MachineType::AnyTagged(), constant_pool,
+                              entry_offset);
+}
+
+
+Node* InterpreterAssembler::LoadFixedArrayElement(Node* fixed_array,
+                                                  int index) {
+  Node* entry_offset =
+      IntPtrAdd(IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag),
+                WordShl(Int32Constant(index), kPointerSizeLog2));
+  return raw_assembler_->Load(MachineType::AnyTagged(), fixed_array,
+                              entry_offset);
+}
+
+
+Node* InterpreterAssembler::LoadObjectField(Node* object, int offset) {
+  return raw_assembler_->Load(MachineType::AnyTagged(), object,
+                              IntPtrConstant(offset - kHeapObjectTag));
+}
+
+
+Node* InterpreterAssembler::LoadContextSlot(Node* context, int slot_index) {
+  return raw_assembler_->Load(MachineType::AnyTagged(), context,
+                              IntPtrConstant(Context::SlotOffset(slot_index)));
+}
+
+
+Node* InterpreterAssembler::LoadContextSlot(Node* context, Node* slot_index) {
+  Node* offset =
+      IntPtrAdd(WordShl(slot_index, kPointerSizeLog2),
+                Int32Constant(Context::kHeaderSize - kHeapObjectTag));
+  return raw_assembler_->Load(MachineType::AnyTagged(), context, offset);
+}
+
+
+Node* InterpreterAssembler::StoreContextSlot(Node* context, Node* slot_index,
+                                             Node* value) {
+  Node* offset =
+      IntPtrAdd(WordShl(slot_index, kPointerSizeLog2),
+                Int32Constant(Context::kHeaderSize - kHeapObjectTag));
+  return raw_assembler_->Store(MachineRepresentation::kTagged, context, offset,
+                               value, kFullWriteBarrier);
+}
+
+
+Node* InterpreterAssembler::LoadTypeFeedbackVector() {
+  Node* function = raw_assembler_->Load(
+      MachineType::AnyTagged(), RegisterFileRawPointer(),
+      IntPtrConstant(InterpreterFrameConstants::kFunctionFromRegisterPointer));
+  Node* shared_info =
+      LoadObjectField(function, JSFunction::kSharedFunctionInfoOffset);
+  Node* vector =
+      LoadObjectField(shared_info, SharedFunctionInfo::kFeedbackVectorOffset);
+  return vector;
+}
+
+
+Node* InterpreterAssembler::Projection(int index, Node* node) {
+  return raw_assembler_->Projection(index, node);
+}
+
+
+Node* InterpreterAssembler::CallConstruct(Node* new_target, Node* constructor,
+                                          Node* first_arg, Node* arg_count) {
+  Callable callable = CodeFactory::InterpreterPushArgsAndConstruct(isolate());
+  CallDescriptor* descriptor = Linkage::GetStubCallDescriptor(
+      isolate(), zone(), callable.descriptor(), 0, CallDescriptor::kNoFlags);
+
+  Node* code_target = HeapConstant(callable.code());
+
+  Node** args = zone()->NewArray<Node*>(5);
+  args[0] = arg_count;
+  args[1] = new_target;
+  args[2] = constructor;
+  args[3] = first_arg;
+  args[4] = GetContext();
+
+  return CallN(descriptor, code_target, args);
+}
+
+
+void InterpreterAssembler::CallPrologue() {
+  StoreRegister(SmiTag(bytecode_offset_),
+                InterpreterFrameConstants::kBytecodeOffsetFromRegisterPointer);
+}
+
+
+void InterpreterAssembler::CallEpilogue() {
+  // Restore the bytecode offset from the stack frame.
+  bytecode_offset_ = SmiUntag(LoadRegister(
+      InterpreterFrameConstants::kBytecodeOffsetFromRegisterPointer));
+}
+
+
+Node* InterpreterAssembler::CallN(CallDescriptor* descriptor, Node* code_target,
+                                  Node** args) {
+  CallPrologue();
+
+  Node* stack_pointer_before_call = nullptr;
+  if (FLAG_debug_code) {
+    stack_pointer_before_call = raw_assembler_->LoadStackPointer();
+  }
+  Node* return_val = raw_assembler_->CallN(descriptor, code_target, args);
+  if (FLAG_debug_code) {
+    Node* stack_pointer_after_call = raw_assembler_->LoadStackPointer();
+    AbortIfWordNotEqual(stack_pointer_before_call, stack_pointer_after_call,
+                        kUnexpectedStackPointer);
+  }
+
+  CallEpilogue();
+  return return_val;
+}
+
+
+Node* InterpreterAssembler::CallJS(Node* function, Node* first_arg,
+                                   Node* arg_count) {
+  Callable callable = CodeFactory::InterpreterPushArgsAndCall(isolate());
+  CallDescriptor* descriptor = Linkage::GetStubCallDescriptor(
+      isolate(), zone(), callable.descriptor(), 0, CallDescriptor::kNoFlags);
+
+  Node* code_target = HeapConstant(callable.code());
+
+  Node** args = zone()->NewArray<Node*>(4);
+  args[0] = arg_count;
+  args[1] = first_arg;
+  args[2] = function;
+  args[3] = GetContext();
+
+  return CallN(descriptor, code_target, args);
+}
+
+
+Node* InterpreterAssembler::CallIC(CallInterfaceDescriptor descriptor,
+                                   Node* target, Node** args) {
+  CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor(
+      isolate(), zone(), descriptor, 0, CallDescriptor::kNoFlags);
+  return CallN(call_descriptor, target, args);
+}
+
+
+Node* InterpreterAssembler::CallIC(CallInterfaceDescriptor descriptor,
+                                   Node* target, Node* arg1, Node* arg2,
+                                   Node* arg3) {
+  Node** args = zone()->NewArray<Node*>(4);
+  args[0] = arg1;
+  args[1] = arg2;
+  args[2] = arg3;
+  args[3] = GetContext();
+  return CallIC(descriptor, target, args);
+}
+
+
+Node* InterpreterAssembler::CallIC(CallInterfaceDescriptor descriptor,
+                                   Node* target, Node* arg1, Node* arg2,
+                                   Node* arg3, Node* arg4) {
+  Node** args = zone()->NewArray<Node*>(5);
+  args[0] = arg1;
+  args[1] = arg2;
+  args[2] = arg3;
+  args[3] = arg4;
+  args[4] = GetContext();
+  return CallIC(descriptor, target, args);
+}
+
+
+Node* InterpreterAssembler::CallIC(CallInterfaceDescriptor descriptor,
+                                   Node* target, Node* arg1, Node* arg2,
+                                   Node* arg3, Node* arg4, Node* arg5) {
+  Node** args = zone()->NewArray<Node*>(6);
+  args[0] = arg1;
+  args[1] = arg2;
+  args[2] = arg3;
+  args[3] = arg4;
+  args[4] = arg5;
+  args[5] = GetContext();
+  return CallIC(descriptor, target, args);
+}
+
+
+Node* InterpreterAssembler::CallRuntime(Node* function_id, Node* first_arg,
+                                        Node* arg_count, int result_size) {
+  Callable callable = CodeFactory::InterpreterCEntry(isolate(), result_size);
+  CallDescriptor* descriptor = Linkage::GetStubCallDescriptor(
+      isolate(), zone(), callable.descriptor(), 0, CallDescriptor::kNoFlags,
+      Operator::kNoProperties, MachineType::AnyTagged(), result_size);
+  Node* code_target = HeapConstant(callable.code());
+
+  // Get the function entry from the function id.
+  Node* function_table = raw_assembler_->ExternalConstant(
+      ExternalReference::runtime_function_table_address(isolate()));
+  Node* function_offset = raw_assembler_->Int32Mul(
+      function_id, Int32Constant(sizeof(Runtime::Function)));
+  Node* function = IntPtrAdd(function_table, function_offset);
+  Node* function_entry =
+      raw_assembler_->Load(MachineType::Pointer(), function,
+                           Int32Constant(offsetof(Runtime::Function, entry)));
+
+  Node** args = zone()->NewArray<Node*>(4);
+  args[0] = arg_count;
+  args[1] = first_arg;
+  args[2] = function_entry;
+  args[3] = GetContext();
+
+  return CallN(descriptor, code_target, args);
+}
+
+
+Node* InterpreterAssembler::CallRuntime(Runtime::FunctionId function_id,
+                                        Node* arg1) {
+  CallPrologue();
+  Node* return_val =
+      raw_assembler_->CallRuntime1(function_id, arg1, GetContext());
+  CallEpilogue();
+  return return_val;
+}
+
+
+Node* InterpreterAssembler::CallRuntime(Runtime::FunctionId function_id,
+                                        Node* arg1, Node* arg2) {
+  CallPrologue();
+  Node* return_val =
+      raw_assembler_->CallRuntime2(function_id, arg1, arg2, GetContext());
+  CallEpilogue();
+  return return_val;
+}
+
+
+Node* InterpreterAssembler::CallRuntime(Runtime::FunctionId function_id,
+                                        Node* arg1, Node* arg2, Node* arg3,
+                                        Node* arg4) {
+  CallPrologue();
+  Node* return_val = raw_assembler_->CallRuntime4(function_id, arg1, arg2, arg3,
+                                                  arg4, GetContext());
+  CallEpilogue();
+  return return_val;
+}
+
+
+void InterpreterAssembler::Return() {
+  Node* exit_trampoline_code_object =
+      HeapConstant(isolate()->builtins()->InterpreterExitTrampoline());
+  // If the order of the parameters you need to change the call signature below.
+  STATIC_ASSERT(0 == Linkage::kInterpreterAccumulatorParameter);
+  STATIC_ASSERT(1 == Linkage::kInterpreterRegisterFileParameter);
+  STATIC_ASSERT(2 == Linkage::kInterpreterBytecodeOffsetParameter);
+  STATIC_ASSERT(3 == Linkage::kInterpreterBytecodeArrayParameter);
+  STATIC_ASSERT(4 == Linkage::kInterpreterDispatchTableParameter);
+  STATIC_ASSERT(5 == Linkage::kInterpreterContextParameter);
+  Node* args[] = { GetAccumulator(),
+                   RegisterFileRawPointer(),
+                   BytecodeOffset(),
+                   BytecodeArrayTaggedPointer(),
+                   DispatchTableRawPointer(),
+                   GetContext() };
+  raw_assembler_->TailCallN(call_descriptor(), exit_trampoline_code_object,
+                            args);
+}
+
+
+Node* InterpreterAssembler::Advance(int delta) {
+  return IntPtrAdd(BytecodeOffset(), Int32Constant(delta));
+}
+
+
+Node* InterpreterAssembler::Advance(Node* delta) {
+  return raw_assembler_->IntPtrAdd(BytecodeOffset(), delta);
+}
+
+
+void InterpreterAssembler::Jump(Node* delta) { DispatchTo(Advance(delta)); }
+
+
+void InterpreterAssembler::JumpIfWordEqual(Node* lhs, Node* rhs, Node* delta) {
+  RawMachineLabel match, no_match;
+  Node* condition = raw_assembler_->WordEqual(lhs, rhs);
+  raw_assembler_->Branch(condition, &match, &no_match);
+  raw_assembler_->Bind(&match);
+  DispatchTo(Advance(delta));
+  raw_assembler_->Bind(&no_match);
+  Dispatch();
+}
+
+
+void InterpreterAssembler::Dispatch() {
+  DispatchTo(Advance(interpreter::Bytecodes::Size(bytecode_)));
+}
+
+
+void InterpreterAssembler::DispatchTo(Node* new_bytecode_offset) {
+  Node* target_bytecode = raw_assembler_->Load(
+      MachineType::Uint8(), BytecodeArrayTaggedPointer(), new_bytecode_offset);
+
+  // TODO(rmcilroy): Create a code target dispatch table to avoid conversion
+  // from code object on every dispatch.
+  Node* target_code_object = raw_assembler_->Load(
+      MachineType::Pointer(), DispatchTableRawPointer(),
+      raw_assembler_->Word32Shl(target_bytecode,
+                                Int32Constant(kPointerSizeLog2)));
+
+  // If the order of the parameters you need to change the call signature below.
+  STATIC_ASSERT(0 == Linkage::kInterpreterAccumulatorParameter);
+  STATIC_ASSERT(1 == Linkage::kInterpreterRegisterFileParameter);
+  STATIC_ASSERT(2 == Linkage::kInterpreterBytecodeOffsetParameter);
+  STATIC_ASSERT(3 == Linkage::kInterpreterBytecodeArrayParameter);
+  STATIC_ASSERT(4 == Linkage::kInterpreterDispatchTableParameter);
+  STATIC_ASSERT(5 == Linkage::kInterpreterContextParameter);
+  Node* args[] = { GetAccumulator(),
+                   RegisterFileRawPointer(),
+                   new_bytecode_offset,
+                   BytecodeArrayTaggedPointer(),
+                   DispatchTableRawPointer(),
+                   GetContext() };
+  raw_assembler_->TailCallN(call_descriptor(), target_code_object, args);
+}
+
+
+void InterpreterAssembler::Abort(BailoutReason bailout_reason) {
+  Node* abort_id = SmiTag(Int32Constant(bailout_reason));
+  Node* ret_value = CallRuntime(Runtime::kAbort, abort_id);
+  // Unreached, but keeps turbofan happy.
+  raw_assembler_->Return(ret_value);
+}
+
+
+void InterpreterAssembler::AbortIfWordNotEqual(Node* lhs, Node* rhs,
+                                               BailoutReason bailout_reason) {
+  RawMachineLabel match, no_match;
+  Node* condition = raw_assembler_->WordEqual(lhs, rhs);
+  raw_assembler_->Branch(condition, &match, &no_match);
+  raw_assembler_->Bind(&no_match);
+  Abort(bailout_reason);
+  raw_assembler_->Bind(&match);
+}
+
+
+// static
+bool InterpreterAssembler::TargetSupportsUnalignedAccess() {
+#if V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
+  return false;
+#elif V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_PPC
+  return CpuFeatures::IsSupported(UNALIGNED_ACCESSES);
+#elif V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_X87
+  return true;
+#else
+#error "Unknown Architecture"
+#endif
+}
+
+
+// RawMachineAssembler delegate helpers:
+Isolate* InterpreterAssembler::isolate() { return raw_assembler_->isolate(); }
+
+
+Graph* InterpreterAssembler::graph() { return raw_assembler_->graph(); }
+
+
+CallDescriptor* InterpreterAssembler::call_descriptor() const {
+  return raw_assembler_->call_descriptor();
+}
+
+
+Zone* InterpreterAssembler::zone() { return raw_assembler_->zone(); }
+
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/interpreter-assembler.h b/src/compiler/interpreter-assembler.h
new file mode 100644
index 0000000..fb79d3e
--- /dev/null
+++ b/src/compiler/interpreter-assembler.h
@@ -0,0 +1,224 @@
+// Copyright 2015 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.
+
+#ifndef V8_COMPILER_INTERPRETER_ASSEMBLER_H_
+#define V8_COMPILER_INTERPRETER_ASSEMBLER_H_
+
+// Clients of this interface shouldn't depend on lots of compiler internals.
+// Do not include anything from src/compiler here!
+#include "src/allocation.h"
+#include "src/base/smart-pointers.h"
+#include "src/builtins.h"
+#include "src/frames.h"
+#include "src/interpreter/bytecodes.h"
+#include "src/runtime/runtime.h"
+
+namespace v8 {
+namespace internal {
+
+class CallInterfaceDescriptor;
+class Isolate;
+class Zone;
+
+namespace compiler {
+
+class CallDescriptor;
+class Graph;
+class Node;
+class Operator;
+class RawMachineAssembler;
+class Schedule;
+
+class InterpreterAssembler {
+ public:
+  InterpreterAssembler(Isolate* isolate, Zone* zone,
+                       interpreter::Bytecode bytecode);
+  virtual ~InterpreterAssembler();
+
+  Handle<Code> GenerateCode();
+
+  // Returns the count immediate for bytecode operand |operand_index| in the
+  // current bytecode.
+  Node* BytecodeOperandCount(int operand_index);
+  // Returns the index immediate for bytecode operand |operand_index| in the
+  // current bytecode.
+  Node* BytecodeOperandIdx(int operand_index);
+  // Returns the Imm8 immediate for bytecode operand |operand_index| in the
+  // current bytecode.
+  Node* BytecodeOperandImm(int operand_index);
+  // Returns the register index for bytecode operand |operand_index| in the
+  // current bytecode.
+  Node* BytecodeOperandReg(int operand_index);
+
+  // Accumulator.
+  Node* GetAccumulator();
+  void SetAccumulator(Node* value);
+
+  // Context.
+  Node* GetContext();
+  void SetContext(Node* value);
+
+  // Loads from and stores to the interpreter register file.
+  Node* LoadRegister(int offset);
+  Node* LoadRegister(interpreter::Register reg);
+  Node* LoadRegister(Node* reg_index);
+  Node* StoreRegister(Node* value, int offset);
+  Node* StoreRegister(Node* value, interpreter::Register reg);
+  Node* StoreRegister(Node* value, Node* reg_index);
+
+  // Returns the next consecutive register.
+  Node* NextRegister(Node* reg_index);
+
+  // Returns the location in memory of the register |reg_index| in the
+  // interpreter register file.
+  Node* RegisterLocation(Node* reg_index);
+
+  // Constants.
+  Node* Int32Constant(int value);
+  Node* IntPtrConstant(intptr_t value);
+  Node* NumberConstant(double value);
+  Node* HeapConstant(Handle<HeapObject> object);
+  Node* BooleanConstant(bool value);
+
+  // Tag and untag Smi values.
+  Node* SmiTag(Node* value);
+  Node* SmiUntag(Node* value);
+
+  // Basic arithmetic operations.
+  Node* IntPtrAdd(Node* a, Node* b);
+  Node* IntPtrSub(Node* a, Node* b);
+  Node* WordShl(Node* value, int shift);
+
+  // Load constant at |index| in the constant pool.
+  Node* LoadConstantPoolEntry(Node* index);
+
+  // Load an element from a fixed array on the heap.
+  Node* LoadFixedArrayElement(Node* fixed_array, int index);
+
+  // Load a field from an object on the heap.
+  Node* LoadObjectField(Node* object, int offset);
+
+  // Load |slot_index| from |context|.
+  Node* LoadContextSlot(Node* context, int slot_index);
+  Node* LoadContextSlot(Node* context, Node* slot_index);
+  // Stores |value| into |slot_index| of |context|.
+  Node* StoreContextSlot(Node* context, Node* slot_index, Node* value);
+
+  // Load the TypeFeedbackVector for the current function.
+  Node* LoadTypeFeedbackVector();
+
+  // Project the output value at index |index|
+  Node* Projection(int index, Node* node);
+
+  // Call constructor |constructor| with |arg_count| arguments (not
+  // including receiver) and the first argument located at
+  // |first_arg|. The |new_target| is the same as the
+  // |constructor| for the new keyword, but differs for the super
+  // keyword.
+  Node* CallConstruct(Node* new_target, Node* constructor, Node* first_arg,
+                      Node* arg_count);
+
+  // Call JSFunction or Callable |function| with |arg_count|
+  // arguments (not including receiver) and the first argument
+  // located at |first_arg|.
+  Node* CallJS(Node* function, Node* first_arg, Node* arg_count);
+
+  // Call an IC code stub.
+  Node* CallIC(CallInterfaceDescriptor descriptor, Node* target, Node* arg1,
+               Node* arg2, Node* arg3);
+  Node* CallIC(CallInterfaceDescriptor descriptor, Node* target, Node* arg1,
+               Node* arg2, Node* arg3, Node* arg4);
+  Node* CallIC(CallInterfaceDescriptor descriptor, Node* target, Node* arg1,
+               Node* arg2, Node* arg3, Node* arg4, Node* arg5);
+
+  // Call runtime function.
+  Node* CallRuntime(Node* function_id, Node* first_arg, Node* arg_count,
+                    int return_size = 1);
+  Node* CallRuntime(Runtime::FunctionId function_id, Node* arg1);
+  Node* CallRuntime(Runtime::FunctionId function_id, Node* arg1, Node* arg2);
+  Node* CallRuntime(Runtime::FunctionId function_id, Node* arg1, Node* arg2,
+                    Node* arg3, Node* arg4);
+
+  // Jump relative to the current bytecode by |jump_offset|.
+  void Jump(Node* jump_offset);
+
+  // Jump relative to the current bytecode by |jump_offset| if the
+  // word values |lhs| and |rhs| are equal.
+  void JumpIfWordEqual(Node* lhs, Node* rhs, Node* jump_offset);
+
+  // Returns from the function.
+  void Return();
+
+  // Dispatch to the bytecode.
+  void Dispatch();
+
+  // Abort with the given bailout reason.
+  void Abort(BailoutReason bailout_reason);
+
+ protected:
+  static bool TargetSupportsUnalignedAccess();
+
+  // Protected helpers (for testing) which delegate to RawMachineAssembler.
+  CallDescriptor* call_descriptor() const;
+  Graph* graph();
+
+ private:
+  // Returns a raw pointer to start of the register file on the stack.
+  Node* RegisterFileRawPointer();
+  // Returns a tagged pointer to the current function's BytecodeArray object.
+  Node* BytecodeArrayTaggedPointer();
+  // Returns the offset from the BytecodeArrayPointer of the current bytecode.
+  Node* BytecodeOffset();
+  // Returns a raw pointer to first entry in the interpreter dispatch table.
+  Node* DispatchTableRawPointer();
+
+  // Saves and restores interpreter bytecode offset to the interpreter stack
+  // frame when performing a call.
+  void CallPrologue();
+  void CallEpilogue();
+
+  // Returns the offset of register |index| relative to RegisterFilePointer().
+  Node* RegisterFrameOffset(Node* index);
+
+  Node* SmiShiftBitsConstant();
+  Node* BytecodeOperand(int operand_index);
+  Node* BytecodeOperandSignExtended(int operand_index);
+  Node* BytecodeOperandShort(int operand_index);
+  Node* BytecodeOperandShortSignExtended(int operand_index);
+
+  Node* CallN(CallDescriptor* descriptor, Node* code_target, Node** args);
+  Node* CallIC(CallInterfaceDescriptor descriptor, Node* target, Node** args);
+
+  // Returns BytecodeOffset() advanced by delta bytecodes. Note: this does not
+  // update BytecodeOffset() itself.
+  Node* Advance(int delta);
+  Node* Advance(Node* delta);
+
+  // Starts next instruction dispatch at |new_bytecode_offset|.
+  void DispatchTo(Node* new_bytecode_offset);
+
+  // Abort operations for debug code.
+  void AbortIfWordNotEqual(Node* lhs, Node* rhs, BailoutReason bailout_reason);
+
+  // Private helpers which delegate to RawMachineAssembler.
+  Isolate* isolate();
+  Zone* zone();
+
+  interpreter::Bytecode bytecode_;
+  base::SmartPointer<RawMachineAssembler> raw_assembler_;
+
+  Node* accumulator_;
+  Node* bytecode_offset_;
+  Node* context_;
+
+  bool code_generated_;
+
+  DISALLOW_COPY_AND_ASSIGN(InterpreterAssembler);
+};
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_INTERPRETER_ASSEMBLER_H_
diff --git a/src/compiler/js-builtin-reducer.cc b/src/compiler/js-builtin-reducer.cc
index 263b0fe..a7a7da5 100644
--- a/src/compiler/js-builtin-reducer.cc
+++ b/src/compiler/js-builtin-reducer.cc
@@ -2,12 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "src/compiler/diamond.h"
-#include "src/compiler/graph-inl.h"
 #include "src/compiler/js-builtin-reducer.h"
 #include "src/compiler/js-graph.h"
 #include "src/compiler/node-matchers.h"
-#include "src/compiler/node-properties-inl.h"
+#include "src/compiler/node-properties.h"
+#include "src/compiler/simplified-operator.h"
+#include "src/objects-inl.h"
 #include "src/types.h"
 
 namespace v8 {
@@ -15,17 +15,6 @@
 namespace compiler {
 
 
-// Helper method that assumes replacement nodes are pure values that don't
-// produce an effect. Replaces {node} with {reduction} and relaxes effects.
-static Reduction ReplaceWithPureReduction(Node* node, Reduction reduction) {
-  if (reduction.Changed()) {
-    NodeProperties::ReplaceWithValue(node, reduction.replacement());
-    return reduction;
-  }
-  return Reducer::NoChange();
-}
-
-
 // Helper class to access JSCallFunction nodes that are potential candidates
 // for reduction when they have a BuiltinFunctionId associated with them.
 class JSCallReduction {
@@ -36,17 +25,17 @@
   // constant callee being a well-known builtin with a BuiltinFunctionId.
   bool HasBuiltinFunctionId() {
     if (node_->opcode() != IrOpcode::kJSCallFunction) return false;
-    HeapObjectMatcher<Object> m(NodeProperties::GetValueInput(node_, 0));
-    if (!m.HasValue() || !m.Value().handle()->IsJSFunction()) return false;
-    Handle<JSFunction> function = Handle<JSFunction>::cast(m.Value().handle());
+    HeapObjectMatcher m(NodeProperties::GetValueInput(node_, 0));
+    if (!m.HasValue() || !m.Value()->IsJSFunction()) return false;
+    Handle<JSFunction> function = Handle<JSFunction>::cast(m.Value());
     return function->shared()->HasBuiltinFunctionId();
   }
 
   // Retrieves the BuiltinFunctionId as described above.
   BuiltinFunctionId GetBuiltinFunctionId() {
     DCHECK_EQ(IrOpcode::kJSCallFunction, node_->opcode());
-    HeapObjectMatcher<Object> m(NodeProperties::GetValueInput(node_, 0));
-    Handle<JSFunction> function = Handle<JSFunction>::cast(m.Value().handle());
+    HeapObjectMatcher m(NodeProperties::GetValueInput(node_, 0));
+    Handle<JSFunction> function = Handle<JSFunction>::cast(m.Value());
     return function->shared()->builtin_function_id();
   }
 
@@ -56,20 +45,20 @@
   // Determines whether the call takes one input of the given type.
   bool InputsMatchOne(Type* t1) {
     return GetJSCallArity() == 1 &&
-           NodeProperties::GetBounds(GetJSCallInput(0)).upper->Is(t1);
+           NodeProperties::GetType(GetJSCallInput(0))->Is(t1);
   }
 
   // Determines whether the call takes two inputs of the given types.
   bool InputsMatchTwo(Type* t1, Type* t2) {
     return GetJSCallArity() == 2 &&
-           NodeProperties::GetBounds(GetJSCallInput(0)).upper->Is(t1) &&
-           NodeProperties::GetBounds(GetJSCallInput(1)).upper->Is(t2);
+           NodeProperties::GetType(GetJSCallInput(0))->Is(t1) &&
+           NodeProperties::GetType(GetJSCallInput(1))->Is(t2);
   }
 
   // Determines whether the call takes inputs all of the given type.
   bool InputsMatchAll(Type* t) {
     for (int i = 0; i < GetJSCallArity(); i++) {
-      if (!NodeProperties::GetBounds(GetJSCallInput(i)).upper->Is(t)) {
+      if (!NodeProperties::GetType(GetJSCallInput(i))->Is(t)) {
         return false;
       }
     }
@@ -97,40 +86,8 @@
 };
 
 
-JSBuiltinReducer::JSBuiltinReducer(JSGraph* jsgraph)
-    : jsgraph_(jsgraph), simplified_(jsgraph->zone()) {}
-
-
-// ECMA-262, section 15.8.2.1.
-Reduction JSBuiltinReducer::ReduceMathAbs(Node* node) {
-  JSCallReduction r(node);
-  if (r.InputsMatchOne(Type::Unsigned32())) {
-    // Math.abs(a:uint32) -> a
-    return Replace(r.left());
-  }
-  if (r.InputsMatchOne(Type::Number())) {
-    // Math.abs(a:number) -> (a > 0 ? a : 0 - a)
-    Node* const value = r.left();
-    Node* const zero = jsgraph()->ZeroConstant();
-    return Replace(graph()->NewNode(
-        common()->Select(kMachNone),
-        graph()->NewNode(simplified()->NumberLessThan(), zero, value), value,
-        graph()->NewNode(simplified()->NumberSubtract(), zero, value)));
-  }
-  return NoChange();
-}
-
-
-// ECMA-262, section 15.8.2.17.
-Reduction JSBuiltinReducer::ReduceMathSqrt(Node* node) {
-  JSCallReduction r(node);
-  if (r.InputsMatchOne(Type::Number())) {
-    // Math.sqrt(a:number) -> Float64Sqrt(a)
-    Node* value = graph()->NewNode(machine()->Float64Sqrt(), r.left());
-    return Replace(value);
-  }
-  return NoChange();
-}
+JSBuiltinReducer::JSBuiltinReducer(Editor* editor, JSGraph* jsgraph)
+    : AdvancedReducer(editor), jsgraph_(jsgraph) {}
 
 
 // ECMA-262, section 15.8.2.11.
@@ -150,9 +107,9 @@
     for (int i = 1; i < r.GetJSCallArity(); i++) {
       Node* const input = r.GetJSCallInput(i);
       value = graph()->NewNode(
-          common()->Select(kMachNone),
-          graph()->NewNode(simplified()->NumberLessThan(), input, value), input,
-          value);
+          common()->Select(MachineRepresentation::kNone),
+          graph()->NewNode(simplified()->NumberLessThan(), input, value), value,
+          input);
     }
     return Replace(value);
   }
@@ -185,62 +142,40 @@
 }
 
 
-// ES6 draft 10-14-14, section 20.2.2.16.
-Reduction JSBuiltinReducer::ReduceMathFloor(Node* node) {
-  if (!machine()->HasFloat64Floor()) return NoChange();
-  JSCallReduction r(node);
-  if (r.InputsMatchOne(Type::Number())) {
-    // Math.floor(a:number) -> Float64Floor(a)
-    Node* value = graph()->NewNode(machine()->Float64Floor(), r.left());
-    return Replace(value);
-  }
-  return NoChange();
-}
-
-
-// ES6 draft 10-14-14, section 20.2.2.10.
-Reduction JSBuiltinReducer::ReduceMathCeil(Node* node) {
-  if (!machine()->HasFloat64Ceil()) return NoChange();
-  JSCallReduction r(node);
-  if (r.InputsMatchOne(Type::Number())) {
-    // Math.ceil(a:number) -> Float64Ceil(a)
-    Node* value = graph()->NewNode(machine()->Float64Ceil(), r.left());
-    return Replace(value);
-  }
-  return NoChange();
-}
-
-
 Reduction JSBuiltinReducer::Reduce(Node* node) {
+  Reduction reduction = NoChange();
   JSCallReduction r(node);
 
   // Dispatch according to the BuiltinFunctionId if present.
   if (!r.HasBuiltinFunctionId()) return NoChange();
   switch (r.GetBuiltinFunctionId()) {
-    case kMathAbs:
-      return ReplaceWithPureReduction(node, ReduceMathAbs(node));
-    case kMathSqrt:
-      return ReplaceWithPureReduction(node, ReduceMathSqrt(node));
     case kMathMax:
-      return ReplaceWithPureReduction(node, ReduceMathMax(node));
+      reduction = ReduceMathMax(node);
+      break;
     case kMathImul:
-      return ReplaceWithPureReduction(node, ReduceMathImul(node));
+      reduction = ReduceMathImul(node);
+      break;
     case kMathFround:
-      return ReplaceWithPureReduction(node, ReduceMathFround(node));
-    case kMathFloor:
-      return ReplaceWithPureReduction(node, ReduceMathFloor(node));
-    case kMathCeil:
-      return ReplaceWithPureReduction(node, ReduceMathCeil(node));
+      reduction = ReduceMathFround(node);
+      break;
     default:
       break;
   }
-  return NoChange();
+
+  // Replace builtin call assuming replacement nodes are pure values that don't
+  // produce an effect. Replaces {node} with {reduction} and relaxes effects.
+  if (reduction.Changed()) ReplaceWithValue(node, reduction.replacement());
+
+  return reduction;
 }
 
 
 Graph* JSBuiltinReducer::graph() const { return jsgraph()->graph(); }
 
 
+Isolate* JSBuiltinReducer::isolate() const { return jsgraph()->isolate(); }
+
+
 CommonOperatorBuilder* JSBuiltinReducer::common() const {
   return jsgraph()->common();
 }
@@ -250,6 +185,11 @@
   return jsgraph()->machine();
 }
 
+
+SimplifiedOperatorBuilder* JSBuiltinReducer::simplified() const {
+  return jsgraph()->simplified();
+}
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/src/compiler/js-builtin-reducer.h b/src/compiler/js-builtin-reducer.h
index ac6f266..cfacdc1 100644
--- a/src/compiler/js-builtin-reducer.h
+++ b/src/compiler/js-builtin-reducer.h
@@ -6,7 +6,6 @@
 #define V8_COMPILER_JS_BUILTIN_REDUCER_H_
 
 #include "src/compiler/graph-reducer.h"
-#include "src/compiler/simplified-operator.h"
 
 namespace v8 {
 namespace internal {
@@ -16,32 +15,30 @@
 class CommonOperatorBuilder;
 class JSGraph;
 class MachineOperatorBuilder;
+class SimplifiedOperatorBuilder;
 
 
-class JSBuiltinReducer FINAL : public Reducer {
+class JSBuiltinReducer final : public AdvancedReducer {
  public:
-  explicit JSBuiltinReducer(JSGraph* jsgraph);
-  ~JSBuiltinReducer() FINAL {}
+  explicit JSBuiltinReducer(Editor* editor, JSGraph* jsgraph);
+  ~JSBuiltinReducer() final {}
 
-  Reduction Reduce(Node* node) FINAL;
+  Reduction Reduce(Node* node) final;
 
  private:
-  Reduction ReduceMathAbs(Node* node);
-  Reduction ReduceMathSqrt(Node* node);
+  Reduction ReduceFunctionCall(Node* node);
   Reduction ReduceMathMax(Node* node);
   Reduction ReduceMathImul(Node* node);
   Reduction ReduceMathFround(Node* node);
-  Reduction ReduceMathFloor(Node* node);
-  Reduction ReduceMathCeil(Node* node);
 
-  JSGraph* jsgraph() const { return jsgraph_; }
   Graph* graph() const;
+  JSGraph* jsgraph() const { return jsgraph_; }
+  Isolate* isolate() const;
   CommonOperatorBuilder* common() const;
   MachineOperatorBuilder* machine() const;
-  SimplifiedOperatorBuilder* simplified() { return &simplified_; }
+  SimplifiedOperatorBuilder* simplified() const;
 
   JSGraph* jsgraph_;
-  SimplifiedOperatorBuilder simplified_;
 };
 
 }  // namespace compiler
diff --git a/src/compiler/js-call-reducer.cc b/src/compiler/js-call-reducer.cc
new file mode 100644
index 0000000..a15d6fd
--- /dev/null
+++ b/src/compiler/js-call-reducer.cc
@@ -0,0 +1,557 @@
+// Copyright 2015 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/js-call-reducer.h"
+
+#include "src/compiler/js-graph.h"
+#include "src/compiler/node-matchers.h"
+#include "src/objects-inl.h"
+#include "src/type-feedback-vector-inl.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+namespace {
+
+VectorSlotPair CallCountFeedback(VectorSlotPair p) {
+  // Extract call count from {p}.
+  if (!p.IsValid()) return VectorSlotPair();
+  CallICNexus n(p.vector(), p.slot());
+  int const call_count = n.ExtractCallCount();
+  if (call_count <= 0) return VectorSlotPair();
+
+  // Create megamorphic CallIC feedback with the given {call_count}.
+  StaticFeedbackVectorSpec spec;
+  FeedbackVectorSlot slot = spec.AddCallICSlot();
+  Handle<TypeFeedbackMetadata> metadata =
+      TypeFeedbackMetadata::New(n.GetIsolate(), &spec);
+  Handle<TypeFeedbackVector> vector =
+      TypeFeedbackVector::New(n.GetIsolate(), metadata);
+  CallICNexus nexus(vector, slot);
+  nexus.ConfigureMegamorphic(call_count);
+  return VectorSlotPair(vector, slot);
+}
+
+}  // namespace
+
+
+Reduction JSCallReducer::Reduce(Node* node) {
+  switch (node->opcode()) {
+    case IrOpcode::kJSCallConstruct:
+      return ReduceJSCallConstruct(node);
+    case IrOpcode::kJSCallFunction:
+      return ReduceJSCallFunction(node);
+    default:
+      break;
+  }
+  return NoChange();
+}
+
+
+// ES6 section 22.1.1 The Array Constructor
+Reduction JSCallReducer::ReduceArrayConstructor(Node* node) {
+  DCHECK_EQ(IrOpcode::kJSCallFunction, node->opcode());
+  Node* target = NodeProperties::GetValueInput(node, 0);
+  CallFunctionParameters const& p = CallFunctionParametersOf(node->op());
+
+  // Check if we have an allocation site from the CallIC.
+  Handle<AllocationSite> site;
+  if (p.feedback().IsValid()) {
+    CallICNexus nexus(p.feedback().vector(), p.feedback().slot());
+    Handle<Object> feedback(nexus.GetFeedback(), isolate());
+    if (feedback->IsAllocationSite()) {
+      site = Handle<AllocationSite>::cast(feedback);
+    }
+  }
+
+  // Turn the {node} into a {JSCreateArray} call.
+  DCHECK_LE(2u, p.arity());
+  size_t const arity = p.arity() - 2;
+  NodeProperties::ReplaceValueInput(node, target, 0);
+  NodeProperties::ReplaceValueInput(node, target, 1);
+  NodeProperties::RemoveFrameStateInput(node, 1);
+  // TODO(bmeurer): We might need to propagate the tail call mode to
+  // the JSCreateArray operator, because an Array call in tail call
+  // position must always properly consume the parent stack frame.
+  NodeProperties::ChangeOp(node, javascript()->CreateArray(arity, site));
+  return Changed(node);
+}
+
+
+// ES6 section 20.1.1 The Number Constructor
+Reduction JSCallReducer::ReduceNumberConstructor(Node* node) {
+  DCHECK_EQ(IrOpcode::kJSCallFunction, node->opcode());
+  CallFunctionParameters const& p = CallFunctionParametersOf(node->op());
+
+  // Turn the {node} into a {JSToNumber} call.
+  DCHECK_LE(2u, p.arity());
+  Node* value = (p.arity() == 2) ? jsgraph()->ZeroConstant()
+                                 : NodeProperties::GetValueInput(node, 2);
+  NodeProperties::RemoveFrameStateInput(node, 1);
+  NodeProperties::ReplaceValueInputs(node, value);
+  NodeProperties::ChangeOp(node, javascript()->ToNumber());
+  return Changed(node);
+}
+
+
+// ES6 section 19.2.3.1 Function.prototype.apply ( thisArg, argArray )
+Reduction JSCallReducer::ReduceFunctionPrototypeApply(Node* node) {
+  DCHECK_EQ(IrOpcode::kJSCallFunction, node->opcode());
+  Node* target = NodeProperties::GetValueInput(node, 0);
+  CallFunctionParameters const& p = CallFunctionParametersOf(node->op());
+  Handle<JSFunction> apply =
+      Handle<JSFunction>::cast(HeapObjectMatcher(target).Value());
+  size_t arity = p.arity();
+  DCHECK_LE(2u, arity);
+  ConvertReceiverMode convert_mode = ConvertReceiverMode::kAny;
+  if (arity == 2) {
+    // Neither thisArg nor argArray was provided.
+    convert_mode = ConvertReceiverMode::kNullOrUndefined;
+    node->ReplaceInput(0, node->InputAt(1));
+    node->ReplaceInput(1, jsgraph()->UndefinedConstant());
+  } else if (arity == 3) {
+    // The argArray was not provided, just remove the {target}.
+    node->RemoveInput(0);
+    --arity;
+  } else if (arity == 4) {
+    // Check if argArray is an arguments object, and {node} is the only value
+    // user of argArray (except for value uses in frame states).
+    Node* arg_array = NodeProperties::GetValueInput(node, 3);
+    if (arg_array->opcode() != IrOpcode::kJSCreateArguments) return NoChange();
+    for (Edge edge : arg_array->use_edges()) {
+      if (edge.from()->opcode() == IrOpcode::kStateValues) continue;
+      if (!NodeProperties::IsValueEdge(edge)) continue;
+      if (edge.from() == node) continue;
+      return NoChange();
+    }
+    // Get to the actual frame state from which to extract the arguments;
+    // we can only optimize this in case the {node} was already inlined into
+    // some other function (and same for the {arg_array}).
+    CreateArgumentsParameters const& p =
+        CreateArgumentsParametersOf(arg_array->op());
+    Node* frame_state = NodeProperties::GetFrameStateInput(arg_array, 0);
+    Node* outer_state = frame_state->InputAt(kFrameStateOuterStateInput);
+    if (outer_state->opcode() != IrOpcode::kFrameState) return NoChange();
+    FrameStateInfo outer_info = OpParameter<FrameStateInfo>(outer_state);
+    if (outer_info.type() == FrameStateType::kArgumentsAdaptor) {
+      // Need to take the parameters from the arguments adaptor.
+      frame_state = outer_state;
+    }
+    FrameStateInfo state_info = OpParameter<FrameStateInfo>(frame_state);
+    if (p.type() == CreateArgumentsParameters::kMappedArguments) {
+      // Mapped arguments (sloppy mode) cannot be handled if they are aliased.
+      Handle<SharedFunctionInfo> shared;
+      if (!state_info.shared_info().ToHandle(&shared)) return NoChange();
+      if (shared->internal_formal_parameter_count() != 0) return NoChange();
+    }
+    // Remove the argArray input from the {node}.
+    node->RemoveInput(static_cast<int>(--arity));
+    // Add the actual parameters to the {node}, skipping the receiver.
+    Node* const parameters = frame_state->InputAt(kFrameStateParametersInput);
+    for (int i = p.start_index() + 1; i < state_info.parameter_count(); ++i) {
+      node->InsertInput(graph()->zone(), static_cast<int>(arity),
+                        parameters->InputAt(i));
+      ++arity;
+    }
+    // Drop the {target} from the {node}.
+    node->RemoveInput(0);
+    --arity;
+  } else {
+    return NoChange();
+  }
+  // Change {node} to the new {JSCallFunction} operator.
+  NodeProperties::ChangeOp(
+      node, javascript()->CallFunction(arity, p.language_mode(),
+                                       CallCountFeedback(p.feedback()),
+                                       convert_mode, p.tail_call_mode()));
+  // Change context of {node} to the Function.prototype.apply context,
+  // to ensure any exception is thrown in the correct context.
+  NodeProperties::ReplaceContextInput(
+      node, jsgraph()->HeapConstant(handle(apply->context(), isolate())));
+  // Try to further reduce the JSCallFunction {node}.
+  Reduction const reduction = ReduceJSCallFunction(node);
+  return reduction.Changed() ? reduction : Changed(node);
+}
+
+
+// ES6 section 19.2.3.3 Function.prototype.call (thisArg, ...args)
+Reduction JSCallReducer::ReduceFunctionPrototypeCall(Node* node) {
+  DCHECK_EQ(IrOpcode::kJSCallFunction, node->opcode());
+  CallFunctionParameters const& p = CallFunctionParametersOf(node->op());
+  Handle<JSFunction> call = Handle<JSFunction>::cast(
+      HeapObjectMatcher(NodeProperties::GetValueInput(node, 0)).Value());
+  // Change context of {node} to the Function.prototype.call context,
+  // to ensure any exception is thrown in the correct context.
+  NodeProperties::ReplaceContextInput(
+      node, jsgraph()->HeapConstant(handle(call->context(), isolate())));
+  // Remove the target from {node} and use the receiver as target instead, and
+  // the thisArg becomes the new target.  If thisArg was not provided, insert
+  // undefined instead.
+  size_t arity = p.arity();
+  DCHECK_LE(2u, arity);
+  ConvertReceiverMode convert_mode;
+  if (arity == 2) {
+    // The thisArg was not provided, use undefined as receiver.
+    convert_mode = ConvertReceiverMode::kNullOrUndefined;
+    node->ReplaceInput(0, node->InputAt(1));
+    node->ReplaceInput(1, jsgraph()->UndefinedConstant());
+  } else {
+    // Just remove the target, which is the first value input.
+    convert_mode = ConvertReceiverMode::kAny;
+    node->RemoveInput(0);
+    --arity;
+  }
+  NodeProperties::ChangeOp(
+      node, javascript()->CallFunction(arity, p.language_mode(),
+                                       CallCountFeedback(p.feedback()),
+                                       convert_mode, p.tail_call_mode()));
+  // Try to further reduce the JSCallFunction {node}.
+  Reduction const reduction = ReduceJSCallFunction(node);
+  return reduction.Changed() ? reduction : Changed(node);
+}
+
+
+Reduction JSCallReducer::ReduceJSCallFunction(Node* node) {
+  DCHECK_EQ(IrOpcode::kJSCallFunction, node->opcode());
+  CallFunctionParameters const& p = CallFunctionParametersOf(node->op());
+  Node* target = NodeProperties::GetValueInput(node, 0);
+  Node* context = NodeProperties::GetContextInput(node);
+  Node* frame_state = NodeProperties::GetFrameStateInput(node, 1);
+  Node* control = NodeProperties::GetControlInput(node);
+  Node* effect = NodeProperties::GetEffectInput(node);
+
+  // Try to specialize JSCallFunction {node}s with constant {target}s.
+  HeapObjectMatcher m(target);
+  if (m.HasValue()) {
+    if (m.Value()->IsJSFunction()) {
+      Handle<JSFunction> function = Handle<JSFunction>::cast(m.Value());
+      Handle<SharedFunctionInfo> shared(function->shared(), isolate());
+
+      // Raise a TypeError if the {target} is a "classConstructor".
+      if (IsClassConstructor(shared->kind())) {
+        NodeProperties::RemoveFrameStateInput(node, 0);
+        NodeProperties::ReplaceValueInputs(node, target);
+        NodeProperties::ChangeOp(
+            node, javascript()->CallRuntime(
+                      Runtime::kThrowConstructorNonCallableError, 1));
+        return Changed(node);
+      }
+
+      // Check for known builtin functions.
+      if (shared->HasBuiltinFunctionId()) {
+        switch (shared->builtin_function_id()) {
+          case kFunctionApply:
+            return ReduceFunctionPrototypeApply(node);
+          case kFunctionCall:
+            return ReduceFunctionPrototypeCall(node);
+          default:
+            break;
+        }
+      }
+
+      // Check for the Array constructor.
+      if (*function == function->native_context()->array_function()) {
+        return ReduceArrayConstructor(node);
+      }
+
+      // Check for the Number constructor.
+      if (*function == function->native_context()->number_function()) {
+        return ReduceNumberConstructor(node);
+      }
+    } else if (m.Value()->IsJSBoundFunction()) {
+      Handle<JSBoundFunction> function =
+          Handle<JSBoundFunction>::cast(m.Value());
+      Handle<JSReceiver> bound_target_function(
+          function->bound_target_function(), isolate());
+      Handle<Object> bound_this(function->bound_this(), isolate());
+      Handle<FixedArray> bound_arguments(function->bound_arguments(),
+                                         isolate());
+      CallFunctionParameters const& p = CallFunctionParametersOf(node->op());
+      ConvertReceiverMode const convert_mode =
+          (bound_this->IsNull() || bound_this->IsUndefined())
+              ? ConvertReceiverMode::kNullOrUndefined
+              : ConvertReceiverMode::kNotNullOrUndefined;
+      size_t arity = p.arity();
+      DCHECK_LE(2u, arity);
+      // Patch {node} to use [[BoundTargetFunction]] and [[BoundThis]].
+      NodeProperties::ReplaceValueInput(
+          node, jsgraph()->Constant(bound_target_function), 0);
+      NodeProperties::ReplaceValueInput(node, jsgraph()->Constant(bound_this),
+                                        1);
+      // Insert the [[BoundArguments]] for {node}.
+      for (int i = 0; i < bound_arguments->length(); ++i) {
+        node->InsertInput(
+            graph()->zone(), i + 2,
+            jsgraph()->Constant(handle(bound_arguments->get(i), isolate())));
+        arity++;
+      }
+      NodeProperties::ChangeOp(
+          node, javascript()->CallFunction(arity, p.language_mode(),
+                                           CallCountFeedback(p.feedback()),
+                                           convert_mode, p.tail_call_mode()));
+      // Try to further reduce the JSCallFunction {node}.
+      Reduction const reduction = ReduceJSCallFunction(node);
+      return reduction.Changed() ? reduction : Changed(node);
+    }
+
+    // Don't mess with other {node}s that have a constant {target}.
+    // TODO(bmeurer): Also support proxies here.
+    return NoChange();
+  }
+
+  // Not much we can do if deoptimization support is disabled.
+  if (!(flags() & kDeoptimizationEnabled)) return NoChange();
+
+  // Extract feedback from the {node} using the CallICNexus.
+  if (!p.feedback().IsValid()) return NoChange();
+  CallICNexus nexus(p.feedback().vector(), p.feedback().slot());
+  Handle<Object> feedback(nexus.GetFeedback(), isolate());
+  if (feedback->IsAllocationSite()) {
+    // Retrieve the Array function from the {node}.
+    Node* array_function;
+    Handle<Context> native_context;
+    if (GetNativeContext(node).ToHandle(&native_context)) {
+      array_function = jsgraph()->HeapConstant(
+          handle(native_context->array_function(), isolate()));
+    } else {
+      Node* native_context = effect = graph()->NewNode(
+          javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true),
+          context, context, effect);
+      array_function = effect = graph()->NewNode(
+          javascript()->LoadContext(0, Context::ARRAY_FUNCTION_INDEX, true),
+          native_context, native_context, effect);
+    }
+
+    // Check that the {target} is still the {array_function}.
+    Node* check = effect =
+        graph()->NewNode(javascript()->StrictEqual(), target, array_function,
+                         context, effect, control);
+    Node* branch =
+        graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
+    Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+    Node* deoptimize =
+        graph()->NewNode(common()->Deoptimize(DeoptimizeKind::kEager),
+                         frame_state, effect, if_false);
+    // TODO(bmeurer): This should be on the AdvancedReducer somehow.
+    NodeProperties::MergeControlToEnd(graph(), common(), deoptimize);
+    control = graph()->NewNode(common()->IfTrue(), branch);
+
+    // Turn the {node} into a {JSCreateArray} call.
+    NodeProperties::ReplaceValueInput(node, array_function, 0);
+    NodeProperties::ReplaceEffectInput(node, effect);
+    NodeProperties::ReplaceControlInput(node, control);
+    return ReduceArrayConstructor(node);
+  } else if (feedback->IsWeakCell()) {
+    Handle<WeakCell> cell = Handle<WeakCell>::cast(feedback);
+    if (cell->value()->IsJSFunction()) {
+      Node* target_function =
+          jsgraph()->Constant(handle(cell->value(), isolate()));
+
+      // Check that the {target} is still the {target_function}.
+      Node* check = effect =
+          graph()->NewNode(javascript()->StrictEqual(), target, target_function,
+                           context, effect, control);
+      Node* branch =
+          graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
+      Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+      Node* deoptimize =
+          graph()->NewNode(common()->Deoptimize(DeoptimizeKind::kEager),
+                           frame_state, effect, if_false);
+      // TODO(bmeurer): This should be on the AdvancedReducer somehow.
+      NodeProperties::MergeControlToEnd(graph(), common(), deoptimize);
+      control = graph()->NewNode(common()->IfTrue(), branch);
+
+      // Specialize the JSCallFunction node to the {target_function}.
+      NodeProperties::ReplaceValueInput(node, target_function, 0);
+      NodeProperties::ReplaceEffectInput(node, effect);
+      NodeProperties::ReplaceControlInput(node, control);
+
+      // Try to further reduce the JSCallFunction {node}.
+      Reduction const reduction = ReduceJSCallFunction(node);
+      return reduction.Changed() ? reduction : Changed(node);
+    }
+  }
+  return NoChange();
+}
+
+
+Reduction JSCallReducer::ReduceJSCallConstruct(Node* node) {
+  DCHECK_EQ(IrOpcode::kJSCallConstruct, node->opcode());
+  CallConstructParameters const& p = CallConstructParametersOf(node->op());
+  DCHECK_LE(2u, p.arity());
+  int const arity = static_cast<int>(p.arity() - 2);
+  Node* target = NodeProperties::GetValueInput(node, 0);
+  Node* new_target = NodeProperties::GetValueInput(node, arity + 1);
+  Node* context = NodeProperties::GetContextInput(node);
+  Node* frame_state = NodeProperties::GetFrameStateInput(node, 1);
+  Node* effect = NodeProperties::GetEffectInput(node);
+  Node* control = NodeProperties::GetControlInput(node);
+
+  // Try to specialize JSCallConstruct {node}s with constant {target}s.
+  HeapObjectMatcher m(target);
+  if (m.HasValue()) {
+    if (m.Value()->IsJSFunction()) {
+      Handle<JSFunction> function = Handle<JSFunction>::cast(m.Value());
+
+      // Raise a TypeError if the {target} is not a constructor.
+      if (!function->IsConstructor()) {
+        // Drop the lazy bailout location and use the eager bailout point for
+        // the runtime function (actually as lazy bailout point). It doesn't
+        // really matter which bailout location we use since we never really
+        // go back after throwing the exception.
+        NodeProperties::RemoveFrameStateInput(node, 0);
+        NodeProperties::ReplaceValueInputs(node, target);
+        NodeProperties::ChangeOp(
+            node,
+            javascript()->CallRuntime(Runtime::kThrowCalledNonCallable, 1));
+        return Changed(node);
+      }
+
+      // Check for the ArrayConstructor.
+      if (*function == function->native_context()->array_function()) {
+        // Check if we have an allocation site.
+        Handle<AllocationSite> site;
+        if (p.feedback().IsValid()) {
+          Handle<Object> feedback(
+              p.feedback().vector()->Get(p.feedback().slot()), isolate());
+          if (feedback->IsAllocationSite()) {
+            site = Handle<AllocationSite>::cast(feedback);
+          }
+        }
+
+        // Turn the {node} into a {JSCreateArray} call.
+        NodeProperties::RemoveFrameStateInput(node, 1);
+        for (int i = arity; i > 0; --i) {
+          NodeProperties::ReplaceValueInput(
+              node, NodeProperties::GetValueInput(node, i), i + 1);
+        }
+        NodeProperties::ReplaceValueInput(node, new_target, 1);
+        NodeProperties::ChangeOp(node, javascript()->CreateArray(arity, site));
+        return Changed(node);
+      }
+    }
+
+    // Don't mess with other {node}s that have a constant {target}.
+    // TODO(bmeurer): Also support optimizing bound functions and proxies here.
+    return NoChange();
+  }
+
+  // Not much we can do if deoptimization support is disabled.
+  if (!(flags() & kDeoptimizationEnabled)) return NoChange();
+
+  // TODO(mvstanton): Use ConstructICNexus here, once available.
+  Handle<Object> feedback;
+  if (!p.feedback().IsValid()) return NoChange();
+  feedback = handle(p.feedback().vector()->Get(p.feedback().slot()), isolate());
+  if (feedback->IsAllocationSite()) {
+    // The feedback is an AllocationSite, which means we have called the
+    // Array function and collected transition (and pretenuring) feedback
+    // for the resulting arrays.  This has to be kept in sync with the
+    // implementation of the CallConstructStub.
+    Handle<AllocationSite> site = Handle<AllocationSite>::cast(feedback);
+
+    // Retrieve the Array function from the {node}.
+    Node* array_function;
+    Handle<Context> native_context;
+    if (GetNativeContext(node).ToHandle(&native_context)) {
+      array_function = jsgraph()->HeapConstant(
+          handle(native_context->array_function(), isolate()));
+    } else {
+      Node* native_context = effect = graph()->NewNode(
+          javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true),
+          context, context, effect);
+      array_function = effect = graph()->NewNode(
+          javascript()->LoadContext(0, Context::ARRAY_FUNCTION_INDEX, true),
+          native_context, native_context, effect);
+    }
+
+    // Check that the {target} is still the {array_function}.
+    Node* check = effect =
+        graph()->NewNode(javascript()->StrictEqual(), target, array_function,
+                         context, effect, control);
+    Node* branch =
+        graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
+    Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+    Node* deoptimize =
+        graph()->NewNode(common()->Deoptimize(DeoptimizeKind::kEager),
+                         frame_state, effect, if_false);
+    // TODO(bmeurer): This should be on the AdvancedReducer somehow.
+    NodeProperties::MergeControlToEnd(graph(), common(), deoptimize);
+    control = graph()->NewNode(common()->IfTrue(), branch);
+
+    // Turn the {node} into a {JSCreateArray} call.
+    NodeProperties::ReplaceEffectInput(node, effect);
+    NodeProperties::ReplaceControlInput(node, control);
+    NodeProperties::RemoveFrameStateInput(node, 1);
+    for (int i = arity; i > 0; --i) {
+      NodeProperties::ReplaceValueInput(
+          node, NodeProperties::GetValueInput(node, i), i + 1);
+    }
+    NodeProperties::ReplaceValueInput(node, new_target, 1);
+    NodeProperties::ChangeOp(node, javascript()->CreateArray(arity, site));
+    return Changed(node);
+  } else if (feedback->IsWeakCell()) {
+    Handle<WeakCell> cell = Handle<WeakCell>::cast(feedback);
+    if (cell->value()->IsJSFunction()) {
+      Node* target_function =
+          jsgraph()->Constant(handle(cell->value(), isolate()));
+
+      // Check that the {target} is still the {target_function}.
+      Node* check = effect =
+          graph()->NewNode(javascript()->StrictEqual(), target, target_function,
+                           context, effect, control);
+      Node* branch =
+          graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
+      Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+      Node* deoptimize =
+          graph()->NewNode(common()->Deoptimize(DeoptimizeKind::kEager),
+                           frame_state, effect, if_false);
+      // TODO(bmeurer): This should be on the AdvancedReducer somehow.
+      NodeProperties::MergeControlToEnd(graph(), common(), deoptimize);
+      control = graph()->NewNode(common()->IfTrue(), branch);
+
+      // Specialize the JSCallConstruct node to the {target_function}.
+      NodeProperties::ReplaceValueInput(node, target_function, 0);
+      NodeProperties::ReplaceEffectInput(node, effect);
+      NodeProperties::ReplaceControlInput(node, control);
+      if (target == new_target) {
+        NodeProperties::ReplaceValueInput(node, target_function, arity + 1);
+      }
+
+      // Try to further reduce the JSCallConstruct {node}.
+      Reduction const reduction = ReduceJSCallConstruct(node);
+      return reduction.Changed() ? reduction : Changed(node);
+    }
+  }
+
+  return NoChange();
+}
+
+
+MaybeHandle<Context> JSCallReducer::GetNativeContext(Node* node) {
+  Node* const context = NodeProperties::GetContextInput(node);
+  return NodeProperties::GetSpecializationNativeContext(context,
+                                                        native_context());
+}
+
+
+Graph* JSCallReducer::graph() const { return jsgraph()->graph(); }
+
+
+Isolate* JSCallReducer::isolate() const { return jsgraph()->isolate(); }
+
+
+CommonOperatorBuilder* JSCallReducer::common() const {
+  return jsgraph()->common();
+}
+
+
+JSOperatorBuilder* JSCallReducer::javascript() const {
+  return jsgraph()->javascript();
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/js-call-reducer.h b/src/compiler/js-call-reducer.h
new file mode 100644
index 0000000..9ffae15
--- /dev/null
+++ b/src/compiler/js-call-reducer.h
@@ -0,0 +1,67 @@
+// Copyright 2015 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.
+
+#ifndef V8_COMPILER_JS_CALL_REDUCER_H_
+#define V8_COMPILER_JS_CALL_REDUCER_H_
+
+#include "src/base/flags.h"
+#include "src/compiler/graph-reducer.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+// Forward declarations.
+class CommonOperatorBuilder;
+class JSGraph;
+class JSOperatorBuilder;
+
+
+// Performs strength reduction on {JSCallConstruct} and {JSCallFunction} nodes,
+// which might allow inlining or other optimizations to be performed afterwards.
+class JSCallReducer final : public Reducer {
+ public:
+  // Flags that control the mode of operation.
+  enum Flag {
+    kNoFlags = 0u,
+    kDeoptimizationEnabled = 1u << 0,
+  };
+  typedef base::Flags<Flag> Flags;
+
+  JSCallReducer(JSGraph* jsgraph, Flags flags,
+                MaybeHandle<Context> native_context)
+      : jsgraph_(jsgraph), flags_(flags), native_context_(native_context) {}
+
+  Reduction Reduce(Node* node) final;
+
+ private:
+  Reduction ReduceArrayConstructor(Node* node);
+  Reduction ReduceNumberConstructor(Node* node);
+  Reduction ReduceFunctionPrototypeApply(Node* node);
+  Reduction ReduceFunctionPrototypeCall(Node* node);
+  Reduction ReduceJSCallConstruct(Node* node);
+  Reduction ReduceJSCallFunction(Node* node);
+
+  MaybeHandle<Context> GetNativeContext(Node* node);
+
+  Graph* graph() const;
+  Flags flags() const { return flags_; }
+  JSGraph* jsgraph() const { return jsgraph_; }
+  Isolate* isolate() const;
+  MaybeHandle<Context> native_context() const { return native_context_; }
+  CommonOperatorBuilder* common() const;
+  JSOperatorBuilder* javascript() const;
+
+  JSGraph* const jsgraph_;
+  Flags const flags_;
+  MaybeHandle<Context> const native_context_;
+};
+
+DEFINE_OPERATORS_FOR_FLAGS(JSCallReducer::Flags)
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_JS_CALL_REDUCER_H_
diff --git a/src/compiler/js-context-relaxation.cc b/src/compiler/js-context-relaxation.cc
new file mode 100644
index 0000000..0ca3c0c
--- /dev/null
+++ b/src/compiler/js-context-relaxation.cc
@@ -0,0 +1,67 @@
+// 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/frame-states.h"
+#include "src/compiler/js-context-relaxation.h"
+#include "src/compiler/js-operator.h"
+#include "src/compiler/node.h"
+#include "src/compiler/node-properties.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+Reduction JSContextRelaxation::Reduce(Node* node) {
+  switch (node->opcode()) {
+    case IrOpcode::kJSCallFunction:
+    case IrOpcode::kJSToNumber: {
+      Node* frame_state = NodeProperties::GetFrameStateInput(node, 0);
+      Node* outer_frame = frame_state;
+      Node* original_context = NodeProperties::GetContextInput(node);
+      Node* candidate_new_context = original_context;
+      do {
+        FrameStateInfo frame_state_info(
+            OpParameter<FrameStateInfo>(outer_frame->op()));
+        const FrameStateFunctionInfo* function_info =
+            frame_state_info.function_info();
+        if (function_info == nullptr ||
+            (function_info->context_calling_mode() ==
+             CALL_CHANGES_NATIVE_CONTEXT)) {
+          break;
+        }
+        candidate_new_context = outer_frame->InputAt(kFrameStateContextInput);
+        outer_frame = outer_frame->InputAt(kFrameStateOuterStateInput);
+      } while (outer_frame->opcode() == IrOpcode::kFrameState);
+
+      while (true) {
+        switch (candidate_new_context->opcode()) {
+          case IrOpcode::kParameter:
+          case IrOpcode::kJSCreateModuleContext:
+          case IrOpcode::kJSCreateScriptContext:
+            if (candidate_new_context != original_context) {
+              NodeProperties::ReplaceContextInput(node, candidate_new_context);
+              return Changed(node);
+            } else {
+              return NoChange();
+            }
+          case IrOpcode::kJSCreateCatchContext:
+          case IrOpcode::kJSCreateWithContext:
+          case IrOpcode::kJSCreateBlockContext:
+            candidate_new_context =
+                NodeProperties::GetContextInput(candidate_new_context);
+            break;
+          default:
+            return NoChange();
+        }
+      }
+    }
+    default:
+      break;
+  }
+  return NoChange();
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/js-context-relaxation.h b/src/compiler/js-context-relaxation.h
new file mode 100644
index 0000000..4320e92
--- /dev/null
+++ b/src/compiler/js-context-relaxation.h
@@ -0,0 +1,32 @@
+// 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.
+
+#ifndef V8_COMPILER_JS_CONTEXT_RELAXATION_H_
+#define V8_COMPILER_JS_CONTEXT_RELAXATION_H_
+
+#include "src/compiler/graph-reducer.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+// Ensures that operations that only need to access the native context use the
+// outer-most context rather than the specific context given by the AST graph
+// builder. This makes it possible to use these operations with context
+// specialization (e.g. for generating stubs) without forcing inner contexts to
+// be embedded in generated code thus causing leaks and potentially using the
+// wrong native context (i.e. stubs are shared between native contexts).
+class JSContextRelaxation final : public Reducer {
+ public:
+  JSContextRelaxation() {}
+  ~JSContextRelaxation() final {}
+
+  Reduction Reduce(Node* node) final;
+};
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_JS_CONTEXT_RELAXATION_H_
diff --git a/src/compiler/js-context-specialization.cc b/src/compiler/js-context-specialization.cc
index a700b47..4d9d1d9 100644
--- a/src/compiler/js-context-specialization.cc
+++ b/src/compiler/js-context-specialization.cc
@@ -4,48 +4,51 @@
 
 #include "src/compiler/js-context-specialization.h"
 
-#include "src/compiler.h"
 #include "src/compiler/common-operator.h"
-#include "src/compiler/graph-inl.h"
+#include "src/compiler/js-graph.h"
 #include "src/compiler/js-operator.h"
 #include "src/compiler/node-matchers.h"
-#include "src/compiler/node-properties-inl.h"
+#include "src/compiler/node-properties.h"
+#include "src/contexts.h"
+#include "src/objects-inl.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
-Reduction JSContextSpecializer::Reduce(Node* node) {
-  if (node == context_) {
-    Node* constant = jsgraph_->Constant(info_->context());
-    NodeProperties::ReplaceWithValue(node, constant);
-    return Replace(constant);
-  }
-  if (node->opcode() == IrOpcode::kJSLoadContext) {
-    return ReduceJSLoadContext(node);
-  }
-  if (node->opcode() == IrOpcode::kJSStoreContext) {
-    return ReduceJSStoreContext(node);
+Reduction JSContextSpecialization::Reduce(Node* node) {
+  switch (node->opcode()) {
+    case IrOpcode::kJSLoadContext:
+      return ReduceJSLoadContext(node);
+    case IrOpcode::kJSStoreContext:
+      return ReduceJSStoreContext(node);
+    default:
+      break;
   }
   return NoChange();
 }
 
 
-Reduction JSContextSpecializer::ReduceJSLoadContext(Node* node) {
+MaybeHandle<Context> JSContextSpecialization::GetSpecializationContext(
+    Node* node) {
+  DCHECK(node->opcode() == IrOpcode::kJSLoadContext ||
+         node->opcode() == IrOpcode::kJSStoreContext);
+  Node* const object = NodeProperties::GetValueInput(node, 0);
+  return NodeProperties::GetSpecializationContext(object, context());
+}
+
+
+Reduction JSContextSpecialization::ReduceJSLoadContext(Node* node) {
   DCHECK_EQ(IrOpcode::kJSLoadContext, node->opcode());
 
-  HeapObjectMatcher<Context> m(NodeProperties::GetValueInput(node, 0));
-  // If the context is not constant, no reduction can occur.
-  if (!m.HasValue()) {
-    return NoChange();
-  }
-
-  const ContextAccess& access = ContextAccessOf(node->op());
+  // Get the specialization context from the node.
+  Handle<Context> context;
+  if (!GetSpecializationContext(node).ToHandle(&context)) return NoChange();
 
   // Find the right parent context.
-  Context* context = *m.Value().handle();
+  const ContextAccess& access = ContextAccessOf(node->op());
   for (size_t i = access.depth(); i > 0; --i) {
-    context = context->previous();
+    context = handle(context->previous(), isolate());
   }
 
   // If the access itself is mutable, only fold-in the parent.
@@ -56,13 +59,12 @@
     }
     const Operator* op = jsgraph_->javascript()->LoadContext(
         0, access.index(), access.immutable());
-    node->set_op(op);
-    Handle<Object> context_handle = Handle<Object>(context, info_->isolate());
-    node->ReplaceInput(0, jsgraph_->Constant(context_handle));
+    node->ReplaceInput(0, jsgraph_->Constant(context));
+    NodeProperties::ChangeOp(node, op);
     return Changed(node);
   }
-  Handle<Object> value = Handle<Object>(
-      context->get(static_cast<int>(access.index())), info_->isolate());
+  Handle<Object> value =
+      handle(context->get(static_cast<int>(access.index())), isolate());
 
   // Even though the context slot is immutable, the context might have escaped
   // before the function to which it belongs has initialized the slot.
@@ -76,41 +78,44 @@
   // TODO(titzer): record the specialization for sharing code across multiple
   // contexts that have the same value in the corresponding context slot.
   Node* constant = jsgraph_->Constant(value);
-  NodeProperties::ReplaceWithValue(node, constant);
+  ReplaceWithValue(node, constant);
   return Replace(constant);
 }
 
 
-Reduction JSContextSpecializer::ReduceJSStoreContext(Node* node) {
+Reduction JSContextSpecialization::ReduceJSStoreContext(Node* node) {
   DCHECK_EQ(IrOpcode::kJSStoreContext, node->opcode());
 
-  HeapObjectMatcher<Context> m(NodeProperties::GetValueInput(node, 0));
-  // If the context is not constant, no reduction can occur.
-  if (!m.HasValue()) {
-    return NoChange();
-  }
-
-  const ContextAccess& access = ContextAccessOf(node->op());
+  // Get the specialization context from the node.
+  Handle<Context> context;
+  if (!GetSpecializationContext(node).ToHandle(&context)) return NoChange();
 
   // The access does not have to look up a parent, nothing to fold.
+  const ContextAccess& access = ContextAccessOf(node->op());
   if (access.depth() == 0) {
     return NoChange();
   }
 
   // Find the right parent context.
-  Context* context = *m.Value().handle();
   for (size_t i = access.depth(); i > 0; --i) {
-    context = context->previous();
+    context = handle(context->previous(), isolate());
   }
 
-  const Operator* op = jsgraph_->javascript()->StoreContext(0, access.index());
-  node->set_op(op);
-  Handle<Object> new_context_handle = Handle<Object>(context, info_->isolate());
-  node->ReplaceInput(0, jsgraph_->Constant(new_context_handle));
-
+  node->ReplaceInput(0, jsgraph_->Constant(context));
+  NodeProperties::ChangeOp(node, javascript()->StoreContext(0, access.index()));
   return Changed(node);
 }
 
+
+Isolate* JSContextSpecialization::isolate() const {
+  return jsgraph()->isolate();
+}
+
+
+JSOperatorBuilder* JSContextSpecialization::javascript() const {
+  return jsgraph()->javascript();
+}
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/src/compiler/js-context-specialization.h b/src/compiler/js-context-specialization.h
index 298d3a3..ef784fc 100644
--- a/src/compiler/js-context-specialization.h
+++ b/src/compiler/js-context-specialization.h
@@ -6,34 +6,46 @@
 #define V8_COMPILER_JS_CONTEXT_SPECIALIZATION_H_
 
 #include "src/compiler/graph-reducer.h"
-#include "src/compiler/js-graph.h"
-#include "src/contexts.h"
-#include "src/v8.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
+// Forward declarations.
+class JSGraph;
+class JSOperatorBuilder;
+
+
 // Specializes a given JSGraph to a given context, potentially constant folding
 // some {LoadContext} nodes or strength reducing some {StoreContext} nodes.
-class JSContextSpecializer : public Reducer {
+class JSContextSpecialization final : public AdvancedReducer {
  public:
-  JSContextSpecializer(CompilationInfo* info, JSGraph* jsgraph, Node* context)
-      : info_(info), jsgraph_(jsgraph), context_(context) {}
+  JSContextSpecialization(Editor* editor, JSGraph* jsgraph,
+                          MaybeHandle<Context> context)
+      : AdvancedReducer(editor), jsgraph_(jsgraph), context_(context) {}
 
-  Reduction Reduce(Node* node) OVERRIDE;
+  Reduction Reduce(Node* node) final;
 
-  // Visible for unit testing.
+ private:
   Reduction ReduceJSLoadContext(Node* node);
   Reduction ReduceJSStoreContext(Node* node);
 
- private:
-  CompilationInfo* info_;
-  JSGraph* jsgraph_;
-  Node* context_;
+  // Returns the {Context} to specialize {node} to (if any).
+  MaybeHandle<Context> GetSpecializationContext(Node* node);
+
+  Isolate* isolate() const;
+  JSOperatorBuilder* javascript() const;
+  JSGraph* jsgraph() const { return jsgraph_; }
+  MaybeHandle<Context> context() const { return context_; }
+
+  JSGraph* const jsgraph_;
+  MaybeHandle<Context> context_;
+
+  DISALLOW_COPY_AND_ASSIGN(JSContextSpecialization);
 };
-}
-}
-}  // namespace v8::internal::compiler
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
 
 #endif  // V8_COMPILER_JS_CONTEXT_SPECIALIZATION_H_
diff --git a/src/compiler/js-frame-specialization.cc b/src/compiler/js-frame-specialization.cc
new file mode 100644
index 0000000..769d615
--- /dev/null
+++ b/src/compiler/js-frame-specialization.cc
@@ -0,0 +1,75 @@
+// Copyright 2015 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/js-frame-specialization.h"
+
+#include "src/compiler/js-graph.h"
+#include "src/compiler/linkage.h"
+#include "src/frames-inl.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+Reduction JSFrameSpecialization::Reduce(Node* node) {
+  switch (node->opcode()) {
+    case IrOpcode::kOsrValue:
+      return ReduceOsrValue(node);
+    case IrOpcode::kParameter:
+      return ReduceParameter(node);
+    default:
+      break;
+  }
+  return NoChange();
+}
+
+
+Reduction JSFrameSpecialization::ReduceOsrValue(Node* node) {
+  DCHECK_EQ(IrOpcode::kOsrValue, node->opcode());
+  Handle<Object> value;
+  int const index = OpParameter<int>(node);
+  int const parameters_count = frame()->ComputeParametersCount() + 1;
+  if (index == Linkage::kOsrContextSpillSlotIndex) {
+    value = handle(frame()->context(), isolate());
+  } else if (index >= parameters_count) {
+    value = handle(frame()->GetExpression(index - parameters_count), isolate());
+  } else {
+    // The OsrValue index 0 is the receiver.
+    value =
+        handle(index ? frame()->GetParameter(index - 1) : frame()->receiver(),
+               isolate());
+  }
+  return Replace(jsgraph()->Constant(value));
+}
+
+
+Reduction JSFrameSpecialization::ReduceParameter(Node* node) {
+  DCHECK_EQ(IrOpcode::kParameter, node->opcode());
+  Handle<Object> value;
+  int const index = ParameterIndexOf(node->op());
+  int const parameters_count = frame()->ComputeParametersCount() + 1;
+  if (index == Linkage::kJSCallClosureParamIndex) {
+    // The Parameter index references the closure.
+    value = handle(frame()->function(), isolate());
+  } else if (index == Linkage::GetJSCallArgCountParamIndex(parameters_count)) {
+    // The Parameter index references the parameter count.
+    value = handle(Smi::FromInt(parameters_count - 1), isolate());
+  } else if (index == Linkage::GetJSCallContextParamIndex(parameters_count)) {
+    // The Parameter index references the context.
+    value = handle(frame()->context(), isolate());
+  } else {
+    // The Parameter index 0 is the receiver.
+    value =
+        handle(index ? frame()->GetParameter(index - 1) : frame()->receiver(),
+               isolate());
+  }
+  return Replace(jsgraph()->Constant(value));
+}
+
+
+Isolate* JSFrameSpecialization::isolate() const { return jsgraph()->isolate(); }
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/js-frame-specialization.h b/src/compiler/js-frame-specialization.h
new file mode 100644
index 0000000..90b3ca5
--- /dev/null
+++ b/src/compiler/js-frame-specialization.h
@@ -0,0 +1,48 @@
+// Copyright 2015 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.
+
+#ifndef V8_COMPILER_JS_FRAME_SPECIALIZATION_H_
+#define V8_COMPILER_JS_FRAME_SPECIALIZATION_H_
+
+#include "src/compiler/graph-reducer.h"
+
+namespace v8 {
+namespace internal {
+
+// Forward declarations.
+class JavaScriptFrame;
+
+namespace compiler {
+
+// Forward declarations.
+class JSGraph;
+
+
+class JSFrameSpecialization final : public Reducer {
+ public:
+  JSFrameSpecialization(JavaScriptFrame const* frame, JSGraph* jsgraph)
+      : frame_(frame), jsgraph_(jsgraph) {}
+  ~JSFrameSpecialization() final {}
+
+  Reduction Reduce(Node* node) final;
+
+ private:
+  Reduction ReduceOsrValue(Node* node);
+  Reduction ReduceParameter(Node* node);
+
+  Isolate* isolate() const;
+  JavaScriptFrame const* frame() const { return frame_; }
+  JSGraph* jsgraph() const { return jsgraph_; }
+
+  JavaScriptFrame const* const frame_;
+  JSGraph* const jsgraph_;
+
+  DISALLOW_COPY_AND_ASSIGN(JSFrameSpecialization);
+};
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_JS_FRAME_SPECIALIZATION_H_
diff --git a/src/compiler/js-generic-lowering.cc b/src/compiler/js-generic-lowering.cc
index 4886442..15ce908 100644
--- a/src/compiler/js-generic-lowering.cc
+++ b/src/compiler/js-generic-lowering.cc
@@ -5,32 +5,35 @@
 #include "src/code-factory.h"
 #include "src/code-stubs.h"
 #include "src/compiler/common-operator.h"
-#include "src/compiler/graph-inl.h"
 #include "src/compiler/js-generic-lowering.h"
+#include "src/compiler/js-graph.h"
 #include "src/compiler/machine-operator.h"
-#include "src/compiler/node-aux-data-inl.h"
 #include "src/compiler/node-matchers.h"
-#include "src/compiler/node-properties-inl.h"
-#include "src/unique.h"
+#include "src/compiler/node-properties.h"
+#include "src/compiler/operator-properties.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
-JSGenericLowering::JSGenericLowering(CompilationInfo* info, JSGraph* jsgraph)
-    : info_(info),
-      jsgraph_(jsgraph),
-      linkage_(new (jsgraph->zone()) Linkage(jsgraph->zone(), info)) {}
-
-
-void JSGenericLowering::PatchOperator(Node* node, const Operator* op) {
-  node->set_op(op);
+static CallDescriptor::Flags AdjustFrameStatesForCall(Node* node) {
+  int count = OperatorProperties::GetFrameStateInputCount(node->op());
+  if (count > 1) {
+    int index = NodeProperties::FirstFrameStateIndex(node) + 1;
+    do {
+      node->RemoveInput(index);
+    } while (--count > 1);
+  }
+  return count > 0 ? CallDescriptor::kNeedsFrameState
+                   : CallDescriptor::kNoFlags;
 }
 
 
-void JSGenericLowering::PatchInsertInput(Node* node, int index, Node* input) {
-  node->InsertInput(zone(), index, input);
-}
+JSGenericLowering::JSGenericLowering(bool is_typing_enabled, JSGraph* jsgraph)
+    : is_typing_enabled_(is_typing_enabled), jsgraph_(jsgraph) {}
+
+
+JSGenericLowering::~JSGenericLowering() {}
 
 
 Reduction JSGenericLowering::Reduce(Node* node) {
@@ -45,11 +48,11 @@
       // TODO(mstarzinger): If typing is enabled then simplified lowering will
       // have inserted the correct ChangeBoolToBit, otherwise we need to perform
       // poor-man's representation inference here and insert manual change.
-      if (!info()->is_typing_enabled()) {
-        Node* test = graph()->NewNode(machine()->WordEqual(), node->InputAt(0),
+      if (!is_typing_enabled_) {
+        Node* condition = node->InputAt(0);
+        Node* test = graph()->NewNode(machine()->WordEqual(), condition,
                                       jsgraph()->TrueConstant());
         node->ReplaceInput(0, test);
-        break;
       }
       // Fall-through.
     default:
@@ -60,10 +63,15 @@
 }
 
 
-#define REPLACE_BINARY_OP_IC_CALL(op, token)                             \
-  void JSGenericLowering::Lower##op(Node* node) {                        \
-    ReplaceWithStubCall(node, CodeFactory::BinaryOpIC(isolate(), token), \
-                        CallDescriptor::kPatchableCallSiteWithNop);      \
+#define REPLACE_BINARY_OP_IC_CALL(Op, token)                                  \
+  void JSGenericLowering::Lower##Op(Node* node) {                             \
+    BinaryOperationParameters const& p =                                      \
+        BinaryOperationParametersOf(node->op());                              \
+    CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);             \
+    ReplaceWithStubCall(node,                                                 \
+                        CodeFactory::BinaryOpIC(isolate(), token,             \
+                                                strength(p.language_mode())), \
+                        CallDescriptor::kPatchableCallSiteWithNop | flags);   \
   }
 REPLACE_BINARY_OP_IC_CALL(JSBitwiseOr, Token::BIT_OR)
 REPLACE_BINARY_OP_IC_CALL(JSBitwiseXor, Token::BIT_XOR)
@@ -79,123 +87,136 @@
 #undef REPLACE_BINARY_OP_IC_CALL
 
 
-#define REPLACE_COMPARE_IC_CALL(op, token)        \
-  void JSGenericLowering::Lower##op(Node* node) { \
-    ReplaceWithCompareIC(node, token);            \
+// These ops are not language mode dependent; we arbitrarily pass Strength::WEAK
+// here.
+#define REPLACE_COMPARE_IC_CALL(op, token)             \
+  void JSGenericLowering::Lower##op(Node* node) {      \
+    ReplaceWithCompareIC(node, token, Strength::WEAK); \
   }
 REPLACE_COMPARE_IC_CALL(JSEqual, Token::EQ)
 REPLACE_COMPARE_IC_CALL(JSNotEqual, Token::NE)
 REPLACE_COMPARE_IC_CALL(JSStrictEqual, Token::EQ_STRICT)
 REPLACE_COMPARE_IC_CALL(JSStrictNotEqual, Token::NE_STRICT)
-REPLACE_COMPARE_IC_CALL(JSLessThan, Token::LT)
-REPLACE_COMPARE_IC_CALL(JSGreaterThan, Token::GT)
-REPLACE_COMPARE_IC_CALL(JSLessThanOrEqual, Token::LTE)
-REPLACE_COMPARE_IC_CALL(JSGreaterThanOrEqual, Token::GTE)
 #undef REPLACE_COMPARE_IC_CALL
 
 
+#define REPLACE_COMPARE_IC_CALL_WITH_LANGUAGE_MODE(op, token)        \
+  void JSGenericLowering::Lower##op(Node* node) {                    \
+    ReplaceWithCompareIC(node, token,                                \
+                         strength(OpParameter<LanguageMode>(node))); \
+  }
+REPLACE_COMPARE_IC_CALL_WITH_LANGUAGE_MODE(JSLessThan, Token::LT)
+REPLACE_COMPARE_IC_CALL_WITH_LANGUAGE_MODE(JSGreaterThan, Token::GT)
+REPLACE_COMPARE_IC_CALL_WITH_LANGUAGE_MODE(JSLessThanOrEqual, Token::LTE)
+REPLACE_COMPARE_IC_CALL_WITH_LANGUAGE_MODE(JSGreaterThanOrEqual, Token::GTE)
+#undef REPLACE_COMPARE_IC_CALL_WITH_LANGUAGE_MODE
+
+
 #define REPLACE_RUNTIME_CALL(op, fun)             \
   void JSGenericLowering::Lower##op(Node* node) { \
     ReplaceWithRuntimeCall(node, fun);            \
   }
-REPLACE_RUNTIME_CALL(JSTypeOf, Runtime::kTypeof)
-REPLACE_RUNTIME_CALL(JSCreate, Runtime::kAbort)
 REPLACE_RUNTIME_CALL(JSCreateFunctionContext, Runtime::kNewFunctionContext)
-REPLACE_RUNTIME_CALL(JSCreateCatchContext, Runtime::kPushCatchContext)
 REPLACE_RUNTIME_CALL(JSCreateWithContext, Runtime::kPushWithContext)
-REPLACE_RUNTIME_CALL(JSCreateBlockContext, Runtime::kPushBlockContext)
 REPLACE_RUNTIME_CALL(JSCreateModuleContext, Runtime::kPushModuleContext)
-REPLACE_RUNTIME_CALL(JSCreateScriptContext, Runtime::kAbort)
+REPLACE_RUNTIME_CALL(JSConvertReceiver, Runtime::kConvertReceiver)
 #undef REPLACE_RUNTIME
 
 
-#define REPLACE_UNIMPLEMENTED(op) \
-  void JSGenericLowering::Lower##op(Node* node) { UNIMPLEMENTED(); }
-REPLACE_UNIMPLEMENTED(JSToName)
-REPLACE_UNIMPLEMENTED(JSYield)
-REPLACE_UNIMPLEMENTED(JSDebugger)
-#undef REPLACE_UNIMPLEMENTED
-
-
 static CallDescriptor::Flags FlagsForNode(Node* node) {
   CallDescriptor::Flags result = CallDescriptor::kNoFlags;
-  if (OperatorProperties::HasFrameStateInput(node->op())) {
+  if (OperatorProperties::GetFrameStateInputCount(node->op()) > 0) {
     result |= CallDescriptor::kNeedsFrameState;
   }
   return result;
 }
 
 
-void JSGenericLowering::ReplaceWithCompareIC(Node* node, Token::Value token) {
-  Callable callable = CodeFactory::CompareIC(isolate(), token);
-  bool has_frame_state = OperatorProperties::HasFrameStateInput(node->op());
-  CallDescriptor* desc_compare = linkage()->GetStubCallDescriptor(
-      callable.descriptor(), 0,
-      CallDescriptor::kPatchableCallSiteWithNop | FlagsForNode(node));
+void JSGenericLowering::ReplaceWithCompareIC(Node* node, Token::Value token,
+                                             Strength str) {
+  Callable callable = CodeFactory::CompareIC(isolate(), token, str);
+
+  // Create a new call node asking a CompareIC for help.
   NodeVector inputs(zone());
   inputs.reserve(node->InputCount() + 1);
   inputs.push_back(jsgraph()->HeapConstant(callable.code()));
   inputs.push_back(NodeProperties::GetValueInput(node, 0));
   inputs.push_back(NodeProperties::GetValueInput(node, 1));
   inputs.push_back(NodeProperties::GetContextInput(node));
-  if (node->op()->HasProperty(Operator::kPure)) {
-    // A pure (strict) comparison doesn't have an effect, control or frame
-    // state.  But for the graph, we need to add control and effect inputs.
-    DCHECK(!has_frame_state);
-    inputs.push_back(graph()->start());
-    inputs.push_back(graph()->start());
-  } else {
-    DCHECK(has_frame_state == FLAG_turbo_deoptimization);
-    if (FLAG_turbo_deoptimization) {
-      inputs.push_back(NodeProperties::GetFrameStateInput(node));
-    }
-    inputs.push_back(NodeProperties::GetEffectInput(node));
-    inputs.push_back(NodeProperties::GetControlInput(node));
+  // Some comparisons (StrictEqual) don't have an effect, control or frame
+  // state inputs, so handle those cases here.
+  if (OperatorProperties::GetFrameStateInputCount(node->op()) > 0) {
+    inputs.push_back(NodeProperties::GetFrameStateInput(node, 0));
   }
+  Node* effect = (node->op()->EffectInputCount() > 0)
+                     ? NodeProperties::GetEffectInput(node)
+                     : graph()->start();
+  inputs.push_back(effect);
+  Node* control = (node->op()->ControlInputCount() > 0)
+                      ? NodeProperties::GetControlInput(node)
+                      : graph()->start();
+  inputs.push_back(control);
+  CallDescriptor* desc_compare = Linkage::GetStubCallDescriptor(
+      isolate(), zone(), callable.descriptor(), 0,
+      CallDescriptor::kPatchableCallSiteWithNop | FlagsForNode(node),
+      Operator::kNoProperties, MachineType::IntPtr());
   Node* compare =
       graph()->NewNode(common()->Call(desc_compare),
                        static_cast<int>(inputs.size()), &inputs.front());
 
-  node->ReplaceInput(0, compare);
-  node->ReplaceInput(1, jsgraph()->SmiConstant(token));
-
-  if (has_frame_state) {
-    // Remove the frame state from inputs.
-    node->RemoveInput(NodeProperties::FirstFrameStateIndex(node));
+  // Decide how the return value from the above CompareIC can be converted into
+  // a JavaScript boolean oddball depending on the given token.
+  Node* false_value = jsgraph()->FalseConstant();
+  Node* true_value = jsgraph()->TrueConstant();
+  const Operator* op = nullptr;
+  switch (token) {
+    case Token::EQ:  // a == 0
+    case Token::EQ_STRICT:
+      op = machine()->WordEqual();
+      break;
+    case Token::NE:  // a != 0 becomes !(a == 0)
+    case Token::NE_STRICT:
+      op = machine()->WordEqual();
+      std::swap(true_value, false_value);
+      break;
+    case Token::LT:  // a < 0
+      op = machine()->IntLessThan();
+      break;
+    case Token::GT:  // a > 0 becomes !(a <= 0)
+      op = machine()->IntLessThanOrEqual();
+      std::swap(true_value, false_value);
+      break;
+    case Token::LTE:  // a <= 0
+      op = machine()->IntLessThanOrEqual();
+      break;
+    case Token::GTE:  // a >= 0 becomes !(a < 0)
+      op = machine()->IntLessThan();
+      std::swap(true_value, false_value);
+      break;
+    default:
+      UNREACHABLE();
   }
+  Node* booleanize = graph()->NewNode(op, compare, jsgraph()->ZeroConstant());
 
-  ReplaceWithRuntimeCall(node, Runtime::kBooleanize);
+  // Finally patch the original node to select a boolean.
+  NodeProperties::ReplaceUses(node, node, compare, compare, compare);
+  node->TrimInputCount(3);
+  node->ReplaceInput(0, booleanize);
+  node->ReplaceInput(1, true_value);
+  node->ReplaceInput(2, false_value);
+  NodeProperties::ChangeOp(node,
+                           common()->Select(MachineRepresentation::kTagged));
 }
 
 
 void JSGenericLowering::ReplaceWithStubCall(Node* node, Callable callable,
                                             CallDescriptor::Flags flags) {
   Operator::Properties properties = node->op()->properties();
-  CallDescriptor* desc = linkage()->GetStubCallDescriptor(
-      callable.descriptor(), 0, flags | FlagsForNode(node), properties);
+  CallDescriptor* desc = Linkage::GetStubCallDescriptor(
+      isolate(), zone(), callable.descriptor(), 0, flags, properties);
   Node* stub_code = jsgraph()->HeapConstant(callable.code());
-  PatchInsertInput(node, 0, stub_code);
-  PatchOperator(node, common()->Call(desc));
-}
-
-
-void JSGenericLowering::ReplaceWithBuiltinCall(Node* node,
-                                               Builtins::JavaScript id,
-                                               int nargs) {
-  Operator::Properties properties = node->op()->properties();
-  Callable callable =
-      CodeFactory::CallFunction(isolate(), nargs - 1, NO_CALL_FUNCTION_FLAGS);
-  CallDescriptor* desc = linkage()->GetStubCallDescriptor(
-      callable.descriptor(), nargs, FlagsForNode(node), properties);
-  // TODO(mstarzinger): Accessing the builtins object this way prevents sharing
-  // of code across native contexts. Fix this by loading from given context.
-  Handle<JSFunction> function(
-      JSFunction::cast(info()->context()->builtins()->javascript_builtin(id)));
-  Node* stub_code = jsgraph()->HeapConstant(callable.code());
-  Node* function_node = jsgraph()->HeapConstant(function);
-  PatchInsertInput(node, 0, stub_code);
-  PatchInsertInput(node, 1, function_node);
-  PatchOperator(node, common()->Call(desc));
+  node->InsertInput(zone(), 0, stub_code);
+  NodeProperties::ChangeOp(node, common()->Call(desc));
 }
 
 
@@ -205,109 +226,172 @@
   Operator::Properties properties = node->op()->properties();
   const Runtime::Function* fun = Runtime::FunctionForId(f);
   int nargs = (nargs_override < 0) ? fun->nargs : nargs_override;
-  CallDescriptor* desc =
-      linkage()->GetRuntimeCallDescriptor(f, nargs, properties);
+  CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor(
+      zone(), f, nargs, properties, CallDescriptor::kNeedsFrameState);
   Node* ref = jsgraph()->ExternalConstant(ExternalReference(f, isolate()));
   Node* arity = jsgraph()->Int32Constant(nargs);
-  PatchInsertInput(node, 0, jsgraph()->CEntryStubConstant(fun->result_size));
-  PatchInsertInput(node, nargs + 1, ref);
-  PatchInsertInput(node, nargs + 2, arity);
-  PatchOperator(node, common()->Call(desc));
+  node->InsertInput(zone(), 0, jsgraph()->CEntryStubConstant(fun->result_size));
+  node->InsertInput(zone(), nargs + 1, ref);
+  node->InsertInput(zone(), nargs + 2, arity);
+  NodeProperties::ChangeOp(node, common()->Call(desc));
 }
 
 
-void JSGenericLowering::LowerJSUnaryNot(Node* node) {
-  Callable callable = CodeFactory::ToBoolean(
-      isolate(), ToBooleanStub::RESULT_AS_INVERSE_ODDBALL);
-  ReplaceWithStubCall(node, callable, CallDescriptor::kPatchableCallSite);
+void JSGenericLowering::LowerJSTypeOf(Node* node) {
+  CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
+  Callable callable = CodeFactory::Typeof(isolate());
+  ReplaceWithStubCall(node, callable, flags);
 }
 
 
 void JSGenericLowering::LowerJSToBoolean(Node* node) {
-  Callable callable =
-      CodeFactory::ToBoolean(isolate(), ToBooleanStub::RESULT_AS_ODDBALL);
-  ReplaceWithStubCall(node, callable, CallDescriptor::kPatchableCallSite);
+  CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
+  Callable callable = CodeFactory::ToBoolean(isolate());
+  ReplaceWithStubCall(node, callable,
+                      CallDescriptor::kPatchableCallSite | flags);
 }
 
 
 void JSGenericLowering::LowerJSToNumber(Node* node) {
+  CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
   Callable callable = CodeFactory::ToNumber(isolate());
-  ReplaceWithStubCall(node, callable, FlagsForNode(node));
+  ReplaceWithStubCall(node, callable, flags);
 }
 
 
 void JSGenericLowering::LowerJSToString(Node* node) {
-  ReplaceWithBuiltinCall(node, Builtins::TO_STRING, 1);
+  CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
+  Callable callable = CodeFactory::ToString(isolate());
+  ReplaceWithStubCall(node, callable, flags);
+}
+
+
+void JSGenericLowering::LowerJSToName(Node* node) {
+  ReplaceWithRuntimeCall(node, Runtime::kToName);
 }
 
 
 void JSGenericLowering::LowerJSToObject(Node* node) {
-  ReplaceWithBuiltinCall(node, Builtins::TO_OBJECT, 1);
+  CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
+  Callable callable = CodeFactory::ToObject(isolate());
+  ReplaceWithStubCall(node, callable, flags);
 }
 
 
 void JSGenericLowering::LowerJSLoadProperty(Node* node) {
-  const LoadPropertyParameters& p = LoadPropertyParametersOf(node->op());
-  Callable callable = CodeFactory::KeyedLoadICInOptimizedCode(isolate());
-  if (FLAG_vector_ics) {
-    PatchInsertInput(node, 2, jsgraph()->SmiConstant(p.feedback().index()));
-    PatchInsertInput(node, 3, jsgraph()->HeapConstant(p.feedback().vector()));
-  }
-  ReplaceWithStubCall(node, callable, CallDescriptor::kPatchableCallSite);
+  CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
+  const PropertyAccess& p = PropertyAccessOf(node->op());
+  Callable callable = CodeFactory::KeyedLoadICInOptimizedCode(
+      isolate(), p.language_mode(), UNINITIALIZED);
+  node->InsertInput(zone(), 2, jsgraph()->SmiConstant(p.feedback().index()));
+  ReplaceWithStubCall(node, callable, flags);
 }
 
 
 void JSGenericLowering::LowerJSLoadNamed(Node* node) {
-  const LoadNamedParameters& p = LoadNamedParametersOf(node->op());
-  Callable callable =
-      CodeFactory::LoadICInOptimizedCode(isolate(), p.contextual_mode());
-  PatchInsertInput(node, 1, jsgraph()->HeapConstant(p.name()));
-  if (FLAG_vector_ics) {
-    PatchInsertInput(node, 2, jsgraph()->SmiConstant(p.feedback().index()));
-    PatchInsertInput(node, 3, jsgraph()->HeapConstant(p.feedback().vector()));
-  }
-  ReplaceWithStubCall(node, callable, CallDescriptor::kPatchableCallSite);
+  CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
+  NamedAccess const& p = NamedAccessOf(node->op());
+  Callable callable = CodeFactory::LoadICInOptimizedCode(
+      isolate(), NOT_INSIDE_TYPEOF, p.language_mode(), UNINITIALIZED);
+  node->InsertInput(zone(), 1, jsgraph()->HeapConstant(p.name()));
+  node->InsertInput(zone(), 2, jsgraph()->SmiConstant(p.feedback().index()));
+  ReplaceWithStubCall(node, callable, flags);
+}
+
+
+void JSGenericLowering::LowerJSLoadGlobal(Node* node) {
+  Node* context = NodeProperties::GetContextInput(node);
+  Node* effect = NodeProperties::GetEffectInput(node);
+  CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
+  const LoadGlobalParameters& p = LoadGlobalParametersOf(node->op());
+  Callable callable = CodeFactory::LoadICInOptimizedCode(
+      isolate(), p.typeof_mode(), SLOPPY, UNINITIALIZED);
+  // Load global object from the context.
+  Node* native_context =
+      graph()->NewNode(machine()->Load(MachineType::AnyTagged()), context,
+                       jsgraph()->IntPtrConstant(
+                           Context::SlotOffset(Context::NATIVE_CONTEXT_INDEX)),
+                       effect, graph()->start());
+  Node* global = graph()->NewNode(
+      machine()->Load(MachineType::AnyTagged()), native_context,
+      jsgraph()->IntPtrConstant(Context::SlotOffset(Context::EXTENSION_INDEX)),
+      effect, graph()->start());
+  node->InsertInput(zone(), 0, global);
+  node->InsertInput(zone(), 1, jsgraph()->HeapConstant(p.name()));
+  node->InsertInput(zone(), 2, jsgraph()->SmiConstant(p.feedback().index()));
+  ReplaceWithStubCall(node, callable, flags);
 }
 
 
 void JSGenericLowering::LowerJSStoreProperty(Node* node) {
-  StrictMode strict_mode = OpParameter<StrictMode>(node);
-  Callable callable = CodeFactory::KeyedStoreIC(isolate(), strict_mode);
-  ReplaceWithStubCall(node, callable, CallDescriptor::kPatchableCallSite);
+  CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
+  PropertyAccess const& p = PropertyAccessOf(node->op());
+  LanguageMode language_mode = p.language_mode();
+  Callable callable = CodeFactory::KeyedStoreICInOptimizedCode(
+      isolate(), language_mode, UNINITIALIZED);
+  DCHECK(p.feedback().index() != -1);
+  node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.feedback().index()));
+  ReplaceWithStubCall(node, callable,
+                      CallDescriptor::kPatchableCallSite | flags);
 }
 
 
 void JSGenericLowering::LowerJSStoreNamed(Node* node) {
-  const StoreNamedParameters& p = StoreNamedParametersOf(node->op());
-  Callable callable = CodeFactory::StoreIC(isolate(), p.strict_mode());
-  PatchInsertInput(node, 1, jsgraph()->HeapConstant(p.name()));
-  ReplaceWithStubCall(node, callable, CallDescriptor::kPatchableCallSite);
+  CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
+  NamedAccess const& p = NamedAccessOf(node->op());
+  Callable callable = CodeFactory::StoreICInOptimizedCode(
+      isolate(), p.language_mode(), UNINITIALIZED);
+  node->InsertInput(zone(), 1, jsgraph()->HeapConstant(p.name()));
+  DCHECK(p.feedback().index() != -1);
+  node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.feedback().index()));
+  ReplaceWithStubCall(node, callable,
+                      CallDescriptor::kPatchableCallSite | flags);
+}
+
+
+void JSGenericLowering::LowerJSStoreGlobal(Node* node) {
+  Node* context = NodeProperties::GetContextInput(node);
+  Node* effect = NodeProperties::GetEffectInput(node);
+  CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
+  const StoreGlobalParameters& p = StoreGlobalParametersOf(node->op());
+  Callable callable = CodeFactory::StoreICInOptimizedCode(
+      isolate(), p.language_mode(), UNINITIALIZED);
+  // Load global object from the context.
+  Node* native_context =
+      graph()->NewNode(machine()->Load(MachineType::AnyTagged()), context,
+                       jsgraph()->IntPtrConstant(
+                           Context::SlotOffset(Context::NATIVE_CONTEXT_INDEX)),
+                       effect, graph()->start());
+  Node* global = graph()->NewNode(
+      machine()->Load(MachineType::AnyTagged()), native_context,
+      jsgraph()->IntPtrConstant(Context::SlotOffset(Context::EXTENSION_INDEX)),
+      effect, graph()->start());
+  node->InsertInput(zone(), 0, global);
+  node->InsertInput(zone(), 1, jsgraph()->HeapConstant(p.name()));
+  DCHECK(p.feedback().index() != -1);
+  node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.feedback().index()));
+  ReplaceWithStubCall(node, callable,
+                      CallDescriptor::kPatchableCallSite | flags);
 }
 
 
 void JSGenericLowering::LowerJSDeleteProperty(Node* node) {
-  StrictMode strict_mode = OpParameter<StrictMode>(node);
-  PatchInsertInput(node, 2, jsgraph()->SmiConstant(strict_mode));
-  ReplaceWithBuiltinCall(node, Builtins::DELETE, 3);
+  LanguageMode language_mode = OpParameter<LanguageMode>(node);
+  ReplaceWithRuntimeCall(node, is_strict(language_mode)
+                                   ? Runtime::kDeleteProperty_Strict
+                                   : Runtime::kDeleteProperty_Sloppy);
 }
 
 
 void JSGenericLowering::LowerJSHasProperty(Node* node) {
-  ReplaceWithBuiltinCall(node, Builtins::IN, 2);
+  ReplaceWithRuntimeCall(node, Runtime::kHasProperty);
 }
 
 
 void JSGenericLowering::LowerJSInstanceOf(Node* node) {
-  InstanceofStub::Flags flags = static_cast<InstanceofStub::Flags>(
-      InstanceofStub::kReturnTrueFalseObject |
-      InstanceofStub::kArgsInRegisters);
-  InstanceofStub stub(isolate(), flags);
-  CallInterfaceDescriptor d = stub.GetCallInterfaceDescriptor();
-  CallDescriptor* desc =
-      linkage()->GetStubCallDescriptor(d, 0, FlagsForNode(node));
-  Node* stub_code = jsgraph()->HeapConstant(stub.GetCode());
-  PatchInsertInput(node, 0, stub_code);
-  PatchOperator(node, common()->Call(desc));
+  CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
+  Callable callable = CodeFactory::InstanceOf(isolate());
+  ReplaceWithStubCall(node, callable, flags);
 }
 
 
@@ -315,7 +399,7 @@
   const ContextAccess& access = ContextAccessOf(node->op());
   for (size_t i = 0; i < access.depth(); ++i) {
     node->ReplaceInput(
-        0, graph()->NewNode(machine()->Load(kMachAnyTagged),
+        0, graph()->NewNode(machine()->Load(MachineType::AnyTagged()),
                             NodeProperties::GetValueInput(node, 0),
                             jsgraph()->Int32Constant(
                                 Context::SlotOffset(Context::PREVIOUS_INDEX)),
@@ -325,7 +409,7 @@
   node->ReplaceInput(1, jsgraph()->Int32Constant(Context::SlotOffset(
                             static_cast<int>(access.index()))));
   node->AppendInput(zone(), graph()->start());
-  PatchOperator(node, machine()->Load(kMachAnyTagged));
+  NodeProperties::ChangeOp(node, machine()->Load(MachineType::AnyTagged()));
 }
 
 
@@ -333,7 +417,7 @@
   const ContextAccess& access = ContextAccessOf(node->op());
   for (size_t i = 0; i < access.depth(); ++i) {
     node->ReplaceInput(
-        0, graph()->NewNode(machine()->Load(kMachAnyTagged),
+        0, graph()->NewNode(machine()->Load(MachineType::AnyTagged()),
                             NodeProperties::GetValueInput(node, 0),
                             jsgraph()->Int32Constant(
                                 Context::SlotOffset(Context::PREVIOUS_INDEX)),
@@ -343,86 +427,454 @@
   node->ReplaceInput(2, NodeProperties::GetValueInput(node, 1));
   node->ReplaceInput(1, jsgraph()->Int32Constant(Context::SlotOffset(
                             static_cast<int>(access.index()))));
-  PatchOperator(node, machine()->Store(StoreRepresentation(kMachAnyTagged,
-                                                           kFullWriteBarrier)));
+  NodeProperties::ChangeOp(
+      node, machine()->Store(StoreRepresentation(MachineRepresentation::kTagged,
+                                                 kFullWriteBarrier)));
+}
+
+
+void JSGenericLowering::LowerJSLoadDynamic(Node* node) {
+  const DynamicAccess& access = DynamicAccessOf(node->op());
+  Runtime::FunctionId function_id =
+      (access.typeof_mode() == NOT_INSIDE_TYPEOF)
+          ? Runtime::kLoadLookupSlot
+          : Runtime::kLoadLookupSlotNoReferenceError;
+  Node* projection = graph()->NewNode(common()->Projection(0), node);
+  NodeProperties::ReplaceUses(node, projection, node, node, node);
+  node->RemoveInput(NodeProperties::FirstValueIndex(node));
+  node->InsertInput(zone(), 1, jsgraph()->Constant(access.name()));
+  ReplaceWithRuntimeCall(node, function_id);
+  projection->ReplaceInput(0, node);
+}
+
+
+void JSGenericLowering::LowerJSCreate(Node* node) {
+  ReplaceWithRuntimeCall(node, Runtime::kNewObject);
+}
+
+
+void JSGenericLowering::LowerJSCreateArguments(Node* node) {
+  const CreateArgumentsParameters& p = CreateArgumentsParametersOf(node->op());
+  switch (p.type()) {
+    case CreateArgumentsParameters::kMappedArguments:
+      ReplaceWithRuntimeCall(node, Runtime::kNewSloppyArguments_Generic);
+      break;
+    case CreateArgumentsParameters::kUnmappedArguments:
+      ReplaceWithRuntimeCall(node, Runtime::kNewStrictArguments_Generic);
+      break;
+    case CreateArgumentsParameters::kRestArray:
+      node->InsertInput(zone(), 1, jsgraph()->Constant(p.start_index()));
+      ReplaceWithRuntimeCall(node, Runtime::kNewRestArguments_Generic);
+      break;
+  }
+}
+
+
+void JSGenericLowering::LowerJSCreateArray(Node* node) {
+  CreateArrayParameters const& p = CreateArrayParametersOf(node->op());
+  int const arity = static_cast<int>(p.arity());
+  Node* new_target = node->InputAt(1);
+  // TODO(turbofan): We embed the AllocationSite from the Operator at this
+  // point, which we should not do once we want to both consume the feedback
+  // but at the same time shared the optimized code across native contexts,
+  // as the AllocationSite is associated with a single native context (it's
+  // stored in the type feedback vector after all). Once we go for cross
+  // context code generation, we should somehow find a way to get to the
+  // allocation site for the actual native context at runtime.
+  Node* type_info = p.site().is_null() ? jsgraph()->UndefinedConstant()
+                                       : jsgraph()->HeapConstant(p.site());
+  node->RemoveInput(1);
+  node->InsertInput(zone(), 1 + arity, new_target);
+  node->InsertInput(zone(), 2 + arity, type_info);
+  ReplaceWithRuntimeCall(node, Runtime::kNewArray, arity + 3);
+}
+
+
+void JSGenericLowering::LowerJSCreateClosure(Node* node) {
+  CreateClosureParameters p = CreateClosureParametersOf(node->op());
+  node->InsertInput(zone(), 0, jsgraph()->HeapConstant(p.shared_info()));
+  ReplaceWithRuntimeCall(node, (p.pretenure() == TENURED)
+                                   ? Runtime::kNewClosure_Tenured
+                                   : Runtime::kNewClosure);
+}
+
+
+void JSGenericLowering::LowerJSCreateIterResultObject(Node* node) {
+  ReplaceWithRuntimeCall(node, Runtime::kCreateIterResultObject);
+}
+
+
+void JSGenericLowering::LowerJSCreateLiteralArray(Node* node) {
+  CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
+  node->InsertInput(zone(), 1, jsgraph()->SmiConstant(p.index()));
+  node->InsertInput(zone(), 2, jsgraph()->HeapConstant(p.constant()));
+  node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.flags()));
+  ReplaceWithRuntimeCall(node, Runtime::kCreateArrayLiteral);
+}
+
+
+void JSGenericLowering::LowerJSCreateLiteralObject(Node* node) {
+  CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
+  node->InsertInput(zone(), 1, jsgraph()->SmiConstant(p.index()));
+  node->InsertInput(zone(), 2, jsgraph()->HeapConstant(p.constant()));
+  node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.flags()));
+  ReplaceWithRuntimeCall(node, Runtime::kCreateObjectLiteral);
+}
+
+
+void JSGenericLowering::LowerJSCreateLiteralRegExp(Node* node) {
+  CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
+  CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
+  Callable callable = CodeFactory::FastCloneRegExp(isolate());
+  Node* literal_index = jsgraph()->SmiConstant(p.index());
+  Node* literal_flags = jsgraph()->SmiConstant(p.flags());
+  Node* pattern = jsgraph()->HeapConstant(p.constant());
+  node->InsertInput(graph()->zone(), 1, literal_index);
+  node->InsertInput(graph()->zone(), 2, pattern);
+  node->InsertInput(graph()->zone(), 3, literal_flags);
+  ReplaceWithStubCall(node, callable, flags);
+}
+
+
+void JSGenericLowering::LowerJSCreateCatchContext(Node* node) {
+  Handle<String> name = OpParameter<Handle<String>>(node);
+  node->InsertInput(zone(), 0, jsgraph()->HeapConstant(name));
+  ReplaceWithRuntimeCall(node, Runtime::kPushCatchContext);
+}
+
+
+void JSGenericLowering::LowerJSCreateBlockContext(Node* node) {
+  Handle<ScopeInfo> scope_info = OpParameter<Handle<ScopeInfo>>(node);
+  node->InsertInput(zone(), 0, jsgraph()->HeapConstant(scope_info));
+  ReplaceWithRuntimeCall(node, Runtime::kPushBlockContext);
+}
+
+
+void JSGenericLowering::LowerJSCreateScriptContext(Node* node) {
+  Handle<ScopeInfo> scope_info = OpParameter<Handle<ScopeInfo>>(node);
+  node->InsertInput(zone(), 1, jsgraph()->HeapConstant(scope_info));
+  ReplaceWithRuntimeCall(node, Runtime::kNewScriptContext);
 }
 
 
 void JSGenericLowering::LowerJSCallConstruct(Node* node) {
-  int arity = OpParameter<int>(node);
-  CallConstructStub stub(isolate(), NO_CALL_CONSTRUCTOR_FLAGS);
-  CallInterfaceDescriptor d = stub.GetCallInterfaceDescriptor();
-  CallDescriptor* desc =
-      linkage()->GetStubCallDescriptor(d, arity, FlagsForNode(node));
-  Node* stub_code = jsgraph()->HeapConstant(stub.GetCode());
-  Node* construct = NodeProperties::GetValueInput(node, 0);
-  PatchInsertInput(node, 0, stub_code);
-  PatchInsertInput(node, 1, jsgraph()->Int32Constant(arity - 1));
-  PatchInsertInput(node, 2, construct);
-  PatchInsertInput(node, 3, jsgraph()->UndefinedConstant());
-  PatchOperator(node, common()->Call(desc));
-}
-
-
-bool JSGenericLowering::TryLowerDirectJSCall(Node* node) {
-  // Lower to a direct call to a constant JSFunction if legal.
-  const CallFunctionParameters& p = CallFunctionParametersOf(node->op());
-  int arg_count = static_cast<int>(p.arity() - 2);
-
-  // Check the function is a constant and is really a JSFunction.
-  HeapObjectMatcher<Object> function_const(node->InputAt(0));
-  if (!function_const.HasValue()) return false;  // not a constant.
-  Handle<Object> func = function_const.Value().handle();
-  if (!func->IsJSFunction()) return false;  // not a function.
-  Handle<JSFunction> function = Handle<JSFunction>::cast(func);
-  if (arg_count != function->shared()->formal_parameter_count()) return false;
-
-  // Check the receiver doesn't need to be wrapped.
-  Node* receiver = node->InputAt(1);
-  if (!NodeProperties::IsTyped(receiver)) return false;
-  Type* ok_receiver = Type::Union(Type::Undefined(), Type::Receiver(), zone());
-  if (!NodeProperties::GetBounds(receiver).upper->Is(ok_receiver)) return false;
-
-  int index = NodeProperties::FirstContextIndex(node);
-
-  // TODO(titzer): total hack to share function context constants.
-  // Remove this when the JSGraph canonicalizes heap constants.
-  Node* context = node->InputAt(index);
-  HeapObjectMatcher<Context> context_const(context);
-  if (!context_const.HasValue() ||
-      *(context_const.Value().handle()) != function->context()) {
-    context = jsgraph()->HeapConstant(Handle<Context>(function->context()));
-  }
-  node->ReplaceInput(index, context);
-  CallDescriptor* desc = linkage()->GetJSCallDescriptor(
-      1 + arg_count, jsgraph()->zone(), FlagsForNode(node));
-  PatchOperator(node, common()->Call(desc));
-  return true;
+  CallConstructParameters const& p = CallConstructParametersOf(node->op());
+  int const arg_count = static_cast<int>(p.arity() - 2);
+  CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
+  Callable callable = CodeFactory::Construct(isolate());
+  CallDescriptor* desc = Linkage::GetStubCallDescriptor(
+      isolate(), zone(), callable.descriptor(), arg_count + 1, flags);
+  Node* stub_code = jsgraph()->HeapConstant(callable.code());
+  Node* stub_arity = jsgraph()->Int32Constant(arg_count);
+  Node* new_target = node->InputAt(arg_count + 1);
+  Node* receiver = jsgraph()->UndefinedConstant();
+  node->RemoveInput(arg_count + 1);  // Drop new target.
+  node->InsertInput(zone(), 0, stub_code);
+  node->InsertInput(zone(), 2, new_target);
+  node->InsertInput(zone(), 3, stub_arity);
+  node->InsertInput(zone(), 4, receiver);
+  NodeProperties::ChangeOp(node, common()->Call(desc));
 }
 
 
 void JSGenericLowering::LowerJSCallFunction(Node* node) {
-  // Fast case: call function directly.
-  if (TryLowerDirectJSCall(node)) return;
-
-  // General case: CallFunctionStub.
-  const CallFunctionParameters& p = CallFunctionParametersOf(node->op());
-  int arg_count = static_cast<int>(p.arity() - 2);
-  CallFunctionStub stub(isolate(), arg_count, p.flags());
-  CallInterfaceDescriptor d = stub.GetCallInterfaceDescriptor();
-  CallDescriptor* desc = linkage()->GetStubCallDescriptor(
-      d, static_cast<int>(p.arity() - 1), FlagsForNode(node));
-  Node* stub_code = jsgraph()->HeapConstant(stub.GetCode());
-  PatchInsertInput(node, 0, stub_code);
-  PatchOperator(node, common()->Call(desc));
+  CallFunctionParameters const& p = CallFunctionParametersOf(node->op());
+  int const arg_count = static_cast<int>(p.arity() - 2);
+  ConvertReceiverMode const mode = p.convert_mode();
+  Callable callable = CodeFactory::Call(isolate(), mode);
+  CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
+  if (p.tail_call_mode() == TailCallMode::kAllow) {
+    flags |= CallDescriptor::kSupportsTailCalls;
+  }
+  CallDescriptor* desc = Linkage::GetStubCallDescriptor(
+      isolate(), zone(), callable.descriptor(), arg_count + 1, flags);
+  Node* stub_code = jsgraph()->HeapConstant(callable.code());
+  Node* stub_arity = jsgraph()->Int32Constant(arg_count);
+  node->InsertInput(zone(), 0, stub_code);
+  node->InsertInput(zone(), 2, stub_arity);
+  NodeProperties::ChangeOp(node, common()->Call(desc));
 }
 
 
 void JSGenericLowering::LowerJSCallRuntime(Node* node) {
   const CallRuntimeParameters& p = CallRuntimeParametersOf(node->op());
+  AdjustFrameStatesForCall(node);
   ReplaceWithRuntimeCall(node, p.id(), static_cast<int>(p.arity()));
 }
 
+
+void JSGenericLowering::LowerJSForInDone(Node* node) {
+  ReplaceWithRuntimeCall(node, Runtime::kForInDone);
+}
+
+
+void JSGenericLowering::LowerJSForInNext(Node* node) {
+  ReplaceWithRuntimeCall(node, Runtime::kForInNext);
+}
+
+
+void JSGenericLowering::LowerJSForInPrepare(Node* node) {
+  Node* object = NodeProperties::GetValueInput(node, 0);
+  Node* context = NodeProperties::GetContextInput(node);
+  Node* effect = NodeProperties::GetEffectInput(node);
+  Node* control = NodeProperties::GetControlInput(node);
+  Node* frame_state = NodeProperties::GetFrameStateInput(node, 0);
+
+  // Get the set of properties to enumerate.
+  Runtime::Function const* function =
+      Runtime::FunctionForId(Runtime::kGetPropertyNamesFast);
+  CallDescriptor const* descriptor = Linkage::GetRuntimeCallDescriptor(
+      zone(), function->function_id, 1, Operator::kNoProperties,
+      CallDescriptor::kNeedsFrameState);
+  Node* cache_type = effect = graph()->NewNode(
+      common()->Call(descriptor),
+      jsgraph()->CEntryStubConstant(function->result_size), object,
+      jsgraph()->ExternalConstant(function->function_id),
+      jsgraph()->Int32Constant(1), context, frame_state, effect, control);
+  control = graph()->NewNode(common()->IfSuccess(), cache_type);
+
+  Node* object_map = effect = graph()->NewNode(
+      machine()->Load(MachineType::AnyTagged()), object,
+      jsgraph()->IntPtrConstant(HeapObject::kMapOffset - kHeapObjectTag),
+      effect, control);
+  Node* cache_type_map = effect = graph()->NewNode(
+      machine()->Load(MachineType::AnyTagged()), cache_type,
+      jsgraph()->IntPtrConstant(HeapObject::kMapOffset - kHeapObjectTag),
+      effect, control);
+  Node* meta_map = jsgraph()->HeapConstant(isolate()->factory()->meta_map());
+
+  // If we got a map from the GetPropertyNamesFast runtime call, we can do a
+  // fast modification check. Otherwise, we got a fixed array, and we have to
+  // perform a slow check on every iteration.
+  Node* check0 =
+      graph()->NewNode(machine()->WordEqual(), cache_type_map, meta_map);
+  Node* branch0 =
+      graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
+
+  Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
+  Node* cache_array_true0;
+  Node* cache_length_true0;
+  Node* cache_type_true0;
+  Node* etrue0;
+  {
+    // Enum cache case.
+    Node* cache_type_enum_length = etrue0 = graph()->NewNode(
+        machine()->Load(MachineType::Uint32()), cache_type,
+        jsgraph()->IntPtrConstant(Map::kBitField3Offset - kHeapObjectTag),
+        effect, if_true0);
+    cache_type_enum_length =
+        graph()->NewNode(machine()->Word32And(), cache_type_enum_length,
+                         jsgraph()->Uint32Constant(Map::EnumLengthBits::kMask));
+
+    Node* check1 =
+        graph()->NewNode(machine()->Word32Equal(), cache_type_enum_length,
+                         jsgraph()->Int32Constant(0));
+    Node* branch1 =
+        graph()->NewNode(common()->Branch(BranchHint::kTrue), check1, if_true0);
+
+    Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
+    Node* cache_array_true1;
+    Node* etrue1;
+    {
+      // No properties to enumerate.
+      cache_array_true1 =
+          jsgraph()->HeapConstant(isolate()->factory()->empty_fixed_array());
+      etrue1 = etrue0;
+    }
+
+    Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
+    Node* cache_array_false1;
+    Node* efalse1;
+    {
+      // Load the enumeration cache from the instance descriptors of {object}.
+      Node* object_map_descriptors = efalse1 = graph()->NewNode(
+          machine()->Load(MachineType::AnyTagged()), object_map,
+          jsgraph()->IntPtrConstant(Map::kDescriptorsOffset - kHeapObjectTag),
+          etrue0, if_false1);
+      Node* object_map_enum_cache = efalse1 = graph()->NewNode(
+          machine()->Load(MachineType::AnyTagged()), object_map_descriptors,
+          jsgraph()->IntPtrConstant(DescriptorArray::kEnumCacheOffset -
+                                    kHeapObjectTag),
+          efalse1, if_false1);
+      cache_array_false1 = efalse1 = graph()->NewNode(
+          machine()->Load(MachineType::AnyTagged()), object_map_enum_cache,
+          jsgraph()->IntPtrConstant(
+              DescriptorArray::kEnumCacheBridgeCacheOffset - kHeapObjectTag),
+          efalse1, if_false1);
+    }
+
+    if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
+    etrue0 =
+        graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_true0);
+    cache_array_true0 =
+        graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
+                         cache_array_true1, cache_array_false1, if_true0);
+
+    cache_length_true0 = graph()->NewNode(
+        machine()->WordShl(),
+        machine()->Is64()
+            ? graph()->NewNode(machine()->ChangeUint32ToUint64(),
+                               cache_type_enum_length)
+            : cache_type_enum_length,
+        jsgraph()->Int32Constant(kSmiShiftSize + kSmiTagSize));
+    cache_type_true0 = cache_type;
+  }
+
+  Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
+  Node* cache_array_false0;
+  Node* cache_length_false0;
+  Node* cache_type_false0;
+  Node* efalse0;
+  {
+    // FixedArray case.
+    cache_type_false0 = jsgraph()->OneConstant();  // Smi means slow check
+    cache_array_false0 = cache_type;
+    cache_length_false0 = efalse0 = graph()->NewNode(
+        machine()->Load(MachineType::AnyTagged()), cache_array_false0,
+        jsgraph()->IntPtrConstant(FixedArray::kLengthOffset - kHeapObjectTag),
+        effect, if_false0);
+  }
+
+  control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
+  effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
+  Node* cache_array =
+      graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
+                       cache_array_true0, cache_array_false0, control);
+  Node* cache_length =
+      graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
+                       cache_length_true0, cache_length_false0, control);
+  cache_type =
+      graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
+                       cache_type_true0, cache_type_false0, control);
+
+  for (auto edge : node->use_edges()) {
+    if (NodeProperties::IsEffectEdge(edge)) {
+      edge.UpdateTo(effect);
+    } else if (NodeProperties::IsControlEdge(edge)) {
+      Node* const use = edge.from();
+      if (use->opcode() == IrOpcode::kIfSuccess) {
+        use->ReplaceUses(control);
+        use->Kill();
+      } else if (use->opcode() == IrOpcode::kIfException) {
+        edge.UpdateTo(cache_type_true0);
+      } else {
+        UNREACHABLE();
+      }
+    } else {
+      Node* const use = edge.from();
+      DCHECK(NodeProperties::IsValueEdge(edge));
+      DCHECK_EQ(IrOpcode::kProjection, use->opcode());
+      switch (ProjectionIndexOf(use->op())) {
+        case 0:
+          use->ReplaceUses(cache_type);
+          break;
+        case 1:
+          use->ReplaceUses(cache_array);
+          break;
+        case 2:
+          use->ReplaceUses(cache_length);
+          break;
+        default:
+          UNREACHABLE();
+          break;
+      }
+      use->Kill();
+    }
+  }
+}
+
+
+void JSGenericLowering::LowerJSForInStep(Node* node) {
+  ReplaceWithRuntimeCall(node, Runtime::kForInStep);
+}
+
+
+void JSGenericLowering::LowerJSLoadMessage(Node* node) {
+  ExternalReference message_address =
+      ExternalReference::address_of_pending_message_obj(isolate());
+  node->RemoveInput(NodeProperties::FirstContextIndex(node));
+  node->InsertInput(zone(), 0, jsgraph()->ExternalConstant(message_address));
+  node->InsertInput(zone(), 1, jsgraph()->IntPtrConstant(0));
+  NodeProperties::ChangeOp(node, machine()->Load(MachineType::AnyTagged()));
+}
+
+
+void JSGenericLowering::LowerJSStoreMessage(Node* node) {
+  ExternalReference message_address =
+      ExternalReference::address_of_pending_message_obj(isolate());
+  node->RemoveInput(NodeProperties::FirstContextIndex(node));
+  node->InsertInput(zone(), 0, jsgraph()->ExternalConstant(message_address));
+  node->InsertInput(zone(), 1, jsgraph()->IntPtrConstant(0));
+  StoreRepresentation representation(MachineRepresentation::kTagged,
+                                     kNoWriteBarrier);
+  NodeProperties::ChangeOp(node, machine()->Store(representation));
+}
+
+
+void JSGenericLowering::LowerJSYield(Node* node) { UNIMPLEMENTED(); }
+
+
+void JSGenericLowering::LowerJSStackCheck(Node* node) {
+  Node* effect = NodeProperties::GetEffectInput(node);
+  Node* control = NodeProperties::GetControlInput(node);
+
+  Node* limit = graph()->NewNode(
+      machine()->Load(MachineType::Pointer()),
+      jsgraph()->ExternalConstant(
+          ExternalReference::address_of_stack_limit(isolate())),
+      jsgraph()->IntPtrConstant(0), effect, control);
+  Node* pointer = graph()->NewNode(machine()->LoadStackPointer());
+
+  Node* check = graph()->NewNode(machine()->UintLessThan(), limit, pointer);
+  Node* branch =
+      graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
+
+  Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
+  Node* etrue = effect;
+
+  Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+  NodeProperties::ReplaceControlInput(node, if_false);
+  Node* efalse = node;
+
+  Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
+  Node* ephi = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, merge);
+
+  // Wire the new diamond into the graph, {node} can still throw.
+  NodeProperties::ReplaceUses(node, node, ephi, node, node);
+  NodeProperties::ReplaceEffectInput(ephi, efalse, 1);
+
+  // TODO(mstarzinger): This iteration cuts out the IfSuccess projection from
+  // the node and places it inside the diamond. Come up with a helper method!
+  for (Node* use : node->uses()) {
+    if (use->opcode() == IrOpcode::kIfSuccess) {
+      use->ReplaceUses(merge);
+      merge->ReplaceInput(1, use);
+    }
+  }
+
+  // Turn the stack check into a runtime call.
+  ReplaceWithRuntimeCall(node, Runtime::kStackGuard);
+}
+
+
+Zone* JSGenericLowering::zone() const { return graph()->zone(); }
+
+
+Isolate* JSGenericLowering::isolate() const { return jsgraph()->isolate(); }
+
+
+Graph* JSGenericLowering::graph() const { return jsgraph()->graph(); }
+
+
+CommonOperatorBuilder* JSGenericLowering::common() const {
+  return jsgraph()->common();
+}
+
+
+MachineOperatorBuilder* JSGenericLowering::machine() const {
+  return jsgraph()->machine();
+}
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/src/compiler/js-generic-lowering.h b/src/compiler/js-generic-lowering.h
index f626338..ffce912 100644
--- a/src/compiler/js-generic-lowering.h
+++ b/src/compiler/js-generic-lowering.h
@@ -5,11 +5,8 @@
 #ifndef V8_COMPILER_JS_GENERIC_LOWERING_H_
 #define V8_COMPILER_JS_GENERIC_LOWERING_H_
 
-#include "src/allocation.h"
 #include "src/code-factory.h"
-#include "src/compiler/graph.h"
 #include "src/compiler/graph-reducer.h"
-#include "src/compiler/js-graph.h"
 #include "src/compiler/linkage.h"
 #include "src/compiler/opcodes.h"
 
@@ -19,17 +16,18 @@
 
 // Forward declarations.
 class CommonOperatorBuilder;
+class JSGraph;
 class MachineOperatorBuilder;
 class Linkage;
 
 
 // Lowers JS-level operators to runtime and IC calls in the "generic" case.
-class JSGenericLowering FINAL : public Reducer {
+class JSGenericLowering final : public Reducer {
  public:
-  JSGenericLowering(CompilationInfo* info, JSGraph* graph);
-  ~JSGenericLowering() FINAL {}
+  JSGenericLowering(bool is_typing_enabled, JSGraph* jsgraph);
+  ~JSGenericLowering() final;
 
-  Reduction Reduce(Node* node) FINAL;
+  Reduction Reduce(Node* node) final;
 
  protected:
 #define DECLARE_LOWER(x) void Lower##x(Node* node);
@@ -37,32 +35,21 @@
   JS_OP_LIST(DECLARE_LOWER)
 #undef DECLARE_LOWER
 
-  // Helpers to patch existing nodes in the graph.
-  void PatchOperator(Node* node, const Operator* new_op);
-  void PatchInsertInput(Node* node, int index, Node* input);
-
   // Helpers to replace existing nodes with a generic call.
-  void ReplaceWithCompareIC(Node* node, Token::Value token);
+  void ReplaceWithCompareIC(Node* node, Token::Value token, Strength strength);
   void ReplaceWithStubCall(Node* node, Callable c, CallDescriptor::Flags flags);
-  void ReplaceWithBuiltinCall(Node* node, Builtins::JavaScript id, int args);
   void ReplaceWithRuntimeCall(Node* node, Runtime::FunctionId f, int args = -1);
 
-  // Helper for optimization of JSCallFunction.
-  bool TryLowerDirectJSCall(Node* node);
-
-  Zone* zone() const { return graph()->zone(); }
-  Isolate* isolate() const { return zone()->isolate(); }
+  Zone* zone() const;
+  Isolate* isolate() const;
   JSGraph* jsgraph() const { return jsgraph_; }
-  Graph* graph() const { return jsgraph()->graph(); }
-  Linkage* linkage() const { return linkage_; }
-  CompilationInfo* info() const { return info_; }
-  CommonOperatorBuilder* common() const { return jsgraph()->common(); }
-  MachineOperatorBuilder* machine() const { return jsgraph()->machine(); }
+  Graph* graph() const;
+  CommonOperatorBuilder* common() const;
+  MachineOperatorBuilder* machine() const;
 
  private:
-  CompilationInfo* info_;
-  JSGraph* jsgraph_;
-  Linkage* linkage_;
+  bool const is_typing_enabled_;
+  JSGraph* const jsgraph_;
 };
 
 }  // namespace compiler
diff --git a/src/compiler/js-global-object-specialization.cc b/src/compiler/js-global-object-specialization.cc
new file mode 100644
index 0000000..e6f01b3
--- /dev/null
+++ b/src/compiler/js-global-object-specialization.cc
@@ -0,0 +1,320 @@
+// Copyright 2015 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/js-global-object-specialization.h"
+
+#include "src/compilation-dependencies.h"
+#include "src/compiler/access-builder.h"
+#include "src/compiler/common-operator.h"
+#include "src/compiler/js-graph.h"
+#include "src/compiler/js-operator.h"
+#include "src/compiler/node-properties.h"
+#include "src/compiler/simplified-operator.h"
+#include "src/lookup.h"
+#include "src/objects-inl.h"  // TODO(mstarzinger): Temporary cycle breaker!
+#include "src/type-cache.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+struct JSGlobalObjectSpecialization::ScriptContextTableLookupResult {
+  Handle<Context> context;
+  bool immutable;
+  int index;
+};
+
+
+JSGlobalObjectSpecialization::JSGlobalObjectSpecialization(
+    Editor* editor, JSGraph* jsgraph, Flags flags,
+    MaybeHandle<Context> native_context, CompilationDependencies* dependencies)
+    : AdvancedReducer(editor),
+      jsgraph_(jsgraph),
+      flags_(flags),
+      native_context_(native_context),
+      dependencies_(dependencies),
+      type_cache_(TypeCache::Get()) {}
+
+
+Reduction JSGlobalObjectSpecialization::Reduce(Node* node) {
+  switch (node->opcode()) {
+    case IrOpcode::kJSLoadGlobal:
+      return ReduceJSLoadGlobal(node);
+    case IrOpcode::kJSStoreGlobal:
+      return ReduceJSStoreGlobal(node);
+    default:
+      break;
+  }
+  return NoChange();
+}
+
+
+Reduction JSGlobalObjectSpecialization::ReduceJSLoadGlobal(Node* node) {
+  DCHECK_EQ(IrOpcode::kJSLoadGlobal, node->opcode());
+  Handle<Name> name = LoadGlobalParametersOf(node->op()).name();
+  Node* effect = NodeProperties::GetEffectInput(node);
+  Node* control = NodeProperties::GetControlInput(node);
+
+  // Retrieve the global object from the given {node}.
+  Handle<JSGlobalObject> global_object;
+  if (!GetGlobalObject(node).ToHandle(&global_object)) return NoChange();
+
+  // Try to lookup the name on the script context table first (lexical scoping).
+  ScriptContextTableLookupResult result;
+  if (LookupInScriptContextTable(global_object, name, &result)) {
+    if (result.context->is_the_hole(result.index)) return NoChange();
+    Node* context = jsgraph()->HeapConstant(result.context);
+    Node* value = effect = graph()->NewNode(
+        javascript()->LoadContext(0, result.index, result.immutable), context,
+        context, effect);
+    ReplaceWithValue(node, value, effect);
+    return Replace(value);
+  }
+
+  // Lookup on the global object instead.  We only deal with own data
+  // properties of the global object here (represented as PropertyCell).
+  LookupIterator it(global_object, name, LookupIterator::OWN);
+  if (it.state() != LookupIterator::DATA) return NoChange();
+  Handle<PropertyCell> property_cell = it.GetPropertyCell();
+  PropertyDetails property_details = property_cell->property_details();
+  Handle<Object> property_cell_value(property_cell->value(), isolate());
+
+  // Load from non-configurable, read-only data property on the global
+  // object can be constant-folded, even without deoptimization support.
+  if (!property_details.IsConfigurable() && property_details.IsReadOnly()) {
+    Node* value = jsgraph()->Constant(property_cell_value);
+    ReplaceWithValue(node, value);
+    return Replace(value);
+  }
+
+  // Load from non-configurable, data property on the global can be lowered to
+  // a field load, even without deoptimization, because the property cannot be
+  // deleted or reconfigured to an accessor/interceptor property.  Yet, if
+  // deoptimization support is available, we can constant-fold certain global
+  // properties or at least lower them to field loads annotated with more
+  // precise type feedback.
+  Type* property_cell_value_type = Type::Tagged();
+  if (flags() & kDeoptimizationEnabled) {
+    // Record a code dependency on the cell if we can benefit from the
+    // additional feedback, or the global property is configurable (i.e.
+    // can be deleted or reconfigured to an accessor property).
+    if (property_details.cell_type() != PropertyCellType::kMutable ||
+        property_details.IsConfigurable()) {
+      dependencies()->AssumePropertyCell(property_cell);
+    }
+
+    // Load from constant/undefined global property can be constant-folded.
+    if ((property_details.cell_type() == PropertyCellType::kConstant ||
+         property_details.cell_type() == PropertyCellType::kUndefined)) {
+      Node* value = jsgraph()->Constant(property_cell_value);
+      ReplaceWithValue(node, value);
+      return Replace(value);
+    }
+
+    // Load from constant type cell can benefit from type feedback.
+    if (property_details.cell_type() == PropertyCellType::kConstantType) {
+      // Compute proper type based on the current value in the cell.
+      if (property_cell_value->IsSmi()) {
+        property_cell_value_type = type_cache_.kSmi;
+      } else if (property_cell_value->IsNumber()) {
+        property_cell_value_type = type_cache_.kHeapNumber;
+      } else {
+        Handle<Map> property_cell_value_map(
+            Handle<HeapObject>::cast(property_cell_value)->map(), isolate());
+        property_cell_value_type =
+            Type::Class(property_cell_value_map, graph()->zone());
+      }
+    }
+  } else if (property_details.IsConfigurable()) {
+    // Access to configurable global properties requires deoptimization support.
+    return NoChange();
+  }
+  Node* value = effect = graph()->NewNode(
+      simplified()->LoadField(
+          AccessBuilder::ForPropertyCellValue(property_cell_value_type)),
+      jsgraph()->HeapConstant(property_cell), effect, control);
+  ReplaceWithValue(node, value, effect, control);
+  return Replace(value);
+}
+
+
+Reduction JSGlobalObjectSpecialization::ReduceJSStoreGlobal(Node* node) {
+  DCHECK_EQ(IrOpcode::kJSStoreGlobal, node->opcode());
+  Handle<Name> name = StoreGlobalParametersOf(node->op()).name();
+  Node* value = NodeProperties::GetValueInput(node, 0);
+  Node* frame_state = NodeProperties::GetFrameStateInput(node, 1);
+  Node* effect = NodeProperties::GetEffectInput(node);
+  Node* control = NodeProperties::GetControlInput(node);
+
+  // Retrieve the global object from the given {node}.
+  Handle<JSGlobalObject> global_object;
+  if (!GetGlobalObject(node).ToHandle(&global_object)) return NoChange();
+
+  // Try to lookup the name on the script context table first (lexical scoping).
+  ScriptContextTableLookupResult result;
+  if (LookupInScriptContextTable(global_object, name, &result)) {
+    if (result.context->is_the_hole(result.index)) return NoChange();
+    if (result.immutable) return NoChange();
+    Node* context = jsgraph()->HeapConstant(result.context);
+    effect = graph()->NewNode(javascript()->StoreContext(0, result.index),
+                              context, value, context, effect, control);
+    ReplaceWithValue(node, value, effect, control);
+    return Replace(value);
+  }
+
+  // Lookup on the global object instead.  We only deal with own data
+  // properties of the global object here (represented as PropertyCell).
+  LookupIterator it(global_object, name, LookupIterator::OWN);
+  if (it.state() != LookupIterator::DATA) return NoChange();
+  Handle<PropertyCell> property_cell = it.GetPropertyCell();
+  PropertyDetails property_details = property_cell->property_details();
+  Handle<Object> property_cell_value(property_cell->value(), isolate());
+
+  // Don't even bother trying to lower stores to read-only data properties.
+  if (property_details.IsReadOnly()) return NoChange();
+  switch (property_details.cell_type()) {
+    case PropertyCellType::kUndefined: {
+      return NoChange();
+    }
+    case PropertyCellType::kConstant: {
+      // Store to constant property cell requires deoptimization support,
+      // because we might even need to eager deoptimize for mismatch.
+      if (!(flags() & kDeoptimizationEnabled)) return NoChange();
+      dependencies()->AssumePropertyCell(property_cell);
+      Node* check =
+          graph()->NewNode(simplified()->ReferenceEqual(Type::Tagged()), value,
+                           jsgraph()->Constant(property_cell_value));
+      Node* branch =
+          graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
+      Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+      Node* deoptimize =
+          graph()->NewNode(common()->Deoptimize(DeoptimizeKind::kEager),
+                           frame_state, effect, if_false);
+      // TODO(bmeurer): This should be on the AdvancedReducer somehow.
+      NodeProperties::MergeControlToEnd(graph(), common(), deoptimize);
+      control = graph()->NewNode(common()->IfTrue(), branch);
+      break;
+    }
+    case PropertyCellType::kConstantType: {
+      // Store to constant-type property cell requires deoptimization support,
+      // because we might even need to eager deoptimize for mismatch.
+      if (!(flags() & kDeoptimizationEnabled)) return NoChange();
+      dependencies()->AssumePropertyCell(property_cell);
+      Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), value);
+      Type* property_cell_value_type = Type::TaggedSigned();
+      if (property_cell_value->IsHeapObject()) {
+        // Deoptimize if the {value} is a Smi.
+        Node* branch = graph()->NewNode(common()->Branch(BranchHint::kFalse),
+                                        check, control);
+        Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
+        Node* deoptimize =
+            graph()->NewNode(common()->Deoptimize(DeoptimizeKind::kEager),
+                             frame_state, effect, if_true);
+        // TODO(bmeurer): This should be on the AdvancedReducer somehow.
+        NodeProperties::MergeControlToEnd(graph(), common(), deoptimize);
+        control = graph()->NewNode(common()->IfFalse(), branch);
+
+        // Load the {value} map check against the {property_cell} map.
+        Node* value_map = effect =
+            graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
+                             value, effect, control);
+        Handle<Map> property_cell_value_map(
+            Handle<HeapObject>::cast(property_cell_value)->map(), isolate());
+        check = graph()->NewNode(
+            simplified()->ReferenceEqual(Type::Any()), value_map,
+            jsgraph()->HeapConstant(property_cell_value_map));
+        property_cell_value_type = Type::TaggedPointer();
+      }
+      Node* branch =
+          graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
+      Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+      Node* deoptimize =
+          graph()->NewNode(common()->Deoptimize(DeoptimizeKind::kEager),
+                           frame_state, effect, if_false);
+      // TODO(bmeurer): This should be on the AdvancedReducer somehow.
+      NodeProperties::MergeControlToEnd(graph(), common(), deoptimize);
+      control = graph()->NewNode(common()->IfTrue(), branch);
+      effect = graph()->NewNode(
+          simplified()->StoreField(
+              AccessBuilder::ForPropertyCellValue(property_cell_value_type)),
+          jsgraph()->HeapConstant(property_cell), value, effect, control);
+      break;
+    }
+    case PropertyCellType::kMutable: {
+      // Store to non-configurable, data property on the global can be lowered
+      // to a field store, even without deoptimization, because the property
+      // cannot be deleted or reconfigured to an accessor/interceptor property.
+      if (property_details.IsConfigurable()) {
+        // With deoptimization support, we can lower stores even to configurable
+        // data properties on the global object, by adding a code dependency on
+        // the cell.
+        if (!(flags() & kDeoptimizationEnabled)) return NoChange();
+        dependencies()->AssumePropertyCell(property_cell);
+      }
+      effect = graph()->NewNode(
+          simplified()->StoreField(AccessBuilder::ForPropertyCellValue()),
+          jsgraph()->HeapConstant(property_cell), value, effect, control);
+      break;
+    }
+  }
+  ReplaceWithValue(node, value, effect, control);
+  return Replace(value);
+}
+
+
+MaybeHandle<JSGlobalObject> JSGlobalObjectSpecialization::GetGlobalObject(
+    Node* node) {
+  Node* const context = NodeProperties::GetContextInput(node);
+  return NodeProperties::GetSpecializationGlobalObject(context,
+                                                       native_context());
+}
+
+
+bool JSGlobalObjectSpecialization::LookupInScriptContextTable(
+    Handle<JSGlobalObject> global_object, Handle<Name> name,
+    ScriptContextTableLookupResult* result) {
+  if (!name->IsString()) return false;
+  Handle<ScriptContextTable> script_context_table(
+      global_object->native_context()->script_context_table(), isolate());
+  ScriptContextTable::LookupResult lookup_result;
+  if (!ScriptContextTable::Lookup(script_context_table,
+                                  Handle<String>::cast(name), &lookup_result)) {
+    return false;
+  }
+  Handle<Context> script_context = ScriptContextTable::GetContext(
+      script_context_table, lookup_result.context_index);
+  result->context = script_context;
+  result->immutable = IsImmutableVariableMode(lookup_result.mode);
+  result->index = lookup_result.slot_index;
+  return true;
+}
+
+
+Graph* JSGlobalObjectSpecialization::graph() const {
+  return jsgraph()->graph();
+}
+
+
+Isolate* JSGlobalObjectSpecialization::isolate() const {
+  return jsgraph()->isolate();
+}
+
+
+CommonOperatorBuilder* JSGlobalObjectSpecialization::common() const {
+  return jsgraph()->common();
+}
+
+
+JSOperatorBuilder* JSGlobalObjectSpecialization::javascript() const {
+  return jsgraph()->javascript();
+}
+
+
+SimplifiedOperatorBuilder* JSGlobalObjectSpecialization::simplified() const {
+  return jsgraph()->simplified();
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/js-global-object-specialization.h b/src/compiler/js-global-object-specialization.h
new file mode 100644
index 0000000..83d890c
--- /dev/null
+++ b/src/compiler/js-global-object-specialization.h
@@ -0,0 +1,83 @@
+// Copyright 2015 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.
+
+#ifndef V8_COMPILER_JS_GLOBAL_OBJECT_SPECIALIZATION_H_
+#define V8_COMPILER_JS_GLOBAL_OBJECT_SPECIALIZATION_H_
+
+#include "src/base/flags.h"
+#include "src/compiler/graph-reducer.h"
+
+namespace v8 {
+namespace internal {
+
+// Forward declarations.
+class CompilationDependencies;
+class TypeCache;
+
+
+namespace compiler {
+
+// Forward declarations.
+class CommonOperatorBuilder;
+class JSGraph;
+class JSOperatorBuilder;
+class SimplifiedOperatorBuilder;
+
+
+// Specializes a given JSGraph to a given global object, potentially constant
+// folding some {JSLoadGlobal} nodes or strength reducing some {JSStoreGlobal}
+// nodes.
+class JSGlobalObjectSpecialization final : public AdvancedReducer {
+ public:
+  // Flags that control the mode of operation.
+  enum Flag {
+    kNoFlags = 0u,
+    kDeoptimizationEnabled = 1u << 0,
+  };
+  typedef base::Flags<Flag> Flags;
+
+  JSGlobalObjectSpecialization(Editor* editor, JSGraph* jsgraph, Flags flags,
+                               MaybeHandle<Context> native_context,
+                               CompilationDependencies* dependencies);
+
+  Reduction Reduce(Node* node) final;
+
+ private:
+  Reduction ReduceJSLoadGlobal(Node* node);
+  Reduction ReduceJSStoreGlobal(Node* node);
+
+  // Retrieve the global object from the given {node} if known.
+  MaybeHandle<JSGlobalObject> GetGlobalObject(Node* node);
+
+  struct ScriptContextTableLookupResult;
+  bool LookupInScriptContextTable(Handle<JSGlobalObject> global_object,
+                                  Handle<Name> name,
+                                  ScriptContextTableLookupResult* result);
+
+  Graph* graph() const;
+  JSGraph* jsgraph() const { return jsgraph_; }
+  Isolate* isolate() const;
+  CommonOperatorBuilder* common() const;
+  JSOperatorBuilder* javascript() const;
+  SimplifiedOperatorBuilder* simplified() const;
+  Flags flags() const { return flags_; }
+  MaybeHandle<Context> native_context() const { return native_context_; }
+  CompilationDependencies* dependencies() const { return dependencies_; }
+
+  JSGraph* const jsgraph_;
+  Flags const flags_;
+  MaybeHandle<Context> native_context_;
+  CompilationDependencies* const dependencies_;
+  TypeCache const& type_cache_;
+
+  DISALLOW_COPY_AND_ASSIGN(JSGlobalObjectSpecialization);
+};
+
+DEFINE_OPERATORS_FOR_FLAGS(JSGlobalObjectSpecialization::Flags)
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_JS_GLOBAL_OBJECT_SPECIALIZATION_H_
diff --git a/src/compiler/js-graph.cc b/src/compiler/js-graph.cc
index 7759ba1..e938798 100644
--- a/src/compiler/js-graph.cc
+++ b/src/compiler/js-graph.cc
@@ -4,110 +4,82 @@
 
 #include "src/code-stubs.h"
 #include "src/compiler/js-graph.h"
-#include "src/compiler/node-properties-inl.h"
+#include "src/compiler/node-properties.h"
 #include "src/compiler/typer.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
-Node* JSGraph::ImmovableHeapConstant(Handle<HeapObject> object) {
-  Unique<HeapObject> unique = Unique<HeapObject>::CreateImmovable(object);
-  return graph()->NewNode(common()->HeapConstant(unique));
-}
+#define CACHED(name, expr) \
+  cached_nodes_[name] ? cached_nodes_[name] : (cached_nodes_[name] = (expr))
 
 
 Node* JSGraph::CEntryStubConstant(int result_size) {
   if (result_size == 1) {
-    if (!c_entry_stub_constant_.is_set()) {
-      c_entry_stub_constant_.set(
-          ImmovableHeapConstant(CEntryStub(isolate(), 1).GetCode()));
-    }
-    return c_entry_stub_constant_.get();
+    return CACHED(kCEntryStubConstant,
+                  HeapConstant(CEntryStub(isolate(), 1).GetCode()));
   }
+  return HeapConstant(CEntryStub(isolate(), result_size).GetCode());
+}
 
-  return ImmovableHeapConstant(CEntryStub(isolate(), result_size).GetCode());
+
+Node* JSGraph::EmptyFixedArrayConstant() {
+  return CACHED(kEmptyFixedArrayConstant,
+                HeapConstant(factory()->empty_fixed_array()));
 }
 
 
 Node* JSGraph::UndefinedConstant() {
-  if (!undefined_constant_.is_set()) {
-    undefined_constant_.set(
-        ImmovableHeapConstant(factory()->undefined_value()));
-  }
-  return undefined_constant_.get();
+  return CACHED(kUndefinedConstant, HeapConstant(factory()->undefined_value()));
 }
 
 
 Node* JSGraph::TheHoleConstant() {
-  if (!the_hole_constant_.is_set()) {
-    the_hole_constant_.set(ImmovableHeapConstant(factory()->the_hole_value()));
-  }
-  return the_hole_constant_.get();
+  return CACHED(kTheHoleConstant, HeapConstant(factory()->the_hole_value()));
 }
 
 
 Node* JSGraph::TrueConstant() {
-  if (!true_constant_.is_set()) {
-    true_constant_.set(ImmovableHeapConstant(factory()->true_value()));
-  }
-  return true_constant_.get();
+  return CACHED(kTrueConstant, HeapConstant(factory()->true_value()));
 }
 
 
 Node* JSGraph::FalseConstant() {
-  if (!false_constant_.is_set()) {
-    false_constant_.set(ImmovableHeapConstant(factory()->false_value()));
-  }
-  return false_constant_.get();
+  return CACHED(kFalseConstant, HeapConstant(factory()->false_value()));
 }
 
 
 Node* JSGraph::NullConstant() {
-  if (!null_constant_.is_set()) {
-    null_constant_.set(ImmovableHeapConstant(factory()->null_value()));
-  }
-  return null_constant_.get();
+  return CACHED(kNullConstant, HeapConstant(factory()->null_value()));
 }
 
 
 Node* JSGraph::ZeroConstant() {
-  if (!zero_constant_.is_set()) zero_constant_.set(NumberConstant(0.0));
-  return zero_constant_.get();
+  return CACHED(kZeroConstant, NumberConstant(0.0));
 }
 
 
 Node* JSGraph::OneConstant() {
-  if (!one_constant_.is_set()) one_constant_.set(NumberConstant(1.0));
-  return one_constant_.get();
+  return CACHED(kOneConstant, NumberConstant(1.0));
 }
 
 
 Node* JSGraph::NaNConstant() {
-  if (!nan_constant_.is_set()) {
-    nan_constant_.set(NumberConstant(base::OS::nan_value()));
-  }
-  return nan_constant_.get();
-}
-
-
-Node* JSGraph::HeapConstant(Unique<HeapObject> value) {
-  // TODO(turbofan): canonicalize heap constants using Unique<T>
-  return graph()->NewNode(common()->HeapConstant(value));
+  return CACHED(kNaNConstant,
+                NumberConstant(std::numeric_limits<double>::quiet_NaN()));
 }
 
 
 Node* JSGraph::HeapConstant(Handle<HeapObject> value) {
-  // TODO(titzer): We could also match against the addresses of immortable
-  // immovables here, even without access to the heap, thus always
-  // canonicalizing references to them.
-  // return HeapConstant(Unique<Object>::CreateUninitialized(value));
-  // TODO(turbofan): This is a work-around to make Unique::HashCode() work for
-  // value numbering. We need some sane way to compute a unique hash code for
-  // arbitrary handles here.
-  Unique<HeapObject> unique(reinterpret_cast<Address>(*value.location()),
-                            value);
-  return HeapConstant(unique);
+  if (value->IsConsString()) {
+    value = String::Flatten(Handle<String>::cast(value), TENURED);
+  }
+  Node** loc = cache_.FindHeapConstant(value);
+  if (*loc == nullptr) {
+    *loc = graph()->NewNode(common()->HeapConstant(value));
+  }
+  return *loc;
 }
 
 
@@ -148,7 +120,7 @@
 
 Node* JSGraph::Int32Constant(int32_t value) {
   Node** loc = cache_.FindInt32Constant(value);
-  if (*loc == NULL) {
+  if (*loc == nullptr) {
     *loc = graph()->NewNode(common()->Int32Constant(value));
   }
   return *loc;
@@ -157,7 +129,7 @@
 
 Node* JSGraph::Int64Constant(int64_t value) {
   Node** loc = cache_.FindInt64Constant(value);
-  if (*loc == NULL) {
+  if (*loc == nullptr) {
     *loc = graph()->NewNode(common()->Int64Constant(value));
   }
   return *loc;
@@ -166,7 +138,7 @@
 
 Node* JSGraph::NumberConstant(double value) {
   Node** loc = cache_.FindNumberConstant(value);
-  if (*loc == NULL) {
+  if (*loc == nullptr) {
     *loc = graph()->NewNode(common()->NumberConstant(value));
   }
   return *loc;
@@ -175,7 +147,7 @@
 
 Node* JSGraph::Float32Constant(float value) {
   Node** loc = cache_.FindFloat32Constant(value);
-  if (*loc == NULL) {
+  if (*loc == nullptr) {
     *loc = graph()->NewNode(common()->Float32Constant(value));
   }
   return *loc;
@@ -184,7 +156,7 @@
 
 Node* JSGraph::Float64Constant(double value) {
   Node** loc = cache_.FindFloat64Constant(value);
-  if (*loc == NULL) {
+  if (*loc == nullptr) {
     *loc = graph()->NewNode(common()->Float64Constant(value));
   }
   return *loc;
@@ -193,21 +165,44 @@
 
 Node* JSGraph::ExternalConstant(ExternalReference reference) {
   Node** loc = cache_.FindExternalConstant(reference);
-  if (*loc == NULL) {
+  if (*loc == nullptr) {
     *loc = graph()->NewNode(common()->ExternalConstant(reference));
   }
   return *loc;
 }
 
 
+Node* JSGraph::ExternalConstant(Runtime::FunctionId function_id) {
+  return ExternalConstant(ExternalReference(function_id, isolate()));
+}
+
+
+Node* JSGraph::EmptyFrameState() {
+  Node* empty_frame_state = cached_nodes_[kEmptyFrameState];
+  if (!empty_frame_state || empty_frame_state->IsDead()) {
+    Node* state_values = graph()->NewNode(common()->StateValues(0));
+    empty_frame_state = graph()->NewNode(
+        common()->FrameState(BailoutId::None(),
+                             OutputFrameStateCombine::Ignore(), nullptr),
+        state_values, state_values, state_values, NoContextConstant(),
+        UndefinedConstant(), graph()->start());
+    cached_nodes_[kEmptyFrameState] = empty_frame_state;
+  }
+  return empty_frame_state;
+}
+
+
+Node* JSGraph::Dead() {
+  return CACHED(kDead, graph()->NewNode(common()->Dead()));
+}
+
+
 void JSGraph::GetCachedNodes(NodeVector* nodes) {
   cache_.GetCachedNodes(nodes);
-  SetOncePointer<Node>* ptrs[] = {
-      &c_entry_stub_constant_, &undefined_constant_, &the_hole_constant_,
-      &true_constant_,         &false_constant_,     &null_constant_,
-      &zero_constant_,         &one_constant_,       &nan_constant_};
-  for (size_t i = 0; i < arraysize(ptrs); i++) {
-    if (ptrs[i]->is_set()) nodes->push_back(ptrs[i]->get());
+  for (size_t i = 0; i < arraysize(cached_nodes_); i++) {
+    if (Node* node = cached_nodes_[i]) {
+      if (!node->IsDead()) nodes->push_back(node);
+    }
   }
 }
 
diff --git a/src/compiler/js-graph.h b/src/compiler/js-graph.h
index 040a745..5a25ed0 100644
--- a/src/compiler/js-graph.h
+++ b/src/compiler/js-graph.h
@@ -11,28 +11,36 @@
 #include "src/compiler/js-operator.h"
 #include "src/compiler/machine-operator.h"
 #include "src/compiler/node-properties.h"
+#include "src/isolate.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
+class SimplifiedOperatorBuilder;
 class Typer;
 
 // Implements a facade on a Graph, enhancing the graph with JS-specific
-// notions, including a builder for for JS* operators, canonicalized global
+// notions, including various builders for operators, canonicalized global
 // constants, and various helper methods.
 class JSGraph : public ZoneObject {
  public:
-  JSGraph(Graph* graph, CommonOperatorBuilder* common,
-          JSOperatorBuilder* javascript, MachineOperatorBuilder* machine)
-      : graph_(graph),
+  JSGraph(Isolate* isolate, Graph* graph, CommonOperatorBuilder* common,
+          JSOperatorBuilder* javascript, SimplifiedOperatorBuilder* simplified,
+          MachineOperatorBuilder* machine)
+      : isolate_(isolate),
+        graph_(graph),
         common_(common),
         javascript_(javascript),
+        simplified_(simplified),
         machine_(machine),
-        cache_(zone()) {}
+        cache_(zone()) {
+    for (int i = 0; i < kNumCachedNodes; i++) cached_nodes_[i] = nullptr;
+  }
 
   // Canonicalized global constants.
   Node* CEntryStubConstant(int result_size);
+  Node* EmptyFixedArrayConstant();
   Node* UndefinedConstant();
   Node* TheHoleConstant();
   Node* TrueConstant();
@@ -42,10 +50,6 @@
   Node* OneConstant();
   Node* NaNConstant();
 
-  // Creates a HeapConstant node, possibly canonicalized, without inspecting the
-  // object.
-  Node* HeapConstant(Unique<HeapObject> value);
-
   // Creates a HeapConstant node, possibly canonicalized, and may access the
   // heap to inspect the object.
   Node* HeapConstant(Handle<HeapObject> value);
@@ -99,6 +103,7 @@
 
   // Creates an ExternalConstant node, usually canonicalized.
   Node* ExternalConstant(ExternalReference ref);
+  Node* ExternalConstant(Runtime::FunctionId function_id);
 
   Node* SmiConstant(int32_t immediate) {
     DCHECK(Smi::IsValid(immediate));
@@ -109,36 +114,50 @@
   // stubs and runtime functions that do not require a context.
   Node* NoContextConstant() { return ZeroConstant(); }
 
-  JSOperatorBuilder* javascript() { return javascript_; }
-  CommonOperatorBuilder* common() { return common_; }
-  MachineOperatorBuilder* machine() { return machine_; }
-  Graph* graph() { return graph_; }
-  Zone* zone() { return graph()->zone(); }
-  Isolate* isolate() { return zone()->isolate(); }
-  Factory* factory() { return isolate()->factory(); }
+  // Creates an empty frame states for cases where we know that a function
+  // cannot deopt.
+  Node* EmptyFrameState();
+
+  // Create a control node that serves as dependency for dead nodes.
+  Node* Dead();
+
+  CommonOperatorBuilder* common() const { return common_; }
+  JSOperatorBuilder* javascript() const { return javascript_; }
+  SimplifiedOperatorBuilder* simplified() const { return simplified_; }
+  MachineOperatorBuilder* machine() const { return machine_; }
+  Graph* graph() const { return graph_; }
+  Zone* zone() const { return graph()->zone(); }
+  Isolate* isolate() const { return isolate_; }
+  Factory* factory() const { return isolate()->factory(); }
 
   void GetCachedNodes(NodeVector* nodes);
 
  private:
+  enum CachedNode {
+    kCEntryStubConstant,
+    kEmptyFixedArrayConstant,
+    kUndefinedConstant,
+    kTheHoleConstant,
+    kTrueConstant,
+    kFalseConstant,
+    kNullConstant,
+    kZeroConstant,
+    kOneConstant,
+    kNaNConstant,
+    kEmptyFrameState,
+    kDead,
+    kNumCachedNodes  // Must remain last.
+  };
+
+  Isolate* isolate_;
   Graph* graph_;
   CommonOperatorBuilder* common_;
   JSOperatorBuilder* javascript_;
+  SimplifiedOperatorBuilder* simplified_;
   MachineOperatorBuilder* machine_;
-
-  // TODO(titzer): make this into a simple array.
-  SetOncePointer<Node> c_entry_stub_constant_;
-  SetOncePointer<Node> undefined_constant_;
-  SetOncePointer<Node> the_hole_constant_;
-  SetOncePointer<Node> true_constant_;
-  SetOncePointer<Node> false_constant_;
-  SetOncePointer<Node> null_constant_;
-  SetOncePointer<Node> zero_constant_;
-  SetOncePointer<Node> one_constant_;
-  SetOncePointer<Node> nan_constant_;
-
   CommonNodeCache cache_;
+  Node* cached_nodes_[kNumCachedNodes];
 
-  Node* ImmovableHeapConstant(Handle<HeapObject> value);
   Node* NumberConstant(double value);
 
   DISALLOW_COPY_AND_ASSIGN(JSGraph);
diff --git a/src/compiler/js-inlining-heuristic.cc b/src/compiler/js-inlining-heuristic.cc
new file mode 100644
index 0000000..cd5637b
--- /dev/null
+++ b/src/compiler/js-inlining-heuristic.cc
@@ -0,0 +1,141 @@
+// Copyright 2015 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/js-inlining-heuristic.h"
+
+#include "src/compiler.h"
+#include "src/compiler/node-matchers.h"
+#include "src/objects-inl.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+Reduction JSInliningHeuristic::Reduce(Node* node) {
+  if (!IrOpcode::IsInlineeOpcode(node->opcode())) return NoChange();
+
+  // Check if we already saw that {node} before, and if so, just skip it.
+  if (seen_.find(node->id()) != seen_.end()) return NoChange();
+  seen_.insert(node->id());
+
+  Node* callee = node->InputAt(0);
+  HeapObjectMatcher match(callee);
+  if (!match.HasValue() || !match.Value()->IsJSFunction()) return NoChange();
+  Handle<JSFunction> function = Handle<JSFunction>::cast(match.Value());
+
+  // Functions marked with %SetForceInlineFlag are immediately inlined.
+  if (function->shared()->force_inline()) {
+    return inliner_.ReduceJSCall(node, function);
+  }
+
+  // Handling of special inlining modes right away:
+  //  - For restricted inlining: stop all handling at this point.
+  //  - For stressing inlining: immediately handle all functions.
+  switch (mode_) {
+    case kRestrictedInlining:
+      return NoChange();
+    case kStressInlining:
+      return inliner_.ReduceJSCall(node, function);
+    case kGeneralInlining:
+      break;
+  }
+
+  // ---------------------------------------------------------------------------
+  // Everything below this line is part of the inlining heuristic.
+  // ---------------------------------------------------------------------------
+
+  // Built-in functions are handled by the JSBuiltinReducer.
+  if (function->shared()->HasBuiltinFunctionId()) return NoChange();
+
+  // Don't inline builtins.
+  if (function->shared()->IsBuiltin()) return NoChange();
+
+  // Quick check on source code length to avoid parsing large candidate.
+  if (function->shared()->SourceSize() > FLAG_max_inlined_source_size) {
+    return NoChange();
+  }
+
+  // Quick check on the size of the AST to avoid parsing large candidate.
+  if (function->shared()->ast_node_count() > FLAG_max_inlined_nodes) {
+    return NoChange();
+  }
+
+  // Avoid inlining within or across the boundary of asm.js code.
+  if (info_->shared_info()->asm_function()) return NoChange();
+  if (function->shared()->asm_function()) return NoChange();
+
+  // Stop inlinining once the maximum allowed level is reached.
+  int level = 0;
+  for (Node* frame_state = NodeProperties::GetFrameStateInput(node, 0);
+       frame_state->opcode() == IrOpcode::kFrameState;
+       frame_state = NodeProperties::GetFrameStateInput(frame_state, 0)) {
+    if (++level > FLAG_max_inlining_levels) return NoChange();
+  }
+
+  // Gather feedback on how often this call site has been hit before.
+  int calls = -1;  // Same default as CallICNexus::ExtractCallCount.
+  // TODO(turbofan): We also want call counts for constructor calls.
+  if (node->opcode() == IrOpcode::kJSCallFunction) {
+    CallFunctionParameters p = CallFunctionParametersOf(node->op());
+    if (p.feedback().IsValid()) {
+      CallICNexus nexus(p.feedback().vector(), p.feedback().slot());
+      calls = nexus.ExtractCallCount();
+    }
+  }
+
+  // ---------------------------------------------------------------------------
+  // Everything above this line is part of the inlining heuristic.
+  // ---------------------------------------------------------------------------
+
+  // In the general case we remember the candidate for later.
+  candidates_.insert({function, node, calls});
+  return NoChange();
+}
+
+
+void JSInliningHeuristic::Finalize() {
+  if (candidates_.empty()) return;  // Nothing to do without candidates.
+  if (FLAG_trace_turbo_inlining) PrintCandidates();
+
+  // We inline at most one candidate in every iteration of the fixpoint.
+  // This is to ensure that we don't consume the full inlining budget
+  // on things that aren't called very often.
+  // TODO(bmeurer): Use std::priority_queue instead of std::set here.
+  while (!candidates_.empty()) {
+    if (cumulative_count_ > FLAG_max_inlined_nodes_cumulative) return;
+    auto i = candidates_.begin();
+    Candidate candidate = *i;
+    candidates_.erase(i);
+    // Make sure we don't try to inline dead candidate nodes.
+    if (!candidate.node->IsDead()) {
+      Reduction r = inliner_.ReduceJSCall(candidate.node, candidate.function);
+      if (r.Changed()) {
+        cumulative_count_ += candidate.function->shared()->ast_node_count();
+        return;
+      }
+    }
+  }
+}
+
+
+bool JSInliningHeuristic::CandidateCompare::operator()(
+    const Candidate& left, const Candidate& right) const {
+  return left.node != right.node && left.calls >= right.calls;
+}
+
+
+void JSInliningHeuristic::PrintCandidates() {
+  PrintF("Candidates for inlining (size=%zu):\n", candidates_.size());
+  for (const Candidate& candidate : candidates_) {
+    PrintF("  id:%d, calls:%d, size[source]:%d, size[ast]:%d / %s\n",
+           candidate.node->id(), candidate.calls,
+           candidate.function->shared()->SourceSize(),
+           candidate.function->shared()->ast_node_count(),
+           candidate.function->shared()->DebugName()->ToCString().get());
+  }
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/js-inlining-heuristic.h b/src/compiler/js-inlining-heuristic.h
new file mode 100644
index 0000000..7f57747
--- /dev/null
+++ b/src/compiler/js-inlining-heuristic.h
@@ -0,0 +1,62 @@
+// Copyright 2015 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.
+
+#ifndef V8_COMPILER_JS_INLINING_HEURISTIC_H_
+#define V8_COMPILER_JS_INLINING_HEURISTIC_H_
+
+#include "src/compiler/js-inlining.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+class JSInliningHeuristic final : public AdvancedReducer {
+ public:
+  enum Mode { kGeneralInlining, kRestrictedInlining, kStressInlining };
+  JSInliningHeuristic(Editor* editor, Mode mode, Zone* local_zone,
+                      CompilationInfo* info, JSGraph* jsgraph)
+      : AdvancedReducer(editor),
+        mode_(mode),
+        inliner_(editor, local_zone, info, jsgraph),
+        candidates_(local_zone),
+        seen_(local_zone),
+        info_(info) {}
+
+  Reduction Reduce(Node* node) final;
+
+  // Processes the list of candidates gathered while the reducer was running,
+  // and inlines call sites that the heuristic determines to be important.
+  void Finalize() final;
+
+ private:
+  struct Candidate {
+    Handle<JSFunction> function;  // The call target being inlined.
+    Node* node;                   // The call site at which to inline.
+    int calls;                    // Number of times the call site was hit.
+  };
+
+  // Comparator for candidates.
+  struct CandidateCompare {
+    bool operator()(const Candidate& left, const Candidate& right) const;
+  };
+
+  // Candidates are kept in a sorted set of unique candidates.
+  typedef ZoneSet<Candidate, CandidateCompare> Candidates;
+
+  // Dumps candidates to console.
+  void PrintCandidates();
+
+  Mode const mode_;
+  JSInliner inliner_;
+  Candidates candidates_;
+  ZoneSet<NodeId> seen_;
+  CompilationInfo* info_;
+  int cumulative_count_ = 0;
+};
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_JS_INLINING_HEURISTIC_H_
diff --git a/src/compiler/js-inlining.cc b/src/compiler/js-inlining.cc
index d143382..99a1547 100644
--- a/src/compiler/js-inlining.cc
+++ b/src/compiler/js-inlining.cc
@@ -2,270 +2,187 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "src/ast.h"
-#include "src/ast-numbering.h"
-#include "src/compiler/access-builder.h"
+#include "src/compiler/js-inlining.h"
+
+#include "src/ast/ast.h"
+#include "src/ast/ast-numbering.h"
+#include "src/ast/scopes.h"
+#include "src/compiler.h"
+#include "src/compiler/all-nodes.h"
 #include "src/compiler/ast-graph-builder.h"
 #include "src/compiler/common-operator.h"
-#include "src/compiler/graph-inl.h"
-#include "src/compiler/graph-visualizer.h"
-#include "src/compiler/js-inlining.h"
-#include "src/compiler/js-intrinsic-builder.h"
+#include "src/compiler/graph-reducer.h"
 #include "src/compiler/js-operator.h"
-#include "src/compiler/node-aux-data-inl.h"
 #include "src/compiler/node-matchers.h"
-#include "src/compiler/node-properties-inl.h"
-#include "src/compiler/simplified-operator.h"
-#include "src/compiler/typer.h"
-#include "src/full-codegen.h"
-#include "src/parser.h"
-#include "src/rewriter.h"
-#include "src/scopes.h"
-
+#include "src/compiler/node-properties.h"
+#include "src/compiler/operator-properties.h"
+#include "src/isolate-inl.h"
+#include "src/parsing/parser.h"
+#include "src/parsing/rewriter.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
-class InlinerVisitor : public NullNodeVisitor {
- public:
-  explicit InlinerVisitor(JSInliner* inliner) : inliner_(inliner) {}
+#define TRACE(...)                                      \
+  do {                                                  \
+    if (FLAG_trace_turbo_inlining) PrintF(__VA_ARGS__); \
+  } while (false)
 
-  void Post(Node* node) {
-    switch (node->opcode()) {
-      case IrOpcode::kJSCallFunction:
-        inliner_->TryInlineJSCall(node);
-        break;
-      case IrOpcode::kJSCallRuntime:
-        if (FLAG_turbo_inlining_intrinsics) {
-          inliner_->TryInlineRuntimeCall(node);
-        }
-        break;
-      default:
-        break;
-    }
+
+// Provides convenience accessors for the common layout of nodes having either
+// the {JSCallFunction} or the {JSCallConstruct} operator.
+class JSCallAccessor {
+ public:
+  explicit JSCallAccessor(Node* call) : call_(call) {
+    DCHECK(call->opcode() == IrOpcode::kJSCallFunction ||
+           call->opcode() == IrOpcode::kJSCallConstruct);
+  }
+
+  Node* target() {
+    // Both, {JSCallFunction} and {JSCallConstruct}, have same layout here.
+    return call_->InputAt(0);
+  }
+
+  Node* receiver() {
+    DCHECK_EQ(IrOpcode::kJSCallFunction, call_->opcode());
+    return call_->InputAt(1);
+  }
+
+  Node* new_target() {
+    DCHECK_EQ(IrOpcode::kJSCallConstruct, call_->opcode());
+    return call_->InputAt(formal_arguments() + 1);
+  }
+
+  Node* frame_state_before() {
+    return NodeProperties::GetFrameStateInput(call_, 1);
+  }
+
+  Node* frame_state_after() {
+    // Both, {JSCallFunction} and {JSCallConstruct}, have frame state after.
+    return NodeProperties::GetFrameStateInput(call_, 0);
+  }
+
+  int formal_arguments() {
+    // Both, {JSCallFunction} and {JSCallConstruct}, have two extra inputs:
+    //  - JSCallConstruct: Includes target function and new target.
+    //  - JSCallFunction: Includes target function and receiver.
+    return call_->op()->ValueInputCount() - 2;
   }
 
  private:
-  JSInliner* inliner_;
+  Node* call_;
 };
 
 
-void JSInliner::Inline() {
-  InlinerVisitor visitor(this);
-  jsgraph_->graph()->VisitNodeInputsFromEnd(&visitor);
-}
-
-
-// A facade on a JSFunction's graph to facilitate inlining. It assumes the
-// that the function graph has only one return statement, and provides
-// {UnifyReturn} to convert a function graph to that end.
-class Inlinee {
- public:
-  Inlinee(Node* start, Node* end) : start_(start), end_(end) {}
-
-  // Returns the last regular control node, that is
-  // the last control node before the end node.
-  Node* end_block() { return NodeProperties::GetControlInput(unique_return()); }
-
-  // Return the effect output of the graph,
-  // that is the effect input of the return statement of the inlinee.
-  Node* effect_output() {
-    return NodeProperties::GetEffectInput(unique_return());
-  }
-  // Return the value output of the graph,
-  // that is the value input of the return statement of the inlinee.
-  Node* value_output() {
-    return NodeProperties::GetValueInput(unique_return(), 0);
-  }
-  // Return the unique return statement of the graph.
-  Node* unique_return() {
-    Node* unique_return = NodeProperties::GetControlInput(end_);
-    DCHECK_EQ(IrOpcode::kReturn, unique_return->opcode());
-    return unique_return;
-  }
-
-  // Counts JSFunction, Receiver, arguments, context but not effect, control.
-  size_t total_parameters() { return start_->op()->ValueOutputCount(); }
-
-  // Counts only formal parameters.
-  size_t formal_parameters() {
-    DCHECK_GE(total_parameters(), 3);
-    return total_parameters() - 3;
-  }
-
-  // Inline this graph at {call}, use {jsgraph} and its zone to create
-  // any new nodes.
-  void InlineAtCall(JSGraph* jsgraph, Node* call);
-
-  // Ensure that only a single return reaches the end node.
-  static void UnifyReturn(JSGraph* jsgraph);
-
- private:
-  Node* start_;
-  Node* end_;
-};
-
-
-void Inlinee::UnifyReturn(JSGraph* jsgraph) {
-  Graph* graph = jsgraph->graph();
-
-  Node* final_merge = NodeProperties::GetControlInput(graph->end(), 0);
-  if (final_merge->opcode() == IrOpcode::kReturn) {
-    // nothing to do
-    return;
-  }
-  DCHECK_EQ(IrOpcode::kMerge, final_merge->opcode());
-
-  int predecessors = final_merge->op()->ControlInputCount();
-
-  const Operator* op_phi = jsgraph->common()->Phi(kMachAnyTagged, predecessors);
-  const Operator* op_ephi = jsgraph->common()->EffectPhi(predecessors);
-
-  NodeVector values(jsgraph->zone());
-  NodeVector effects(jsgraph->zone());
-  // Iterate over all control flow predecessors,
-  // which must be return statements.
-  for (Edge edge : final_merge->input_edges()) {
-    Node* input = edge.to();
-    switch (input->opcode()) {
-      case IrOpcode::kReturn:
-        values.push_back(NodeProperties::GetValueInput(input, 0));
-        effects.push_back(NodeProperties::GetEffectInput(input));
-        edge.UpdateTo(NodeProperties::GetControlInput(input));
-        input->RemoveAllInputs();
-        break;
-      default:
-        UNREACHABLE();
-        break;
-    }
-  }
-  values.push_back(final_merge);
-  effects.push_back(final_merge);
-  Node* phi =
-      graph->NewNode(op_phi, static_cast<int>(values.size()), &values.front());
-  Node* ephi = graph->NewNode(op_ephi, static_cast<int>(effects.size()),
-                              &effects.front());
-  Node* new_return =
-      graph->NewNode(jsgraph->common()->Return(), phi, ephi, final_merge);
-  graph->end()->ReplaceInput(0, new_return);
-}
-
-
-class CopyVisitor : public NullNodeVisitor {
+class CopyVisitor {
  public:
   CopyVisitor(Graph* source_graph, Graph* target_graph, Zone* temp_zone)
-      : copies_(source_graph->NodeCount(), NULL, temp_zone),
-        sentinels_(source_graph->NodeCount(), NULL, temp_zone),
+      : sentinel_op_(IrOpcode::kDead, Operator::kNoProperties, "Sentinel", 0, 0,
+                     0, 0, 0, 0),
+        sentinel_(target_graph->NewNode(&sentinel_op_)),
+        copies_(source_graph->NodeCount(), sentinel_, temp_zone),
         source_graph_(source_graph),
         target_graph_(target_graph),
-        temp_zone_(temp_zone),
-        sentinel_op_(IrOpcode::kDead, Operator::kNoProperties, "sentinel", 0, 0,
-                     0, 0, 0, 0) {}
+        temp_zone_(temp_zone) {}
 
-  void Post(Node* original) {
-    NodeVector inputs(temp_zone_);
-    for (Node* const node : original->inputs()) {
-      inputs.push_back(GetCopy(node));
-    }
-
-    // Reuse the operator in the copy. This assumes that op lives in a zone
-    // that lives longer than graph()'s zone.
-    Node* copy =
-        target_graph_->NewNode(original->op(), static_cast<int>(inputs.size()),
-                               (inputs.empty() ? NULL : &inputs.front()));
-    copies_[original->id()] = copy;
-  }
-
-  Node* GetCopy(Node* original) {
-    Node* copy = copies_[original->id()];
-    if (copy == NULL) {
-      copy = GetSentinel(original);
-    }
-    DCHECK_NE(NULL, copy);
-    return copy;
-  }
+  Node* GetCopy(Node* orig) { return copies_[orig->id()]; }
 
   void CopyGraph() {
-    source_graph_->VisitNodeInputsFromEnd(this);
-    ReplaceSentinels();
+    NodeVector inputs(temp_zone_);
+    // TODO(bmeurer): AllNodes should be turned into something like
+    // Graph::CollectNodesReachableFromEnd() and the gray set stuff should be
+    // removed since it's only needed by the visualizer.
+    AllNodes all(temp_zone_, source_graph_);
+    // Copy all nodes reachable from end.
+    for (Node* orig : all.live) {
+      Node* copy = GetCopy(orig);
+      if (copy != sentinel_) {
+        // Mapping already exists.
+        continue;
+      }
+      // Copy the node.
+      inputs.clear();
+      for (Node* input : orig->inputs()) inputs.push_back(copies_[input->id()]);
+      copy = target_graph_->NewNode(orig->op(), orig->InputCount(),
+                                    inputs.empty() ? nullptr : &inputs[0]);
+      copies_[orig->id()] = copy;
+    }
+    // For missing inputs.
+    for (Node* orig : all.live) {
+      Node* copy = copies_[orig->id()];
+      for (int i = 0; i < copy->InputCount(); ++i) {
+        Node* input = copy->InputAt(i);
+        if (input == sentinel_) {
+          copy->ReplaceInput(i, GetCopy(orig->InputAt(i)));
+        }
+      }
+    }
   }
 
-  const NodeVector& copies() { return copies_; }
+  const NodeVector& copies() const { return copies_; }
 
  private:
-  void ReplaceSentinels() {
-    for (NodeId id = 0; id < source_graph_->NodeCount(); ++id) {
-      Node* sentinel = sentinels_[id];
-      if (sentinel == NULL) continue;
-      Node* copy = copies_[id];
-      DCHECK_NE(NULL, copy);
-      sentinel->ReplaceUses(copy);
-    }
-  }
-
-  Node* GetSentinel(Node* original) {
-    if (sentinels_[original->id()] == NULL) {
-      sentinels_[original->id()] = target_graph_->NewNode(&sentinel_op_);
-    }
-    return sentinels_[original->id()];
-  }
-
+  Operator const sentinel_op_;
+  Node* const sentinel_;
   NodeVector copies_;
-  NodeVector sentinels_;
-  Graph* source_graph_;
-  Graph* target_graph_;
-  Zone* temp_zone_;
-  Operator sentinel_op_;
+  Graph* const source_graph_;
+  Graph* const target_graph_;
+  Zone* const temp_zone_;
 };
 
 
-void Inlinee::InlineAtCall(JSGraph* jsgraph, Node* call) {
+Reduction JSInliner::InlineCall(Node* call, Node* new_target, Node* context,
+                                Node* frame_state, Node* start, Node* end) {
   // The scheduler is smart enough to place our code; we just ensure {control}
-  // becomes the control input of the start of the inlinee.
+  // becomes the control input of the start of the inlinee, and {effect} becomes
+  // the effect input of the start of the inlinee.
   Node* control = NodeProperties::GetControlInput(call);
+  Node* effect = NodeProperties::GetEffectInput(call);
 
-  // The inlinee uses the context from the JSFunction object. This will
-  // also be the effect dependency for the inlinee as it produces an effect.
-  SimplifiedOperatorBuilder simplified(jsgraph->zone());
-  Node* context = jsgraph->graph()->NewNode(
-      simplified.LoadField(AccessBuilder::ForJSFunctionContext()),
-      NodeProperties::GetValueInput(call, 0),
-      NodeProperties::GetEffectInput(call), control);
+  int const inlinee_new_target_index =
+      static_cast<int>(start->op()->ValueOutputCount()) - 3;
+  int const inlinee_arity_index =
+      static_cast<int>(start->op()->ValueOutputCount()) - 2;
+  int const inlinee_context_index =
+      static_cast<int>(start->op()->ValueOutputCount()) - 1;
 
-  // Context is last argument.
-  int inlinee_context_index = static_cast<int>(total_parameters()) - 1;
-  // {inliner_inputs} counts JSFunction, Receiver, arguments, but not
-  // context, effect, control.
+  // {inliner_inputs} counts JSFunction, receiver, arguments, but not
+  // new target value, argument count, context, effect or control.
   int inliner_inputs = call->op()->ValueInputCount();
   // Iterate over all uses of the start node.
-  for (Edge edge : start_->use_edges()) {
+  for (Edge edge : start->use_edges()) {
     Node* use = edge.from();
     switch (use->opcode()) {
       case IrOpcode::kParameter: {
-        int index = 1 + OpParameter<int>(use->op());
-        if (index < inliner_inputs && index < inlinee_context_index) {
+        int index = 1 + ParameterIndexOf(use->op());
+        DCHECK_LE(index, inlinee_context_index);
+        if (index < inliner_inputs && index < inlinee_new_target_index) {
           // There is an input from the call, and the index is a value
           // projection but not the context, so rewire the input.
-          NodeProperties::ReplaceWithValue(use, call->InputAt(index));
+          Replace(use, call->InputAt(index));
+        } else if (index == inlinee_new_target_index) {
+          // The projection is requesting the new target value.
+          Replace(use, new_target);
+        } else if (index == inlinee_arity_index) {
+          // The projection is requesting the number of arguments.
+          Replace(use, jsgraph_->Int32Constant(inliner_inputs - 2));
         } else if (index == inlinee_context_index) {
-          // This is the context projection, rewire it to the context from the
-          // JSFunction object.
-          NodeProperties::ReplaceWithValue(use, context);
-        } else if (index < inlinee_context_index) {
-          // Call has fewer arguments than required, fill with undefined.
-          NodeProperties::ReplaceWithValue(use, jsgraph->UndefinedConstant());
+          // The projection is requesting the inlinee function context.
+          Replace(use, context);
         } else {
-          // We got too many arguments, discard for now.
-          // TODO(sigurds): Fix to treat arguments array correctly.
+          // Call has fewer arguments than required, fill with undefined.
+          Replace(use, jsgraph_->UndefinedConstant());
         }
         break;
       }
       default:
         if (NodeProperties::IsEffectEdge(edge)) {
-          edge.UpdateTo(context);
+          edge.UpdateTo(effect);
         } else if (NodeProperties::IsControlEdge(edge)) {
           edge.UpdateTo(control);
+        } else if (NodeProperties::IsFrameStateEdge(edge)) {
+          edge.UpdateTo(frame_state);
         } else {
           UNREACHABLE();
         }
@@ -273,65 +190,69 @@
     }
   }
 
-  NodeProperties::ReplaceWithValue(call, value_output(), effect_output());
-  call->RemoveAllInputs();
-  DCHECK_EQ(0, call->UseCount());
+  NodeVector values(local_zone_);
+  NodeVector effects(local_zone_);
+  NodeVector controls(local_zone_);
+  for (Node* const input : end->inputs()) {
+    switch (input->opcode()) {
+      case IrOpcode::kReturn:
+        values.push_back(NodeProperties::GetValueInput(input, 0));
+        effects.push_back(NodeProperties::GetEffectInput(input));
+        controls.push_back(NodeProperties::GetControlInput(input));
+        break;
+      case IrOpcode::kDeoptimize:
+      case IrOpcode::kTerminate:
+      case IrOpcode::kThrow:
+        NodeProperties::MergeControlToEnd(jsgraph_->graph(), jsgraph_->common(),
+                                          input);
+        break;
+      default:
+        UNREACHABLE();
+        break;
+    }
+  }
+  DCHECK_EQ(values.size(), effects.size());
+  DCHECK_EQ(values.size(), controls.size());
+
+  // Depending on whether the inlinee produces a value, we either replace value
+  // uses with said value or kill value uses if no value can be returned.
+  if (values.size() > 0) {
+    int const input_count = static_cast<int>(controls.size());
+    Node* control_output = jsgraph_->graph()->NewNode(
+        jsgraph_->common()->Merge(input_count), input_count, &controls.front());
+    values.push_back(control_output);
+    effects.push_back(control_output);
+    Node* value_output = jsgraph_->graph()->NewNode(
+        jsgraph_->common()->Phi(MachineRepresentation::kTagged, input_count),
+        static_cast<int>(values.size()), &values.front());
+    Node* effect_output = jsgraph_->graph()->NewNode(
+        jsgraph_->common()->EffectPhi(input_count),
+        static_cast<int>(effects.size()), &effects.front());
+    ReplaceWithValue(call, value_output, effect_output, control_output);
+    return Changed(value_output);
+  } else {
+    ReplaceWithValue(call, call, call, jsgraph_->Dead());
+    return Changed(call);
+  }
 }
 
 
-// TODO(turbofan) Provide such accessors for every node, possibly even
-// generate them.
-class JSCallFunctionAccessor {
- public:
-  explicit JSCallFunctionAccessor(Node* call) : call_(call) {
-    DCHECK_EQ(IrOpcode::kJSCallFunction, call->opcode());
-  }
+Node* JSInliner::CreateArtificialFrameState(Node* node, Node* outer_frame_state,
+                                            int parameter_count,
+                                            FrameStateType frame_state_type,
+                                            Handle<SharedFunctionInfo> shared) {
+  const FrameStateFunctionInfo* state_info =
+      jsgraph_->common()->CreateFrameStateFunctionInfo(
+          frame_state_type, parameter_count + 1, 0, shared,
+          CALL_MAINTAINS_NATIVE_CONTEXT);
 
-  Node* jsfunction() { return call_->InputAt(0); }
-
-  Node* receiver() { return call_->InputAt(1); }
-
-  Node* formal_argument(size_t index) {
-    DCHECK(index < formal_arguments());
-    return call_->InputAt(static_cast<int>(2 + index));
-  }
-
-  size_t formal_arguments() {
-    // {value_inputs} includes jsfunction and receiver.
-    size_t value_inputs = call_->op()->ValueInputCount();
-    DCHECK_GE(call_->InputCount(), 2);
-    return value_inputs - 2;
-  }
-
-  Node* frame_state() { return NodeProperties::GetFrameStateInput(call_); }
-
- private:
-  Node* call_;
-};
-
-
-void JSInliner::AddClosureToFrameState(Node* frame_state,
-                                       Handle<JSFunction> jsfunction) {
-  FrameStateCallInfo call_info = OpParameter<FrameStateCallInfo>(frame_state);
   const Operator* op = jsgraph_->common()->FrameState(
-      FrameStateType::JS_FRAME, call_info.bailout_id(),
-      call_info.state_combine(), jsfunction);
-  frame_state->set_op(op);
-}
-
-
-Node* JSInliner::CreateArgumentsAdaptorFrameState(JSCallFunctionAccessor* call,
-                                                  Handle<JSFunction> jsfunction,
-                                                  Zone* temp_zone) {
-  const Operator* op = jsgraph_->common()->FrameState(
-      FrameStateType::ARGUMENTS_ADAPTOR, BailoutId(-1),
-      OutputFrameStateCombine::Ignore(), jsfunction);
+      BailoutId(-1), OutputFrameStateCombine::Ignore(), state_info);
   const Operator* op0 = jsgraph_->common()->StateValues(0);
   Node* node0 = jsgraph_->graph()->NewNode(op0);
-  NodeVector params(temp_zone);
-  params.push_back(call->receiver());
-  for (size_t argument = 0; argument != call->formal_arguments(); ++argument) {
-    params.push_back(call->formal_argument(argument));
+  NodeVector params(local_zone_);
+  for (int parameter = 0; parameter < parameter_count + 1; ++parameter) {
+    params.push_back(node->InputAt(1 + parameter));
   }
   const Operator* op_param =
       jsgraph_->common()->StateValues(static_cast<int>(params.size()));
@@ -339,151 +260,261 @@
       op_param, static_cast<int>(params.size()), &params.front());
   return jsgraph_->graph()->NewNode(op, params_node, node0, node0,
                                     jsgraph_->UndefinedConstant(),
-                                    call->frame_state());
+                                    node->InputAt(0), outer_frame_state);
 }
 
 
-void JSInliner::TryInlineJSCall(Node* call_node) {
-  JSCallFunctionAccessor call(call_node);
+namespace {
 
-  HeapObjectMatcher<JSFunction> match(call.jsfunction());
-  if (!match.HasValue()) {
-    return;
+// TODO(mstarzinger,verwaest): Move this predicate onto SharedFunctionInfo?
+bool NeedsImplicitReceiver(Handle<JSFunction> function, Isolate* isolate) {
+  Code* construct_stub = function->shared()->construct_stub();
+  return construct_stub != *isolate->builtins()->JSBuiltinsConstructStub() &&
+         construct_stub != *isolate->builtins()->ConstructedNonConstructable();
+}
+
+}  // namespace
+
+
+Reduction JSInliner::Reduce(Node* node) {
+  if (!IrOpcode::IsInlineeOpcode(node->opcode())) return NoChange();
+
+  // This reducer can handle both normal function calls as well a constructor
+  // calls whenever the target is a constant function object, as follows:
+  //  - JSCallFunction(target:constant, receiver, args...)
+  //  - JSCallConstruct(target:constant, args..., new.target)
+  HeapObjectMatcher match(node->InputAt(0));
+  if (!match.HasValue() || !match.Value()->IsJSFunction()) return NoChange();
+  Handle<JSFunction> function = Handle<JSFunction>::cast(match.Value());
+
+  return ReduceJSCall(node, function);
+}
+
+
+Reduction JSInliner::ReduceJSCall(Node* node, Handle<JSFunction> function) {
+  DCHECK(IrOpcode::IsInlineeOpcode(node->opcode()));
+  JSCallAccessor call(node);
+
+  // Function must be inlineable.
+  if (!function->shared()->IsInlineable()) {
+    TRACE("Not inlining %s into %s because callee is not inlineable\n",
+          function->shared()->DebugName()->ToCString().get(),
+          info_->shared_info()->DebugName()->ToCString().get());
+    return NoChange();
   }
 
-  Handle<JSFunction> function = match.Value().handle();
+  // Constructor must be constructable.
+  if (node->opcode() == IrOpcode::kJSCallConstruct &&
+      !function->IsConstructor()) {
+    TRACE("Not inlining %s into %s because constructor is not constructable.\n",
+          function->shared()->DebugName()->ToCString().get(),
+          info_->shared_info()->DebugName()->ToCString().get());
+    return NoChange();
+  }
 
-  if (function->shared()->native()) {
-    if (FLAG_trace_turbo_inlining) {
-      SmartArrayPointer<char> name =
-          function->shared()->DebugName()->ToCString();
-      PrintF("Not Inlining %s into %s because inlinee is native\n", name.get(),
-             info_->shared_info()->DebugName()->ToCString().get());
+  // Class constructors are callable, but [[Call]] will raise an exception.
+  // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList ).
+  if (node->opcode() == IrOpcode::kJSCallFunction &&
+      IsClassConstructor(function->shared()->kind())) {
+    TRACE("Not inlining %s into %s because callee is a class constructor.\n",
+          function->shared()->DebugName()->ToCString().get(),
+          info_->shared_info()->DebugName()->ToCString().get());
+    return NoChange();
+  }
+
+  // Function contains break points.
+  if (function->shared()->HasDebugInfo()) {
+    TRACE("Not inlining %s into %s because callee may contain break points\n",
+          function->shared()->DebugName()->ToCString().get(),
+          info_->shared_info()->DebugName()->ToCString().get());
+    return NoChange();
+  }
+
+  // Disallow cross native-context inlining for now. This means that all parts
+  // of the resulting code will operate on the same global object.
+  // This also prevents cross context leaks for asm.js code, where we could
+  // inline functions from a different context and hold on to that context (and
+  // closure) from the code object.
+  // TODO(turbofan): We might want to revisit this restriction later when we
+  // have a need for this, and we know how to model different native contexts
+  // in the same graph in a compositional way.
+  if (function->context()->native_context() !=
+      info_->context()->native_context()) {
+    TRACE("Not inlining %s into %s because of different native contexts\n",
+          function->shared()->DebugName()->ToCString().get(),
+          info_->shared_info()->DebugName()->ToCString().get());
+    return NoChange();
+  }
+
+  // TODO(turbofan): TranslatedState::GetAdaptedArguments() currently relies on
+  // not inlining recursive functions. We might want to relax that at some
+  // point.
+  for (Node* frame_state = call.frame_state_after();
+       frame_state->opcode() == IrOpcode::kFrameState;
+       frame_state = frame_state->InputAt(kFrameStateOuterStateInput)) {
+    FrameStateInfo const& info = OpParameter<FrameStateInfo>(frame_state);
+    Handle<SharedFunctionInfo> shared_info;
+    if (info.shared_info().ToHandle(&shared_info) &&
+        *shared_info == function->shared()) {
+      TRACE("Not inlining %s into %s because call is recursive\n",
+            function->shared()->DebugName()->ToCString().get(),
+            info_->shared_info()->DebugName()->ToCString().get());
+      return NoChange();
     }
-    return;
   }
 
-  CompilationInfoWithZone info(function);
-  // TODO(wingo): ParseAndAnalyze can fail due to stack overflow.
-  CHECK(Compiler::ParseAndAnalyze(&info));
-  CHECK(Compiler::EnsureDeoptimizationSupport(&info));
+  // TODO(turbofan): Inlining into a try-block is not yet supported.
+  if (NodeProperties::IsExceptionalCall(node)) {
+    TRACE("Not inlining %s into %s because of surrounding try-block\n",
+          function->shared()->DebugName()->ToCString().get(),
+          info_->shared_info()->DebugName()->ToCString().get());
+    return NoChange();
+  }
 
-  if (info.scope()->arguments() != NULL && info.strict_mode() != STRICT) {
-    // For now do not inline functions that use their arguments array.
-    SmartArrayPointer<char> name = function->shared()->DebugName()->ToCString();
-    if (FLAG_trace_turbo_inlining) {
-      PrintF(
-          "Not Inlining %s into %s because inlinee uses arguments "
-          "array\n",
-          name.get(), info_->shared_info()->DebugName()->ToCString().get());
+  Zone zone;
+  ParseInfo parse_info(&zone, function);
+  CompilationInfo info(&parse_info);
+  if (info_->is_deoptimization_enabled()) {
+    info.MarkAsDeoptimizationEnabled();
+  }
+
+  if (!Compiler::ParseAndAnalyze(info.parse_info())) {
+    TRACE("Not inlining %s into %s because parsing failed\n",
+          function->shared()->DebugName()->ToCString().get(),
+          info_->shared_info()->DebugName()->ToCString().get());
+    if (info_->isolate()->has_pending_exception()) {
+      info_->isolate()->clear_pending_exception();
     }
-    return;
+    return NoChange();
   }
 
-  if (FLAG_trace_turbo_inlining) {
-    SmartArrayPointer<char> name = function->shared()->DebugName()->ToCString();
-    PrintF("Inlining %s into %s\n", name.get(),
-           info_->shared_info()->DebugName()->ToCString().get());
+  // In strong mode, in case of too few arguments we need to throw a TypeError
+  // so we must not inline this call.
+  int parameter_count = info.literal()->parameter_count();
+  if (is_strong(info.language_mode()) &&
+      call.formal_arguments() < parameter_count) {
+    TRACE("Not inlining %s into %s because too few arguments for strong mode\n",
+          function->shared()->DebugName()->ToCString().get(),
+          info_->shared_info()->DebugName()->ToCString().get());
+    return NoChange();
   }
 
-  Graph graph(info.zone());
-  JSGraph jsgraph(&graph, jsgraph_->common(), jsgraph_->javascript(),
+  if (!Compiler::EnsureDeoptimizationSupport(&info)) {
+    TRACE("Not inlining %s into %s because deoptimization support failed\n",
+          function->shared()->DebugName()->ToCString().get(),
+          info_->shared_info()->DebugName()->ToCString().get());
+    return NoChange();
+  }
+  // Remember that we inlined this function. This needs to be called right
+  // after we ensure deoptimization support so that the code flusher
+  // does not remove the code with the deoptimization support.
+  info_->AddInlinedFunction(info.shared_info());
+
+  // ----------------------------------------------------------------
+  // After this point, we've made a decision to inline this function.
+  // We shall not bailout from inlining if we got here.
+
+  TRACE("Inlining %s into %s\n",
+        function->shared()->DebugName()->ToCString().get(),
+        info_->shared_info()->DebugName()->ToCString().get());
+
+  // TODO(mstarzinger): We could use the temporary zone for the graph because
+  // nodes are copied. This however leads to Zone-Types being allocated in the
+  // wrong zone and makes the engine explode at high speeds. Explosion bad!
+  Graph graph(jsgraph_->zone());
+  JSGraph jsgraph(info.isolate(), &graph, jsgraph_->common(),
+                  jsgraph_->javascript(), jsgraph_->simplified(),
                   jsgraph_->machine());
-
   AstGraphBuilder graph_builder(local_zone_, &info, &jsgraph);
-  graph_builder.CreateGraph();
-  Inlinee::UnifyReturn(&jsgraph);
+  graph_builder.CreateGraph(false);
 
-  CopyVisitor visitor(&graph, jsgraph_->graph(), info.zone());
+  CopyVisitor visitor(&graph, jsgraph_->graph(), &zone);
   visitor.CopyGraph();
 
-  Inlinee inlinee(visitor.GetCopy(graph.start()), visitor.GetCopy(graph.end()));
+  Node* start = visitor.GetCopy(graph.start());
+  Node* end = visitor.GetCopy(graph.end());
+  Node* frame_state = call.frame_state_after();
+  Node* new_target = jsgraph_->UndefinedConstant();
 
-  if (FLAG_turbo_deoptimization) {
-    Node* outer_frame_state = call.frame_state();
-    // Insert argument adaptor frame if required.
-    if (call.formal_arguments() != inlinee.formal_parameters()) {
-      outer_frame_state =
-          CreateArgumentsAdaptorFrameState(&call, function, info.zone());
-    }
-
-    for (NodeVectorConstIter it = visitor.copies().begin();
-         it != visitor.copies().end(); ++it) {
-      Node* node = *it;
-      if (node != NULL && node->opcode() == IrOpcode::kFrameState) {
-        AddClosureToFrameState(node, function);
-        NodeProperties::ReplaceFrameStateInput(node, outer_frame_state);
-      }
-    }
+  // Insert nodes around the call that model the behavior required for a
+  // constructor dispatch (allocate implicit receiver and check return value).
+  // This models the behavior usually accomplished by our {JSConstructStub}.
+  // Note that the context has to be the callers context (input to call node).
+  Node* receiver = jsgraph_->UndefinedConstant();  // Implicit receiver.
+  if (node->opcode() == IrOpcode::kJSCallConstruct &&
+      NeedsImplicitReceiver(function, info_->isolate())) {
+    Node* effect = NodeProperties::GetEffectInput(node);
+    Node* context = NodeProperties::GetContextInput(node);
+    Node* create = jsgraph_->graph()->NewNode(
+        jsgraph_->javascript()->Create(), call.target(), call.new_target(),
+        context, call.frame_state_before(), effect);
+    NodeProperties::ReplaceEffectInput(node, create);
+    // Insert a check of the return value to determine whether the return value
+    // or the implicit receiver should be selected as a result of the call.
+    Node* check = jsgraph_->graph()->NewNode(
+        jsgraph_->javascript()->CallRuntime(Runtime::kInlineIsJSReceiver, 1),
+        node, context, node, start);
+    Node* select = jsgraph_->graph()->NewNode(
+        jsgraph_->common()->Select(MachineRepresentation::kTagged), check, node,
+        create);
+    NodeProperties::ReplaceUses(node, select, check, node, node);
+    NodeProperties::ReplaceValueInput(select, node, 1);
+    NodeProperties::ReplaceValueInput(check, node, 0);
+    NodeProperties::ReplaceEffectInput(check, node);
+    receiver = create;  // The implicit receiver.
   }
 
-  inlinee.InlineAtCall(jsgraph_, call_node);
+  // Swizzle the inputs of the {JSCallConstruct} node to look like inputs to a
+  // normal {JSCallFunction} node so that the rest of the inlining machinery
+  // behaves as if we were dealing with a regular function invocation.
+  if (node->opcode() == IrOpcode::kJSCallConstruct) {
+    new_target = call.new_target();  // Retrieve new target value input.
+    node->RemoveInput(call.formal_arguments() + 1);  // Drop new target.
+    node->InsertInput(jsgraph_->graph()->zone(), 1, receiver);
+    // Insert a construct stub frame into the chain of frame states. This will
+    // reconstruct the proper frame when deoptimizing within the constructor.
+    frame_state = CreateArtificialFrameState(
+        node, frame_state, call.formal_arguments(),
+        FrameStateType::kConstructStub, info.shared_info());
+  }
+
+  // The inlinee specializes to the context from the JSFunction object.
+  // TODO(turbofan): We might want to load the context from the JSFunction at
+  // runtime in case we only know the SharedFunctionInfo once we have dynamic
+  // type feedback in the compiler.
+  Node* context = jsgraph_->Constant(handle(function->context()));
+
+  // Insert a JSConvertReceiver node for sloppy callees. Note that the context
+  // passed into this node has to be the callees context (loaded above). Note
+  // that the frame state passed to the JSConvertReceiver must be the frame
+  // state _before_ the call; it is not necessary to fiddle with the receiver
+  // in that frame state tho, as the conversion of the receiver can be repeated
+  // any number of times, it's not observable.
+  if (node->opcode() == IrOpcode::kJSCallFunction &&
+      is_sloppy(info.language_mode()) && !function->shared()->native()) {
+    const CallFunctionParameters& p = CallFunctionParametersOf(node->op());
+    Node* effect = NodeProperties::GetEffectInput(node);
+    Node* convert = jsgraph_->graph()->NewNode(
+        jsgraph_->javascript()->ConvertReceiver(p.convert_mode()),
+        call.receiver(), context, call.frame_state_before(), effect, start);
+    NodeProperties::ReplaceValueInput(node, convert, 1);
+    NodeProperties::ReplaceEffectInput(node, convert);
+  }
+
+  // Insert argument adaptor frame if required. The callees formal parameter
+  // count (i.e. value outputs of start node minus target, receiver, new target,
+  // arguments count and context) have to match the number of arguments passed
+  // to the call.
+  DCHECK_EQ(parameter_count, start->op()->ValueOutputCount() - 5);
+  if (call.formal_arguments() != parameter_count) {
+    frame_state = CreateArtificialFrameState(
+        node, frame_state, call.formal_arguments(),
+        FrameStateType::kArgumentsAdaptor, info.shared_info());
+  }
+
+  return InlineCall(node, new_target, context, frame_state, start, end);
 }
 
-
-class JSCallRuntimeAccessor {
- public:
-  explicit JSCallRuntimeAccessor(Node* call) : call_(call) {
-    DCHECK_EQ(IrOpcode::kJSCallRuntime, call->opcode());
-  }
-
-  Node* formal_argument(size_t index) {
-    DCHECK(index < formal_arguments());
-    return call_->InputAt(static_cast<int>(index));
-  }
-
-  size_t formal_arguments() {
-    size_t value_inputs = call_->op()->ValueInputCount();
-    return value_inputs;
-  }
-
-  Node* frame_state() const {
-    return NodeProperties::GetFrameStateInput(call_);
-  }
-  Node* context() const { return NodeProperties::GetContextInput(call_); }
-  Node* control() const { return NodeProperties::GetControlInput(call_); }
-  Node* effect() const { return NodeProperties::GetEffectInput(call_); }
-
-  const Runtime::Function* function() const {
-    return Runtime::FunctionForId(CallRuntimeParametersOf(call_->op()).id());
-  }
-
-  NodeVector inputs(Zone* zone) const {
-    NodeVector inputs(zone);
-    for (Node* const node : call_->inputs()) {
-      inputs.push_back(node);
-    }
-    return inputs;
-  }
-
- private:
-  Node* call_;
-};
-
-
-void JSInliner::TryInlineRuntimeCall(Node* call_node) {
-  JSCallRuntimeAccessor call(call_node);
-  const Runtime::Function* f = call.function();
-
-  if (f->intrinsic_type != Runtime::IntrinsicType::INLINE) {
-    return;
-  }
-
-  JSIntrinsicBuilder intrinsic_builder(jsgraph_);
-
-  ResultAndEffect r = intrinsic_builder.BuildGraphFor(
-      f->function_id, call.inputs(jsgraph_->zone()));
-
-  if (r.first != NULL) {
-    if (FLAG_trace_turbo_inlining) {
-      PrintF("Inlining %s into %s\n", f->name,
-             info_->shared_info()->DebugName()->ToCString().get());
-    }
-    NodeProperties::ReplaceWithValue(call_node, r.first, r.second);
-    call_node->RemoveAllInputs();
-    DCHECK_EQ(0, call_node->UseCount());
-  }
-}
-}
-}
-}  // namespace v8::internal::compiler
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/js-inlining.h b/src/compiler/js-inlining.h
index eef29d6..99eff96 100644
--- a/src/compiler/js-inlining.h
+++ b/src/compiler/js-inlining.h
@@ -6,37 +6,51 @@
 #define V8_COMPILER_JS_INLINING_H_
 
 #include "src/compiler/js-graph.h"
-#include "src/v8.h"
+#include "src/compiler/graph-reducer.h"
 
 namespace v8 {
 namespace internal {
+
+// Forward declarations.
+class CompilationInfo;
+
 namespace compiler {
 
-class JSCallFunctionAccessor;
-
-class JSInliner {
+// The JSInliner provides the core graph inlining machinery. Note that this
+// class only deals with the mechanics of how to inline one graph into another,
+// heuristics that decide what and how much to inline are beyond its scope.
+class JSInliner final : public AdvancedReducer {
  public:
-  JSInliner(Zone* local_zone, CompilationInfo* info, JSGraph* jsgraph)
-      : local_zone_(local_zone), info_(info), jsgraph_(jsgraph) {}
+  JSInliner(Editor* editor, Zone* local_zone, CompilationInfo* info,
+            JSGraph* jsgraph)
+      : AdvancedReducer(editor),
+        local_zone_(local_zone),
+        info_(info),
+        jsgraph_(jsgraph) {}
 
-  void Inline();
-  void TryInlineJSCall(Node* node);
-  void TryInlineRuntimeCall(Node* node);
+  // Reducer interface, eagerly inlines everything.
+  Reduction Reduce(Node* node) final;
+
+  // Can be used by inlining heuristics or by testing code directly, without
+  // using the above generic reducer interface of the inlining machinery.
+  Reduction ReduceJSCall(Node* node, Handle<JSFunction> function);
 
  private:
-  friend class InlinerVisitor;
   Zone* local_zone_;
   CompilationInfo* info_;
   JSGraph* jsgraph_;
 
-  Node* CreateArgumentsAdaptorFrameState(JSCallFunctionAccessor* call,
-                                         Handle<JSFunction> jsfunction,
-                                         Zone* temp_zone);
-  void AddClosureToFrameState(Node* frame_state, Handle<JSFunction> jsfunction);
-  static void UnifyReturn(Graph* graph);
+  Node* CreateArtificialFrameState(Node* node, Node* outer_frame_state,
+                                   int parameter_count,
+                                   FrameStateType frame_state_type,
+                                   Handle<SharedFunctionInfo> shared);
+
+  Reduction InlineCall(Node* call, Node* new_target, Node* context,
+                       Node* frame_state, Node* start, Node* end);
 };
-}
-}
-}  // namespace v8::internal::compiler
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
 
 #endif  // V8_COMPILER_JS_INLINING_H_
diff --git a/src/compiler/js-intrinsic-builder.cc b/src/compiler/js-intrinsic-builder.cc
deleted file mode 100644
index 80b6968..0000000
--- a/src/compiler/js-intrinsic-builder.cc
+++ /dev/null
@@ -1,140 +0,0 @@
-// 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/access-builder.h"
-#include "src/compiler/common-operator.h"
-#include "src/compiler/diamond.h"
-#include "src/compiler/js-intrinsic-builder.h"
-#include "src/compiler/js-operator.h"
-#include "src/compiler/simplified-operator.h"
-
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-ResultAndEffect JSIntrinsicBuilder::BuildGraphFor(Runtime::FunctionId id,
-                                                  const NodeVector& arguments) {
-  switch (id) {
-    case Runtime::kInlineIsSmi:
-      return BuildGraphFor_IsSmi(arguments);
-    case Runtime::kInlineIsNonNegativeSmi:
-      return BuildGraphFor_IsNonNegativeSmi(arguments);
-    case Runtime::kInlineIsArray:
-      return BuildMapCheck(arguments[0], arguments[2], JS_ARRAY_TYPE);
-    case Runtime::kInlineIsRegExp:
-      return BuildMapCheck(arguments[0], arguments[2], JS_REGEXP_TYPE);
-    case Runtime::kInlineIsFunction:
-      return BuildMapCheck(arguments[0], arguments[2], JS_FUNCTION_TYPE);
-    case Runtime::kInlineValueOf:
-      return BuildGraphFor_ValueOf(arguments);
-    default:
-      break;
-  }
-  return ResultAndEffect();
-}
-
-ResultAndEffect JSIntrinsicBuilder::BuildGraphFor_IsSmi(
-    const NodeVector& arguments) {
-  Node* object = arguments[0];
-  SimplifiedOperatorBuilder simplified(jsgraph_->zone());
-  Node* condition = graph()->NewNode(simplified.ObjectIsSmi(), object);
-
-  return ResultAndEffect(condition, arguments[2]);
-}
-
-
-ResultAndEffect JSIntrinsicBuilder::BuildGraphFor_IsNonNegativeSmi(
-    const NodeVector& arguments) {
-  Node* object = arguments[0];
-  SimplifiedOperatorBuilder simplified(jsgraph_->zone());
-  Node* condition =
-      graph()->NewNode(simplified.ObjectIsNonNegativeSmi(), object);
-
-  return ResultAndEffect(condition, arguments[2]);
-}
-
-
-/*
- * if (_isSmi(object)) {
- *   return false
- * } else {
- *   return %_GetMapInstanceType(object) == map_type
- * }
- */
-ResultAndEffect JSIntrinsicBuilder::BuildMapCheck(Node* object, Node* effect,
-                                                  InstanceType map_type) {
-  SimplifiedOperatorBuilder simplified(jsgraph_->zone());
-
-  Node* is_smi = graph()->NewNode(simplified.ObjectIsSmi(), object);
-  Diamond d(graph(), common(), is_smi);
-
-  Node* map = graph()->NewNode(simplified.LoadField(AccessBuilder::ForMap()),
-                               object, effect, d.if_false);
-
-  Node* instance_type = graph()->NewNode(
-      simplified.LoadField(AccessBuilder::ForMapInstanceType()), map, map,
-      d.if_false);
-
-  Node* has_map_type =
-      graph()->NewNode(jsgraph_->machine()->Word32Equal(), instance_type,
-                       jsgraph_->Int32Constant(map_type));
-
-  Node* phi = d.Phi(static_cast<MachineType>(kTypeBool | kRepTagged),
-                    jsgraph_->FalseConstant(), has_map_type);
-
-  Node* ephi = d.EffectPhi(effect, instance_type);
-
-  return ResultAndEffect(phi, ephi);
-}
-
-
-/*
- * if (%_isSmi(object)) {
- *   return object;
- * } else if (%_GetMapInstanceType(object) == JS_VALUE_TYPE) {
- *   return %_LoadValueField(object);
- * } else {
- *   return object;
- * }
- */
-ResultAndEffect JSIntrinsicBuilder::BuildGraphFor_ValueOf(
-    const NodeVector& arguments) {
-  Node* object = arguments[0];
-  Node* effect = arguments[2];
-  SimplifiedOperatorBuilder simplified(jsgraph_->zone());
-
-  Node* is_smi = graph()->NewNode(simplified.ObjectIsSmi(), object);
-
-  Diamond if_is_smi(graph(), common(), is_smi);
-
-  Node* map = graph()->NewNode(simplified.LoadField(AccessBuilder::ForMap()),
-                               object, effect, if_is_smi.if_false);
-
-  Node* instance_type = graph()->NewNode(
-      simplified.LoadField(AccessBuilder::ForMapInstanceType()), map, map,
-      if_is_smi.if_false);
-
-  Node* is_value =
-      graph()->NewNode(jsgraph_->machine()->Word32Equal(), instance_type,
-                       jsgraph_->Constant(JS_VALUE_TYPE));
-
-  Diamond if_is_value(graph(), common(), is_value);
-  if_is_value.Nest(if_is_smi, false);
-
-  Node* value =
-      graph()->NewNode(simplified.LoadField(AccessBuilder::ForValue()), object,
-                       instance_type, if_is_value.if_true);
-
-  Node* phi_is_value = if_is_value.Phi(kTypeAny, value, object);
-
-  Node* phi = if_is_smi.Phi(kTypeAny, object, phi_is_value);
-
-  Node* ephi = if_is_smi.EffectPhi(effect, instance_type);
-
-  return ResultAndEffect(phi, ephi);
-}
-}
-}
-}  // namespace v8::internal::compiler
diff --git a/src/compiler/js-intrinsic-builder.h b/src/compiler/js-intrinsic-builder.h
deleted file mode 100644
index 9336be6..0000000
--- a/src/compiler/js-intrinsic-builder.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// 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.
-
-#ifndef V8_COMPILER_JS_INTRINSIC_BUILDER_H_
-#define V8_COMPILER_JS_INTRINSIC_BUILDER_H_
-
-#include "src/compiler/js-graph.h"
-#include "src/v8.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-typedef std::pair<Node*, Node*> ResultAndEffect;
-
-class JSIntrinsicBuilder {
- public:
-  explicit JSIntrinsicBuilder(JSGraph* jsgraph) : jsgraph_(jsgraph) {}
-
-  ResultAndEffect BuildGraphFor(Runtime::FunctionId id,
-                                const NodeVector& arguments);
-
- private:
-  ResultAndEffect BuildMapCheck(Node* object, Node* effect,
-                                InstanceType map_type);
-  ResultAndEffect BuildGraphFor_IsSmi(const NodeVector& arguments);
-  ResultAndEffect BuildGraphFor_IsNonNegativeSmi(const NodeVector& arguments);
-  ResultAndEffect BuildGraphFor_ValueOf(const NodeVector& arguments);
-
-
-  Graph* graph() const { return jsgraph_->graph(); }
-  CommonOperatorBuilder* common() const { return jsgraph_->common(); }
-  JSGraph* jsgraph_;
-};
-}
-}
-}  // namespace v8::internal::compiler
-
-#endif  // V8_COMPILER_JS_INTRINSIC_BUILDER_H_
diff --git a/src/compiler/js-intrinsic-lowering.cc b/src/compiler/js-intrinsic-lowering.cc
new file mode 100644
index 0000000..ca5cb93
--- /dev/null
+++ b/src/compiler/js-intrinsic-lowering.cc
@@ -0,0 +1,702 @@
+// Copyright 2015 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/js-intrinsic-lowering.h"
+
+#include <stack>
+
+#include "src/code-factory.h"
+#include "src/compiler/access-builder.h"
+#include "src/compiler/js-graph.h"
+#include "src/compiler/linkage.h"
+#include "src/compiler/node-matchers.h"
+#include "src/compiler/node-properties.h"
+#include "src/compiler/operator-properties.h"
+#include "src/counters.h"
+#include "src/objects-inl.h"
+#include "src/type-cache.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+JSIntrinsicLowering::JSIntrinsicLowering(Editor* editor, JSGraph* jsgraph,
+                                         DeoptimizationMode mode)
+    : AdvancedReducer(editor),
+      jsgraph_(jsgraph),
+      mode_(mode),
+      type_cache_(TypeCache::Get()) {}
+
+
+Reduction JSIntrinsicLowering::Reduce(Node* node) {
+  if (node->opcode() != IrOpcode::kJSCallRuntime) return NoChange();
+  const Runtime::Function* const f =
+      Runtime::FunctionForId(CallRuntimeParametersOf(node->op()).id());
+  if (f->intrinsic_type != Runtime::IntrinsicType::INLINE) return NoChange();
+  switch (f->function_id) {
+    case Runtime::kInlineConstructDouble:
+      return ReduceConstructDouble(node);
+    case Runtime::kInlineCreateIterResultObject:
+      return ReduceCreateIterResultObject(node);
+    case Runtime::kInlineDeoptimizeNow:
+      return ReduceDeoptimizeNow(node);
+    case Runtime::kInlineDoubleHi:
+      return ReduceDoubleHi(node);
+    case Runtime::kInlineDoubleLo:
+      return ReduceDoubleLo(node);
+    case Runtime::kInlineIncrementStatsCounter:
+      return ReduceIncrementStatsCounter(node);
+    case Runtime::kInlineIsArray:
+      return ReduceIsInstanceType(node, JS_ARRAY_TYPE);
+    case Runtime::kInlineIsDate:
+      return ReduceIsInstanceType(node, JS_DATE_TYPE);
+    case Runtime::kInlineIsTypedArray:
+      return ReduceIsInstanceType(node, JS_TYPED_ARRAY_TYPE);
+    case Runtime::kInlineIsFunction:
+      return ReduceIsFunction(node);
+    case Runtime::kInlineIsRegExp:
+      return ReduceIsInstanceType(node, JS_REGEXP_TYPE);
+    case Runtime::kInlineIsJSReceiver:
+      return ReduceIsJSReceiver(node);
+    case Runtime::kInlineIsSmi:
+      return ReduceIsSmi(node);
+    case Runtime::kInlineJSValueGetValue:
+      return ReduceJSValueGetValue(node);
+    case Runtime::kInlineMathClz32:
+      return ReduceMathClz32(node);
+    case Runtime::kInlineMathFloor:
+      return ReduceMathFloor(node);
+    case Runtime::kInlineMathSqrt:
+      return ReduceMathSqrt(node);
+    case Runtime::kInlineValueOf:
+      return ReduceValueOf(node);
+    case Runtime::kInlineIsMinusZero:
+      return ReduceIsMinusZero(node);
+    case Runtime::kInlineFixedArrayGet:
+      return ReduceFixedArrayGet(node);
+    case Runtime::kInlineFixedArraySet:
+      return ReduceFixedArraySet(node);
+    case Runtime::kInlineRegExpConstructResult:
+      return ReduceRegExpConstructResult(node);
+    case Runtime::kInlineRegExpExec:
+      return ReduceRegExpExec(node);
+    case Runtime::kInlineRegExpFlags:
+      return ReduceRegExpFlags(node);
+    case Runtime::kInlineRegExpSource:
+      return ReduceRegExpSource(node);
+    case Runtime::kInlineSubString:
+      return ReduceSubString(node);
+    case Runtime::kInlineToInteger:
+      return ReduceToInteger(node);
+    case Runtime::kInlineToLength:
+      return ReduceToLength(node);
+    case Runtime::kInlineToName:
+      return ReduceToName(node);
+    case Runtime::kInlineToNumber:
+      return ReduceToNumber(node);
+    case Runtime::kInlineToObject:
+      return ReduceToObject(node);
+    case Runtime::kInlineToPrimitive:
+      return ReduceToPrimitive(node);
+    case Runtime::kInlineToString:
+      return ReduceToString(node);
+    case Runtime::kInlineCall:
+      return ReduceCall(node);
+    case Runtime::kInlineTailCall:
+      return ReduceTailCall(node);
+    case Runtime::kInlineGetSuperConstructor:
+      return ReduceGetSuperConstructor(node);
+    default:
+      break;
+  }
+  return NoChange();
+}
+
+
+Reduction JSIntrinsicLowering::ReduceCreateIterResultObject(Node* node) {
+  Node* const value = NodeProperties::GetValueInput(node, 0);
+  Node* const done = NodeProperties::GetValueInput(node, 1);
+  Node* const context = NodeProperties::GetContextInput(node);
+  Node* const effect = NodeProperties::GetEffectInput(node);
+  return Change(node, javascript()->CreateIterResultObject(), value, done,
+                context, effect);
+}
+
+
+Reduction JSIntrinsicLowering::ReduceConstructDouble(Node* node) {
+  Node* high = NodeProperties::GetValueInput(node, 0);
+  Node* low = NodeProperties::GetValueInput(node, 1);
+  Node* value =
+      graph()->NewNode(machine()->Float64InsertHighWord32(),
+                       graph()->NewNode(machine()->Float64InsertLowWord32(),
+                                        jsgraph()->Constant(0), low),
+                       high);
+  ReplaceWithValue(node, value);
+  return Replace(value);
+}
+
+
+Reduction JSIntrinsicLowering::ReduceDeoptimizeNow(Node* node) {
+  if (mode() != kDeoptimizationEnabled) return NoChange();
+  Node* const frame_state = NodeProperties::GetFrameStateInput(node, 0);
+  Node* const effect = NodeProperties::GetEffectInput(node);
+  Node* const control = NodeProperties::GetControlInput(node);
+
+  // TODO(bmeurer): Move MergeControlToEnd() to the AdvancedReducer.
+  Node* deoptimize =
+      graph()->NewNode(common()->Deoptimize(DeoptimizeKind::kEager),
+                       frame_state, effect, control);
+  NodeProperties::MergeControlToEnd(graph(), common(), deoptimize);
+
+  node->TrimInputCount(0);
+  NodeProperties::ChangeOp(node, common()->Dead());
+  return Changed(node);
+}
+
+
+Reduction JSIntrinsicLowering::ReduceDoubleHi(Node* node) {
+  return Change(node, machine()->Float64ExtractHighWord32());
+}
+
+
+Reduction JSIntrinsicLowering::ReduceDoubleLo(Node* node) {
+  return Change(node, machine()->Float64ExtractLowWord32());
+}
+
+
+Reduction JSIntrinsicLowering::ReduceIncrementStatsCounter(Node* node) {
+  if (!FLAG_native_code_counters) return ChangeToUndefined(node);
+  HeapObjectMatcher m(NodeProperties::GetValueInput(node, 0));
+  if (!m.HasValue() || !m.Value()->IsString()) {
+    return ChangeToUndefined(node);
+  }
+  base::SmartArrayPointer<char> name =
+      Handle<String>::cast(m.Value())->ToCString();
+  StatsCounter counter(jsgraph()->isolate(), name.get());
+  if (!counter.Enabled()) return ChangeToUndefined(node);
+
+  Node* effect = NodeProperties::GetEffectInput(node);
+  Node* control = NodeProperties::GetControlInput(node);
+  FieldAccess access = AccessBuilder::ForStatsCounter();
+  Node* cnt = jsgraph()->ExternalConstant(ExternalReference(&counter));
+  Node* load =
+      graph()->NewNode(simplified()->LoadField(access), cnt, effect, control);
+  Node* inc =
+      graph()->NewNode(machine()->Int32Add(), load, jsgraph()->OneConstant());
+  Node* store = graph()->NewNode(simplified()->StoreField(access), cnt, inc,
+                                 load, control);
+  return ChangeToUndefined(node, store);
+}
+
+
+Reduction JSIntrinsicLowering::ReduceIsInstanceType(
+    Node* node, InstanceType instance_type) {
+  // if (%_IsSmi(value)) {
+  //   return false;
+  // } else {
+  //   return %_GetInstanceType(%_GetMap(value)) == instance_type;
+  // }
+  Node* value = NodeProperties::GetValueInput(node, 0);
+  Node* effect = NodeProperties::GetEffectInput(node);
+  Node* control = NodeProperties::GetControlInput(node);
+
+  Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), value);
+  Node* branch = graph()->NewNode(common()->Branch(), check, control);
+
+  Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
+  Node* etrue = effect;
+  Node* vtrue = jsgraph()->FalseConstant();
+
+  Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+  Node* efalse = graph()->NewNode(
+      simplified()->LoadField(AccessBuilder::ForMapInstanceType()),
+      graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), value,
+                       effect, if_false),
+      effect, if_false);
+  Node* vfalse = graph()->NewNode(machine()->Word32Equal(), efalse,
+                                  jsgraph()->Int32Constant(instance_type));
+
+  Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
+
+  // Replace all effect uses of {node} with the {ephi}.
+  Node* ephi = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, merge);
+  ReplaceWithValue(node, node, ephi);
+
+  // Turn the {node} into a Phi.
+  return Change(node, common()->Phi(MachineRepresentation::kTagged, 2), vtrue,
+                vfalse, merge);
+}
+
+
+Reduction JSIntrinsicLowering::ReduceIsFunction(Node* node) {
+  Node* value = NodeProperties::GetValueInput(node, 0);
+  Type* value_type = NodeProperties::GetType(value);
+  Node* effect = NodeProperties::GetEffectInput(node);
+  Node* control = NodeProperties::GetControlInput(node);
+  if (value_type->Is(Type::Function())) {
+    value = jsgraph()->TrueConstant();
+  } else {
+    // if (%_IsSmi(value)) {
+    //   return false;
+    // } else {
+    //   return FIRST_FUNCTION_TYPE <= %_GetInstanceType(%_GetMap(value))
+    // }
+    STATIC_ASSERT(LAST_TYPE == LAST_FUNCTION_TYPE);
+
+    Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), value);
+    Node* branch = graph()->NewNode(common()->Branch(), check, control);
+
+    Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
+    Node* etrue = effect;
+    Node* vtrue = jsgraph()->FalseConstant();
+
+    Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+    Node* efalse = graph()->NewNode(
+        simplified()->LoadField(AccessBuilder::ForMapInstanceType()),
+        graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
+                         value, effect, if_false),
+        effect, if_false);
+    Node* vfalse =
+        graph()->NewNode(machine()->Uint32LessThanOrEqual(),
+                         jsgraph()->Int32Constant(FIRST_FUNCTION_TYPE), efalse);
+
+    control = graph()->NewNode(common()->Merge(2), if_true, if_false);
+    effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
+    value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
+                             vtrue, vfalse, control);
+  }
+  ReplaceWithValue(node, node, effect, control);
+  return Replace(value);
+}
+
+
+Reduction JSIntrinsicLowering::ReduceIsJSReceiver(Node* node) {
+  Node* value = NodeProperties::GetValueInput(node, 0);
+  Type* value_type = NodeProperties::GetType(value);
+  Node* effect = NodeProperties::GetEffectInput(node);
+  Node* control = NodeProperties::GetControlInput(node);
+  if (value_type->Is(Type::Receiver())) {
+    value = jsgraph()->TrueConstant();
+  } else if (!value_type->Maybe(Type::Receiver())) {
+    value = jsgraph()->FalseConstant();
+  } else {
+    // if (%_IsSmi(value)) {
+    //   return false;
+    // } else {
+    //   return FIRST_JS_RECEIVER_TYPE <= %_GetInstanceType(%_GetMap(value))
+    // }
+    STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE);
+
+    Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), value);
+    Node* branch = graph()->NewNode(common()->Branch(), check, control);
+
+    Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
+    Node* etrue = effect;
+    Node* vtrue = jsgraph()->FalseConstant();
+
+    Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+    Node* efalse = graph()->NewNode(
+        simplified()->LoadField(AccessBuilder::ForMapInstanceType()),
+        graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
+                         value, effect, if_false),
+        effect, if_false);
+    Node* vfalse = graph()->NewNode(
+        machine()->Uint32LessThanOrEqual(),
+        jsgraph()->Int32Constant(FIRST_JS_RECEIVER_TYPE), efalse);
+
+    control = graph()->NewNode(common()->Merge(2), if_true, if_false);
+    effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
+    value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
+                             vtrue, vfalse, control);
+  }
+  ReplaceWithValue(node, node, effect, control);
+  return Replace(value);
+}
+
+
+Reduction JSIntrinsicLowering::ReduceIsSmi(Node* node) {
+  return Change(node, simplified()->ObjectIsSmi());
+}
+
+
+Reduction JSIntrinsicLowering::ReduceJSValueGetValue(Node* node) {
+  Node* value = NodeProperties::GetValueInput(node, 0);
+  Node* effect = NodeProperties::GetEffectInput(node);
+  Node* control = NodeProperties::GetControlInput(node);
+  return Change(node, simplified()->LoadField(AccessBuilder::ForValue()), value,
+                effect, control);
+}
+
+
+Reduction JSIntrinsicLowering::ReduceMathClz32(Node* node) {
+  return Change(node, machine()->Word32Clz());
+}
+
+
+Reduction JSIntrinsicLowering::ReduceMathFloor(Node* node) {
+  if (!machine()->Float64RoundDown().IsSupported()) return NoChange();
+  return Change(node, machine()->Float64RoundDown().op());
+}
+
+
+Reduction JSIntrinsicLowering::ReduceMathSqrt(Node* node) {
+  return Change(node, machine()->Float64Sqrt());
+}
+
+
+Reduction JSIntrinsicLowering::ReduceValueOf(Node* node) {
+  // if (%_IsSmi(value)) {
+  //   return value;
+  // } else if (%_GetInstanceType(%_GetMap(value)) == JS_VALUE_TYPE) {
+  //   return %_GetValue(value);
+  // } else {
+  //   return value;
+  // }
+  const Operator* const merge_op = common()->Merge(2);
+  const Operator* const ephi_op = common()->EffectPhi(2);
+  const Operator* const phi_op =
+      common()->Phi(MachineRepresentation::kTagged, 2);
+
+  Node* value = NodeProperties::GetValueInput(node, 0);
+  Node* effect = NodeProperties::GetEffectInput(node);
+  Node* control = NodeProperties::GetControlInput(node);
+
+  Node* check0 = graph()->NewNode(simplified()->ObjectIsSmi(), value);
+  Node* branch0 = graph()->NewNode(common()->Branch(), check0, control);
+
+  Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
+  Node* etrue0 = effect;
+  Node* vtrue0 = value;
+
+  Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
+  Node* efalse0;
+  Node* vfalse0;
+  {
+    Node* check1 = graph()->NewNode(
+        machine()->Word32Equal(),
+        graph()->NewNode(
+            simplified()->LoadField(AccessBuilder::ForMapInstanceType()),
+            graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
+                             value, effect, if_false0),
+            effect, if_false0),
+        jsgraph()->Int32Constant(JS_VALUE_TYPE));
+    Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0);
+
+    Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
+    Node* etrue1 =
+        graph()->NewNode(simplified()->LoadField(AccessBuilder::ForValue()),
+                         value, effect, if_true1);
+    Node* vtrue1 = etrue1;
+
+    Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
+    Node* efalse1 = effect;
+    Node* vfalse1 = value;
+
+    Node* merge1 = graph()->NewNode(merge_op, if_true1, if_false1);
+    efalse0 = graph()->NewNode(ephi_op, etrue1, efalse1, merge1);
+    vfalse0 = graph()->NewNode(phi_op, vtrue1, vfalse1, merge1);
+  }
+
+  Node* merge0 = graph()->NewNode(merge_op, if_true0, if_false0);
+
+  // Replace all effect uses of {node} with the {ephi0}.
+  Node* ephi0 = graph()->NewNode(ephi_op, etrue0, efalse0, merge0);
+  ReplaceWithValue(node, node, ephi0);
+
+  // Turn the {node} into a Phi.
+  return Change(node, phi_op, vtrue0, vfalse0, merge0);
+}
+
+
+Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op) {
+  // Replace all effect uses of {node} with the effect dependency.
+  RelaxEffectsAndControls(node);
+  // Remove the inputs corresponding to context, effect and control.
+  NodeProperties::RemoveNonValueInputs(node);
+  // Finally update the operator to the new one.
+  NodeProperties::ChangeOp(node, op);
+  return Changed(node);
+}
+
+
+Reduction JSIntrinsicLowering::ReduceIsMinusZero(Node* node) {
+  Node* value = NodeProperties::GetValueInput(node, 0);
+  Node* effect = NodeProperties::GetEffectInput(node);
+
+  Node* double_lo =
+      graph()->NewNode(machine()->Float64ExtractLowWord32(), value);
+  Node* check1 = graph()->NewNode(machine()->Word32Equal(), double_lo,
+                                  jsgraph()->ZeroConstant());
+
+  Node* double_hi =
+      graph()->NewNode(machine()->Float64ExtractHighWord32(), value);
+  Node* check2 = graph()->NewNode(
+      machine()->Word32Equal(), double_hi,
+      jsgraph()->Int32Constant(static_cast<int32_t>(0x80000000)));
+
+  ReplaceWithValue(node, node, effect);
+
+  Node* and_result = graph()->NewNode(machine()->Word32And(), check1, check2);
+
+  return Change(node, machine()->Word32Equal(), and_result,
+                jsgraph()->Int32Constant(1));
+}
+
+
+Reduction JSIntrinsicLowering::ReduceFixedArrayGet(Node* node) {
+  Node* base = node->InputAt(0);
+  Node* index = node->InputAt(1);
+  Node* effect = NodeProperties::GetEffectInput(node);
+  Node* control = NodeProperties::GetControlInput(node);
+  return Change(
+      node, simplified()->LoadElement(AccessBuilder::ForFixedArrayElement()),
+      base, index, effect, control);
+}
+
+
+Reduction JSIntrinsicLowering::ReduceFixedArraySet(Node* node) {
+  Node* base = node->InputAt(0);
+  Node* index = node->InputAt(1);
+  Node* value = node->InputAt(2);
+  Node* effect = NodeProperties::GetEffectInput(node);
+  Node* control = NodeProperties::GetControlInput(node);
+  Node* store = (graph()->NewNode(
+      simplified()->StoreElement(AccessBuilder::ForFixedArrayElement()), base,
+      index, value, effect, control));
+  ReplaceWithValue(node, value, store);
+  return Changed(store);
+}
+
+
+Reduction JSIntrinsicLowering::ReduceRegExpConstructResult(Node* node) {
+  // TODO(bmeurer): Introduce JSCreateRegExpResult?
+  return Change(node, CodeFactory::RegExpConstructResult(isolate()), 0);
+}
+
+
+Reduction JSIntrinsicLowering::ReduceRegExpExec(Node* node) {
+  return Change(node, CodeFactory::RegExpExec(isolate()), 4);
+}
+
+
+Reduction JSIntrinsicLowering::ReduceRegExpFlags(Node* node) {
+  Node* const receiver = NodeProperties::GetValueInput(node, 0);
+  Node* const effect = NodeProperties::GetEffectInput(node);
+  Node* const control = NodeProperties::GetControlInput(node);
+  Operator const* const op =
+      simplified()->LoadField(AccessBuilder::ForJSRegExpFlags());
+  return Change(node, op, receiver, effect, control);
+}
+
+
+Reduction JSIntrinsicLowering::ReduceRegExpSource(Node* node) {
+  Node* const receiver = NodeProperties::GetValueInput(node, 0);
+  Node* const effect = NodeProperties::GetEffectInput(node);
+  Node* const control = NodeProperties::GetControlInput(node);
+  Operator const* const op =
+      simplified()->LoadField(AccessBuilder::ForJSRegExpSource());
+  return Change(node, op, receiver, effect, control);
+}
+
+
+Reduction JSIntrinsicLowering::ReduceSubString(Node* node) {
+  return Change(node, CodeFactory::SubString(isolate()), 3);
+}
+
+
+Reduction JSIntrinsicLowering::ReduceToInteger(Node* node) {
+  Node* value = NodeProperties::GetValueInput(node, 0);
+  Type* value_type = NodeProperties::GetType(value);
+  if (value_type->Is(type_cache().kIntegerOrMinusZero)) {
+    ReplaceWithValue(node, value);
+    return Replace(value);
+  }
+  return NoChange();
+}
+
+
+Reduction JSIntrinsicLowering::ReduceToName(Node* node) {
+  NodeProperties::ChangeOp(node, javascript()->ToName());
+  return Changed(node);
+}
+
+
+Reduction JSIntrinsicLowering::ReduceToNumber(Node* node) {
+  NodeProperties::ChangeOp(node, javascript()->ToNumber());
+  return Changed(node);
+}
+
+
+Reduction JSIntrinsicLowering::ReduceToLength(Node* node) {
+  Node* value = NodeProperties::GetValueInput(node, 0);
+  Type* value_type = NodeProperties::GetType(value);
+  if (value_type->Is(type_cache().kIntegerOrMinusZero)) {
+    if (value_type->Max() <= 0.0) {
+      value = jsgraph()->ZeroConstant();
+    } else if (value_type->Min() >= kMaxSafeInteger) {
+      value = jsgraph()->Constant(kMaxSafeInteger);
+    } else {
+      if (value_type->Min() <= 0.0) {
+        value = graph()->NewNode(
+            common()->Select(MachineRepresentation::kTagged),
+            graph()->NewNode(simplified()->NumberLessThanOrEqual(), value,
+                             jsgraph()->ZeroConstant()),
+            jsgraph()->ZeroConstant(), value);
+        value_type = Type::Range(0.0, value_type->Max(), graph()->zone());
+        NodeProperties::SetType(value, value_type);
+      }
+      if (value_type->Max() > kMaxSafeInteger) {
+        value = graph()->NewNode(
+            common()->Select(MachineRepresentation::kTagged),
+            graph()->NewNode(simplified()->NumberLessThanOrEqual(),
+                             jsgraph()->Constant(kMaxSafeInteger), value),
+            jsgraph()->Constant(kMaxSafeInteger), value);
+        value_type =
+            Type::Range(value_type->Min(), kMaxSafeInteger, graph()->zone());
+        NodeProperties::SetType(value, value_type);
+      }
+    }
+    ReplaceWithValue(node, value);
+    return Replace(value);
+  }
+  return Change(node, CodeFactory::ToLength(isolate()), 0);
+}
+
+
+Reduction JSIntrinsicLowering::ReduceToObject(Node* node) {
+  NodeProperties::ChangeOp(node, javascript()->ToObject());
+  return Changed(node);
+}
+
+
+Reduction JSIntrinsicLowering::ReduceToPrimitive(Node* node) {
+  Node* value = NodeProperties::GetValueInput(node, 0);
+  Type* value_type = NodeProperties::GetType(value);
+  if (value_type->Is(Type::Primitive())) {
+    ReplaceWithValue(node, value);
+    return Replace(value);
+  }
+  return NoChange();
+}
+
+
+Reduction JSIntrinsicLowering::ReduceToString(Node* node) {
+  NodeProperties::ChangeOp(node, javascript()->ToString());
+  return Changed(node);
+}
+
+
+Reduction JSIntrinsicLowering::ReduceCall(Node* node) {
+  size_t const arity = CallRuntimeParametersOf(node->op()).arity();
+  NodeProperties::ChangeOp(
+      node, javascript()->CallFunction(arity, STRICT, VectorSlotPair(),
+                                       ConvertReceiverMode::kAny,
+                                       TailCallMode::kDisallow));
+  return Changed(node);
+}
+
+
+Reduction JSIntrinsicLowering::ReduceTailCall(Node* node) {
+  size_t const arity = CallRuntimeParametersOf(node->op()).arity();
+  NodeProperties::ChangeOp(
+      node, javascript()->CallFunction(arity, STRICT, VectorSlotPair(),
+                                       ConvertReceiverMode::kAny,
+                                       TailCallMode::kAllow));
+  return Changed(node);
+}
+
+
+Reduction JSIntrinsicLowering::ReduceGetSuperConstructor(Node* node) {
+  Node* active_function = NodeProperties::GetValueInput(node, 0);
+  Node* effect = NodeProperties::GetEffectInput(node);
+  Node* control = NodeProperties::GetControlInput(node);
+  Node* active_function_map = effect =
+      graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
+                       active_function, effect, control);
+  return Change(node, simplified()->LoadField(AccessBuilder::ForMapPrototype()),
+                active_function_map, effect, control);
+}
+
+
+Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op, Node* a,
+                                      Node* b) {
+  RelaxControls(node);
+  node->ReplaceInput(0, a);
+  node->ReplaceInput(1, b);
+  node->TrimInputCount(2);
+  NodeProperties::ChangeOp(node, op);
+  return Changed(node);
+}
+
+
+Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op, Node* a,
+                                      Node* b, Node* c) {
+  RelaxControls(node);
+  node->ReplaceInput(0, a);
+  node->ReplaceInput(1, b);
+  node->ReplaceInput(2, c);
+  node->TrimInputCount(3);
+  NodeProperties::ChangeOp(node, op);
+  return Changed(node);
+}
+
+
+Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op, Node* a,
+                                      Node* b, Node* c, Node* d) {
+  RelaxControls(node);
+  node->ReplaceInput(0, a);
+  node->ReplaceInput(1, b);
+  node->ReplaceInput(2, c);
+  node->ReplaceInput(3, d);
+  node->TrimInputCount(4);
+  NodeProperties::ChangeOp(node, op);
+  return Changed(node);
+}
+
+
+Reduction JSIntrinsicLowering::ChangeToUndefined(Node* node, Node* effect) {
+  ReplaceWithValue(node, jsgraph()->UndefinedConstant(), effect);
+  return Changed(node);
+}
+
+
+Reduction JSIntrinsicLowering::Change(Node* node, Callable const& callable,
+                                      int stack_parameter_count) {
+  CallDescriptor const* const desc = Linkage::GetStubCallDescriptor(
+      isolate(), graph()->zone(), callable.descriptor(), stack_parameter_count,
+      CallDescriptor::kNeedsFrameState, node->op()->properties());
+  node->InsertInput(graph()->zone(), 0,
+                    jsgraph()->HeapConstant(callable.code()));
+  NodeProperties::ChangeOp(node, common()->Call(desc));
+  return Changed(node);
+}
+
+
+Graph* JSIntrinsicLowering::graph() const { return jsgraph()->graph(); }
+
+
+Isolate* JSIntrinsicLowering::isolate() const { return jsgraph()->isolate(); }
+
+
+CommonOperatorBuilder* JSIntrinsicLowering::common() const {
+  return jsgraph()->common();
+}
+
+JSOperatorBuilder* JSIntrinsicLowering::javascript() const {
+  return jsgraph_->javascript();
+}
+
+
+MachineOperatorBuilder* JSIntrinsicLowering::machine() const {
+  return jsgraph()->machine();
+}
+
+
+SimplifiedOperatorBuilder* JSIntrinsicLowering::simplified() const {
+  return jsgraph()->simplified();
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/js-intrinsic-lowering.h b/src/compiler/js-intrinsic-lowering.h
new file mode 100644
index 0000000..1977a58
--- /dev/null
+++ b/src/compiler/js-intrinsic-lowering.h
@@ -0,0 +1,103 @@
+// Copyright 2015 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.
+
+#ifndef V8_COMPILER_JS_INTRINSIC_LOWERING_H_
+#define V8_COMPILER_JS_INTRINSIC_LOWERING_H_
+
+#include "src/compiler/common-operator.h"
+#include "src/compiler/graph-reducer.h"
+
+namespace v8 {
+namespace internal {
+
+// Forward declarations.
+class Callable;
+class TypeCache;
+
+
+namespace compiler {
+
+// Forward declarations.
+class CommonOperatorBuilder;
+class JSOperatorBuilder;
+class JSGraph;
+class MachineOperatorBuilder;
+class SimplifiedOperatorBuilder;
+
+
+// Lowers certain JS-level runtime calls.
+class JSIntrinsicLowering final : public AdvancedReducer {
+ public:
+  enum DeoptimizationMode { kDeoptimizationEnabled, kDeoptimizationDisabled };
+
+  JSIntrinsicLowering(Editor* editor, JSGraph* jsgraph,
+                      DeoptimizationMode mode);
+  ~JSIntrinsicLowering() final {}
+
+  Reduction Reduce(Node* node) final;
+
+ private:
+  Reduction ReduceConstructDouble(Node* node);
+  Reduction ReduceCreateIterResultObject(Node* node);
+  Reduction ReduceDeoptimizeNow(Node* node);
+  Reduction ReduceDoubleHi(Node* node);
+  Reduction ReduceDoubleLo(Node* node);
+  Reduction ReduceIncrementStatsCounter(Node* node);
+  Reduction ReduceIsMinusZero(Node* node);
+  Reduction ReduceIsInstanceType(Node* node, InstanceType instance_type);
+  Reduction ReduceIsFunction(Node* node);
+  Reduction ReduceIsJSReceiver(Node* node);
+  Reduction ReduceIsSmi(Node* node);
+  Reduction ReduceJSValueGetValue(Node* node);
+  Reduction ReduceMathClz32(Node* node);
+  Reduction ReduceMathFloor(Node* node);
+  Reduction ReduceMathSqrt(Node* node);
+  Reduction ReduceValueOf(Node* node);
+  Reduction ReduceFixedArrayGet(Node* node);
+  Reduction ReduceFixedArraySet(Node* node);
+  Reduction ReduceRegExpConstructResult(Node* node);
+  Reduction ReduceRegExpExec(Node* node);
+  Reduction ReduceRegExpFlags(Node* node);
+  Reduction ReduceRegExpSource(Node* node);
+  Reduction ReduceSubString(Node* node);
+  Reduction ReduceToInteger(Node* node);
+  Reduction ReduceToLength(Node* node);
+  Reduction ReduceToName(Node* node);
+  Reduction ReduceToNumber(Node* node);
+  Reduction ReduceToObject(Node* node);
+  Reduction ReduceToPrimitive(Node* node);
+  Reduction ReduceToString(Node* node);
+  Reduction ReduceCall(Node* node);
+  Reduction ReduceTailCall(Node* node);
+  Reduction ReduceGetSuperConstructor(Node* node);
+
+  Reduction Change(Node* node, const Operator* op);
+  Reduction Change(Node* node, const Operator* op, Node* a, Node* b);
+  Reduction Change(Node* node, const Operator* op, Node* a, Node* b, Node* c);
+  Reduction Change(Node* node, const Operator* op, Node* a, Node* b, Node* c,
+                   Node* d);
+  Reduction ChangeToUndefined(Node* node, Node* effect = nullptr);
+  Reduction Change(Node* node, Callable const& callable,
+                   int stack_parameter_count);
+
+  Graph* graph() const;
+  JSGraph* jsgraph() const { return jsgraph_; }
+  Isolate* isolate() const;
+  CommonOperatorBuilder* common() const;
+  JSOperatorBuilder* javascript() const;
+  MachineOperatorBuilder* machine() const;
+  SimplifiedOperatorBuilder* simplified() const;
+  DeoptimizationMode mode() const { return mode_; }
+  TypeCache const& type_cache() const { return type_cache_; }
+
+  JSGraph* const jsgraph_;
+  DeoptimizationMode const mode_;
+  TypeCache const& type_cache_;
+};
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_JS_INTRINSIC_LOWERING_H_
diff --git a/src/compiler/js-native-context-specialization.cc b/src/compiler/js-native-context-specialization.cc
new file mode 100644
index 0000000..06cf770
--- /dev/null
+++ b/src/compiler/js-native-context-specialization.cc
@@ -0,0 +1,1033 @@
+// Copyright 2015 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/js-native-context-specialization.h"
+
+#include "src/accessors.h"
+#include "src/code-factory.h"
+#include "src/compilation-dependencies.h"
+#include "src/compiler/access-builder.h"
+#include "src/compiler/access-info.h"
+#include "src/compiler/js-graph.h"
+#include "src/compiler/js-operator.h"
+#include "src/compiler/linkage.h"
+#include "src/compiler/node-matchers.h"
+#include "src/field-index-inl.h"
+#include "src/isolate-inl.h"
+#include "src/objects-inl.h"  // TODO(mstarzinger): Temporary cycle breaker!
+#include "src/type-cache.h"
+#include "src/type-feedback-vector.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+JSNativeContextSpecialization::JSNativeContextSpecialization(
+    Editor* editor, JSGraph* jsgraph, Flags flags,
+    MaybeHandle<Context> native_context, CompilationDependencies* dependencies,
+    Zone* zone)
+    : AdvancedReducer(editor),
+      jsgraph_(jsgraph),
+      flags_(flags),
+      native_context_(native_context),
+      dependencies_(dependencies),
+      zone_(zone),
+      type_cache_(TypeCache::Get()) {}
+
+
+Reduction JSNativeContextSpecialization::Reduce(Node* node) {
+  switch (node->opcode()) {
+    case IrOpcode::kJSLoadNamed:
+      return ReduceJSLoadNamed(node);
+    case IrOpcode::kJSStoreNamed:
+      return ReduceJSStoreNamed(node);
+    case IrOpcode::kJSLoadProperty:
+      return ReduceJSLoadProperty(node);
+    case IrOpcode::kJSStoreProperty:
+      return ReduceJSStoreProperty(node);
+    default:
+      break;
+  }
+  return NoChange();
+}
+
+
+Reduction JSNativeContextSpecialization::ReduceNamedAccess(
+    Node* node, Node* value, MapHandleList const& receiver_maps,
+    Handle<Name> name, AccessMode access_mode, LanguageMode language_mode,
+    Node* index) {
+  DCHECK(node->opcode() == IrOpcode::kJSLoadNamed ||
+         node->opcode() == IrOpcode::kJSStoreNamed ||
+         node->opcode() == IrOpcode::kJSLoadProperty ||
+         node->opcode() == IrOpcode::kJSStoreProperty);
+  Node* receiver = NodeProperties::GetValueInput(node, 0);
+  Node* frame_state = NodeProperties::GetFrameStateInput(node, 1);
+  Node* effect = NodeProperties::GetEffectInput(node);
+  Node* control = NodeProperties::GetControlInput(node);
+
+  // Not much we can do if deoptimization support is disabled.
+  if (!(flags() & kDeoptimizationEnabled)) return NoChange();
+
+  // Retrieve the native context from the given {node}.
+  Handle<Context> native_context;
+  if (!GetNativeContext(node).ToHandle(&native_context)) return NoChange();
+
+  // Compute property access infos for the receiver maps.
+  AccessInfoFactory access_info_factory(dependencies(), native_context,
+                                        graph()->zone());
+  ZoneVector<PropertyAccessInfo> access_infos(zone());
+  if (!access_info_factory.ComputePropertyAccessInfos(
+          receiver_maps, name, access_mode, &access_infos)) {
+    return NoChange();
+  }
+
+  // Nothing to do if we have no non-deprecated maps.
+  if (access_infos.empty()) return NoChange();
+
+  // The final states for every polymorphic branch. We join them with
+  // Merge++Phi+EffectPhi at the bottom.
+  ZoneVector<Node*> values(zone());
+  ZoneVector<Node*> effects(zone());
+  ZoneVector<Node*> controls(zone());
+
+  // The list of "exiting" controls, which currently go to a single deoptimize.
+  // TODO(bmeurer): Consider using an IC as fallback.
+  Node* const exit_effect = effect;
+  ZoneVector<Node*> exit_controls(zone());
+
+  // Ensure that {index} matches the specified {name} (if {index} is given).
+  if (index != nullptr) {
+    Node* check = graph()->NewNode(simplified()->ReferenceEqual(Type::Name()),
+                                   index, jsgraph()->HeapConstant(name));
+    Node* branch =
+        graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
+    exit_controls.push_back(graph()->NewNode(common()->IfFalse(), branch));
+    control = graph()->NewNode(common()->IfTrue(), branch);
+  }
+
+  // Ensure that {receiver} is a heap object.
+  Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), receiver);
+  Node* branch = graph()->NewNode(common()->Branch(), check, control);
+  control = graph()->NewNode(common()->IfFalse(), branch);
+  Node* receiverissmi_control = graph()->NewNode(common()->IfTrue(), branch);
+  Node* receiverissmi_effect = effect;
+
+  // Load the {receiver} map. The resulting effect is the dominating effect for
+  // all (polymorphic) branches.
+  Node* receiver_map = effect =
+      graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
+                       receiver, effect, control);
+
+  // Generate code for the various different property access patterns.
+  Node* fallthrough_control = control;
+  for (PropertyAccessInfo const& access_info : access_infos) {
+    Node* this_value = value;
+    Node* this_receiver = receiver;
+    Node* this_effect = effect;
+    Node* this_control;
+
+    // Perform map check on {receiver}.
+    Type* receiver_type = access_info.receiver_type();
+    if (receiver_type->Is(Type::String())) {
+      // Emit an instance type check for strings.
+      Node* receiver_instance_type = this_effect = graph()->NewNode(
+          simplified()->LoadField(AccessBuilder::ForMapInstanceType()),
+          receiver_map, this_effect, fallthrough_control);
+      Node* check =
+          graph()->NewNode(machine()->Uint32LessThan(), receiver_instance_type,
+                           jsgraph()->Uint32Constant(FIRST_NONSTRING_TYPE));
+      Node* branch =
+          graph()->NewNode(common()->Branch(), check, fallthrough_control);
+      fallthrough_control = graph()->NewNode(common()->IfFalse(), branch);
+      this_control = graph()->NewNode(common()->IfTrue(), branch);
+    } else {
+      // Emit a (sequence of) map checks for other {receiver}s.
+      ZoneVector<Node*> this_controls(zone());
+      ZoneVector<Node*> this_effects(zone());
+      for (auto i = access_info.receiver_type()->Classes(); !i.Done();
+           i.Advance()) {
+        Handle<Map> map = i.Current();
+        Node* check =
+            graph()->NewNode(simplified()->ReferenceEqual(Type::Internal()),
+                             receiver_map, jsgraph()->Constant(map));
+        Node* branch =
+            graph()->NewNode(common()->Branch(), check, fallthrough_control);
+        fallthrough_control = graph()->NewNode(common()->IfFalse(), branch);
+        this_controls.push_back(graph()->NewNode(common()->IfTrue(), branch));
+        this_effects.push_back(this_effect);
+      }
+
+      // The Number case requires special treatment to also deal with Smis.
+      if (receiver_type->Is(Type::Number())) {
+        // Join this check with the "receiver is smi" check above, and mark the
+        // "receiver is smi" check as "consumed" so that we don't deoptimize if
+        // the {receiver} is actually a Smi.
+        if (receiverissmi_control != nullptr) {
+          this_controls.push_back(receiverissmi_control);
+          this_effects.push_back(receiverissmi_effect);
+          receiverissmi_control = receiverissmi_effect = nullptr;
+        }
+      }
+
+      // Create dominating Merge+EffectPhi for this {receiver} type.
+      int const this_control_count = static_cast<int>(this_controls.size());
+      this_control =
+          (this_control_count == 1)
+              ? this_controls.front()
+              : graph()->NewNode(common()->Merge(this_control_count),
+                                 this_control_count, &this_controls.front());
+      this_effects.push_back(this_control);
+      int const this_effect_count = static_cast<int>(this_effects.size());
+      this_effect =
+          (this_control_count == 1)
+              ? this_effects.front()
+              : graph()->NewNode(common()->EffectPhi(this_control_count),
+                                 this_effect_count, &this_effects.front());
+    }
+
+    // Determine actual holder and perform prototype chain checks.
+    Handle<JSObject> holder;
+    if (access_info.holder().ToHandle(&holder)) {
+      AssumePrototypesStable(receiver_type, native_context, holder);
+    }
+
+    // Generate the actual property access.
+    if (access_info.IsNotFound()) {
+      DCHECK_EQ(AccessMode::kLoad, access_mode);
+      if (is_strong(language_mode)) {
+        // TODO(bmeurer/mstarzinger): Add support for lowering inside try
+        // blocks rewiring the IfException edge to a runtime call/throw.
+        exit_controls.push_back(this_control);
+        continue;
+      } else {
+        this_value = jsgraph()->UndefinedConstant();
+      }
+    } else if (access_info.IsDataConstant()) {
+      this_value = jsgraph()->Constant(access_info.constant());
+      if (access_mode == AccessMode::kStore) {
+        Node* check = graph()->NewNode(
+            simplified()->ReferenceEqual(Type::Tagged()), value, this_value);
+        Node* branch = graph()->NewNode(common()->Branch(BranchHint::kTrue),
+                                        check, this_control);
+        exit_controls.push_back(graph()->NewNode(common()->IfFalse(), branch));
+        this_control = graph()->NewNode(common()->IfTrue(), branch);
+      }
+    } else {
+      DCHECK(access_info.IsDataField());
+      FieldIndex const field_index = access_info.field_index();
+      FieldCheck const field_check = access_info.field_check();
+      Type* const field_type = access_info.field_type();
+      switch (field_check) {
+        case FieldCheck::kNone:
+          break;
+        case FieldCheck::kJSArrayBufferViewBufferNotNeutered: {
+          Node* this_buffer = this_effect =
+              graph()->NewNode(simplified()->LoadField(
+                                   AccessBuilder::ForJSArrayBufferViewBuffer()),
+                               this_receiver, this_effect, this_control);
+          Node* this_buffer_bit_field = this_effect =
+              graph()->NewNode(simplified()->LoadField(
+                                   AccessBuilder::ForJSArrayBufferBitField()),
+                               this_buffer, this_effect, this_control);
+          Node* check = graph()->NewNode(
+              machine()->Word32Equal(),
+              graph()->NewNode(machine()->Word32And(), this_buffer_bit_field,
+                               jsgraph()->Int32Constant(
+                                   1 << JSArrayBuffer::WasNeutered::kShift)),
+              jsgraph()->Int32Constant(0));
+          Node* branch = graph()->NewNode(common()->Branch(BranchHint::kFalse),
+                                          check, this_control);
+          exit_controls.push_back(graph()->NewNode(common()->IfTrue(), branch));
+          this_control = graph()->NewNode(common()->IfFalse(), branch);
+          break;
+        }
+      }
+      if (access_mode == AccessMode::kLoad &&
+          access_info.holder().ToHandle(&holder)) {
+        this_receiver = jsgraph()->Constant(holder);
+      }
+      Node* this_storage = this_receiver;
+      if (!field_index.is_inobject()) {
+        this_storage = this_effect = graph()->NewNode(
+            simplified()->LoadField(AccessBuilder::ForJSObjectProperties()),
+            this_storage, this_effect, this_control);
+      }
+      FieldAccess field_access = {kTaggedBase, field_index.offset(), name,
+                                  field_type, MachineType::AnyTagged()};
+      if (access_mode == AccessMode::kLoad) {
+        if (field_type->Is(Type::UntaggedFloat64())) {
+          if (!field_index.is_inobject() || field_index.is_hidden_field() ||
+              !FLAG_unbox_double_fields) {
+            this_storage = this_effect =
+                graph()->NewNode(simplified()->LoadField(field_access),
+                                 this_storage, this_effect, this_control);
+            field_access.offset = HeapNumber::kValueOffset;
+            field_access.name = MaybeHandle<Name>();
+          }
+          field_access.machine_type = MachineType::Float64();
+        }
+        this_value = this_effect =
+            graph()->NewNode(simplified()->LoadField(field_access),
+                             this_storage, this_effect, this_control);
+      } else {
+        DCHECK_EQ(AccessMode::kStore, access_mode);
+        if (field_type->Is(Type::UntaggedFloat64())) {
+          Node* check =
+              graph()->NewNode(simplified()->ObjectIsNumber(), this_value);
+          Node* branch = graph()->NewNode(common()->Branch(BranchHint::kTrue),
+                                          check, this_control);
+          exit_controls.push_back(
+              graph()->NewNode(common()->IfFalse(), branch));
+          this_control = graph()->NewNode(common()->IfTrue(), branch);
+          this_value = graph()->NewNode(common()->Guard(Type::Number()),
+                                        this_value, this_control);
+
+          if (!field_index.is_inobject() || field_index.is_hidden_field() ||
+              !FLAG_unbox_double_fields) {
+            if (access_info.HasTransitionMap()) {
+              // Allocate a MutableHeapNumber for the new property.
+              Callable callable =
+                  CodeFactory::AllocateMutableHeapNumber(isolate());
+              CallDescriptor* desc = Linkage::GetStubCallDescriptor(
+                  isolate(), jsgraph()->zone(), callable.descriptor(), 0,
+                  CallDescriptor::kNoFlags, Operator::kNoThrow);
+              Node* this_box = this_effect = graph()->NewNode(
+                  common()->Call(desc),
+                  jsgraph()->HeapConstant(callable.code()),
+                  jsgraph()->NoContextConstant(), this_effect, this_control);
+              this_effect = graph()->NewNode(
+                  simplified()->StoreField(AccessBuilder::ForHeapNumberValue()),
+                  this_box, this_value, this_effect, this_control);
+              this_value = this_box;
+
+              field_access.type = Type::TaggedPointer();
+            } else {
+              // We just store directly to the MutableHeapNumber.
+              this_storage = this_effect =
+                  graph()->NewNode(simplified()->LoadField(field_access),
+                                   this_storage, this_effect, this_control);
+              field_access.offset = HeapNumber::kValueOffset;
+              field_access.name = MaybeHandle<Name>();
+              field_access.machine_type = MachineType::Float64();
+            }
+          } else {
+            // Unboxed double field, we store directly to the field.
+            field_access.machine_type = MachineType::Float64();
+          }
+        } else if (field_type->Is(Type::TaggedSigned())) {
+          Node* check =
+              graph()->NewNode(simplified()->ObjectIsSmi(), this_value);
+          Node* branch = graph()->NewNode(common()->Branch(BranchHint::kTrue),
+                                          check, this_control);
+          exit_controls.push_back(
+              graph()->NewNode(common()->IfFalse(), branch));
+          this_control = graph()->NewNode(common()->IfTrue(), branch);
+          this_value = graph()->NewNode(common()->Guard(type_cache_.kSmi),
+                                        this_value, this_control);
+        } else if (field_type->Is(Type::TaggedPointer())) {
+          Node* check =
+              graph()->NewNode(simplified()->ObjectIsSmi(), this_value);
+          Node* branch = graph()->NewNode(common()->Branch(BranchHint::kFalse),
+                                          check, this_control);
+          exit_controls.push_back(graph()->NewNode(common()->IfTrue(), branch));
+          this_control = graph()->NewNode(common()->IfFalse(), branch);
+          if (field_type->NumClasses() > 0) {
+            // Emit a (sequence of) map checks for the value.
+            ZoneVector<Node*> this_controls(zone());
+            Node* this_value_map = this_effect = graph()->NewNode(
+                simplified()->LoadField(AccessBuilder::ForMap()), this_value,
+                this_effect, this_control);
+            for (auto i = field_type->Classes(); !i.Done(); i.Advance()) {
+              Handle<Map> field_map(i.Current());
+              check = graph()->NewNode(
+                  simplified()->ReferenceEqual(Type::Internal()),
+                  this_value_map, jsgraph()->Constant(field_map));
+              branch = graph()->NewNode(common()->Branch(BranchHint::kTrue),
+                                        check, this_control);
+              this_control = graph()->NewNode(common()->IfFalse(), branch);
+              this_controls.push_back(
+                  graph()->NewNode(common()->IfTrue(), branch));
+            }
+            exit_controls.push_back(this_control);
+            int const this_control_count =
+                static_cast<int>(this_controls.size());
+            this_control =
+                (this_control_count == 1)
+                    ? this_controls.front()
+                    : graph()->NewNode(common()->Merge(this_control_count),
+                                       this_control_count,
+                                       &this_controls.front());
+          }
+        } else {
+          DCHECK(field_type->Is(Type::Tagged()));
+        }
+        Handle<Map> transition_map;
+        if (access_info.transition_map().ToHandle(&transition_map)) {
+          this_effect = graph()->NewNode(common()->BeginRegion(), this_effect);
+          this_effect = graph()->NewNode(
+              simplified()->StoreField(AccessBuilder::ForMap()), this_receiver,
+              jsgraph()->Constant(transition_map), this_effect, this_control);
+        }
+        this_effect = graph()->NewNode(simplified()->StoreField(field_access),
+                                       this_storage, this_value, this_effect,
+                                       this_control);
+        if (access_info.HasTransitionMap()) {
+          this_effect =
+              graph()->NewNode(common()->FinishRegion(),
+                               jsgraph()->UndefinedConstant(), this_effect);
+        }
+      }
+    }
+
+    // Remember the final state for this property access.
+    values.push_back(this_value);
+    effects.push_back(this_effect);
+    controls.push_back(this_control);
+  }
+
+  // Collect the fallthrough control as final "exit" control.
+  if (fallthrough_control != control) {
+    // Mark the last fallthrough branch as deferred.
+    MarkAsDeferred(fallthrough_control);
+  }
+  exit_controls.push_back(fallthrough_control);
+
+  // Also collect the "receiver is smi" control if we didn't handle the case of
+  // Number primitives in the polymorphic branches above.
+  if (receiverissmi_control != nullptr) {
+    // Mark the "receiver is smi" case as deferred.
+    MarkAsDeferred(receiverissmi_control);
+    DCHECK_EQ(exit_effect, receiverissmi_effect);
+    exit_controls.push_back(receiverissmi_control);
+  }
+
+  // Generate the single "exit" point, where we get if either all map/instance
+  // type checks failed, or one of the assumptions inside one of the cases
+  // failes (i.e. failing prototype chain check).
+  // TODO(bmeurer): Consider falling back to IC here if deoptimization is
+  // disabled.
+  int const exit_control_count = static_cast<int>(exit_controls.size());
+  Node* exit_control =
+      (exit_control_count == 1)
+          ? exit_controls.front()
+          : graph()->NewNode(common()->Merge(exit_control_count),
+                             exit_control_count, &exit_controls.front());
+  Node* deoptimize =
+      graph()->NewNode(common()->Deoptimize(DeoptimizeKind::kEager),
+                       frame_state, exit_effect, exit_control);
+  // TODO(bmeurer): This should be on the AdvancedReducer somehow.
+  NodeProperties::MergeControlToEnd(graph(), common(), deoptimize);
+
+  // Generate the final merge point for all (polymorphic) branches.
+  int const control_count = static_cast<int>(controls.size());
+  if (control_count == 0) {
+    value = effect = control = jsgraph()->Dead();
+  } else if (control_count == 1) {
+    value = values.front();
+    effect = effects.front();
+    control = controls.front();
+  } else {
+    control = graph()->NewNode(common()->Merge(control_count), control_count,
+                               &controls.front());
+    values.push_back(control);
+    value = graph()->NewNode(
+        common()->Phi(MachineRepresentation::kTagged, control_count),
+        control_count + 1, &values.front());
+    effects.push_back(control);
+    effect = graph()->NewNode(common()->EffectPhi(control_count),
+                              control_count + 1, &effects.front());
+  }
+  ReplaceWithValue(node, value, effect, control);
+  return Replace(value);
+}
+
+
+Reduction JSNativeContextSpecialization::ReduceJSLoadNamed(Node* node) {
+  DCHECK_EQ(IrOpcode::kJSLoadNamed, node->opcode());
+  NamedAccess const& p = NamedAccessOf(node->op());
+  Node* const value = jsgraph()->Dead();
+
+  // Extract receiver maps from the LOAD_IC using the LoadICNexus.
+  MapHandleList receiver_maps;
+  if (!p.feedback().IsValid()) return NoChange();
+  LoadICNexus nexus(p.feedback().vector(), p.feedback().slot());
+  if (nexus.ExtractMaps(&receiver_maps) == 0) return NoChange();
+  DCHECK_LT(0, receiver_maps.length());
+
+  // Try to lower the named access based on the {receiver_maps}.
+  return ReduceNamedAccess(node, value, receiver_maps, p.name(),
+                           AccessMode::kLoad, p.language_mode());
+}
+
+
+Reduction JSNativeContextSpecialization::ReduceJSStoreNamed(Node* node) {
+  DCHECK_EQ(IrOpcode::kJSStoreNamed, node->opcode());
+  NamedAccess const& p = NamedAccessOf(node->op());
+  Node* const value = NodeProperties::GetValueInput(node, 1);
+
+  // Extract receiver maps from the STORE_IC using the StoreICNexus.
+  MapHandleList receiver_maps;
+  if (!p.feedback().IsValid()) return NoChange();
+  StoreICNexus nexus(p.feedback().vector(), p.feedback().slot());
+  if (nexus.ExtractMaps(&receiver_maps) == 0) return NoChange();
+  DCHECK_LT(0, receiver_maps.length());
+
+  // Try to lower the named access based on the {receiver_maps}.
+  return ReduceNamedAccess(node, value, receiver_maps, p.name(),
+                           AccessMode::kStore, p.language_mode());
+}
+
+
+Reduction JSNativeContextSpecialization::ReduceElementAccess(
+    Node* node, Node* index, Node* value, MapHandleList const& receiver_maps,
+    AccessMode access_mode, LanguageMode language_mode,
+    KeyedAccessStoreMode store_mode) {
+  DCHECK(node->opcode() == IrOpcode::kJSLoadProperty ||
+         node->opcode() == IrOpcode::kJSStoreProperty);
+  Node* receiver = NodeProperties::GetValueInput(node, 0);
+  Node* context = NodeProperties::GetContextInput(node);
+  Node* frame_state = NodeProperties::GetFrameStateInput(node, 1);
+  Node* effect = NodeProperties::GetEffectInput(node);
+  Node* control = NodeProperties::GetControlInput(node);
+
+  // Not much we can do if deoptimization support is disabled.
+  if (!(flags() & kDeoptimizationEnabled)) return NoChange();
+
+  // TODO(bmeurer): Add support for non-standard stores.
+  if (store_mode != STANDARD_STORE) return NoChange();
+
+  // Retrieve the native context from the given {node}.
+  Handle<Context> native_context;
+  if (!GetNativeContext(node).ToHandle(&native_context)) return NoChange();
+
+  // Compute element access infos for the receiver maps.
+  AccessInfoFactory access_info_factory(dependencies(), native_context,
+                                        graph()->zone());
+  ZoneVector<ElementAccessInfo> access_infos(zone());
+  if (!access_info_factory.ComputeElementAccessInfos(receiver_maps, access_mode,
+                                                     &access_infos)) {
+    return NoChange();
+  }
+
+  // Nothing to do if we have no non-deprecated maps.
+  if (access_infos.empty()) return NoChange();
+
+  // The final states for every polymorphic branch. We join them with
+  // Merge+Phi+EffectPhi at the bottom.
+  ZoneVector<Node*> values(zone());
+  ZoneVector<Node*> effects(zone());
+  ZoneVector<Node*> controls(zone());
+
+  // The list of "exiting" controls, which currently go to a single deoptimize.
+  // TODO(bmeurer): Consider using an IC as fallback.
+  Node* const exit_effect = effect;
+  ZoneVector<Node*> exit_controls(zone());
+
+  // Ensure that {receiver} is a heap object.
+  Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), receiver);
+  Node* branch =
+      graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control);
+  exit_controls.push_back(graph()->NewNode(common()->IfTrue(), branch));
+  control = graph()->NewNode(common()->IfFalse(), branch);
+
+  // Load the {receiver} map. The resulting effect is the dominating effect for
+  // all (polymorphic) branches.
+  Node* receiver_map = effect =
+      graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
+                       receiver, effect, control);
+
+  // Generate code for the various different element access patterns.
+  Node* fallthrough_control = control;
+  for (ElementAccessInfo const& access_info : access_infos) {
+    Node* this_receiver = receiver;
+    Node* this_value = value;
+    Node* this_index = index;
+    Node* this_effect;
+    Node* this_control;
+
+    // Perform map check on {receiver}.
+    Type* receiver_type = access_info.receiver_type();
+    bool receiver_is_jsarray = true;
+    {
+      ZoneVector<Node*> this_controls(zone());
+      ZoneVector<Node*> this_effects(zone());
+      for (auto i = access_info.receiver_type()->Classes(); !i.Done();
+           i.Advance()) {
+        Handle<Map> map = i.Current();
+        Node* check =
+            graph()->NewNode(simplified()->ReferenceEqual(Type::Any()),
+                             receiver_map, jsgraph()->Constant(map));
+        Node* branch =
+            graph()->NewNode(common()->Branch(), check, fallthrough_control);
+        this_controls.push_back(graph()->NewNode(common()->IfTrue(), branch));
+        this_effects.push_back(effect);
+        fallthrough_control = graph()->NewNode(common()->IfFalse(), branch);
+        if (!map->IsJSArrayMap()) receiver_is_jsarray = false;
+      }
+
+      // Generate possible elements kind transitions.
+      for (auto transition : access_info.transitions()) {
+        Handle<Map> transition_source = transition.first;
+        Handle<Map> transition_target = transition.second;
+
+        // Check if {receiver} has the specified {transition_source} map.
+        Node* check = graph()->NewNode(
+            simplified()->ReferenceEqual(Type::Any()), receiver_map,
+            jsgraph()->HeapConstant(transition_source));
+        Node* branch =
+            graph()->NewNode(common()->Branch(), check, fallthrough_control);
+
+        // Migrate {receiver} from {transition_source} to {transition_target}.
+        Node* transition_control = graph()->NewNode(common()->IfTrue(), branch);
+        Node* transition_effect = effect;
+        if (IsSimpleMapChangeTransition(transition_source->elements_kind(),
+                                        transition_target->elements_kind())) {
+          // In-place migration, just store the {transition_target} map.
+          transition_effect = graph()->NewNode(
+              simplified()->StoreField(AccessBuilder::ForMap()), receiver,
+              jsgraph()->HeapConstant(transition_target), transition_effect,
+              transition_control);
+        } else {
+          // Instance migration, let the stub deal with the {receiver}.
+          TransitionElementsKindStub stub(isolate(),
+                                          transition_source->elements_kind(),
+                                          transition_target->elements_kind(),
+                                          transition_source->IsJSArrayMap());
+          CallDescriptor const* const desc = Linkage::GetStubCallDescriptor(
+              isolate(), graph()->zone(), stub.GetCallInterfaceDescriptor(), 0,
+              CallDescriptor::kNeedsFrameState, node->op()->properties());
+          transition_effect = graph()->NewNode(
+              common()->Call(desc), jsgraph()->HeapConstant(stub.GetCode()),
+              receiver, jsgraph()->HeapConstant(transition_target), context,
+              frame_state, transition_effect, transition_control);
+        }
+        this_controls.push_back(transition_control);
+        this_effects.push_back(transition_effect);
+
+        fallthrough_control = graph()->NewNode(common()->IfFalse(), branch);
+      }
+
+      // Create single chokepoint for the control.
+      int const this_control_count = static_cast<int>(this_controls.size());
+      if (this_control_count == 1) {
+        this_control = this_controls.front();
+        this_effect = this_effects.front();
+      } else {
+        this_control =
+            graph()->NewNode(common()->Merge(this_control_count),
+                             this_control_count, &this_controls.front());
+        this_effects.push_back(this_control);
+        this_effect =
+            graph()->NewNode(common()->EffectPhi(this_control_count),
+                             this_control_count + 1, &this_effects.front());
+      }
+    }
+
+    // Certain stores need a prototype chain check because shape changes
+    // could allow callbacks on elements in the prototype chain that are
+    // not compatible with (monomorphic) keyed stores.
+    Handle<JSObject> holder;
+    if (access_info.holder().ToHandle(&holder)) {
+      AssumePrototypesStable(receiver_type, native_context, holder);
+    }
+
+    // Check that the {index} is actually a Number.
+    if (!NumberMatcher(this_index).HasValue()) {
+      Node* check =
+          graph()->NewNode(simplified()->ObjectIsNumber(), this_index);
+      Node* branch = graph()->NewNode(common()->Branch(BranchHint::kTrue),
+                                      check, this_control);
+      exit_controls.push_back(graph()->NewNode(common()->IfFalse(), branch));
+      this_control = graph()->NewNode(common()->IfTrue(), branch);
+      this_index = graph()->NewNode(common()->Guard(Type::Number()), this_index,
+                                    this_control);
+    }
+
+    // Convert the {index} to an unsigned32 value and check if the result is
+    // equal to the original {index}.
+    if (!NumberMatcher(this_index).IsInRange(0.0, kMaxUInt32)) {
+      Node* this_index32 =
+          graph()->NewNode(simplified()->NumberToUint32(), this_index);
+      Node* check = graph()->NewNode(simplified()->NumberEqual(), this_index32,
+                                     this_index);
+      Node* branch = graph()->NewNode(common()->Branch(BranchHint::kTrue),
+                                      check, this_control);
+      exit_controls.push_back(graph()->NewNode(common()->IfFalse(), branch));
+      this_control = graph()->NewNode(common()->IfTrue(), branch);
+      this_index = this_index32;
+    }
+
+    // TODO(bmeurer): We currently specialize based on elements kind. We should
+    // also be able to properly support strings and other JSObjects here.
+    ElementsKind elements_kind = access_info.elements_kind();
+
+    // Load the elements for the {receiver}.
+    Node* this_elements = this_effect = graph()->NewNode(
+        simplified()->LoadField(AccessBuilder::ForJSObjectElements()),
+        this_receiver, this_effect, this_control);
+
+    // Don't try to store to a copy-on-write backing store.
+    if (access_mode == AccessMode::kStore &&
+        IsFastSmiOrObjectElementsKind(elements_kind)) {
+      Node* this_elements_map = this_effect =
+          graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
+                           this_elements, this_effect, this_control);
+      check = graph()->NewNode(
+          simplified()->ReferenceEqual(Type::Any()), this_elements_map,
+          jsgraph()->HeapConstant(factory()->fixed_array_map()));
+      branch = graph()->NewNode(common()->Branch(BranchHint::kTrue), check,
+                                this_control);
+      exit_controls.push_back(graph()->NewNode(common()->IfFalse(), branch));
+      this_control = graph()->NewNode(common()->IfTrue(), branch);
+    }
+
+    // Load the length of the {receiver}.
+    Node* this_length = this_effect =
+        receiver_is_jsarray
+            ? graph()->NewNode(
+                  simplified()->LoadField(
+                      AccessBuilder::ForJSArrayLength(elements_kind)),
+                  this_receiver, this_effect, this_control)
+            : graph()->NewNode(
+                  simplified()->LoadField(AccessBuilder::ForFixedArrayLength()),
+                  this_elements, this_effect, this_control);
+
+    // Check that the {index} is in the valid range for the {receiver}.
+    Node* check = graph()->NewNode(simplified()->NumberLessThan(), this_index,
+                                   this_length);
+    Node* branch = graph()->NewNode(common()->Branch(BranchHint::kTrue), check,
+                                    this_control);
+    exit_controls.push_back(graph()->NewNode(common()->IfFalse(), branch));
+    this_control = graph()->NewNode(common()->IfTrue(), branch);
+
+    // Compute the element access.
+    Type* element_type = Type::Any();
+    MachineType element_machine_type = MachineType::AnyTagged();
+    if (IsFastDoubleElementsKind(elements_kind)) {
+      element_type = type_cache_.kFloat64;
+      element_machine_type = MachineType::Float64();
+    } else if (IsFastSmiElementsKind(elements_kind)) {
+      element_type = type_cache_.kSmi;
+    }
+    ElementAccess element_access = {kTaggedBase, FixedArray::kHeaderSize,
+                                    element_type, element_machine_type};
+
+    // Access the actual element.
+    // TODO(bmeurer): Refactor this into separate methods or even a separate
+    // class that deals with the elements access.
+    if (access_mode == AccessMode::kLoad) {
+      // Compute the real element access type, which includes the hole in case
+      // of holey backing stores.
+      if (elements_kind == FAST_HOLEY_ELEMENTS ||
+          elements_kind == FAST_HOLEY_SMI_ELEMENTS) {
+        element_access.type = Type::Union(
+            element_type,
+            Type::Constant(factory()->the_hole_value(), graph()->zone()),
+            graph()->zone());
+      }
+      // Perform the actual backing store access.
+      this_value = this_effect = graph()->NewNode(
+          simplified()->LoadElement(element_access), this_elements, this_index,
+          this_effect, this_control);
+      // Handle loading from holey backing stores correctly, by either mapping
+      // the hole to undefined if possible, or deoptimizing otherwise.
+      if (elements_kind == FAST_HOLEY_ELEMENTS ||
+          elements_kind == FAST_HOLEY_SMI_ELEMENTS) {
+        // Perform the hole check on the result.
+        Node* check =
+            graph()->NewNode(simplified()->ReferenceEqual(element_access.type),
+                             this_value, jsgraph()->TheHoleConstant());
+        Node* branch = graph()->NewNode(common()->Branch(BranchHint::kFalse),
+                                        check, this_control);
+        Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
+        Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+        // Check if we are allowed to turn the hole into undefined.
+        Type* initial_holey_array_type = Type::Class(
+            handle(isolate()->get_initial_js_array_map(elements_kind)),
+            graph()->zone());
+        if (receiver_type->NowIs(initial_holey_array_type) &&
+            isolate()->IsFastArrayConstructorPrototypeChainIntact()) {
+          // Add a code dependency on the array protector cell.
+          AssumePrototypesStable(receiver_type, native_context,
+                                 isolate()->initial_object_prototype());
+          dependencies()->AssumePropertyCell(factory()->array_protector());
+          // Turn the hole into undefined.
+          this_control =
+              graph()->NewNode(common()->Merge(2), if_true, if_false);
+          this_value = graph()->NewNode(
+              common()->Phi(MachineRepresentation::kTagged, 2),
+              jsgraph()->UndefinedConstant(), this_value, this_control);
+          element_type =
+              Type::Union(element_type, Type::Undefined(), graph()->zone());
+        } else {
+          // Deoptimize in case of the hole.
+          exit_controls.push_back(if_true);
+          this_control = if_false;
+        }
+        // Rename the result to represent the actual type (not polluted by the
+        // hole).
+        this_value = graph()->NewNode(common()->Guard(element_type), this_value,
+                                      this_control);
+      } else if (elements_kind == FAST_HOLEY_DOUBLE_ELEMENTS) {
+        // Perform the hole check on the result.
+        Node* check =
+            graph()->NewNode(simplified()->NumberIsHoleNaN(), this_value);
+        // Check if we are allowed to return the hole directly.
+        Type* initial_holey_array_type = Type::Class(
+            handle(isolate()->get_initial_js_array_map(elements_kind)),
+            graph()->zone());
+        if (receiver_type->NowIs(initial_holey_array_type) &&
+            isolate()->IsFastArrayConstructorPrototypeChainIntact()) {
+          // Add a code dependency on the array protector cell.
+          AssumePrototypesStable(receiver_type, native_context,
+                                 isolate()->initial_object_prototype());
+          dependencies()->AssumePropertyCell(factory()->array_protector());
+          // Turn the hole into undefined.
+          this_value = graph()->NewNode(
+              common()->Select(MachineRepresentation::kTagged,
+                               BranchHint::kFalse),
+              check, jsgraph()->UndefinedConstant(), this_value);
+        } else {
+          // Deoptimize in case of the hole.
+          Node* branch = graph()->NewNode(common()->Branch(BranchHint::kFalse),
+                                          check, this_control);
+          this_control = graph()->NewNode(common()->IfFalse(), branch);
+          exit_controls.push_back(graph()->NewNode(common()->IfTrue(), branch));
+        }
+      }
+    } else {
+      DCHECK_EQ(AccessMode::kStore, access_mode);
+      if (IsFastSmiElementsKind(elements_kind)) {
+        Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), this_value);
+        Node* branch = graph()->NewNode(common()->Branch(BranchHint::kTrue),
+                                        check, this_control);
+        exit_controls.push_back(graph()->NewNode(common()->IfFalse(), branch));
+        this_control = graph()->NewNode(common()->IfTrue(), branch);
+        this_value = graph()->NewNode(common()->Guard(type_cache_.kSmi),
+                                      this_value, this_control);
+      } else if (IsFastDoubleElementsKind(elements_kind)) {
+        Node* check =
+            graph()->NewNode(simplified()->ObjectIsNumber(), this_value);
+        Node* branch = graph()->NewNode(common()->Branch(BranchHint::kTrue),
+                                        check, this_control);
+        exit_controls.push_back(graph()->NewNode(common()->IfFalse(), branch));
+        this_control = graph()->NewNode(common()->IfTrue(), branch);
+        this_value = graph()->NewNode(common()->Guard(Type::Number()),
+                                      this_value, this_control);
+      }
+      this_effect = graph()->NewNode(simplified()->StoreElement(element_access),
+                                     this_elements, this_index, this_value,
+                                     this_effect, this_control);
+    }
+
+    // Remember the final state for this element access.
+    values.push_back(this_value);
+    effects.push_back(this_effect);
+    controls.push_back(this_control);
+  }
+
+  // Collect the fallthrough control as final "exit" control.
+  if (fallthrough_control != control) {
+    // Mark the last fallthrough branch as deferred.
+    MarkAsDeferred(fallthrough_control);
+  }
+  exit_controls.push_back(fallthrough_control);
+
+  // Generate the single "exit" point, where we get if either all map/instance
+  // type checks failed, or one of the assumptions inside one of the cases
+  // failes (i.e. failing prototype chain check).
+  // TODO(bmeurer): Consider falling back to IC here if deoptimization is
+  // disabled.
+  int const exit_control_count = static_cast<int>(exit_controls.size());
+  Node* exit_control =
+      (exit_control_count == 1)
+          ? exit_controls.front()
+          : graph()->NewNode(common()->Merge(exit_control_count),
+                             exit_control_count, &exit_controls.front());
+  Node* deoptimize =
+      graph()->NewNode(common()->Deoptimize(DeoptimizeKind::kEager),
+                       frame_state, exit_effect, exit_control);
+  // TODO(bmeurer): This should be on the AdvancedReducer somehow.
+  NodeProperties::MergeControlToEnd(graph(), common(), deoptimize);
+
+  // Generate the final merge point for all (polymorphic) branches.
+  int const control_count = static_cast<int>(controls.size());
+  if (control_count == 0) {
+    value = effect = control = jsgraph()->Dead();
+  } else if (control_count == 1) {
+    value = values.front();
+    effect = effects.front();
+    control = controls.front();
+  } else {
+    control = graph()->NewNode(common()->Merge(control_count), control_count,
+                               &controls.front());
+    values.push_back(control);
+    value = graph()->NewNode(
+        common()->Phi(MachineRepresentation::kTagged, control_count),
+        control_count + 1, &values.front());
+    effects.push_back(control);
+    effect = graph()->NewNode(common()->EffectPhi(control_count),
+                              control_count + 1, &effects.front());
+  }
+  ReplaceWithValue(node, value, effect, control);
+  return Replace(value);
+}
+
+
+Reduction JSNativeContextSpecialization::ReduceKeyedAccess(
+    Node* node, Node* index, Node* value, FeedbackNexus const& nexus,
+    AccessMode access_mode, LanguageMode language_mode,
+    KeyedAccessStoreMode store_mode) {
+  DCHECK(node->opcode() == IrOpcode::kJSLoadProperty ||
+         node->opcode() == IrOpcode::kJSStoreProperty);
+
+  // Extract receiver maps from the {nexus}.
+  MapHandleList receiver_maps;
+  if (nexus.ExtractMaps(&receiver_maps) == 0) return NoChange();
+  DCHECK_LT(0, receiver_maps.length());
+
+  // Optimize access for constant {index}.
+  HeapObjectMatcher mindex(index);
+  if (mindex.HasValue() && mindex.Value()->IsPrimitive()) {
+    // Keyed access requires a ToPropertyKey on the {index} first before
+    // looking up the property on the object (see ES6 section 12.3.2.1).
+    // We can only do this for non-observable ToPropertyKey invocations,
+    // so we limit the constant indices to primitives at this point.
+    Handle<Name> name;
+    if (Object::ToName(isolate(), mindex.Value()).ToHandle(&name)) {
+      uint32_t array_index;
+      if (name->AsArrayIndex(&array_index)) {
+        // Use the constant array index.
+        index = jsgraph()->Constant(static_cast<double>(array_index));
+      } else {
+        name = factory()->InternalizeName(name);
+        return ReduceNamedAccess(node, value, receiver_maps, name, access_mode,
+                                 language_mode);
+      }
+    }
+  }
+
+  // Check if we have feedback for a named access.
+  if (Name* name = nexus.FindFirstName()) {
+    return ReduceNamedAccess(node, value, receiver_maps,
+                             handle(name, isolate()), access_mode,
+                             language_mode, index);
+  }
+
+  // Try to lower the element access based on the {receiver_maps}.
+  return ReduceElementAccess(node, index, value, receiver_maps, access_mode,
+                             language_mode, store_mode);
+}
+
+
+Reduction JSNativeContextSpecialization::ReduceJSLoadProperty(Node* node) {
+  DCHECK_EQ(IrOpcode::kJSLoadProperty, node->opcode());
+  PropertyAccess const& p = PropertyAccessOf(node->op());
+  Node* const index = NodeProperties::GetValueInput(node, 1);
+  Node* const value = jsgraph()->Dead();
+
+  // Extract receiver maps from the KEYED_LOAD_IC using the KeyedLoadICNexus.
+  if (!p.feedback().IsValid()) return NoChange();
+  KeyedLoadICNexus nexus(p.feedback().vector(), p.feedback().slot());
+
+  // Try to lower the keyed access based on the {nexus}.
+  return ReduceKeyedAccess(node, index, value, nexus, AccessMode::kLoad,
+                           p.language_mode(), STANDARD_STORE);
+}
+
+
+Reduction JSNativeContextSpecialization::ReduceJSStoreProperty(Node* node) {
+  DCHECK_EQ(IrOpcode::kJSStoreProperty, node->opcode());
+  PropertyAccess const& p = PropertyAccessOf(node->op());
+  Node* const index = NodeProperties::GetValueInput(node, 1);
+  Node* const value = NodeProperties::GetValueInput(node, 2);
+
+  // Extract receiver maps from the KEYED_STORE_IC using the KeyedStoreICNexus.
+  if (!p.feedback().IsValid()) return NoChange();
+  KeyedStoreICNexus nexus(p.feedback().vector(), p.feedback().slot());
+
+  // Extract the keyed access store mode from the KEYED_STORE_IC.
+  KeyedAccessStoreMode store_mode = nexus.GetKeyedAccessStoreMode();
+
+  // Try to lower the keyed access based on the {nexus}.
+  return ReduceKeyedAccess(node, index, value, nexus, AccessMode::kStore,
+                           p.language_mode(), store_mode);
+}
+
+
+void JSNativeContextSpecialization::AssumePrototypesStable(
+    Type* receiver_type, Handle<Context> native_context,
+    Handle<JSObject> holder) {
+  // Determine actual holder and perform prototype chain checks.
+  for (auto i = receiver_type->Classes(); !i.Done(); i.Advance()) {
+    Handle<Map> map = i.Current();
+    // Perform the implicit ToObject for primitives here.
+    // Implemented according to ES6 section 7.3.2 GetV (V, P).
+    Handle<JSFunction> constructor;
+    if (Map::GetConstructorFunction(map, native_context)
+            .ToHandle(&constructor)) {
+      map = handle(constructor->initial_map(), isolate());
+    }
+    dependencies()->AssumePrototypeMapsStable(map, holder);
+  }
+}
+
+
+void JSNativeContextSpecialization::MarkAsDeferred(Node* if_projection) {
+  Node* branch = NodeProperties::GetControlInput(if_projection);
+  DCHECK_EQ(IrOpcode::kBranch, branch->opcode());
+  if (if_projection->opcode() == IrOpcode::kIfTrue) {
+    NodeProperties::ChangeOp(branch, common()->Branch(BranchHint::kFalse));
+  } else {
+    DCHECK_EQ(IrOpcode::kIfFalse, if_projection->opcode());
+    NodeProperties::ChangeOp(branch, common()->Branch(BranchHint::kTrue));
+  }
+}
+
+
+MaybeHandle<Context> JSNativeContextSpecialization::GetNativeContext(
+    Node* node) {
+  Node* const context = NodeProperties::GetContextInput(node);
+  return NodeProperties::GetSpecializationNativeContext(context,
+                                                        native_context());
+}
+
+
+Graph* JSNativeContextSpecialization::graph() const {
+  return jsgraph()->graph();
+}
+
+
+Isolate* JSNativeContextSpecialization::isolate() const {
+  return jsgraph()->isolate();
+}
+
+
+Factory* JSNativeContextSpecialization::factory() const {
+  return isolate()->factory();
+}
+
+
+MachineOperatorBuilder* JSNativeContextSpecialization::machine() const {
+  return jsgraph()->machine();
+}
+
+
+CommonOperatorBuilder* JSNativeContextSpecialization::common() const {
+  return jsgraph()->common();
+}
+
+
+JSOperatorBuilder* JSNativeContextSpecialization::javascript() const {
+  return jsgraph()->javascript();
+}
+
+
+SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const {
+  return jsgraph()->simplified();
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/js-native-context-specialization.h b/src/compiler/js-native-context-specialization.h
new file mode 100644
index 0000000..45ff87f
--- /dev/null
+++ b/src/compiler/js-native-context-specialization.h
@@ -0,0 +1,116 @@
+// Copyright 2015 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.
+
+#ifndef V8_COMPILER_JS_NATIVE_CONTEXT_SPECIALIZATION_H_
+#define V8_COMPILER_JS_NATIVE_CONTEXT_SPECIALIZATION_H_
+
+#include "src/base/flags.h"
+#include "src/compiler/graph-reducer.h"
+
+namespace v8 {
+namespace internal {
+
+// Forward declarations.
+class CompilationDependencies;
+class Factory;
+class FeedbackNexus;
+class TypeCache;
+
+
+namespace compiler {
+
+// Forward declarations.
+enum class AccessMode;
+class CommonOperatorBuilder;
+class JSGraph;
+class JSOperatorBuilder;
+class MachineOperatorBuilder;
+class SimplifiedOperatorBuilder;
+
+
+// Specializes a given JSGraph to a given native context, potentially constant
+// folding some {LoadGlobal} nodes or strength reducing some {StoreGlobal}
+// nodes.  And also specializes {LoadNamed} and {StoreNamed} nodes according
+// to type feedback (if available).
+class JSNativeContextSpecialization final : public AdvancedReducer {
+ public:
+  // Flags that control the mode of operation.
+  enum Flag {
+    kNoFlags = 0u,
+    kDeoptimizationEnabled = 1u << 0,
+  };
+  typedef base::Flags<Flag> Flags;
+
+  JSNativeContextSpecialization(Editor* editor, JSGraph* jsgraph, Flags flags,
+                                MaybeHandle<Context> native_context,
+                                CompilationDependencies* dependencies,
+                                Zone* zone);
+
+  Reduction Reduce(Node* node) final;
+
+ private:
+  Reduction ReduceJSLoadNamed(Node* node);
+  Reduction ReduceJSStoreNamed(Node* node);
+  Reduction ReduceJSLoadProperty(Node* node);
+  Reduction ReduceJSStoreProperty(Node* node);
+
+  Reduction ReduceElementAccess(Node* node, Node* index, Node* value,
+                                MapHandleList const& receiver_maps,
+                                AccessMode access_mode,
+                                LanguageMode language_mode,
+                                KeyedAccessStoreMode store_mode);
+  Reduction ReduceKeyedAccess(Node* node, Node* index, Node* value,
+                              FeedbackNexus const& nexus,
+                              AccessMode access_mode,
+                              LanguageMode language_mode,
+                              KeyedAccessStoreMode store_mode);
+  Reduction ReduceNamedAccess(Node* node, Node* value,
+                              MapHandleList const& receiver_maps,
+                              Handle<Name> name, AccessMode access_mode,
+                              LanguageMode language_mode,
+                              Node* index = nullptr);
+
+  // Adds stability dependencies on all prototypes of every class in
+  // {receiver_type} up to (and including) the {holder}.
+  void AssumePrototypesStable(Type* receiver_type,
+                              Handle<Context> native_context,
+                              Handle<JSObject> holder);
+
+  // Assuming that {if_projection} is either IfTrue or IfFalse, adds a hint on
+  // the dominating Branch that {if_projection} is the unlikely (deferred) case.
+  void MarkAsDeferred(Node* if_projection);
+
+  // Retrieve the native context from the given {node} if known.
+  MaybeHandle<Context> GetNativeContext(Node* node);
+
+  Graph* graph() const;
+  JSGraph* jsgraph() const { return jsgraph_; }
+  Isolate* isolate() const;
+  Factory* factory() const;
+  CommonOperatorBuilder* common() const;
+  JSOperatorBuilder* javascript() const;
+  SimplifiedOperatorBuilder* simplified() const;
+  MachineOperatorBuilder* machine() const;
+  Flags flags() const { return flags_; }
+  MaybeHandle<Context> native_context() const { return native_context_; }
+  CompilationDependencies* dependencies() const { return dependencies_; }
+  Zone* zone() const { return zone_; }
+
+  JSGraph* const jsgraph_;
+  Flags const flags_;
+  MaybeHandle<Context> native_context_;
+  CompilationDependencies* const dependencies_;
+  Zone* const zone_;
+  TypeCache const& type_cache_;
+
+  DISALLOW_COPY_AND_ASSIGN(JSNativeContextSpecialization);
+};
+
+DEFINE_OPERATORS_FOR_FLAGS(JSNativeContextSpecialization::Flags)
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_JS_NATIVE_CONTEXT_SPECIALIZATION_H_
diff --git a/src/compiler/js-operator.cc b/src/compiler/js-operator.cc
index aa76a3b..1455f0a 100644
--- a/src/compiler/js-operator.cc
+++ b/src/compiler/js-operator.cc
@@ -9,30 +9,138 @@
 #include "src/base/lazy-instance.h"
 #include "src/compiler/opcodes.h"
 #include "src/compiler/operator.h"
+#include "src/objects-inl.h"  // TODO(mstarzinger): Temporary cycle breaker!
+#include "src/type-feedback-vector-inl.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
-bool operator==(CallFunctionParameters const& lhs,
-                CallFunctionParameters const& rhs) {
-  return lhs.arity() == rhs.arity() && lhs.flags() == rhs.flags();
+VectorSlotPair::VectorSlotPair() {}
+
+
+int VectorSlotPair::index() const {
+  return vector_.is_null() ? -1 : vector_->GetIndex(slot_);
 }
 
 
-bool operator!=(CallFunctionParameters const& lhs,
-                CallFunctionParameters const& rhs) {
+bool operator==(VectorSlotPair const& lhs, VectorSlotPair const& rhs) {
+  return lhs.slot() == rhs.slot() &&
+         lhs.vector().location() == rhs.vector().location();
+}
+
+
+bool operator!=(VectorSlotPair const& lhs, VectorSlotPair const& rhs) {
   return !(lhs == rhs);
 }
 
 
-size_t hash_value(CallFunctionParameters const& p) {
-  return base::hash_combine(p.arity(), p.flags());
+size_t hash_value(VectorSlotPair const& p) {
+  return base::hash_combine(p.slot(), p.vector().location());
+}
+
+
+ConvertReceiverMode ConvertReceiverModeOf(Operator const* op) {
+  DCHECK_EQ(IrOpcode::kJSConvertReceiver, op->opcode());
+  return OpParameter<ConvertReceiverMode>(op);
+}
+
+
+ToBooleanHints ToBooleanHintsOf(Operator const* op) {
+  DCHECK_EQ(IrOpcode::kJSToBoolean, op->opcode());
+  return OpParameter<ToBooleanHints>(op);
+}
+
+
+size_t hash_value(TailCallMode mode) {
+  return base::hash_value(static_cast<unsigned>(mode));
+}
+
+
+std::ostream& operator<<(std::ostream& os, TailCallMode mode) {
+  switch (mode) {
+    case TailCallMode::kAllow:
+      return os << "ALLOW_TAIL_CALLS";
+    case TailCallMode::kDisallow:
+      return os << "DISALLOW_TAIL_CALLS";
+  }
+  UNREACHABLE();
+  return os;
+}
+
+
+bool operator==(BinaryOperationParameters const& lhs,
+                BinaryOperationParameters const& rhs) {
+  return lhs.language_mode() == rhs.language_mode() &&
+         lhs.hints() == rhs.hints();
+}
+
+
+bool operator!=(BinaryOperationParameters const& lhs,
+                BinaryOperationParameters const& rhs) {
+  return !(lhs == rhs);
+}
+
+
+size_t hash_value(BinaryOperationParameters const& p) {
+  return base::hash_combine(p.language_mode(), p.hints());
+}
+
+
+std::ostream& operator<<(std::ostream& os, BinaryOperationParameters const& p) {
+  return os << p.language_mode() << ", " << p.hints();
+}
+
+
+BinaryOperationParameters const& BinaryOperationParametersOf(
+    Operator const* op) {
+  DCHECK(op->opcode() == IrOpcode::kJSBitwiseOr ||
+         op->opcode() == IrOpcode::kJSBitwiseXor ||
+         op->opcode() == IrOpcode::kJSBitwiseAnd ||
+         op->opcode() == IrOpcode::kJSShiftLeft ||
+         op->opcode() == IrOpcode::kJSShiftRight ||
+         op->opcode() == IrOpcode::kJSShiftRightLogical ||
+         op->opcode() == IrOpcode::kJSAdd ||
+         op->opcode() == IrOpcode::kJSSubtract ||
+         op->opcode() == IrOpcode::kJSMultiply ||
+         op->opcode() == IrOpcode::kJSDivide ||
+         op->opcode() == IrOpcode::kJSModulus);
+  return OpParameter<BinaryOperationParameters>(op);
+}
+
+
+bool operator==(CallConstructParameters const& lhs,
+                CallConstructParameters const& rhs) {
+  return lhs.arity() == rhs.arity() && lhs.feedback() == rhs.feedback();
+}
+
+
+bool operator!=(CallConstructParameters const& lhs,
+                CallConstructParameters const& rhs) {
+  return !(lhs == rhs);
+}
+
+
+size_t hash_value(CallConstructParameters const& p) {
+  return base::hash_combine(p.arity(), p.feedback());
+}
+
+
+std::ostream& operator<<(std::ostream& os, CallConstructParameters const& p) {
+  return os << p.arity();
+}
+
+
+CallConstructParameters const& CallConstructParametersOf(Operator const* op) {
+  DCHECK_EQ(IrOpcode::kJSCallConstruct, op->opcode());
+  return OpParameter<CallConstructParameters>(op);
 }
 
 
 std::ostream& operator<<(std::ostream& os, CallFunctionParameters const& p) {
-  return os << p.arity() << ", " << p.flags();
+  os << p.arity() << ", " << p.language_mode() << ", " << p.convert_mode()
+     << ", " << p.tail_call_mode();
+  return os;
 }
 
 
@@ -108,167 +216,342 @@
 }
 
 
-bool operator==(VectorSlotPair const& lhs, VectorSlotPair const& rhs) {
-  return lhs.slot().ToInt() == rhs.slot().ToInt() &&
-         lhs.vector().is_identical_to(rhs.vector());
+DynamicAccess::DynamicAccess(const Handle<String>& name, TypeofMode typeof_mode)
+    : name_(name), typeof_mode_(typeof_mode) {}
+
+
+bool operator==(DynamicAccess const& lhs, DynamicAccess const& rhs) {
+  UNIMPLEMENTED();
+  return true;
 }
 
 
-size_t hash_value(VectorSlotPair const& p) {
-  // TODO(mvstanton): include the vector in the hash.
-  base::hash<int> h;
-  return h(p.slot().ToInt());
+bool operator!=(DynamicAccess const& lhs, DynamicAccess const& rhs) {
+  return !(lhs == rhs);
 }
 
 
-bool operator==(LoadNamedParameters const& lhs,
-                LoadNamedParameters const& rhs) {
-  return lhs.name() == rhs.name() &&
-         lhs.contextual_mode() == rhs.contextual_mode() &&
+size_t hash_value(DynamicAccess const& access) {
+  UNIMPLEMENTED();
+  return 0;
+}
+
+
+std::ostream& operator<<(std::ostream& os, DynamicAccess const& access) {
+  return os << Brief(*access.name()) << ", " << access.typeof_mode();
+}
+
+
+DynamicAccess const& DynamicAccessOf(Operator const* op) {
+  DCHECK_EQ(IrOpcode::kJSLoadDynamic, op->opcode());
+  return OpParameter<DynamicAccess>(op);
+}
+
+
+bool operator==(NamedAccess const& lhs, NamedAccess const& rhs) {
+  return lhs.name().location() == rhs.name().location() &&
+         lhs.language_mode() == rhs.language_mode() &&
          lhs.feedback() == rhs.feedback();
 }
 
 
-bool operator!=(LoadNamedParameters const& lhs,
-                LoadNamedParameters const& rhs) {
+bool operator!=(NamedAccess const& lhs, NamedAccess const& rhs) {
   return !(lhs == rhs);
 }
 
 
-size_t hash_value(LoadNamedParameters const& p) {
-  return base::hash_combine(p.name(), p.contextual_mode(), p.feedback());
+size_t hash_value(NamedAccess const& p) {
+  return base::hash_combine(p.name().location(), p.language_mode(),
+                            p.feedback());
 }
 
 
-std::ostream& operator<<(std::ostream& os, LoadNamedParameters const& p) {
-  return os << Brief(*p.name().handle()) << ", " << p.contextual_mode();
+std::ostream& operator<<(std::ostream& os, NamedAccess const& p) {
+  return os << Brief(*p.name()) << ", " << p.language_mode();
 }
 
 
-std::ostream& operator<<(std::ostream& os, LoadPropertyParameters const& p) {
-  // Nothing special to print.
+NamedAccess const& NamedAccessOf(const Operator* op) {
+  DCHECK(op->opcode() == IrOpcode::kJSLoadNamed ||
+         op->opcode() == IrOpcode::kJSStoreNamed);
+  return OpParameter<NamedAccess>(op);
+}
+
+
+std::ostream& operator<<(std::ostream& os, PropertyAccess const& p) {
+  return os << p.language_mode();
+}
+
+
+bool operator==(PropertyAccess const& lhs, PropertyAccess const& rhs) {
+  return lhs.language_mode() == rhs.language_mode() &&
+         lhs.feedback() == rhs.feedback();
+}
+
+
+bool operator!=(PropertyAccess const& lhs, PropertyAccess const& rhs) {
+  return !(lhs == rhs);
+}
+
+
+PropertyAccess const& PropertyAccessOf(const Operator* op) {
+  DCHECK(op->opcode() == IrOpcode::kJSLoadProperty ||
+         op->opcode() == IrOpcode::kJSStoreProperty);
+  return OpParameter<PropertyAccess>(op);
+}
+
+
+size_t hash_value(PropertyAccess const& p) {
+  return base::hash_combine(p.language_mode(), p.feedback());
+}
+
+
+bool operator==(LoadGlobalParameters const& lhs,
+                LoadGlobalParameters const& rhs) {
+  return lhs.name().location() == rhs.name().location() &&
+         lhs.feedback() == rhs.feedback() &&
+         lhs.typeof_mode() == rhs.typeof_mode();
+}
+
+
+bool operator!=(LoadGlobalParameters const& lhs,
+                LoadGlobalParameters const& rhs) {
+  return !(lhs == rhs);
+}
+
+
+size_t hash_value(LoadGlobalParameters const& p) {
+  return base::hash_combine(p.name().location(), p.typeof_mode());
+}
+
+
+std::ostream& operator<<(std::ostream& os, LoadGlobalParameters const& p) {
+  return os << Brief(*p.name()) << ", " << p.typeof_mode();
+}
+
+
+const LoadGlobalParameters& LoadGlobalParametersOf(const Operator* op) {
+  DCHECK_EQ(IrOpcode::kJSLoadGlobal, op->opcode());
+  return OpParameter<LoadGlobalParameters>(op);
+}
+
+
+bool operator==(StoreGlobalParameters const& lhs,
+                StoreGlobalParameters const& rhs) {
+  return lhs.language_mode() == rhs.language_mode() &&
+         lhs.name().location() == rhs.name().location() &&
+         lhs.feedback() == rhs.feedback();
+}
+
+
+bool operator!=(StoreGlobalParameters const& lhs,
+                StoreGlobalParameters const& rhs) {
+  return !(lhs == rhs);
+}
+
+
+size_t hash_value(StoreGlobalParameters const& p) {
+  return base::hash_combine(p.language_mode(), p.name().location(),
+                            p.feedback());
+}
+
+
+std::ostream& operator<<(std::ostream& os, StoreGlobalParameters const& p) {
+  return os << p.language_mode() << ", " << Brief(*p.name());
+}
+
+
+const StoreGlobalParameters& StoreGlobalParametersOf(const Operator* op) {
+  DCHECK_EQ(IrOpcode::kJSStoreGlobal, op->opcode());
+  return OpParameter<StoreGlobalParameters>(op);
+}
+
+
+bool operator==(CreateArgumentsParameters const& lhs,
+                CreateArgumentsParameters const& rhs) {
+  return lhs.type() == rhs.type() && lhs.start_index() == rhs.start_index();
+}
+
+
+bool operator!=(CreateArgumentsParameters const& lhs,
+                CreateArgumentsParameters const& rhs) {
+  return !(lhs == rhs);
+}
+
+
+size_t hash_value(CreateArgumentsParameters const& p) {
+  return base::hash_combine(p.type(), p.start_index());
+}
+
+
+std::ostream& operator<<(std::ostream& os, CreateArgumentsParameters const& p) {
+  return os << p.type() << ", " << p.start_index();
+}
+
+
+const CreateArgumentsParameters& CreateArgumentsParametersOf(
+    const Operator* op) {
+  DCHECK_EQ(IrOpcode::kJSCreateArguments, op->opcode());
+  return OpParameter<CreateArgumentsParameters>(op);
+}
+
+
+bool operator==(CreateArrayParameters const& lhs,
+                CreateArrayParameters const& rhs) {
+  return lhs.arity() == rhs.arity() &&
+         lhs.site().location() == rhs.site().location();
+}
+
+
+bool operator!=(CreateArrayParameters const& lhs,
+                CreateArrayParameters const& rhs) {
+  return !(lhs == rhs);
+}
+
+
+size_t hash_value(CreateArrayParameters const& p) {
+  return base::hash_combine(p.arity(), p.site().location());
+}
+
+
+std::ostream& operator<<(std::ostream& os, CreateArrayParameters const& p) {
+  os << p.arity();
+  if (!p.site().is_null()) os << ", " << Brief(*p.site());
   return os;
 }
 
 
-bool operator==(LoadPropertyParameters const& lhs,
-                LoadPropertyParameters const& rhs) {
-  return lhs.feedback() == rhs.feedback();
+const CreateArrayParameters& CreateArrayParametersOf(const Operator* op) {
+  DCHECK_EQ(IrOpcode::kJSCreateArray, op->opcode());
+  return OpParameter<CreateArrayParameters>(op);
 }
 
 
-bool operator!=(LoadPropertyParameters const& lhs,
-                LoadPropertyParameters const& rhs) {
+bool operator==(CreateClosureParameters const& lhs,
+                CreateClosureParameters const& rhs) {
+  return lhs.pretenure() == rhs.pretenure() &&
+         lhs.shared_info().location() == rhs.shared_info().location();
+}
+
+
+bool operator!=(CreateClosureParameters const& lhs,
+                CreateClosureParameters const& rhs) {
   return !(lhs == rhs);
 }
 
 
-const LoadPropertyParameters& LoadPropertyParametersOf(const Operator* op) {
-  DCHECK_EQ(IrOpcode::kJSLoadProperty, op->opcode());
-  return OpParameter<LoadPropertyParameters>(op);
+size_t hash_value(CreateClosureParameters const& p) {
+  return base::hash_combine(p.pretenure(), p.shared_info().location());
 }
 
 
-size_t hash_value(LoadPropertyParameters const& p) {
-  return hash_value(p.feedback());
+std::ostream& operator<<(std::ostream& os, CreateClosureParameters const& p) {
+  return os << p.pretenure() << ", " << Brief(*p.shared_info());
 }
 
 
-const LoadNamedParameters& LoadNamedParametersOf(const Operator* op) {
-  DCHECK_EQ(IrOpcode::kJSLoadNamed, op->opcode());
-  return OpParameter<LoadNamedParameters>(op);
+const CreateClosureParameters& CreateClosureParametersOf(const Operator* op) {
+  DCHECK_EQ(IrOpcode::kJSCreateClosure, op->opcode());
+  return OpParameter<CreateClosureParameters>(op);
 }
 
 
-bool operator==(StoreNamedParameters const& lhs,
-                StoreNamedParameters const& rhs) {
-  return lhs.strict_mode() == rhs.strict_mode() && lhs.name() == rhs.name();
+bool operator==(CreateLiteralParameters const& lhs,
+                CreateLiteralParameters const& rhs) {
+  return lhs.constant().location() == rhs.constant().location() &&
+         lhs.flags() == rhs.flags() && lhs.index() == rhs.index();
 }
 
 
-bool operator!=(StoreNamedParameters const& lhs,
-                StoreNamedParameters const& rhs) {
+bool operator!=(CreateLiteralParameters const& lhs,
+                CreateLiteralParameters const& rhs) {
   return !(lhs == rhs);
 }
 
 
-size_t hash_value(StoreNamedParameters const& p) {
-  return base::hash_combine(p.strict_mode(), p.name());
+size_t hash_value(CreateLiteralParameters const& p) {
+  return base::hash_combine(p.constant().location(), p.flags(), p.index());
 }
 
 
-std::ostream& operator<<(std::ostream& os, StoreNamedParameters const& p) {
-  return os << p.strict_mode() << ", " << Brief(*p.name().handle());
+std::ostream& operator<<(std::ostream& os, CreateLiteralParameters const& p) {
+  return os << Brief(*p.constant()) << ", " << p.flags() << ", " << p.index();
 }
 
 
-const StoreNamedParameters& StoreNamedParametersOf(const Operator* op) {
-  DCHECK_EQ(IrOpcode::kJSStoreNamed, op->opcode());
-  return OpParameter<StoreNamedParameters>(op);
+const CreateLiteralParameters& CreateLiteralParametersOf(const Operator* op) {
+  DCHECK(op->opcode() == IrOpcode::kJSCreateLiteralArray ||
+         op->opcode() == IrOpcode::kJSCreateLiteralObject ||
+         op->opcode() == IrOpcode::kJSCreateLiteralRegExp);
+  return OpParameter<CreateLiteralParameters>(op);
 }
 
 
-#define CACHED_OP_LIST(V)                                 \
-  V(Equal, Operator::kNoProperties, 2, 1)                 \
-  V(NotEqual, Operator::kNoProperties, 2, 1)              \
-  V(StrictEqual, Operator::kPure, 2, 1)                   \
-  V(StrictNotEqual, Operator::kPure, 2, 1)                \
-  V(LessThan, Operator::kNoProperties, 2, 1)              \
-  V(GreaterThan, Operator::kNoProperties, 2, 1)           \
-  V(LessThanOrEqual, Operator::kNoProperties, 2, 1)       \
-  V(GreaterThanOrEqual, Operator::kNoProperties, 2, 1)    \
-  V(BitwiseOr, Operator::kNoProperties, 2, 1)             \
-  V(BitwiseXor, Operator::kNoProperties, 2, 1)            \
-  V(BitwiseAnd, Operator::kNoProperties, 2, 1)            \
-  V(ShiftLeft, Operator::kNoProperties, 2, 1)             \
-  V(ShiftRight, Operator::kNoProperties, 2, 1)            \
-  V(ShiftRightLogical, Operator::kNoProperties, 2, 1)     \
-  V(Add, Operator::kNoProperties, 2, 1)                   \
-  V(Subtract, Operator::kNoProperties, 2, 1)              \
-  V(Multiply, Operator::kNoProperties, 2, 1)              \
-  V(Divide, Operator::kNoProperties, 2, 1)                \
-  V(Modulus, Operator::kNoProperties, 2, 1)               \
-  V(UnaryNot, Operator::kPure, 1, 1)                      \
-  V(ToBoolean, Operator::kPure, 1, 1)                     \
-  V(ToNumber, Operator::kNoProperties, 1, 1)              \
-  V(ToString, Operator::kNoProperties, 1, 1)              \
-  V(ToName, Operator::kNoProperties, 1, 1)                \
-  V(ToObject, Operator::kNoProperties, 1, 1)              \
-  V(Yield, Operator::kNoProperties, 1, 1)                 \
-  V(Create, Operator::kEliminatable, 0, 1)                \
-  V(HasProperty, Operator::kNoProperties, 2, 1)           \
-  V(TypeOf, Operator::kPure, 1, 1)                        \
-  V(InstanceOf, Operator::kNoProperties, 2, 1)            \
-  V(Debugger, Operator::kNoProperties, 0, 0)              \
-  V(CreateFunctionContext, Operator::kNoProperties, 1, 1) \
-  V(CreateWithContext, Operator::kNoProperties, 2, 1)     \
-  V(CreateBlockContext, Operator::kNoProperties, 2, 1)    \
-  V(CreateModuleContext, Operator::kNoProperties, 2, 1)   \
-  V(CreateScriptContext, Operator::kNoProperties, 2, 1)
+#define CACHED_OP_LIST(V)                                  \
+  V(Equal, Operator::kNoProperties, 2, 1)                  \
+  V(NotEqual, Operator::kNoProperties, 2, 1)               \
+  V(StrictEqual, Operator::kNoThrow, 2, 1)                 \
+  V(StrictNotEqual, Operator::kNoThrow, 2, 1)              \
+  V(ToNumber, Operator::kNoProperties, 1, 1)               \
+  V(ToString, Operator::kNoProperties, 1, 1)               \
+  V(ToName, Operator::kNoProperties, 1, 1)                 \
+  V(ToObject, Operator::kNoProperties, 1, 1)               \
+  V(Yield, Operator::kNoProperties, 1, 1)                  \
+  V(Create, Operator::kEliminatable, 2, 1)                 \
+  V(CreateIterResultObject, Operator::kEliminatable, 2, 1) \
+  V(HasProperty, Operator::kNoProperties, 2, 1)            \
+  V(TypeOf, Operator::kEliminatable, 1, 1)                 \
+  V(InstanceOf, Operator::kNoProperties, 2, 1)             \
+  V(ForInDone, Operator::kPure, 2, 1)                      \
+  V(ForInNext, Operator::kNoProperties, 4, 1)              \
+  V(ForInPrepare, Operator::kNoProperties, 1, 3)           \
+  V(ForInStep, Operator::kPure, 1, 1)                      \
+  V(LoadMessage, Operator::kNoThrow, 0, 1)                 \
+  V(StoreMessage, Operator::kNoThrow, 1, 0)                \
+  V(StackCheck, Operator::kNoProperties, 0, 0)             \
+  V(CreateWithContext, Operator::kNoProperties, 2, 1)      \
+  V(CreateModuleContext, Operator::kNoProperties, 2, 1)
 
 
-struct JSOperatorGlobalCache FINAL {
+#define CACHED_OP_LIST_WITH_LANGUAGE_MODE(V)        \
+  V(LessThan, Operator::kNoProperties, 2, 1)        \
+  V(GreaterThan, Operator::kNoProperties, 2, 1)     \
+  V(LessThanOrEqual, Operator::kNoProperties, 2, 1) \
+  V(GreaterThanOrEqual, Operator::kNoProperties, 2, 1)
+
+
+struct JSOperatorGlobalCache final {
 #define CACHED(Name, properties, value_input_count, value_output_count)  \
-  struct Name##Operator FINAL : public Operator {                        \
+  struct Name##Operator final : public Operator {                        \
     Name##Operator()                                                     \
         : Operator(IrOpcode::kJS##Name, properties, "JS" #Name,          \
                    value_input_count, Operator::ZeroIfPure(properties),  \
-                   Operator::ZeroIfPure(properties), value_output_count, \
-                   Operator::ZeroIfPure(properties), 0) {}               \
+                   Operator::ZeroIfEliminatable(properties),             \
+                   value_output_count, Operator::ZeroIfPure(properties), \
+                   Operator::ZeroIfNoThrow(properties)) {}               \
   };                                                                     \
   Name##Operator k##Name##Operator;
   CACHED_OP_LIST(CACHED)
 #undef CACHED
 
-  template <StrictMode kStrictMode>
-  struct StorePropertyOperator FINAL : public Operator1<StrictMode> {
-    StorePropertyOperator()
-        : Operator1<StrictMode>(IrOpcode::kJSStoreProperty,
-                                Operator::kNoProperties, "JSStoreProperty", 3,
-                                1, 1, 0, 1, 0, kStrictMode) {}
-  };
-  StorePropertyOperator<SLOPPY> kStorePropertySloppyOperator;
-  StorePropertyOperator<STRICT> kStorePropertyStrictOperator;
+
+#define CACHED_WITH_LANGUAGE_MODE(Name, properties, value_input_count,        \
+                                  value_output_count)                         \
+  template <LanguageMode kLanguageMode>                                       \
+  struct Name##Operator final : public Operator1<LanguageMode> {              \
+    Name##Operator()                                                          \
+        : Operator1<LanguageMode>(                                            \
+              IrOpcode::kJS##Name, properties, "JS" #Name, value_input_count, \
+              Operator::ZeroIfPure(properties),                               \
+              Operator::ZeroIfEliminatable(properties), value_output_count,   \
+              Operator::ZeroIfPure(properties),                               \
+              Operator::ZeroIfNoThrow(properties), kLanguageMode) {}          \
+  };                                                                          \
+  Name##Operator<SLOPPY> k##Name##SloppyOperator;                             \
+  Name##Operator<STRICT> k##Name##StrictOperator;                             \
+  Name##Operator<STRONG> k##Name##StrongOperator;
+  CACHED_OP_LIST_WITH_LANGUAGE_MODE(CACHED_WITH_LANGUAGE_MODE)
+#undef CACHED_WITH_LANGUAGE_MODE
 };
 
 
@@ -288,13 +571,177 @@
 #undef CACHED
 
 
-const Operator* JSOperatorBuilder::CallFunction(size_t arity,
-                                                CallFunctionFlags flags) {
-  CallFunctionParameters parameters(arity, flags);
+#define CACHED_WITH_LANGUAGE_MODE(Name, properties, value_input_count,  \
+                                  value_output_count)                   \
+  const Operator* JSOperatorBuilder::Name(LanguageMode language_mode) { \
+    switch (language_mode) {                                            \
+      case SLOPPY:                                                      \
+        return &cache_.k##Name##SloppyOperator;                         \
+      case STRICT:                                                      \
+        return &cache_.k##Name##StrictOperator;                         \
+      case STRONG:                                                      \
+        return &cache_.k##Name##StrongOperator;                         \
+      default:                                                          \
+        break; /* %*!%^$#@ */                                           \
+    }                                                                   \
+    UNREACHABLE();                                                      \
+    return nullptr;                                                     \
+  }
+CACHED_OP_LIST_WITH_LANGUAGE_MODE(CACHED_WITH_LANGUAGE_MODE)
+#undef CACHED_WITH_LANGUAGE_MODE
+
+
+const Operator* JSOperatorBuilder::BitwiseOr(LanguageMode language_mode,
+                                             BinaryOperationHints hints) {
+  // TODO(turbofan): Cache most important versions of this operator.
+  BinaryOperationParameters parameters(language_mode, hints);
+  return new (zone()) Operator1<BinaryOperationParameters>(  //--
+      IrOpcode::kJSBitwiseOr, Operator::kNoProperties,       // opcode
+      "JSBitwiseOr",                                         // name
+      2, 1, 1, 1, 1, 2,                                      // inputs/outputs
+      parameters);                                           // parameter
+}
+
+
+const Operator* JSOperatorBuilder::BitwiseXor(LanguageMode language_mode,
+                                              BinaryOperationHints hints) {
+  // TODO(turbofan): Cache most important versions of this operator.
+  BinaryOperationParameters parameters(language_mode, hints);
+  return new (zone()) Operator1<BinaryOperationParameters>(  //--
+      IrOpcode::kJSBitwiseXor, Operator::kNoProperties,      // opcode
+      "JSBitwiseXor",                                        // name
+      2, 1, 1, 1, 1, 2,                                      // inputs/outputs
+      parameters);                                           // parameter
+}
+
+
+const Operator* JSOperatorBuilder::BitwiseAnd(LanguageMode language_mode,
+                                              BinaryOperationHints hints) {
+  // TODO(turbofan): Cache most important versions of this operator.
+  BinaryOperationParameters parameters(language_mode, hints);
+  return new (zone()) Operator1<BinaryOperationParameters>(  //--
+      IrOpcode::kJSBitwiseAnd, Operator::kNoProperties,      // opcode
+      "JSBitwiseAnd",                                        // name
+      2, 1, 1, 1, 1, 2,                                      // inputs/outputs
+      parameters);                                           // parameter
+}
+
+
+const Operator* JSOperatorBuilder::ShiftLeft(LanguageMode language_mode,
+                                             BinaryOperationHints hints) {
+  // TODO(turbofan): Cache most important versions of this operator.
+  BinaryOperationParameters parameters(language_mode, hints);
+  return new (zone()) Operator1<BinaryOperationParameters>(  //--
+      IrOpcode::kJSShiftLeft, Operator::kNoProperties,       // opcode
+      "JSShiftLeft",                                         // name
+      2, 1, 1, 1, 1, 2,                                      // inputs/outputs
+      parameters);                                           // parameter
+}
+
+
+const Operator* JSOperatorBuilder::ShiftRight(LanguageMode language_mode,
+                                              BinaryOperationHints hints) {
+  // TODO(turbofan): Cache most important versions of this operator.
+  BinaryOperationParameters parameters(language_mode, hints);
+  return new (zone()) Operator1<BinaryOperationParameters>(  //--
+      IrOpcode::kJSShiftRight, Operator::kNoProperties,      // opcode
+      "JSShiftRight",                                        // name
+      2, 1, 1, 1, 1, 2,                                      // inputs/outputs
+      parameters);                                           // parameter
+}
+
+
+const Operator* JSOperatorBuilder::ShiftRightLogical(
+    LanguageMode language_mode, BinaryOperationHints hints) {
+  // TODO(turbofan): Cache most important versions of this operator.
+  BinaryOperationParameters parameters(language_mode, hints);
+  return new (zone()) Operator1<BinaryOperationParameters>(     //--
+      IrOpcode::kJSShiftRightLogical, Operator::kNoProperties,  // opcode
+      "JSShiftRightLogical",                                    // name
+      2, 1, 1, 1, 1, 2,  // inputs/outputs
+      parameters);       // parameter
+}
+
+
+const Operator* JSOperatorBuilder::Add(LanguageMode language_mode,
+                                       BinaryOperationHints hints) {
+  // TODO(turbofan): Cache most important versions of this operator.
+  BinaryOperationParameters parameters(language_mode, hints);
+  return new (zone()) Operator1<BinaryOperationParameters>(  //--
+      IrOpcode::kJSAdd, Operator::kNoProperties,             // opcode
+      "JSAdd",                                               // name
+      2, 1, 1, 1, 1, 2,                                      // inputs/outputs
+      parameters);                                           // parameter
+}
+
+
+const Operator* JSOperatorBuilder::Subtract(LanguageMode language_mode,
+                                            BinaryOperationHints hints) {
+  // TODO(turbofan): Cache most important versions of this operator.
+  BinaryOperationParameters parameters(language_mode, hints);
+  return new (zone()) Operator1<BinaryOperationParameters>(  //--
+      IrOpcode::kJSSubtract, Operator::kNoProperties,        // opcode
+      "JSSubtract",                                          // name
+      2, 1, 1, 1, 1, 2,                                      // inputs/outputs
+      parameters);                                           // parameter
+}
+
+
+const Operator* JSOperatorBuilder::Multiply(LanguageMode language_mode,
+                                            BinaryOperationHints hints) {
+  // TODO(turbofan): Cache most important versions of this operator.
+  BinaryOperationParameters parameters(language_mode, hints);
+  return new (zone()) Operator1<BinaryOperationParameters>(  //--
+      IrOpcode::kJSMultiply, Operator::kNoProperties,        // opcode
+      "JSMultiply",                                          // name
+      2, 1, 1, 1, 1, 2,                                      // inputs/outputs
+      parameters);                                           // parameter
+}
+
+
+const Operator* JSOperatorBuilder::Divide(LanguageMode language_mode,
+                                          BinaryOperationHints hints) {
+  // TODO(turbofan): Cache most important versions of this operator.
+  BinaryOperationParameters parameters(language_mode, hints);
+  return new (zone()) Operator1<BinaryOperationParameters>(  //--
+      IrOpcode::kJSDivide, Operator::kNoProperties,          // opcode
+      "JSDivide",                                            // name
+      2, 1, 1, 1, 1, 2,                                      // inputs/outputs
+      parameters);                                           // parameter
+}
+
+
+const Operator* JSOperatorBuilder::Modulus(LanguageMode language_mode,
+                                           BinaryOperationHints hints) {
+  // TODO(turbofan): Cache most important versions of this operator.
+  BinaryOperationParameters parameters(language_mode, hints);
+  return new (zone()) Operator1<BinaryOperationParameters>(  //--
+      IrOpcode::kJSModulus, Operator::kNoProperties,         // opcode
+      "JSModulus",                                           // name
+      2, 1, 1, 1, 1, 2,                                      // inputs/outputs
+      parameters);                                           // parameter
+}
+
+
+const Operator* JSOperatorBuilder::ToBoolean(ToBooleanHints hints) {
+  // TODO(turbofan): Cache most important versions of this operator.
+  return new (zone()) Operator1<ToBooleanHints>(        //--
+      IrOpcode::kJSToBoolean, Operator::kEliminatable,  // opcode
+      "JSToBoolean",                                    // name
+      1, 1, 0, 1, 1, 0,                                 // inputs/outputs
+      hints);                                           // parameter
+}
+
+
+const Operator* JSOperatorBuilder::CallFunction(
+    size_t arity, LanguageMode language_mode, VectorSlotPair const& feedback,
+    ConvertReceiverMode convert_mode, TailCallMode tail_call_mode) {
+  CallFunctionParameters parameters(arity, language_mode, feedback,
+                                    tail_call_mode, convert_mode);
   return new (zone()) Operator1<CallFunctionParameters>(   // --
       IrOpcode::kJSCallFunction, Operator::kNoProperties,  // opcode
       "JSCallFunction",                                    // name
-      parameters.arity(), 1, 1, 1, 1, 0,                   // inputs/outputs
+      parameters.arity(), 1, 1, 1, 1, 2,                   // inputs/outputs
       parameters);                                         // parameter
 }
 
@@ -307,105 +754,257 @@
   return new (zone()) Operator1<CallRuntimeParameters>(   // --
       IrOpcode::kJSCallRuntime, Operator::kNoProperties,  // opcode
       "JSCallRuntime",                                    // name
-      parameters.arity(), 1, 1, f->result_size, 1, 0,     // inputs/outputs
+      parameters.arity(), 1, 1, f->result_size, 1, 2,     // inputs/outputs
       parameters);                                        // parameter
 }
 
 
-const Operator* JSOperatorBuilder::CallConstruct(int arguments) {
-  return new (zone()) Operator1<int>(                       // --
+const Operator* JSOperatorBuilder::CallConstruct(
+    size_t arity, VectorSlotPair const& feedback) {
+  CallConstructParameters parameters(arity, feedback);
+  return new (zone()) Operator1<CallConstructParameters>(   // --
       IrOpcode::kJSCallConstruct, Operator::kNoProperties,  // opcode
       "JSCallConstruct",                                    // name
-      arguments, 1, 1, 1, 1, 0,                             // counts
-      arguments);                                           // parameter
+      parameters.arity(), 1, 1, 1, 1, 2,                    // counts
+      parameters);                                          // parameter
 }
 
 
-const Operator* JSOperatorBuilder::LoadNamed(const Unique<Name>& name,
-                                             const VectorSlotPair& feedback,
-                                             ContextualMode contextual_mode) {
-  LoadNamedParameters parameters(name, feedback, contextual_mode);
-  return new (zone()) Operator1<LoadNamedParameters>(   // --
+const Operator* JSOperatorBuilder::ConvertReceiver(
+    ConvertReceiverMode convert_mode) {
+  return new (zone()) Operator1<ConvertReceiverMode>(    // --
+      IrOpcode::kJSConvertReceiver, Operator::kNoThrow,  // opcode
+      "JSConvertReceiver",                               // name
+      1, 1, 1, 1, 1, 0,                                  // counts
+      convert_mode);                                     // parameter
+}
+
+
+const Operator* JSOperatorBuilder::LoadNamed(LanguageMode language_mode,
+                                             Handle<Name> name,
+                                             const VectorSlotPair& feedback) {
+  NamedAccess access(language_mode, name, feedback);
+  return new (zone()) Operator1<NamedAccess>(           // --
       IrOpcode::kJSLoadNamed, Operator::kNoProperties,  // opcode
       "JSLoadNamed",                                    // name
-      1, 1, 1, 1, 1, 0,                                 // counts
-      parameters);                                      // parameter
+      2, 1, 1, 1, 1, 2,                                 // counts
+      access);                                          // parameter
 }
 
 
 const Operator* JSOperatorBuilder::LoadProperty(
-    const VectorSlotPair& feedback) {
-  LoadPropertyParameters parameters(feedback);
-  return new (zone()) Operator1<LoadPropertyParameters>(   // --
+    LanguageMode language_mode, VectorSlotPair const& feedback) {
+  PropertyAccess access(language_mode, feedback);
+  return new (zone()) Operator1<PropertyAccess>(           // --
       IrOpcode::kJSLoadProperty, Operator::kNoProperties,  // opcode
       "JSLoadProperty",                                    // name
-      2, 1, 1, 1, 1, 0,                                    // counts
-      parameters);                                         // parameter
+      3, 1, 1, 1, 1, 2,                                    // counts
+      access);                                             // parameter
 }
 
 
-const Operator* JSOperatorBuilder::StoreProperty(StrictMode strict_mode) {
-  switch (strict_mode) {
-    case SLOPPY:
-      return &cache_.kStorePropertySloppyOperator;
-    case STRICT:
-      return &cache_.kStorePropertyStrictOperator;
-  }
-  UNREACHABLE();
-  return nullptr;
-}
-
-
-const Operator* JSOperatorBuilder::StoreNamed(StrictMode strict_mode,
-                                              const Unique<Name>& name) {
-  StoreNamedParameters parameters(strict_mode, name);
-  return new (zone()) Operator1<StoreNamedParameters>(   // --
+const Operator* JSOperatorBuilder::StoreNamed(LanguageMode language_mode,
+                                              Handle<Name> name,
+                                              VectorSlotPair const& feedback) {
+  NamedAccess access(language_mode, name, feedback);
+  return new (zone()) Operator1<NamedAccess>(            // --
       IrOpcode::kJSStoreNamed, Operator::kNoProperties,  // opcode
       "JSStoreNamed",                                    // name
-      2, 1, 1, 0, 1, 0,                                  // counts
+      3, 1, 1, 0, 1, 2,                                  // counts
+      access);                                           // parameter
+}
+
+
+const Operator* JSOperatorBuilder::StoreProperty(
+    LanguageMode language_mode, VectorSlotPair const& feedback) {
+  PropertyAccess access(language_mode, feedback);
+  return new (zone()) Operator1<PropertyAccess>(            // --
+      IrOpcode::kJSStoreProperty, Operator::kNoProperties,  // opcode
+      "JSStoreProperty",                                    // name
+      4, 1, 1, 0, 1, 2,                                     // counts
+      access);                                              // parameter
+}
+
+
+const Operator* JSOperatorBuilder::DeleteProperty(LanguageMode language_mode) {
+  return new (zone()) Operator1<LanguageMode>(               // --
+      IrOpcode::kJSDeleteProperty, Operator::kNoProperties,  // opcode
+      "JSDeleteProperty",                                    // name
+      2, 1, 1, 1, 1, 2,                                      // counts
+      language_mode);                                        // parameter
+}
+
+
+const Operator* JSOperatorBuilder::LoadGlobal(const Handle<Name>& name,
+                                              const VectorSlotPair& feedback,
+                                              TypeofMode typeof_mode) {
+  LoadGlobalParameters parameters(name, feedback, typeof_mode);
+  return new (zone()) Operator1<LoadGlobalParameters>(   // --
+      IrOpcode::kJSLoadGlobal, Operator::kNoProperties,  // opcode
+      "JSLoadGlobal",                                    // name
+      1, 1, 1, 1, 1, 2,                                  // counts
       parameters);                                       // parameter
 }
 
 
-const Operator* JSOperatorBuilder::DeleteProperty(StrictMode strict_mode) {
-  return new (zone()) Operator1<StrictMode>(                 // --
-      IrOpcode::kJSDeleteProperty, Operator::kNoProperties,  // opcode
-      "JSDeleteProperty",                                    // name
-      2, 1, 1, 1, 1, 0,                                      // counts
-      strict_mode);                                          // parameter
+const Operator* JSOperatorBuilder::StoreGlobal(LanguageMode language_mode,
+                                               const Handle<Name>& name,
+                                               const VectorSlotPair& feedback) {
+  StoreGlobalParameters parameters(language_mode, feedback, name);
+  return new (zone()) Operator1<StoreGlobalParameters>(   // --
+      IrOpcode::kJSStoreGlobal, Operator::kNoProperties,  // opcode
+      "JSStoreGlobal",                                    // name
+      2, 1, 1, 0, 1, 2,                                   // counts
+      parameters);                                        // parameter
 }
 
 
 const Operator* JSOperatorBuilder::LoadContext(size_t depth, size_t index,
                                                bool immutable) {
   ContextAccess access(depth, index, immutable);
-  return new (zone()) Operator1<ContextAccess>(      // --
-      IrOpcode::kJSLoadContext, Operator::kNoWrite,  // opcode
-      "JSLoadContext",                               // name
-      1, 1, 0, 1, 1, 0,                              // counts
-      access);                                       // parameter
+  return new (zone()) Operator1<ContextAccess>(  // --
+      IrOpcode::kJSLoadContext,                  // opcode
+      Operator::kNoWrite | Operator::kNoThrow,   // flags
+      "JSLoadContext",                           // name
+      1, 1, 0, 1, 1, 0,                          // counts
+      access);                                   // parameter
 }
 
 
 const Operator* JSOperatorBuilder::StoreContext(size_t depth, size_t index) {
   ContextAccess access(depth, index, false);
-  return new (zone()) Operator1<ContextAccess>(      // --
-      IrOpcode::kJSStoreContext, Operator::kNoRead,  // opcode
-      "JSStoreContext",                              // name
-      2, 1, 1, 0, 1, 0,                              // counts
-      access);                                       // parameter
+  return new (zone()) Operator1<ContextAccess>(  // --
+      IrOpcode::kJSStoreContext,                 // opcode
+      Operator::kNoRead | Operator::kNoThrow,    // flags
+      "JSStoreContext",                          // name
+      2, 1, 1, 0, 1, 0,                          // counts
+      access);                                   // parameter
+}
+
+
+const Operator* JSOperatorBuilder::LoadDynamic(const Handle<String>& name,
+                                               TypeofMode typeof_mode) {
+  DynamicAccess access(name, typeof_mode);
+  return new (zone()) Operator1<DynamicAccess>(           // --
+      IrOpcode::kJSLoadDynamic, Operator::kNoProperties,  // opcode
+      "JSLoadDynamic",                                    // name
+      2, 1, 1, 1, 1, 2,                                   // counts
+      access);                                            // parameter
+}
+
+
+const Operator* JSOperatorBuilder::CreateArguments(
+    CreateArgumentsParameters::Type type, int start_index) {
+  DCHECK_IMPLIES(start_index, type == CreateArgumentsParameters::kRestArray);
+  CreateArgumentsParameters parameters(type, start_index);
+  return new (zone()) Operator1<CreateArgumentsParameters>(  // --
+      IrOpcode::kJSCreateArguments, Operator::kNoThrow,      // opcode
+      "JSCreateArguments",                                   // name
+      1, 1, 1, 1, 1, 0,                                      // counts
+      parameters);                                           // parameter
+}
+
+
+const Operator* JSOperatorBuilder::CreateArray(size_t arity,
+                                               Handle<AllocationSite> site) {
+  // constructor, new_target, arg1, ..., argN
+  int const value_input_count = static_cast<int>(arity) + 2;
+  CreateArrayParameters parameters(arity, site);
+  return new (zone()) Operator1<CreateArrayParameters>(   // --
+      IrOpcode::kJSCreateArray, Operator::kNoProperties,  // opcode
+      "JSCreateArray",                                    // name
+      value_input_count, 1, 1, 1, 1, 2,                   // counts
+      parameters);                                        // parameter
+}
+
+
+const Operator* JSOperatorBuilder::CreateClosure(
+    Handle<SharedFunctionInfo> shared_info, PretenureFlag pretenure) {
+  CreateClosureParameters parameters(shared_info, pretenure);
+  return new (zone()) Operator1<CreateClosureParameters>(  // --
+      IrOpcode::kJSCreateClosure, Operator::kNoThrow,      // opcode
+      "JSCreateClosure",                                   // name
+      0, 1, 1, 1, 1, 0,                                    // counts
+      parameters);                                         // parameter
+}
+
+
+const Operator* JSOperatorBuilder::CreateLiteralArray(
+    Handle<FixedArray> constant_elements, int literal_flags,
+    int literal_index) {
+  CreateLiteralParameters parameters(constant_elements, literal_flags,
+                                     literal_index);
+  return new (zone()) Operator1<CreateLiteralParameters>(        // --
+      IrOpcode::kJSCreateLiteralArray, Operator::kNoProperties,  // opcode
+      "JSCreateLiteralArray",                                    // name
+      1, 1, 1, 1, 1, 2,                                          // counts
+      parameters);                                               // parameter
+}
+
+
+const Operator* JSOperatorBuilder::CreateLiteralObject(
+    Handle<FixedArray> constant_properties, int literal_flags,
+    int literal_index) {
+  CreateLiteralParameters parameters(constant_properties, literal_flags,
+                                     literal_index);
+  return new (zone()) Operator1<CreateLiteralParameters>(         // --
+      IrOpcode::kJSCreateLiteralObject, Operator::kNoProperties,  // opcode
+      "JSCreateLiteralObject",                                    // name
+      1, 1, 1, 1, 1, 2,                                           // counts
+      parameters);                                                // parameter
+}
+
+
+const Operator* JSOperatorBuilder::CreateLiteralRegExp(
+    Handle<String> constant_pattern, int literal_flags, int literal_index) {
+  CreateLiteralParameters parameters(constant_pattern, literal_flags,
+                                     literal_index);
+  return new (zone()) Operator1<CreateLiteralParameters>(         // --
+      IrOpcode::kJSCreateLiteralRegExp, Operator::kNoProperties,  // opcode
+      "JSCreateLiteralRegExp",                                    // name
+      1, 1, 1, 1, 1, 2,                                           // counts
+      parameters);                                                // parameter
+}
+
+
+const Operator* JSOperatorBuilder::CreateFunctionContext(int slot_count) {
+  return new (zone()) Operator1<int>(                               // --
+      IrOpcode::kJSCreateFunctionContext, Operator::kNoProperties,  // opcode
+      "JSCreateFunctionContext",                                    // name
+      1, 1, 1, 1, 1, 2,                                             // counts
+      slot_count);                                                  // parameter
 }
 
 
 const Operator* JSOperatorBuilder::CreateCatchContext(
-    const Unique<String>& name) {
-  return new (zone()) Operator1<Unique<String>>(                 // --
+    const Handle<String>& name) {
+  return new (zone()) Operator1<Handle<String>>(                 // --
       IrOpcode::kJSCreateCatchContext, Operator::kNoProperties,  // opcode
       "JSCreateCatchContext",                                    // name
-      1, 1, 1, 1, 1, 0,                                          // counts
+      2, 1, 1, 1, 1, 2,                                          // counts
       name);                                                     // parameter
 }
 
+
+const Operator* JSOperatorBuilder::CreateBlockContext(
+    const Handle<ScopeInfo>& scpope_info) {
+  return new (zone()) Operator1<Handle<ScopeInfo>>(              // --
+      IrOpcode::kJSCreateBlockContext, Operator::kNoProperties,  // opcode
+      "JSCreateBlockContext",                                    // name
+      1, 1, 1, 1, 1, 2,                                          // counts
+      scpope_info);                                              // parameter
+}
+
+
+const Operator* JSOperatorBuilder::CreateScriptContext(
+    const Handle<ScopeInfo>& scpope_info) {
+  return new (zone()) Operator1<Handle<ScopeInfo>>(               // --
+      IrOpcode::kJSCreateScriptContext, Operator::kNoProperties,  // opcode
+      "JSCreateScriptContext",                                    // name
+      1, 1, 1, 1, 1, 2,                                           // counts
+      scpope_info);                                               // parameter
+}
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/src/compiler/js-operator.h b/src/compiler/js-operator.h
index e716a8e..ca7c7ea 100644
--- a/src/compiler/js-operator.h
+++ b/src/compiler/js-operator.h
@@ -5,8 +5,8 @@
 #ifndef V8_COMPILER_JS_OPERATOR_H_
 #define V8_COMPILER_JS_OPERATOR_H_
 
+#include "src/compiler/type-hints.h"
 #include "src/runtime/runtime.h"
-#include "src/unique.h"
 
 namespace v8 {
 namespace internal {
@@ -17,23 +17,148 @@
 struct JSOperatorGlobalCache;
 
 
-// Defines the arity and the call flags for a JavaScript function call. This is
-// used as a parameter by JSCallFunction operators.
-class CallFunctionParameters FINAL {
+// Defines a pair of {TypeFeedbackVector} and {TypeFeedbackVectorSlot}, which
+// is used to access the type feedback for a certain {Node}.
+class VectorSlotPair {
  public:
-  CallFunctionParameters(size_t arity, CallFunctionFlags flags)
-      : arity_(arity), flags_(flags) {}
+  VectorSlotPair();
+  VectorSlotPair(Handle<TypeFeedbackVector> vector, FeedbackVectorSlot slot)
+      : vector_(vector), slot_(slot) {}
 
-  size_t arity() const { return arity_; }
-  CallFunctionFlags flags() const { return flags_; }
+  bool IsValid() const { return !vector_.is_null() && !slot_.IsInvalid(); }
+
+  Handle<TypeFeedbackVector> vector() const { return vector_; }
+  FeedbackVectorSlot slot() const { return slot_; }
+
+  int index() const;
 
  private:
-  const size_t arity_;
-  const CallFunctionFlags flags_;
+  const Handle<TypeFeedbackVector> vector_;
+  const FeedbackVectorSlot slot_;
 };
 
-bool operator==(CallFunctionParameters const&, CallFunctionParameters const&);
-bool operator!=(CallFunctionParameters const&, CallFunctionParameters const&);
+bool operator==(VectorSlotPair const&, VectorSlotPair const&);
+bool operator!=(VectorSlotPair const&, VectorSlotPair const&);
+
+size_t hash_value(VectorSlotPair const&);
+
+
+// The ConvertReceiverMode is used as parameter by JSConvertReceiver operators.
+ConvertReceiverMode ConvertReceiverModeOf(Operator const* op);
+
+
+// The ToBooleanHints are used as parameter by JSToBoolean operators.
+ToBooleanHints ToBooleanHintsOf(Operator const* op);
+
+
+// Defines whether tail call optimization is allowed.
+enum class TailCallMode : unsigned { kAllow, kDisallow };
+
+size_t hash_value(TailCallMode);
+
+std::ostream& operator<<(std::ostream&, TailCallMode);
+
+
+// Defines the language mode and hints for a JavaScript binary operations.
+// This is used as parameter by JSAdd, JSSubtract, etc. operators.
+class BinaryOperationParameters final {
+ public:
+  BinaryOperationParameters(LanguageMode language_mode,
+                            BinaryOperationHints hints)
+      : language_mode_(language_mode), hints_(hints) {}
+
+  LanguageMode language_mode() const { return language_mode_; }
+  BinaryOperationHints hints() const { return hints_; }
+
+ private:
+  LanguageMode const language_mode_;
+  BinaryOperationHints const hints_;
+};
+
+bool operator==(BinaryOperationParameters const&,
+                BinaryOperationParameters const&);
+bool operator!=(BinaryOperationParameters const&,
+                BinaryOperationParameters const&);
+
+size_t hash_value(BinaryOperationParameters const&);
+
+std::ostream& operator<<(std::ostream&, BinaryOperationParameters const&);
+
+BinaryOperationParameters const& BinaryOperationParametersOf(Operator const*);
+
+
+// Defines the arity and the feedback for a JavaScript constructor call. This is
+// used as a parameter by JSCallConstruct operators.
+class CallConstructParameters final {
+ public:
+  CallConstructParameters(size_t arity, VectorSlotPair const& feedback)
+      : arity_(arity), feedback_(feedback) {}
+
+  size_t arity() const { return arity_; }
+  VectorSlotPair const& feedback() const { return feedback_; }
+
+ private:
+  size_t const arity_;
+  VectorSlotPair const feedback_;
+};
+
+bool operator==(CallConstructParameters const&, CallConstructParameters const&);
+bool operator!=(CallConstructParameters const&, CallConstructParameters const&);
+
+size_t hash_value(CallConstructParameters const&);
+
+std::ostream& operator<<(std::ostream&, CallConstructParameters const&);
+
+CallConstructParameters const& CallConstructParametersOf(Operator const*);
+
+
+// Defines the arity and the call flags for a JavaScript function call. This is
+// used as a parameter by JSCallFunction operators.
+class CallFunctionParameters final {
+ public:
+  CallFunctionParameters(size_t arity, LanguageMode language_mode,
+                         VectorSlotPair const& feedback,
+                         TailCallMode tail_call_mode,
+                         ConvertReceiverMode convert_mode)
+      : bit_field_(ArityField::encode(arity) |
+                   ConvertReceiverModeField::encode(convert_mode) |
+                   LanguageModeField::encode(language_mode) |
+                   TailCallModeField::encode(tail_call_mode)),
+        feedback_(feedback) {}
+
+  size_t arity() const { return ArityField::decode(bit_field_); }
+  LanguageMode language_mode() const {
+    return LanguageModeField::decode(bit_field_);
+  }
+  ConvertReceiverMode convert_mode() const {
+    return ConvertReceiverModeField::decode(bit_field_);
+  }
+  TailCallMode tail_call_mode() const {
+    return TailCallModeField::decode(bit_field_);
+  }
+  VectorSlotPair const& feedback() const { return feedback_; }
+
+  bool operator==(CallFunctionParameters const& that) const {
+    return this->bit_field_ == that.bit_field_ &&
+           this->feedback_ == that.feedback_;
+  }
+  bool operator!=(CallFunctionParameters const& that) const {
+    return !(*this == that);
+  }
+
+ private:
+  friend size_t hash_value(CallFunctionParameters const& p) {
+    return base::hash_combine(p.bit_field_, p.feedback_);
+  }
+
+  typedef BitField<size_t, 0, 27> ArityField;
+  typedef BitField<ConvertReceiverMode, 27, 2> ConvertReceiverModeField;
+  typedef BitField<LanguageMode, 29, 2> LanguageModeField;
+  typedef BitField<TailCallMode, 31, 1> TailCallModeField;
+
+  const uint32_t bit_field_;
+  const VectorSlotPair feedback_;
+};
 
 size_t hash_value(CallFunctionParameters const&);
 
@@ -44,7 +169,7 @@
 
 // Defines the arity and the ID for a runtime function call. This is used as a
 // parameter by JSCallRuntime operators.
-class CallRuntimeParameters FINAL {
+class CallRuntimeParameters final {
  public:
   CallRuntimeParameters(Runtime::FunctionId id, size_t arity)
       : id_(id), arity_(arity) {}
@@ -70,7 +195,7 @@
 // Defines the location of a context slot relative to a specific scope. This is
 // used as a parameter by JSLoadContext and JSStoreContext operators and allows
 // accessing a context-allocated variable without keeping track of the scope.
-class ContextAccess FINAL {
+class ContextAccess final {
  public:
   ContextAccess(size_t depth, size_t index, bool immutable);
 
@@ -96,106 +221,253 @@
 ContextAccess const& ContextAccessOf(Operator const*);
 
 
-class VectorSlotPair {
+// Defines the name for a dynamic variable lookup. This is used as a parameter
+// by JSLoadDynamic and JSStoreDynamic operators.
+class DynamicAccess final {
  public:
-  VectorSlotPair(Handle<TypeFeedbackVector> vector, FeedbackVectorICSlot slot)
-      : vector_(vector), slot_(slot) {}
+  DynamicAccess(const Handle<String>& name, TypeofMode typeof_mode);
 
-  Handle<TypeFeedbackVector> vector() const { return vector_; }
-  FeedbackVectorICSlot slot() const { return slot_; }
-
-  int index() const { return vector_->GetIndex(slot_); }
+  const Handle<String>& name() const { return name_; }
+  TypeofMode typeof_mode() const { return typeof_mode_; }
 
  private:
-  const Handle<TypeFeedbackVector> vector_;
-  const FeedbackVectorICSlot slot_;
+  const Handle<String> name_;
+  const TypeofMode typeof_mode_;
 };
 
+size_t hash_value(DynamicAccess const&);
 
-bool operator==(VectorSlotPair const& lhs, VectorSlotPair const& rhs);
+bool operator==(DynamicAccess const&, DynamicAccess const&);
+bool operator!=(DynamicAccess const&, DynamicAccess const&);
+
+std::ostream& operator<<(std::ostream&, DynamicAccess const&);
+
+DynamicAccess const& DynamicAccessOf(Operator const*);
+
+
+// Defines the property of an object for a named access. This is
+// used as a parameter by the JSLoadNamed and JSStoreNamed operators.
+class NamedAccess final {
+ public:
+  NamedAccess(LanguageMode language_mode, Handle<Name> name,
+              VectorSlotPair const& feedback)
+      : name_(name), feedback_(feedback), language_mode_(language_mode) {}
+
+  Handle<Name> name() const { return name_; }
+  LanguageMode language_mode() const { return language_mode_; }
+  VectorSlotPair const& feedback() const { return feedback_; }
+
+ private:
+  Handle<Name> const name_;
+  VectorSlotPair const feedback_;
+  LanguageMode const language_mode_;
+};
+
+bool operator==(NamedAccess const&, NamedAccess const&);
+bool operator!=(NamedAccess const&, NamedAccess const&);
+
+size_t hash_value(NamedAccess const&);
+
+std::ostream& operator<<(std::ostream&, NamedAccess const&);
+
+const NamedAccess& NamedAccessOf(const Operator* op);
 
 
 // Defines the property being loaded from an object by a named load. This is
-// used as a parameter by JSLoadNamed operators.
-class LoadNamedParameters FINAL {
+// used as a parameter by JSLoadGlobal operator.
+class LoadGlobalParameters final {
  public:
-  LoadNamedParameters(const Unique<Name>& name, const VectorSlotPair& feedback,
-                      ContextualMode contextual_mode)
-      : name_(name), contextual_mode_(contextual_mode), feedback_(feedback) {}
+  LoadGlobalParameters(const Handle<Name>& name, const VectorSlotPair& feedback,
+                       TypeofMode typeof_mode)
+      : name_(name), feedback_(feedback), typeof_mode_(typeof_mode) {}
 
-  const Unique<Name>& name() const { return name_; }
-  ContextualMode contextual_mode() const { return contextual_mode_; }
+  const Handle<Name>& name() const { return name_; }
+  TypeofMode typeof_mode() const { return typeof_mode_; }
 
   const VectorSlotPair& feedback() const { return feedback_; }
 
  private:
-  const Unique<Name> name_;
-  const ContextualMode contextual_mode_;
+  const Handle<Name> name_;
   const VectorSlotPair feedback_;
+  const TypeofMode typeof_mode_;
 };
 
-bool operator==(LoadNamedParameters const&, LoadNamedParameters const&);
-bool operator!=(LoadNamedParameters const&, LoadNamedParameters const&);
+bool operator==(LoadGlobalParameters const&, LoadGlobalParameters const&);
+bool operator!=(LoadGlobalParameters const&, LoadGlobalParameters const&);
 
-size_t hash_value(LoadNamedParameters const&);
+size_t hash_value(LoadGlobalParameters const&);
 
-std::ostream& operator<<(std::ostream&, LoadNamedParameters const&);
+std::ostream& operator<<(std::ostream&, LoadGlobalParameters const&);
 
-const LoadNamedParameters& LoadNamedParametersOf(const Operator* op);
-
-
-// Defines the property being loaded from an object. This is
-// used as a parameter by JSLoadProperty operators.
-class LoadPropertyParameters FINAL {
- public:
-  explicit LoadPropertyParameters(const VectorSlotPair& feedback)
-      : feedback_(feedback) {}
-
-  const VectorSlotPair& feedback() const { return feedback_; }
-
- private:
-  const VectorSlotPair feedback_;
-};
-
-bool operator==(LoadPropertyParameters const&, LoadPropertyParameters const&);
-bool operator!=(LoadPropertyParameters const&, LoadPropertyParameters const&);
-
-size_t hash_value(LoadPropertyParameters const&);
-
-std::ostream& operator<<(std::ostream&, LoadPropertyParameters const&);
-
-const LoadPropertyParameters& LoadPropertyParametersOf(const Operator* op);
+const LoadGlobalParameters& LoadGlobalParametersOf(const Operator* op);
 
 
 // Defines the property being stored to an object by a named store. This is
-// used as a parameter by JSStoreNamed operators.
-class StoreNamedParameters FINAL {
+// used as a parameter by JSStoreGlobal operator.
+class StoreGlobalParameters final {
  public:
-  StoreNamedParameters(StrictMode strict_mode, const Unique<Name>& name)
-      : strict_mode_(strict_mode), name_(name) {}
+  StoreGlobalParameters(LanguageMode language_mode,
+                        const VectorSlotPair& feedback,
+                        const Handle<Name>& name)
+      : language_mode_(language_mode), name_(name), feedback_(feedback) {}
 
-  StrictMode strict_mode() const { return strict_mode_; }
-  const Unique<Name>& name() const { return name_; }
+  LanguageMode language_mode() const { return language_mode_; }
+  const VectorSlotPair& feedback() const { return feedback_; }
+  const Handle<Name>& name() const { return name_; }
 
  private:
-  const StrictMode strict_mode_;
-  const Unique<Name> name_;
+  const LanguageMode language_mode_;
+  const Handle<Name> name_;
+  const VectorSlotPair feedback_;
 };
 
-bool operator==(StoreNamedParameters const&, StoreNamedParameters const&);
-bool operator!=(StoreNamedParameters const&, StoreNamedParameters const&);
+bool operator==(StoreGlobalParameters const&, StoreGlobalParameters const&);
+bool operator!=(StoreGlobalParameters const&, StoreGlobalParameters const&);
 
-size_t hash_value(StoreNamedParameters const&);
+size_t hash_value(StoreGlobalParameters const&);
 
-std::ostream& operator<<(std::ostream&, StoreNamedParameters const&);
+std::ostream& operator<<(std::ostream&, StoreGlobalParameters const&);
 
-const StoreNamedParameters& StoreNamedParametersOf(const Operator* op);
+const StoreGlobalParameters& StoreGlobalParametersOf(const Operator* op);
+
+
+// Defines the property of an object for a keyed access. This is used
+// as a parameter by the JSLoadProperty and JSStoreProperty operators.
+class PropertyAccess final {
+ public:
+  PropertyAccess(LanguageMode language_mode, VectorSlotPair const& feedback)
+      : feedback_(feedback), language_mode_(language_mode) {}
+
+  LanguageMode language_mode() const { return language_mode_; }
+  VectorSlotPair const& feedback() const { return feedback_; }
+
+ private:
+  VectorSlotPair const feedback_;
+  LanguageMode const language_mode_;
+};
+
+bool operator==(PropertyAccess const&, PropertyAccess const&);
+bool operator!=(PropertyAccess const&, PropertyAccess const&);
+
+size_t hash_value(PropertyAccess const&);
+
+std::ostream& operator<<(std::ostream&, PropertyAccess const&);
+
+PropertyAccess const& PropertyAccessOf(const Operator* op);
+
+
+// Defines specifics about arguments object or rest parameter creation. This is
+// used as a parameter by JSCreateArguments operators.
+class CreateArgumentsParameters final {
+ public:
+  enum Type { kMappedArguments, kUnmappedArguments, kRestArray };
+  CreateArgumentsParameters(Type type, int start_index)
+      : type_(type), start_index_(start_index) {}
+
+  Type type() const { return type_; }
+  int start_index() const { return start_index_; }
+
+ private:
+  const Type type_;
+  const int start_index_;
+};
+
+bool operator==(CreateArgumentsParameters const&,
+                CreateArgumentsParameters const&);
+bool operator!=(CreateArgumentsParameters const&,
+                CreateArgumentsParameters const&);
+
+size_t hash_value(CreateArgumentsParameters const&);
+
+std::ostream& operator<<(std::ostream&, CreateArgumentsParameters const&);
+
+const CreateArgumentsParameters& CreateArgumentsParametersOf(
+    const Operator* op);
+
+
+// Defines shared information for the array that should be created. This is
+// used as parameter by JSCreateArray operators.
+class CreateArrayParameters final {
+ public:
+  explicit CreateArrayParameters(size_t arity, Handle<AllocationSite> site)
+      : arity_(arity), site_(site) {}
+
+  size_t arity() const { return arity_; }
+  Handle<AllocationSite> site() const { return site_; }
+
+ private:
+  size_t const arity_;
+  Handle<AllocationSite> const site_;
+};
+
+bool operator==(CreateArrayParameters const&, CreateArrayParameters const&);
+bool operator!=(CreateArrayParameters const&, CreateArrayParameters const&);
+
+size_t hash_value(CreateArrayParameters const&);
+
+std::ostream& operator<<(std::ostream&, CreateArrayParameters const&);
+
+const CreateArrayParameters& CreateArrayParametersOf(const Operator* op);
+
+
+// Defines shared information for the closure that should be created. This is
+// used as a parameter by JSCreateClosure operators.
+class CreateClosureParameters final {
+ public:
+  CreateClosureParameters(Handle<SharedFunctionInfo> shared_info,
+                          PretenureFlag pretenure)
+      : shared_info_(shared_info), pretenure_(pretenure) {}
+
+  Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
+  PretenureFlag pretenure() const { return pretenure_; }
+
+ private:
+  const Handle<SharedFunctionInfo> shared_info_;
+  const PretenureFlag pretenure_;
+};
+
+bool operator==(CreateClosureParameters const&, CreateClosureParameters const&);
+bool operator!=(CreateClosureParameters const&, CreateClosureParameters const&);
+
+size_t hash_value(CreateClosureParameters const&);
+
+std::ostream& operator<<(std::ostream&, CreateClosureParameters const&);
+
+const CreateClosureParameters& CreateClosureParametersOf(const Operator* op);
+
+
+// Defines shared information for the literal that should be created. This is
+// used as parameter by JSCreateLiteralArray, JSCreateLiteralObject and
+// JSCreateLiteralRegExp operators.
+class CreateLiteralParameters final {
+ public:
+  CreateLiteralParameters(Handle<HeapObject> constant, int flags, int index)
+      : constant_(constant), flags_(flags), index_(index) {}
+
+  Handle<HeapObject> constant() const { return constant_; }
+  int flags() const { return flags_; }
+  int index() const { return index_; }
+
+ private:
+  Handle<HeapObject> const constant_;
+  int const flags_;
+  int const index_;
+};
+
+bool operator==(CreateLiteralParameters const&, CreateLiteralParameters const&);
+bool operator!=(CreateLiteralParameters const&, CreateLiteralParameters const&);
+
+size_t hash_value(CreateLiteralParameters const&);
+
+std::ostream& operator<<(std::ostream&, CreateLiteralParameters const&);
+
+const CreateLiteralParameters& CreateLiteralParametersOf(const Operator* op);
 
 
 // Interface for building JavaScript-level operators, e.g. directly from the
 // AST. Most operators have no parameters, thus can be globally shared for all
 // graphs.
-class JSOperatorBuilder FINAL : public ZoneObject {
+class JSOperatorBuilder final : public ZoneObject {
  public:
   explicit JSOperatorBuilder(Zone* zone);
 
@@ -203,24 +475,33 @@
   const Operator* NotEqual();
   const Operator* StrictEqual();
   const Operator* StrictNotEqual();
-  const Operator* LessThan();
-  const Operator* GreaterThan();
-  const Operator* LessThanOrEqual();
-  const Operator* GreaterThanOrEqual();
-  const Operator* BitwiseOr();
-  const Operator* BitwiseXor();
-  const Operator* BitwiseAnd();
-  const Operator* ShiftLeft();
-  const Operator* ShiftRight();
-  const Operator* ShiftRightLogical();
-  const Operator* Add();
-  const Operator* Subtract();
-  const Operator* Multiply();
-  const Operator* Divide();
-  const Operator* Modulus();
+  const Operator* LessThan(LanguageMode language_mode);
+  const Operator* GreaterThan(LanguageMode language_mode);
+  const Operator* LessThanOrEqual(LanguageMode language_mode);
+  const Operator* GreaterThanOrEqual(LanguageMode language_mode);
+  const Operator* BitwiseOr(LanguageMode language_mode,
+                            BinaryOperationHints hints);
+  const Operator* BitwiseXor(LanguageMode language_mode,
+                             BinaryOperationHints hints);
+  const Operator* BitwiseAnd(LanguageMode language_mode,
+                             BinaryOperationHints hints);
+  const Operator* ShiftLeft(LanguageMode language_mode,
+                            BinaryOperationHints hints);
+  const Operator* ShiftRight(LanguageMode language_mode,
+                             BinaryOperationHints hints);
+  const Operator* ShiftRightLogical(LanguageMode language_mode,
+                                    BinaryOperationHints hints);
+  const Operator* Add(LanguageMode language_mode, BinaryOperationHints hints);
+  const Operator* Subtract(LanguageMode language_mode,
+                           BinaryOperationHints hints);
+  const Operator* Multiply(LanguageMode language_mode,
+                           BinaryOperationHints hints);
+  const Operator* Divide(LanguageMode language_mode,
+                         BinaryOperationHints hints);
+  const Operator* Modulus(LanguageMode language_mode,
+                          BinaryOperationHints hints);
 
-  const Operator* UnaryNot();
-  const Operator* ToBoolean();
+  const Operator* ToBoolean(ToBooleanHints hints);
   const Operator* ToNumber();
   const Operator* ToString();
   const Operator* ToName();
@@ -228,38 +509,75 @@
   const Operator* Yield();
 
   const Operator* Create();
+  const Operator* CreateArguments(CreateArgumentsParameters::Type type,
+                                  int start_index);
+  const Operator* CreateArray(size_t arity, Handle<AllocationSite> site);
+  const Operator* CreateClosure(Handle<SharedFunctionInfo> shared_info,
+                                PretenureFlag pretenure);
+  const Operator* CreateIterResultObject();
+  const Operator* CreateLiteralArray(Handle<FixedArray> constant_elements,
+                                     int literal_flags, int literal_index);
+  const Operator* CreateLiteralObject(Handle<FixedArray> constant_properties,
+                                      int literal_flags, int literal_index);
+  const Operator* CreateLiteralRegExp(Handle<String> constant_pattern,
+                                      int literal_flags, int literal_index);
 
-  const Operator* CallFunction(size_t arity, CallFunctionFlags flags);
+  const Operator* CallFunction(
+      size_t arity, LanguageMode language_mode,
+      VectorSlotPair const& feedback = VectorSlotPair(),
+      ConvertReceiverMode convert_mode = ConvertReceiverMode::kAny,
+      TailCallMode tail_call_mode = TailCallMode::kDisallow);
   const Operator* CallRuntime(Runtime::FunctionId id, size_t arity);
+  const Operator* CallConstruct(size_t arity, VectorSlotPair const& feedback);
 
-  const Operator* CallConstruct(int arguments);
+  const Operator* ConvertReceiver(ConvertReceiverMode convert_mode);
 
-  const Operator* LoadProperty(const VectorSlotPair& feedback);
-  const Operator* LoadNamed(const Unique<Name>& name,
-                            const VectorSlotPair& feedback,
-                            ContextualMode contextual_mode = NOT_CONTEXTUAL);
+  const Operator* LoadProperty(LanguageMode language_mode,
+                               VectorSlotPair const& feedback);
+  const Operator* LoadNamed(LanguageMode language_mode, Handle<Name> name,
+                            VectorSlotPair const& feedback);
 
-  const Operator* StoreProperty(StrictMode strict_mode);
-  const Operator* StoreNamed(StrictMode strict_mode, const Unique<Name>& name);
+  const Operator* StoreProperty(LanguageMode language_mode,
+                                VectorSlotPair const& feedback);
+  const Operator* StoreNamed(LanguageMode language_mode, Handle<Name> name,
+                             VectorSlotPair const& feedback);
 
-  const Operator* DeleteProperty(StrictMode strict_mode);
+  const Operator* DeleteProperty(LanguageMode language_mode);
 
   const Operator* HasProperty();
 
+  const Operator* LoadGlobal(const Handle<Name>& name,
+                             const VectorSlotPair& feedback,
+                             TypeofMode typeof_mode = NOT_INSIDE_TYPEOF);
+  const Operator* StoreGlobal(LanguageMode language_mode,
+                              const Handle<Name>& name,
+                              const VectorSlotPair& feedback);
+
   const Operator* LoadContext(size_t depth, size_t index, bool immutable);
   const Operator* StoreContext(size_t depth, size_t index);
 
+  const Operator* LoadDynamic(const Handle<String>& name,
+                              TypeofMode typeof_mode);
+
   const Operator* TypeOf();
   const Operator* InstanceOf();
-  const Operator* Debugger();
 
-  // TODO(titzer): nail down the static parts of each of these context flavors.
-  const Operator* CreateFunctionContext();
-  const Operator* CreateCatchContext(const Unique<String>& name);
+  const Operator* ForInDone();
+  const Operator* ForInNext();
+  const Operator* ForInPrepare();
+  const Operator* ForInStep();
+
+  const Operator* LoadMessage();
+  const Operator* StoreMessage();
+
+  const Operator* StackCheck();
+
+  const Operator* CreateFunctionContext(int slot_count);
+  const Operator* CreateCatchContext(const Handle<String>& name);
   const Operator* CreateWithContext();
-  const Operator* CreateBlockContext();
+  const Operator* CreateBlockContext(const Handle<ScopeInfo>& scpope_info);
   const Operator* CreateModuleContext();
-  const Operator* CreateScriptContext();
+  const Operator* CreateScriptContext(const Handle<ScopeInfo>& scpope_info);
 
  private:
   Zone* zone() const { return zone_; }
diff --git a/src/compiler/js-typed-lowering.cc b/src/compiler/js-typed-lowering.cc
index 7618375..5e0712a 100644
--- a/src/compiler/js-typed-lowering.cc
+++ b/src/compiler/js-typed-lowering.cc
@@ -2,82 +2,143 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "src/code-factory.h"
+#include "src/compilation-dependencies.h"
 #include "src/compiler/access-builder.h"
-#include "src/compiler/graph-inl.h"
 #include "src/compiler/js-graph.h"
 #include "src/compiler/js-typed-lowering.h"
-#include "src/compiler/node-aux-data-inl.h"
+#include "src/compiler/linkage.h"
 #include "src/compiler/node-matchers.h"
-#include "src/compiler/node-properties-inl.h"
+#include "src/compiler/node-properties.h"
+#include "src/compiler/operator-properties.h"
+#include "src/compiler/state-values-utils.h"
+#include "src/type-cache.h"
 #include "src/types.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
-// TODO(turbofan): js-typed-lowering improvements possible
-// - immediately put in type bounds for all new nodes
-// - relax effects from generic but not-side-effecting operations
+namespace {
 
+// A helper class to construct inline allocations on the simplified operator
+// level. This keeps track of the effect chain for initial stores on a newly
+// allocated object and also provides helpers for commonly allocated objects.
+class AllocationBuilder final {
+ public:
+  AllocationBuilder(JSGraph* jsgraph, Node* effect, Node* control)
+      : jsgraph_(jsgraph),
+        allocation_(nullptr),
+        effect_(effect),
+        control_(control) {}
 
-// Relax the effects of {node} by immediately replacing effect uses of {node}
-// with the effect input to {node}.
-// TODO(turbofan): replace the effect input to {node} with {graph->start()}.
-// TODO(titzer): move into a GraphEditor?
-static void RelaxEffects(Node* node) {
-  NodeProperties::ReplaceWithValue(node, node, NULL);
-}
-
-
-JSTypedLowering::JSTypedLowering(JSGraph* jsgraph, Zone* zone)
-    : jsgraph_(jsgraph), simplified_(graph()->zone()), conversions_(zone) {
-  Handle<Object> zero = factory()->NewNumber(0.0);
-  Handle<Object> one = factory()->NewNumber(1.0);
-  zero_range_ = Type::Range(zero, zero, graph()->zone());
-  one_range_ = Type::Range(one, one, graph()->zone());
-  Handle<Object> thirtyone = factory()->NewNumber(31.0);
-  zero_thirtyone_range_ = Type::Range(zero, thirtyone, graph()->zone());
-  // TODO(jarin): Can we have a correctification of the stupid type system?
-  // These stupid work-arounds are just stupid!
-  shifted_int32_ranges_[0] = Type::Signed32();
-  if (SmiValuesAre31Bits()) {
-    shifted_int32_ranges_[1] = Type::SignedSmall();
-    for (size_t k = 2; k < arraysize(shifted_int32_ranges_); ++k) {
-      Handle<Object> min = factory()->NewNumber(kMinInt / (1 << k));
-      Handle<Object> max = factory()->NewNumber(kMaxInt / (1 << k));
-      shifted_int32_ranges_[k] = Type::Range(min, max, graph()->zone());
-    }
-  } else {
-    for (size_t k = 1; k < arraysize(shifted_int32_ranges_); ++k) {
-      Handle<Object> min = factory()->NewNumber(kMinInt / (1 << k));
-      Handle<Object> max = factory()->NewNumber(kMaxInt / (1 << k));
-      shifted_int32_ranges_[k] = Type::Range(min, max, graph()->zone());
-    }
+  // Primitive allocation of static size.
+  void Allocate(int size, PretenureFlag pretenure = NOT_TENURED) {
+    effect_ = graph()->NewNode(common()->BeginRegion(), effect_);
+    allocation_ =
+        graph()->NewNode(simplified()->Allocate(pretenure),
+                         jsgraph()->Constant(size), effect_, control_);
+    effect_ = allocation_;
   }
-}
 
+  // Primitive store into a field.
+  void Store(const FieldAccess& access, Node* value) {
+    effect_ = graph()->NewNode(simplified()->StoreField(access), allocation_,
+                               value, effect_, control_);
+  }
 
-Reduction JSTypedLowering::ReplaceEagerly(Node* old, Node* node) {
-  NodeProperties::ReplaceWithValue(old, node, node);
-  return Changed(node);
-}
+  // Primitive store into an element.
+  void Store(ElementAccess const& access, Node* index, Node* value) {
+    effect_ = graph()->NewNode(simplified()->StoreElement(access), allocation_,
+                               index, value, effect_, control_);
+  }
+
+  // Compound allocation of a FixedArray.
+  void AllocateArray(int length, Handle<Map> map,
+                     PretenureFlag pretenure = NOT_TENURED) {
+    DCHECK(map->instance_type() == FIXED_ARRAY_TYPE ||
+           map->instance_type() == FIXED_DOUBLE_ARRAY_TYPE);
+    int size = (map->instance_type() == FIXED_ARRAY_TYPE)
+                   ? FixedArray::SizeFor(length)
+                   : FixedDoubleArray::SizeFor(length);
+    Allocate(size, pretenure);
+    Store(AccessBuilder::ForMap(), map);
+    Store(AccessBuilder::ForFixedArrayLength(), jsgraph()->Constant(length));
+  }
+
+  // Compound store of a constant into a field.
+  void Store(const FieldAccess& access, Handle<Object> value) {
+    Store(access, jsgraph()->Constant(value));
+  }
+
+  void FinishAndChange(Node* node) {
+    NodeProperties::SetType(allocation_, NodeProperties::GetType(node));
+    node->ReplaceInput(0, allocation_);
+    node->ReplaceInput(1, effect_);
+    node->TrimInputCount(2);
+    NodeProperties::ChangeOp(node, common()->FinishRegion());
+  }
+
+  Node* Finish() {
+    return graph()->NewNode(common()->FinishRegion(), allocation_, effect_);
+  }
+
+ protected:
+  JSGraph* jsgraph() { return jsgraph_; }
+  Graph* graph() { return jsgraph_->graph(); }
+  CommonOperatorBuilder* common() { return jsgraph_->common(); }
+  SimplifiedOperatorBuilder* simplified() { return jsgraph_->simplified(); }
+
+ private:
+  JSGraph* const jsgraph_;
+  Node* allocation_;
+  Node* effect_;
+  Node* control_;
+};
+
+}  // namespace
 
 
 // A helper class to simplify the process of reducing a single binop node with a
 // JSOperator. This class manages the rewriting of context, control, and effect
 // dependencies during lowering of a binop and contains numerous helper
 // functions for matching the types of inputs to an operation.
-class JSBinopReduction FINAL {
+class JSBinopReduction final {
  public:
   JSBinopReduction(JSTypedLowering* lowering, Node* node)
-      : lowering_(lowering),
-        node_(node),
-        left_type_(NodeProperties::GetBounds(node->InputAt(0)).upper),
-        right_type_(NodeProperties::GetBounds(node->InputAt(1)).upper) {}
+      : lowering_(lowering), node_(node) {}
 
-  void ConvertInputsToNumber() {
-    node_->ReplaceInput(0, ConvertToNumber(left()));
-    node_->ReplaceInput(1, ConvertToNumber(right()));
+  void ConvertInputsToNumber(Node* frame_state) {
+    // To convert the inputs to numbers, we have to provide frame states
+    // for lazy bailouts in the ToNumber conversions.
+    // We use a little hack here: we take the frame state before the binary
+    // operation and use it to construct the frame states for the conversion
+    // so that after the deoptimization, the binary operation IC gets
+    // already converted values from full code. This way we are sure that we
+    // will not re-do any of the side effects.
+
+    Node* left_input = nullptr;
+    Node* right_input = nullptr;
+    bool left_is_primitive = left_type()->Is(Type::PlainPrimitive());
+    bool right_is_primitive = right_type()->Is(Type::PlainPrimitive());
+    bool handles_exception = NodeProperties::IsExceptionalCall(node_);
+
+    if (!left_is_primitive && !right_is_primitive && handles_exception) {
+      ConvertBothInputsToNumber(&left_input, &right_input, frame_state);
+    } else {
+      left_input = left_is_primitive
+                       ? ConvertPlainPrimitiveToNumber(left())
+                       : ConvertSingleInputToNumber(
+                             left(), CreateFrameStateForLeftInput(frame_state));
+      right_input = right_is_primitive
+                        ? ConvertPlainPrimitiveToNumber(right())
+                        : ConvertSingleInputToNumber(
+                              right(), CreateFrameStateForRightInput(
+                                           frame_state, left_input));
+    }
+
+    node_->ReplaceInput(0, left_input);
+    node_->ReplaceInput(1, right_input);
   }
 
   void ConvertInputsToUI32(Signedness left_signedness,
@@ -86,29 +147,11 @@
     node_->ReplaceInput(1, ConvertToUI32(right(), right_signedness));
   }
 
-  void ConvertInputsToString() {
-    node_->ReplaceInput(0, ConvertToString(left()));
-    node_->ReplaceInput(1, ConvertToString(right()));
-  }
-
-  // Convert inputs for bitwise shift operation (ES5 spec 11.7).
-  void ConvertInputsForShift(Signedness left_signedness) {
-    node_->ReplaceInput(0, ConvertToUI32(left(), left_signedness));
-    Node* rnum = ConvertToUI32(right(), kUnsigned);
-    Type* rnum_type = NodeProperties::GetBounds(rnum).upper;
-    if (!rnum_type->Is(lowering_->zero_thirtyone_range_)) {
-      rnum = graph()->NewNode(machine()->Word32And(), rnum,
-                              jsgraph()->Int32Constant(0x1F));
-    }
-    node_->ReplaceInput(1, rnum);
-  }
-
   void SwapInputs() {
     Node* l = left();
     Node* r = right();
     node_->ReplaceInput(0, r);
     node_->ReplaceInput(1, l);
-    std::swap(left_type_, right_type_);
   }
 
   // Remove all effect and control inputs and outputs to this node and change
@@ -120,19 +163,19 @@
     DCHECK_EQ(0, op->ControlInputCount());
     DCHECK_EQ(2, op->ValueInputCount());
 
-    // Remove the effects from the node, if any, and update its effect usages.
+    // Remove the effects from the node, and update its effect/control usages.
     if (node_->op()->EffectInputCount() > 0) {
-      RelaxEffects(node_);
+      lowering_->RelaxEffectsAndControls(node_);
     }
     // Remove the inputs corresponding to context, effect, and control.
     NodeProperties::RemoveNonValueInputs(node_);
     // Finally, update the operator to the new one.
-    node_->set_op(op);
+    NodeProperties::ChangeOp(node_, op);
 
     // TODO(jarin): Replace the explicit typing hack with a call to some method
     // that encapsulates changing the operator and re-typing.
-    Bounds const bounds = NodeProperties::GetBounds(node_);
-    NodeProperties::SetBounds(node_, Bounds::NarrowUpper(bounds, type, zone()));
+    Type* node_type = NodeProperties::GetType(node_);
+    NodeProperties::SetType(node_, Type::Intersect(node_type, type, zone()));
 
     if (invert) {
       // Insert an boolean not to invert the value.
@@ -145,22 +188,61 @@
     return lowering_->Changed(node_);
   }
 
+  Reduction ChangeToStringComparisonOperator(const Operator* op,
+                                             bool invert = false) {
+    if (node_->op()->ControlInputCount() > 0) {
+      lowering_->RelaxControls(node_);
+    }
+    // String comparison operators need effect and control inputs, so copy them
+    // over.
+    Node* effect = NodeProperties::GetEffectInput(node_);
+    Node* control = NodeProperties::GetControlInput(node_);
+    node_->ReplaceInput(2, effect);
+    node_->ReplaceInput(3, control);
+
+    node_->TrimInputCount(4);
+    NodeProperties::ChangeOp(node_, op);
+
+    if (invert) {
+      // Insert a boolean-not to invert the value.
+      Node* value = graph()->NewNode(simplified()->BooleanNot(), node_);
+      node_->ReplaceUses(value);
+      // Note: ReplaceUses() smashes all uses, so smash it back here.
+      value->ReplaceInput(0, node_);
+      return lowering_->Replace(value);
+    }
+    return lowering_->Changed(node_);
+  }
+
   Reduction ChangeToPureOperator(const Operator* op, Type* type) {
     return ChangeToPureOperator(op, false, type);
   }
 
-  bool OneInputIs(Type* t) { return left_type_->Is(t) || right_type_->Is(t); }
-
-  bool BothInputsAre(Type* t) {
-    return left_type_->Is(t) && right_type_->Is(t);
+  // TODO(turbofan): Strong mode should be killed soonish!
+  bool IsStrong() const {
+    if (node_->opcode() == IrOpcode::kJSLessThan ||
+        node_->opcode() == IrOpcode::kJSLessThanOrEqual ||
+        node_->opcode() == IrOpcode::kJSGreaterThan ||
+        node_->opcode() == IrOpcode::kJSGreaterThanOrEqual) {
+      return is_strong(OpParameter<LanguageMode>(node_));
+    }
+    return is_strong(BinaryOperationParametersOf(node_->op()).language_mode());
   }
 
+  bool LeftInputIs(Type* t) { return left_type()->Is(t); }
+
+  bool RightInputIs(Type* t) { return right_type()->Is(t); }
+
+  bool OneInputIs(Type* t) { return LeftInputIs(t) || RightInputIs(t); }
+
+  bool BothInputsAre(Type* t) { return LeftInputIs(t) && RightInputIs(t); }
+
   bool OneInputCannotBe(Type* t) {
-    return !left_type_->Maybe(t) || !right_type_->Maybe(t);
+    return !left_type()->Maybe(t) || !right_type()->Maybe(t);
   }
 
   bool NeitherInputCanBe(Type* t) {
-    return !left_type_->Maybe(t) && !right_type_->Maybe(t);
+    return !left_type()->Maybe(t) && !right_type()->Maybe(t);
   }
 
   Node* effect() { return NodeProperties::GetEffectInput(node_); }
@@ -168,46 +250,161 @@
   Node* context() { return NodeProperties::GetContextInput(node_); }
   Node* left() { return NodeProperties::GetValueInput(node_, 0); }
   Node* right() { return NodeProperties::GetValueInput(node_, 1); }
-  Type* left_type() { return left_type_; }
-  Type* right_type() { return right_type_; }
+  Type* left_type() { return NodeProperties::GetType(node_->InputAt(0)); }
+  Type* right_type() { return NodeProperties::GetType(node_->InputAt(1)); }
 
   SimplifiedOperatorBuilder* simplified() { return lowering_->simplified(); }
   Graph* graph() const { return lowering_->graph(); }
   JSGraph* jsgraph() { return lowering_->jsgraph(); }
   JSOperatorBuilder* javascript() { return lowering_->javascript(); }
   MachineOperatorBuilder* machine() { return lowering_->machine(); }
+  CommonOperatorBuilder* common() { return jsgraph()->common(); }
   Zone* zone() const { return graph()->zone(); }
 
  private:
   JSTypedLowering* lowering_;  // The containing lowering instance.
   Node* node_;                 // The original node.
-  Type* left_type_;            // Cache of the left input's type.
-  Type* right_type_;           // Cache of the right input's type.
 
-  Node* ConvertToString(Node* node) {
-    // Avoid introducing too many eager ToString() operations.
-    Reduction reduced = lowering_->ReduceJSToStringInput(node);
-    if (reduced.Changed()) return reduced.replacement();
-    Node* n = graph()->NewNode(javascript()->ToString(), node, context(),
-                               effect(), control());
+  Node* CreateFrameStateForLeftInput(Node* frame_state) {
+    FrameStateInfo state_info = OpParameter<FrameStateInfo>(frame_state);
+
+    if (state_info.bailout_id() == BailoutId::None()) {
+      // Dummy frame state => just leave it as is.
+      return frame_state;
+    }
+
+    // If the frame state is already the right one, just return it.
+    if (state_info.state_combine().kind() == OutputFrameStateCombine::kPokeAt &&
+        state_info.state_combine().GetOffsetToPokeAt() == 1) {
+      return frame_state;
+    }
+
+    // Here, we smash the result of the conversion into the slot just below
+    // the stack top. This is the slot that full code uses to store the
+    // left operand.
+    const Operator* op = jsgraph()->common()->FrameState(
+        state_info.bailout_id(), OutputFrameStateCombine::PokeAt(1),
+        state_info.function_info());
+
+    return graph()->NewNode(op,
+                            frame_state->InputAt(kFrameStateParametersInput),
+                            frame_state->InputAt(kFrameStateLocalsInput),
+                            frame_state->InputAt(kFrameStateStackInput),
+                            frame_state->InputAt(kFrameStateContextInput),
+                            frame_state->InputAt(kFrameStateFunctionInput),
+                            frame_state->InputAt(kFrameStateOuterStateInput));
+  }
+
+  Node* CreateFrameStateForRightInput(Node* frame_state, Node* converted_left) {
+    FrameStateInfo state_info = OpParameter<FrameStateInfo>(frame_state);
+
+    if (state_info.bailout_id() == BailoutId::None()) {
+      // Dummy frame state => just leave it as is.
+      return frame_state;
+    }
+
+    // Create a frame state that stores the result of the operation to the
+    // top of the stack (i.e., the slot used for the right operand).
+    const Operator* op = jsgraph()->common()->FrameState(
+        state_info.bailout_id(), OutputFrameStateCombine::PokeAt(0),
+        state_info.function_info());
+
+    // Change the left operand {converted_left} on the expression stack.
+    Node* stack = frame_state->InputAt(2);
+    DCHECK_EQ(stack->opcode(), IrOpcode::kStateValues);
+    DCHECK_GE(stack->InputCount(), 2);
+
+    // TODO(jarin) Allocate in a local zone or a reusable buffer.
+    NodeVector new_values(stack->InputCount(), zone());
+    for (int i = 0; i < stack->InputCount(); i++) {
+      if (i == stack->InputCount() - 2) {
+        new_values[i] = converted_left;
+      } else {
+        new_values[i] = stack->InputAt(i);
+      }
+    }
+    Node* new_stack =
+        graph()->NewNode(stack->op(), stack->InputCount(), &new_values.front());
+
+    return graph()->NewNode(
+        op, frame_state->InputAt(kFrameStateParametersInput),
+        frame_state->InputAt(kFrameStateLocalsInput), new_stack,
+        frame_state->InputAt(kFrameStateContextInput),
+        frame_state->InputAt(kFrameStateFunctionInput),
+        frame_state->InputAt(kFrameStateOuterStateInput));
+  }
+
+  Node* ConvertPlainPrimitiveToNumber(Node* node) {
+    DCHECK(NodeProperties::GetType(node)->Is(Type::PlainPrimitive()));
+    // Avoid inserting too many eager ToNumber() operations.
+    Reduction const reduction = lowering_->ReduceJSToNumberInput(node);
+    if (reduction.Changed()) return reduction.replacement();
+    // TODO(jarin) Use PlainPrimitiveToNumber once we have it.
+    return graph()->NewNode(
+        javascript()->ToNumber(), node, jsgraph()->NoContextConstant(),
+        jsgraph()->EmptyFrameState(), graph()->start(), graph()->start());
+  }
+
+  Node* ConvertSingleInputToNumber(Node* node, Node* frame_state) {
+    DCHECK(!NodeProperties::GetType(node)->Is(Type::PlainPrimitive()));
+    Node* const n = graph()->NewNode(javascript()->ToNumber(), node, context(),
+                                     frame_state, effect(), control());
+    NodeProperties::ReplaceUses(node_, node_, node_, n, n);
     update_effect(n);
     return n;
   }
 
-  Node* ConvertToNumber(Node* node) {
-    if (NodeProperties::GetBounds(node).upper->Is(Type::PlainPrimitive())) {
-      return lowering_->ConvertToNumber(node);
+  void ConvertBothInputsToNumber(Node** left_result, Node** right_result,
+                                 Node* frame_state) {
+    Node* projections[2];
+
+    // Find {IfSuccess} and {IfException} continuations of the operation.
+    NodeProperties::CollectControlProjections(node_, projections, 2);
+    IfExceptionHint hint = OpParameter<IfExceptionHint>(projections[1]);
+    Node* if_exception = projections[1];
+    Node* if_success = projections[0];
+
+    // Insert two ToNumber() operations that both potentially throw.
+    Node* left_state = CreateFrameStateForLeftInput(frame_state);
+    Node* left_conv =
+        graph()->NewNode(javascript()->ToNumber(), left(), context(),
+                         left_state, effect(), control());
+    Node* left_success = graph()->NewNode(common()->IfSuccess(), left_conv);
+    Node* right_state = CreateFrameStateForRightInput(frame_state, left_conv);
+    Node* right_conv =
+        graph()->NewNode(javascript()->ToNumber(), right(), context(),
+                         right_state, left_conv, left_success);
+    Node* left_exception =
+        graph()->NewNode(common()->IfException(hint), left_conv, left_conv);
+    Node* right_exception =
+        graph()->NewNode(common()->IfException(hint), right_conv, right_conv);
+    NodeProperties::ReplaceControlInput(if_success, right_conv);
+    update_effect(right_conv);
+
+    // Wire conversions to existing {IfException} continuation.
+    Node* exception_merge = if_exception;
+    Node* exception_value =
+        graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
+                         left_exception, right_exception, exception_merge);
+    Node* exception_effect =
+        graph()->NewNode(common()->EffectPhi(2), left_exception,
+                         right_exception, exception_merge);
+    for (Edge edge : exception_merge->use_edges()) {
+      if (NodeProperties::IsEffectEdge(edge)) edge.UpdateTo(exception_effect);
+      if (NodeProperties::IsValueEdge(edge)) edge.UpdateTo(exception_value);
     }
-    Node* n = graph()->NewNode(javascript()->ToNumber(), node, context(),
-                               effect(), control());
-    update_effect(n);
-    return n;
+    NodeProperties::RemoveType(exception_merge);
+    exception_merge->ReplaceInput(0, left_exception);
+    exception_merge->ReplaceInput(1, right_exception);
+    NodeProperties::ChangeOp(exception_merge, common()->Merge(2));
+
+    *left_result = left_conv;
+    *right_result = right_conv;
   }
 
   Node* ConvertToUI32(Node* node, Signedness signedness) {
     // Avoid introducing too many eager NumberToXXnt32() operations.
-    node = ConvertToNumber(node);
-    Type* type = NodeProperties::GetBounds(node).upper;
+    Type* type = NodeProperties::GetType(node);
     if (signedness == kSigned) {
       if (!type->Is(Type::Signed32())) {
         node = graph()->NewNode(simplified()->NumberToInt32(), node);
@@ -227,127 +424,134 @@
 };
 
 
+// TODO(turbofan): js-typed-lowering improvements possible
+// - immediately put in type bounds for all new nodes
+// - relax effects from generic but not-side-effecting operations
+
+
+JSTypedLowering::JSTypedLowering(Editor* editor,
+                                 CompilationDependencies* dependencies,
+                                 Flags flags, JSGraph* jsgraph, Zone* zone)
+    : AdvancedReducer(editor),
+      dependencies_(dependencies),
+      flags_(flags),
+      jsgraph_(jsgraph),
+      true_type_(Type::Constant(factory()->true_value(), graph()->zone())),
+      false_type_(Type::Constant(factory()->false_value(), graph()->zone())),
+      the_hole_type_(
+          Type::Constant(factory()->the_hole_value(), graph()->zone())),
+      type_cache_(TypeCache::Get()) {
+  for (size_t k = 0; k < arraysize(shifted_int32_ranges_); ++k) {
+    double min = kMinInt / (1 << k);
+    double max = kMaxInt / (1 << k);
+    shifted_int32_ranges_[k] = Type::Range(min, max, graph()->zone());
+  }
+}
+
+
 Reduction JSTypedLowering::ReduceJSAdd(Node* node) {
+  if (flags() & kDisableBinaryOpReduction) return NoChange();
+
   JSBinopReduction r(this, node);
   if (r.BothInputsAre(Type::Number())) {
     // JSAdd(x:number, y:number) => NumberAdd(x, y)
     return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number());
   }
-  if (r.BothInputsAre(Type::Primitive()) &&
-      r.NeitherInputCanBe(Type::StringOrReceiver())) {
+  if (r.NeitherInputCanBe(Type::StringOrReceiver()) && !r.IsStrong()) {
     // JSAdd(x:-string, y:-string) => NumberAdd(ToNumber(x), ToNumber(y))
-    r.ConvertInputsToNumber();
+    Node* frame_state = NodeProperties::GetFrameStateInput(node, 1);
+    r.ConvertInputsToNumber(frame_state);
     return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number());
   }
-#if 0
-  // TODO(turbofan): General ToNumber disabled for now because:
-  //   a) The inserted ToNumber operation screws up observability of valueOf.
-  //   b) Deoptimization at ToNumber doesn't have corresponding bailout id.
-  Type* maybe_string = Type::Union(Type::String(), Type::Receiver(), zone());
-  if (r.NeitherInputCanBe(maybe_string)) {
-    ...
-  }
-#endif
-#if 0
-  // TODO(turbofan): Lowering of StringAdd is disabled for now because:
-  //   a) The inserted ToString operation screws up valueOf vs. toString order.
-  //   b) Deoptimization at ToString doesn't have corresponding bailout id.
-  //   c) Our current StringAddStub is actually non-pure and requires context.
-  if (r.OneInputIs(Type::String())) {
-    // JSAdd(x:string, y:string) => StringAdd(x, y)
-    // JSAdd(x:string, y) => StringAdd(x, ToString(y))
-    // JSAdd(x, y:string) => StringAdd(ToString(x), y)
-    r.ConvertInputsToString();
-    return r.ChangeToPureOperator(simplified()->StringAdd());
-  }
-#endif
-  return NoChange();
-}
-
-
-Reduction JSTypedLowering::ReduceJSBitwiseOr(Node* node) {
-  JSBinopReduction r(this, node);
-  if (r.BothInputsAre(Type::Primitive()) || r.OneInputIs(zero_range_)) {
-    // TODO(jarin): Propagate frame state input from non-primitive input node to
-    // JSToNumber node.
-    // TODO(titzer): some Smi bitwise operations don't really require going
-    // all the way to int32, which can save tagging/untagging for some
-    // operations
-    // on some platforms.
-    // TODO(turbofan): make this heuristic configurable for code size.
-    r.ConvertInputsToUI32(kSigned, kSigned);
-    return r.ChangeToPureOperator(machine()->Word32Or(), Type::Integral32());
+  if (r.BothInputsAre(Type::String())) {
+    // JSAdd(x:string, y:string) => CallStub[StringAdd](x, y)
+    Callable const callable =
+        CodeFactory::StringAdd(isolate(), STRING_ADD_CHECK_NONE, NOT_TENURED);
+    CallDescriptor const* const desc = Linkage::GetStubCallDescriptor(
+        isolate(), graph()->zone(), callable.descriptor(), 0,
+        CallDescriptor::kNeedsFrameState, node->op()->properties());
+    DCHECK_EQ(2, OperatorProperties::GetFrameStateInputCount(node->op()));
+    node->RemoveInput(NodeProperties::FirstFrameStateIndex(node) + 1);
+    node->InsertInput(graph()->zone(), 0,
+                      jsgraph()->HeapConstant(callable.code()));
+    NodeProperties::ChangeOp(node, common()->Call(desc));
+    return Changed(node);
   }
   return NoChange();
 }
 
 
-Reduction JSTypedLowering::ReduceJSMultiply(Node* node) {
+Reduction JSTypedLowering::ReduceJSModulus(Node* node) {
+  if (flags() & kDisableBinaryOpReduction) return NoChange();
+
   JSBinopReduction r(this, node);
-  if (r.BothInputsAre(Type::Primitive()) || r.OneInputIs(one_range_)) {
-    // TODO(jarin): Propagate frame state input from non-primitive input node to
-    // JSToNumber node.
-    r.ConvertInputsToNumber();
-    return r.ChangeToPureOperator(simplified()->NumberMultiply(),
+  if (r.BothInputsAre(Type::Number())) {
+    // JSModulus(x:number, x:number) => NumberModulus(x, y)
+    return r.ChangeToPureOperator(simplified()->NumberModulus(),
                                   Type::Number());
   }
-  // TODO(turbofan): relax/remove the effects of this operator in other cases.
   return NoChange();
 }
 
 
 Reduction JSTypedLowering::ReduceNumberBinop(Node* node,
                                              const Operator* numberOp) {
+  if (flags() & kDisableBinaryOpReduction) return NoChange();
+
   JSBinopReduction r(this, node);
-  if (r.BothInputsAre(Type::Primitive())) {
-    r.ConvertInputsToNumber();
-    return r.ChangeToPureOperator(numberOp, Type::Number());
+  if (r.IsStrong() || numberOp == simplified()->NumberModulus()) {
+    if (r.BothInputsAre(Type::Number())) {
+      return r.ChangeToPureOperator(numberOp, Type::Number());
+    }
+    return NoChange();
   }
-#if 0
-  // TODO(turbofan): General ToNumber disabled for now because:
-  //   a) The inserted ToNumber operation screws up observability of valueOf.
-  //   b) Deoptimization at ToNumber doesn't have corresponding bailout id.
-  if (r.OneInputIs(Type::Primitive())) {
-    // If at least one input is a primitive, then insert appropriate conversions
-    // to number and reduce this operator to the given numeric one.
-    // TODO(turbofan): make this heuristic configurable for code size.
-    r.ConvertInputsToNumber();
-    return r.ChangeToPureOperator(numberOp);
-  }
-#endif
-  // TODO(turbofan): relax/remove the effects of this operator in other cases.
-  return NoChange();
+  Node* frame_state = NodeProperties::GetFrameStateInput(node, 1);
+  r.ConvertInputsToNumber(frame_state);
+  return r.ChangeToPureOperator(numberOp, Type::Number());
 }
 
 
 Reduction JSTypedLowering::ReduceInt32Binop(Node* node, const Operator* intOp) {
+  if (flags() & kDisableBinaryOpReduction) return NoChange();
+
   JSBinopReduction r(this, node);
-  if (r.BothInputsAre(Type::Primitive())) {
-    // TODO(titzer): some Smi bitwise operations don't really require going
-    // all the way to int32, which can save tagging/untagging for some
-    // operations
-    // on some platforms.
-    // TODO(turbofan): make this heuristic configurable for code size.
-    r.ConvertInputsToUI32(kSigned, kSigned);
-    return r.ChangeToPureOperator(intOp, Type::Integral32());
+  if (r.IsStrong()) {
+    if (r.BothInputsAre(Type::Number())) {
+      r.ConvertInputsToUI32(kSigned, kSigned);
+      return r.ChangeToPureOperator(intOp, Type::Integral32());
+    }
+    return NoChange();
   }
-  return NoChange();
+  Node* frame_state = NodeProperties::GetFrameStateInput(node, 1);
+  r.ConvertInputsToNumber(frame_state);
+  r.ConvertInputsToUI32(kSigned, kSigned);
+  return r.ChangeToPureOperator(intOp, Type::Integral32());
 }
 
 
 Reduction JSTypedLowering::ReduceUI32Shift(Node* node,
                                            Signedness left_signedness,
                                            const Operator* shift_op) {
+  if (flags() & kDisableBinaryOpReduction) return NoChange();
+
   JSBinopReduction r(this, node);
-  if (r.BothInputsAre(Type::Primitive())) {
-    r.ConvertInputsForShift(left_signedness);
-    return r.ChangeToPureOperator(shift_op, Type::Integral32());
+  if (r.IsStrong()) {
+    if (r.BothInputsAre(Type::Number())) {
+      r.ConvertInputsToUI32(left_signedness, kUnsigned);
+      return r.ChangeToPureOperator(shift_op);
+    }
+    return NoChange();
   }
-  return NoChange();
+  Node* frame_state = NodeProperties::GetFrameStateInput(node, 1);
+  r.ConvertInputsToNumber(frame_state);
+  r.ConvertInputsToUI32(left_signedness, kUnsigned);
+  return r.ChangeToPureOperator(shift_op);
 }
 
 
 Reduction JSTypedLowering::ReduceJSComparison(Node* node) {
+  if (flags() & kDisableBinaryOpReduction) return NoChange();
+
   JSBinopReduction r(this, node);
   if (r.BothInputsAre(Type::String())) {
     // If both inputs are definitely strings, perform a string comparison.
@@ -370,20 +574,10 @@
       default:
         return NoChange();
     }
-    return r.ChangeToPureOperator(stringOp);
+    r.ChangeToStringComparisonOperator(stringOp);
+    return Changed(node);
   }
-#if 0
-  // TODO(turbofan): General ToNumber disabled for now because:
-  //   a) The inserted ToNumber operation screws up observability of valueOf.
-  //   b) Deoptimization at ToNumber doesn't have corresponding bailout id.
-  Type* maybe_string = Type::Union(Type::String(), Type::Receiver(), zone());
-  if (r.OneInputCannotBe(maybe_string)) {
-    // If one input cannot be a string, then emit a number comparison.
-    ...
-  }
-#endif
-  if (r.BothInputsAre(Type::Primitive()) &&
-      r.OneInputCannotBe(Type::StringOrReceiver())) {
+  if (r.OneInputCannotBe(Type::StringOrReceiver())) {
     const Operator* less_than;
     const Operator* less_than_or_equal;
     if (r.BothInputsAre(Type::Unsigned32())) {
@@ -394,7 +588,11 @@
       less_than_or_equal = machine()->Int32LessThanOrEqual();
     } else {
       // TODO(turbofan): mixed signed/unsigned int32 comparisons.
-      r.ConvertInputsToNumber();
+      if (r.IsStrong() && !r.BothInputsAre(Type::Number())) {
+        return NoChange();
+      }
+      Node* frame_state = NodeProperties::GetFrameStateInput(node, 1);
+      r.ConvertInputsToNumber(frame_state);
       less_than = simplified()->NumberLessThan();
       less_than_or_equal = simplified()->NumberLessThanOrEqual();
     }
@@ -425,40 +623,73 @@
 
 
 Reduction JSTypedLowering::ReduceJSEqual(Node* node, bool invert) {
+  if (flags() & kDisableBinaryOpReduction) return NoChange();
+
   JSBinopReduction r(this, node);
 
   if (r.BothInputsAre(Type::Number())) {
     return r.ChangeToPureOperator(simplified()->NumberEqual(), invert);
   }
   if (r.BothInputsAre(Type::String())) {
-    return r.ChangeToPureOperator(simplified()->StringEqual(), invert);
+    return r.ChangeToStringComparisonOperator(simplified()->StringEqual(),
+                                              invert);
+  }
+  if (r.BothInputsAre(Type::Boolean())) {
+    return r.ChangeToPureOperator(simplified()->ReferenceEqual(Type::Boolean()),
+                                  invert);
   }
   if (r.BothInputsAre(Type::Receiver())) {
     return r.ChangeToPureOperator(
         simplified()->ReferenceEqual(Type::Receiver()), invert);
   }
-  // TODO(turbofan): js-typed-lowering of Equal(undefined)
-  // TODO(turbofan): js-typed-lowering of Equal(null)
-  // TODO(turbofan): js-typed-lowering of Equal(boolean)
+  if (r.OneInputIs(Type::NullOrUndefined())) {
+    Callable const callable = CodeFactory::CompareNilIC(isolate(), kNullValue);
+    CallDescriptor const* const desc = Linkage::GetStubCallDescriptor(
+        isolate(), graph()->zone(), callable.descriptor(), 0,
+        CallDescriptor::kNeedsFrameState, node->op()->properties());
+    node->RemoveInput(r.LeftInputIs(Type::NullOrUndefined()) ? 0 : 1);
+    node->InsertInput(graph()->zone(), 0,
+                      jsgraph()->HeapConstant(callable.code()));
+    NodeProperties::ChangeOp(node, common()->Call(desc));
+    if (invert) {
+      // Insert an boolean not to invert the value.
+      Node* value = graph()->NewNode(simplified()->BooleanNot(), node);
+      node->ReplaceUses(value);
+      // Note: ReplaceUses() smashes all uses, so smash it back here.
+      value->ReplaceInput(0, node);
+      return Replace(value);
+    }
+    return Changed(node);
+  }
   return NoChange();
 }
 
 
 Reduction JSTypedLowering::ReduceJSStrictEqual(Node* node, bool invert) {
+  if (flags() & kDisableBinaryOpReduction) return NoChange();
+
   JSBinopReduction r(this, node);
   if (r.left() == r.right()) {
     // x === x is always true if x != NaN
     if (!r.left_type()->Maybe(Type::NaN())) {
-      return ReplaceEagerly(node, jsgraph()->BooleanConstant(!invert));
+      Node* replacement = jsgraph()->BooleanConstant(!invert);
+      ReplaceWithValue(node, replacement);
+      return Replace(replacement);
     }
   }
   if (r.OneInputCannotBe(Type::NumberOrString())) {
     // For values with canonical representation (i.e. not string nor number) an
     // empty type intersection means the values cannot be strictly equal.
     if (!r.left_type()->Maybe(r.right_type())) {
-      return ReplaceEagerly(node, jsgraph()->BooleanConstant(invert));
+      Node* replacement = jsgraph()->BooleanConstant(invert);
+      ReplaceWithValue(node, replacement);
+      return Replace(replacement);
     }
   }
+  if (r.OneInputIs(the_hole_type_)) {
+    return r.ChangeToPureOperator(simplified()->ReferenceEqual(the_hole_type_),
+                                  invert);
+  }
   if (r.OneInputIs(Type::Undefined())) {
     return r.ChangeToPureOperator(
         simplified()->ReferenceEqual(Type::Undefined()), invert);
@@ -479,8 +710,13 @@
     return r.ChangeToPureOperator(
         simplified()->ReferenceEqual(Type::Receiver()), invert);
   }
+  if (r.BothInputsAre(Type::Unique())) {
+    return r.ChangeToPureOperator(simplified()->ReferenceEqual(Type::Unique()),
+                                  invert);
+  }
   if (r.BothInputsAre(Type::String())) {
-    return r.ChangeToPureOperator(simplified()->StringEqual(), invert);
+    return r.ChangeToStringComparisonOperator(simplified()->StringEqual(),
+                                              invert);
   }
   if (r.BothInputsAre(Type::Number())) {
     return r.ChangeToPureOperator(simplified()->NumberEqual(), invert);
@@ -490,34 +726,35 @@
 }
 
 
-Reduction JSTypedLowering::ReduceJSUnaryNot(Node* node) {
-  Node* input = node->InputAt(0);
-  Type* input_type = NodeProperties::GetBounds(input).upper;
+Reduction JSTypedLowering::ReduceJSToBoolean(Node* node) {
+  Node* const input = node->InputAt(0);
+  Type* const input_type = NodeProperties::GetType(input);
+  Node* const effect = NodeProperties::GetEffectInput(node);
   if (input_type->Is(Type::Boolean())) {
-    // JSUnaryNot(x:boolean,context) => BooleanNot(x)
-    node->set_op(simplified()->BooleanNot());
+    // JSToBoolean(x:boolean) => x
+    ReplaceWithValue(node, input, effect);
+    return Replace(input);
+  } else if (input_type->Is(Type::OrderedNumber())) {
+    // JSToBoolean(x:ordered-number) => BooleanNot(NumberEqual(x,#0))
+    RelaxEffectsAndControls(node);
+    node->ReplaceInput(0, graph()->NewNode(simplified()->NumberEqual(), input,
+                                           jsgraph()->ZeroConstant()));
     node->TrimInputCount(1);
+    NodeProperties::ChangeOp(node, simplified()->BooleanNot());
+    return Changed(node);
+  } else if (input_type->Is(Type::String())) {
+    // JSToBoolean(x:string) => NumberLessThan(#0,x.length)
+    FieldAccess const access = AccessBuilder::ForStringLength();
+    Node* length = graph()->NewNode(simplified()->LoadField(access), input,
+                                    effect, graph()->start());
+    ReplaceWithValue(node, node, length);
+    node->ReplaceInput(0, jsgraph()->ZeroConstant());
+    node->ReplaceInput(1, length);
+    node->TrimInputCount(2);
+    NodeProperties::ChangeOp(node, simplified()->NumberLessThan());
     return Changed(node);
   }
-  // JSUnaryNot(x,context) => BooleanNot(AnyToBoolean(x))
-  node->set_op(simplified()->BooleanNot());
-  node->ReplaceInput(0, graph()->NewNode(simplified()->AnyToBoolean(), input));
-  node->TrimInputCount(1);
-  return Changed(node);
-}
-
-
-Reduction JSTypedLowering::ReduceJSToBoolean(Node* node) {
-  Node* input = node->InputAt(0);
-  Type* input_type = NodeProperties::GetBounds(input).upper;
-  if (input_type->Is(Type::Boolean())) {
-    // JSToBoolean(x:boolean,context) => x
-    return Replace(input);
-  }
-  // JSToBoolean(x,context) => AnyToBoolean(x)
-  node->set_op(simplified()->AnyToBoolean());
-  node->TrimInputCount(1);
-  return Changed(node);
+  return NoChange();
 }
 
 
@@ -528,10 +765,23 @@
     if (result.Changed()) return result;
     return Changed(input);  // JSToNumber(JSToNumber(x)) => JSToNumber(x)
   }
+  // Check for ToNumber truncation of signaling NaN to undefined mapping.
+  if (input->opcode() == IrOpcode::kSelect) {
+    Node* check = NodeProperties::GetValueInput(input, 0);
+    Node* vtrue = NodeProperties::GetValueInput(input, 1);
+    Type* vtrue_type = NodeProperties::GetType(vtrue);
+    Node* vfalse = NodeProperties::GetValueInput(input, 2);
+    Type* vfalse_type = NodeProperties::GetType(vfalse);
+    if (vtrue_type->Is(Type::Undefined()) && vfalse_type->Is(Type::Number())) {
+      if (check->opcode() == IrOpcode::kNumberIsHoleNaN &&
+          check->InputAt(0) == vfalse) {
+        // JSToNumber(Select(NumberIsHoleNaN(x), y:undefined, x:number)) => x
+        return Replace(vfalse);
+      }
+    }
+  }
   // Check if we have a cached conversion.
-  Node* conversion = FindConversion<IrOpcode::kJSToNumber>(input);
-  if (conversion) return Replace(conversion);
-  Type* input_type = NodeProperties::GetBounds(input).upper;
+  Type* input_type = NodeProperties::GetType(input);
   if (input_type->Is(Type::Number())) {
     // JSToNumber(x:number) => x
     return Changed(input);
@@ -558,81 +808,24 @@
   Node* const input = node->InputAt(0);
   Reduction reduction = ReduceJSToNumberInput(input);
   if (reduction.Changed()) {
-    NodeProperties::ReplaceWithValue(node, reduction.replacement());
+    ReplaceWithValue(node, reduction.replacement());
     return reduction;
   }
-  Type* const input_type = NodeProperties::GetBounds(input).upper;
+  Type* const input_type = NodeProperties::GetType(input);
   if (input_type->Is(Type::PlainPrimitive())) {
-    if (input->opcode() == IrOpcode::kPhi) {
-      // JSToNumber(phi(x1,...,xn,control):plain-primitive,context)
-      //   => phi(JSToNumber(x1,no-context),
-      //          ...,
-      //          JSToNumber(xn,no-context),control)
-      int const input_count = input->InputCount() - 1;
-      Node* const control = input->InputAt(input_count);
-      DCHECK_LE(0, input_count);
-      DCHECK(NodeProperties::IsControl(control));
-      DCHECK(NodeProperties::GetBounds(node).upper->Is(Type::Number()));
-      DCHECK(!NodeProperties::GetBounds(input).upper->Is(Type::Number()));
-      RelaxEffects(node);
-      node->set_op(common()->Phi(kMachAnyTagged, input_count));
-      for (int i = 0; i < input_count; ++i) {
-        // We must be very careful not to introduce cycles when pushing
-        // operations into phis. It is safe for {value}, since it appears
-        // as input to the phi that we are replacing, but it's not safe
-        // to simply reuse the context of the {node}. However, ToNumber()
-        // does not require a context anyways, so it's safe to discard it
-        // here and pass the dummy context.
-        Node* const value = ConvertToNumber(input->InputAt(i));
-        if (i < node->InputCount()) {
-          node->ReplaceInput(i, value);
-        } else {
-          node->AppendInput(graph()->zone(), value);
-        }
-      }
-      if (input_count < node->InputCount()) {
-        node->ReplaceInput(input_count, control);
-      } else {
-        node->AppendInput(graph()->zone(), control);
-      }
-      node->TrimInputCount(input_count + 1);
-      return Changed(node);
-    }
-    if (input->opcode() == IrOpcode::kSelect) {
-      // JSToNumber(select(c,x1,x2):plain-primitive,context)
-      //   => select(c,JSToNumber(x1,no-context),JSToNumber(x2,no-context))
-      int const input_count = input->InputCount();
-      BranchHint const input_hint = SelectParametersOf(input->op()).hint();
-      DCHECK_EQ(3, input_count);
-      DCHECK(NodeProperties::GetBounds(node).upper->Is(Type::Number()));
-      DCHECK(!NodeProperties::GetBounds(input).upper->Is(Type::Number()));
-      RelaxEffects(node);
-      node->set_op(common()->Select(kMachAnyTagged, input_hint));
-      node->ReplaceInput(0, input->InputAt(0));
-      for (int i = 1; i < input_count; ++i) {
-        // We must be very careful not to introduce cycles when pushing
-        // operations into selects. It is safe for {value}, since it appears
-        // as input to the select that we are replacing, but it's not safe
-        // to simply reuse the context of the {node}. However, ToNumber()
-        // does not require a context anyways, so it's safe to discard it
-        // here and pass the dummy context.
-        Node* const value = ConvertToNumber(input->InputAt(i));
-        node->ReplaceInput(i, value);
-      }
-      node->TrimInputCount(input_count);
-      return Changed(node);
-    }
-    // Remember this conversion.
-    InsertConversion(node);
-    if (node->InputAt(1) != jsgraph()->NoContextConstant() ||
-        node->InputAt(2) != graph()->start() ||
-        node->InputAt(3) != graph()->start()) {
+    if (NodeProperties::GetContextInput(node) !=
+            jsgraph()->NoContextConstant() ||
+        NodeProperties::GetEffectInput(node) != graph()->start() ||
+        NodeProperties::GetControlInput(node) != graph()->start()) {
       // JSToNumber(x:plain-primitive,context,effect,control)
       //   => JSToNumber(x,no-context,start,start)
-      RelaxEffects(node);
-      node->ReplaceInput(1, jsgraph()->NoContextConstant());
-      node->ReplaceInput(2, graph()->start());
-      node->ReplaceInput(3, graph()->start());
+      RelaxEffectsAndControls(node);
+      NodeProperties::ReplaceContextInput(node, jsgraph()->NoContextConstant());
+      NodeProperties::ReplaceControlInput(node, graph()->start());
+      NodeProperties::ReplaceEffectInput(node, graph()->start());
+      DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
+      NodeProperties::ReplaceFrameStateInput(node, 0,
+                                             jsgraph()->EmptyFrameState());
       return Changed(node);
     }
   }
@@ -647,17 +840,22 @@
     if (result.Changed()) return result;
     return Changed(input);  // JSToString(JSToString(x)) => JSToString(x)
   }
-  Type* input_type = NodeProperties::GetBounds(input).upper;
+  Type* input_type = NodeProperties::GetType(input);
   if (input_type->Is(Type::String())) {
     return Changed(input);  // JSToString(x:string) => x
   }
+  if (input_type->Is(Type::Boolean())) {
+    return Replace(graph()->NewNode(
+        common()->Select(MachineRepresentation::kTagged), input,
+        jsgraph()->HeapConstant(factory()->true_string()),
+        jsgraph()->HeapConstant(factory()->false_string())));
+  }
   if (input_type->Is(Type::Undefined())) {
     return Replace(jsgraph()->HeapConstant(factory()->undefined_string()));
   }
   if (input_type->Is(Type::Null())) {
     return Replace(jsgraph()->HeapConstant(factory()->null_string()));
   }
-  // TODO(turbofan): js-typed-lowering of ToString(x:boolean)
   // TODO(turbofan): js-typed-lowering of ToString(x:number)
   return NoChange();
 }
@@ -668,50 +866,173 @@
   Node* const input = node->InputAt(0);
   Reduction reduction = ReduceJSToStringInput(input);
   if (reduction.Changed()) {
-    NodeProperties::ReplaceWithValue(node, reduction.replacement());
+    ReplaceWithValue(node, reduction.replacement());
     return reduction;
   }
   return NoChange();
 }
 
 
+Reduction JSTypedLowering::ReduceJSToObject(Node* node) {
+  DCHECK_EQ(IrOpcode::kJSToObject, node->opcode());
+  Node* receiver = NodeProperties::GetValueInput(node, 0);
+  Type* receiver_type = NodeProperties::GetType(receiver);
+  Node* context = NodeProperties::GetContextInput(node);
+  Node* frame_state = NodeProperties::GetFrameStateInput(node, 0);
+  Node* effect = NodeProperties::GetEffectInput(node);
+  Node* control = NodeProperties::GetControlInput(node);
+  if (!receiver_type->Is(Type::Receiver())) {
+    // TODO(bmeurer/mstarzinger): Add support for lowering inside try blocks.
+    if (receiver_type->Maybe(Type::NullOrUndefined()) &&
+        NodeProperties::IsExceptionalCall(node)) {
+      // ToObject throws for null or undefined inputs.
+      return NoChange();
+    }
+
+    // Check whether {receiver} is a Smi.
+    Node* check0 = graph()->NewNode(simplified()->ObjectIsSmi(), receiver);
+    Node* branch0 =
+        graph()->NewNode(common()->Branch(BranchHint::kFalse), check0, control);
+    Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
+    Node* etrue0 = effect;
+
+    Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
+    Node* efalse0 = effect;
+
+    // Determine the instance type of {receiver}.
+    Node* receiver_map = efalse0 =
+        graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
+                         receiver, efalse0, if_false0);
+    Node* receiver_instance_type = efalse0 = graph()->NewNode(
+        simplified()->LoadField(AccessBuilder::ForMapInstanceType()),
+        receiver_map, efalse0, if_false0);
+
+    // Check whether {receiver} is a spec object.
+    STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
+    Node* check1 =
+        graph()->NewNode(machine()->Uint32LessThanOrEqual(),
+                         jsgraph()->Uint32Constant(FIRST_JS_RECEIVER_TYPE),
+                         receiver_instance_type);
+    Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kTrue),
+                                     check1, if_false0);
+    Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
+    Node* etrue1 = efalse0;
+
+    Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
+    Node* efalse1 = efalse0;
+
+    // Convert {receiver} using the ToObjectStub.
+    Node* if_convert =
+        graph()->NewNode(common()->Merge(2), if_true0, if_false1);
+    Node* econvert =
+        graph()->NewNode(common()->EffectPhi(2), etrue0, efalse1, if_convert);
+    Node* rconvert;
+    {
+      Callable callable = CodeFactory::ToObject(isolate());
+      CallDescriptor const* const desc = Linkage::GetStubCallDescriptor(
+          isolate(), graph()->zone(), callable.descriptor(), 0,
+          CallDescriptor::kNeedsFrameState, node->op()->properties());
+      rconvert = econvert = graph()->NewNode(
+          common()->Call(desc), jsgraph()->HeapConstant(callable.code()),
+          receiver, context, frame_state, econvert, if_convert);
+    }
+
+    // The {receiver} is already a spec object.
+    Node* if_done = if_true1;
+    Node* edone = etrue1;
+    Node* rdone = receiver;
+
+    control = graph()->NewNode(common()->Merge(2), if_convert, if_done);
+    effect = graph()->NewNode(common()->EffectPhi(2), econvert, edone, control);
+    receiver =
+        graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
+                         rconvert, rdone, control);
+  }
+  ReplaceWithValue(node, receiver, effect, control);
+  return Changed(receiver);
+}
+
+
+Reduction JSTypedLowering::ReduceJSLoadNamed(Node* node) {
+  DCHECK_EQ(IrOpcode::kJSLoadNamed, node->opcode());
+  Node* receiver = NodeProperties::GetValueInput(node, 0);
+  Type* receiver_type = NodeProperties::GetType(receiver);
+  Node* effect = NodeProperties::GetEffectInput(node);
+  Node* control = NodeProperties::GetControlInput(node);
+  Handle<Name> name = NamedAccessOf(node->op()).name();
+  // Optimize "length" property of strings.
+  if (name.is_identical_to(factory()->length_string()) &&
+      receiver_type->Is(Type::String())) {
+    Node* value = effect = graph()->NewNode(
+        simplified()->LoadField(AccessBuilder::ForStringLength()), receiver,
+        effect, control);
+    ReplaceWithValue(node, value, effect);
+    return Replace(value);
+  }
+  // Optimize "prototype" property of functions.
+  if (name.is_identical_to(factory()->prototype_string()) &&
+      receiver_type->IsConstant() &&
+      receiver_type->AsConstant()->Value()->IsJSFunction()) {
+    // TODO(turbofan): This lowering might not kick in if we ever lower
+    // the C++ accessor for "prototype" in an earlier optimization pass.
+    Handle<JSFunction> function =
+        Handle<JSFunction>::cast(receiver_type->AsConstant()->Value());
+    if (function->has_initial_map()) {
+      // We need to add a code dependency on the initial map of the {function}
+      // in order to be notified about changes to the "prototype" of {function},
+      // so it doesn't make sense to continue unless deoptimization is enabled.
+      if (!(flags() & kDeoptimizationEnabled)) return NoChange();
+      Handle<Map> initial_map(function->initial_map(), isolate());
+      dependencies()->AssumeInitialMapCantChange(initial_map);
+      Node* value =
+          jsgraph()->Constant(handle(initial_map->prototype(), isolate()));
+      ReplaceWithValue(node, value);
+      return Replace(value);
+    }
+  }
+  return NoChange();
+}
+
+
 Reduction JSTypedLowering::ReduceJSLoadProperty(Node* node) {
   Node* key = NodeProperties::GetValueInput(node, 1);
   Node* base = NodeProperties::GetValueInput(node, 0);
-  Type* key_type = NodeProperties::GetBounds(key).upper;
-  // TODO(mstarzinger): This lowering is not correct if:
-  //   a) The typed array or it's buffer is neutered.
-  HeapObjectMatcher<Object> mbase(base);
-  if (mbase.HasValue() && mbase.Value().handle()->IsJSTypedArray()) {
+  Type* key_type = NodeProperties::GetType(key);
+  HeapObjectMatcher mbase(base);
+  if (mbase.HasValue() && mbase.Value()->IsJSTypedArray()) {
     Handle<JSTypedArray> const array =
-        Handle<JSTypedArray>::cast(mbase.Value().handle());
-    array->GetBuffer()->set_is_neuterable(false);
-    BufferAccess const access(array->type());
-    size_t const k = ElementSizeLog2Of(access.machine_type());
-    double const byte_length = array->byte_length()->Number();
-    CHECK_LT(k, arraysize(shifted_int32_ranges_));
-    if (IsExternalArrayElementsKind(array->map()->elements_kind()) &&
-        key_type->Is(shifted_int32_ranges_[k]) && byte_length <= kMaxInt) {
-      // JSLoadProperty(typed-array, int32)
-      Handle<ExternalArray> elements =
-          Handle<ExternalArray>::cast(handle(array->elements()));
-      Node* buffer = jsgraph()->PointerConstant(elements->external_pointer());
-      Node* length = jsgraph()->Constant(byte_length);
-      Node* effect = NodeProperties::GetEffectInput(node);
-      Node* control = NodeProperties::GetControlInput(node);
-      // Check if we can avoid the bounds check.
-      if (key_type->Min() >= 0 && key_type->Max() < array->length()->Number()) {
-        Node* load = graph()->NewNode(
-            simplified()->LoadElement(
-                AccessBuilder::ForTypedArrayElement(array->type(), true)),
-            buffer, key, effect, control);
-        return ReplaceEagerly(node, load);
+        Handle<JSTypedArray>::cast(mbase.Value());
+    if (!array->GetBuffer()->was_neutered()) {
+      array->GetBuffer()->set_is_neuterable(false);
+      BufferAccess const access(array->type());
+      size_t const k =
+          ElementSizeLog2Of(access.machine_type().representation());
+      double const byte_length = array->byte_length()->Number();
+      CHECK_LT(k, arraysize(shifted_int32_ranges_));
+      if (key_type->Is(shifted_int32_ranges_[k]) && byte_length <= kMaxInt) {
+        // JSLoadProperty(typed-array, int32)
+        Handle<FixedTypedArrayBase> elements =
+            Handle<FixedTypedArrayBase>::cast(handle(array->elements()));
+        Node* buffer = jsgraph()->PointerConstant(elements->external_pointer());
+        Node* length = jsgraph()->Constant(byte_length);
+        Node* effect = NodeProperties::GetEffectInput(node);
+        Node* control = NodeProperties::GetControlInput(node);
+        // Check if we can avoid the bounds check.
+        if (key_type->Min() >= 0 && key_type->Max() < array->length_value()) {
+          Node* load = graph()->NewNode(
+              simplified()->LoadElement(
+                  AccessBuilder::ForTypedArrayElement(array->type(), true)),
+              buffer, key, effect, control);
+          ReplaceWithValue(node, load, load);
+          return Replace(load);
+        }
+        // Compute byte offset.
+        Node* offset = Word32Shl(key, static_cast<int>(k));
+        Node* load = graph()->NewNode(simplified()->LoadBuffer(access), buffer,
+                                      offset, length, effect, control);
+        ReplaceWithValue(node, load, load);
+        return Replace(load);
       }
-      // Compute byte offset.
-      Node* offset = Word32Shl(key, static_cast<int>(k));
-      Node* load = graph()->NewNode(simplified()->LoadBuffer(access), buffer,
-                                    offset, length, effect, control);
-      return ReplaceEagerly(node, load);
     }
   }
   return NoChange();
@@ -722,95 +1043,264 @@
   Node* key = NodeProperties::GetValueInput(node, 1);
   Node* base = NodeProperties::GetValueInput(node, 0);
   Node* value = NodeProperties::GetValueInput(node, 2);
-  Type* key_type = NodeProperties::GetBounds(key).upper;
-  Type* value_type = NodeProperties::GetBounds(value).upper;
-  // TODO(mstarzinger): This lowering is not correct if:
-  //   a) The typed array or its buffer is neutered.
-  HeapObjectMatcher<Object> mbase(base);
-  if (mbase.HasValue() && mbase.Value().handle()->IsJSTypedArray()) {
+  Type* key_type = NodeProperties::GetType(key);
+  Type* value_type = NodeProperties::GetType(value);
+  HeapObjectMatcher mbase(base);
+  if (mbase.HasValue() && mbase.Value()->IsJSTypedArray()) {
     Handle<JSTypedArray> const array =
-        Handle<JSTypedArray>::cast(mbase.Value().handle());
-    array->GetBuffer()->set_is_neuterable(false);
-    BufferAccess const access(array->type());
-    size_t const k = ElementSizeLog2Of(access.machine_type());
-    double const byte_length = array->byte_length()->Number();
-    CHECK_LT(k, arraysize(shifted_int32_ranges_));
-    if (IsExternalArrayElementsKind(array->map()->elements_kind()) &&
-        access.external_array_type() != kExternalUint8ClampedArray &&
-        key_type->Is(shifted_int32_ranges_[k]) && byte_length <= kMaxInt) {
-      // JSLoadProperty(typed-array, int32)
-      Handle<ExternalArray> elements =
-          Handle<ExternalArray>::cast(handle(array->elements()));
-      Node* buffer = jsgraph()->PointerConstant(elements->external_pointer());
-      Node* length = jsgraph()->Constant(byte_length);
-      Node* context = NodeProperties::GetContextInput(node);
-      Node* effect = NodeProperties::GetEffectInput(node);
-      Node* control = NodeProperties::GetControlInput(node);
-      // Convert to a number first.
-      if (!value_type->Is(Type::Number())) {
-        Reduction number_reduction = ReduceJSToNumberInput(value);
-        if (number_reduction.Changed()) {
-          value = number_reduction.replacement();
-        } else {
-          value = effect = graph()->NewNode(javascript()->ToNumber(), value,
-                                            context, effect, control);
+        Handle<JSTypedArray>::cast(mbase.Value());
+    if (!array->GetBuffer()->was_neutered()) {
+      array->GetBuffer()->set_is_neuterable(false);
+      BufferAccess const access(array->type());
+      size_t const k =
+          ElementSizeLog2Of(access.machine_type().representation());
+      double const byte_length = array->byte_length()->Number();
+      CHECK_LT(k, arraysize(shifted_int32_ranges_));
+      if (access.external_array_type() != kExternalUint8ClampedArray &&
+          key_type->Is(shifted_int32_ranges_[k]) && byte_length <= kMaxInt) {
+        // JSLoadProperty(typed-array, int32)
+        Handle<FixedTypedArrayBase> elements =
+            Handle<FixedTypedArrayBase>::cast(handle(array->elements()));
+        Node* buffer = jsgraph()->PointerConstant(elements->external_pointer());
+        Node* length = jsgraph()->Constant(byte_length);
+        Node* context = NodeProperties::GetContextInput(node);
+        Node* effect = NodeProperties::GetEffectInput(node);
+        Node* control = NodeProperties::GetControlInput(node);
+        // Convert to a number first.
+        if (!value_type->Is(Type::Number())) {
+          Reduction number_reduction = ReduceJSToNumberInput(value);
+          if (number_reduction.Changed()) {
+            value = number_reduction.replacement();
+          } else {
+            Node* frame_state_for_to_number =
+                NodeProperties::GetFrameStateInput(node, 1);
+            value = effect =
+                graph()->NewNode(javascript()->ToNumber(), value, context,
+                                 frame_state_for_to_number, effect, control);
+          }
         }
-      }
-      // For integer-typed arrays, convert to the integer type.
-      if (TypeOf(access.machine_type()) == kTypeInt32 &&
-          !value_type->Is(Type::Signed32())) {
-        value = graph()->NewNode(simplified()->NumberToInt32(), value);
-      } else if (TypeOf(access.machine_type()) == kTypeUint32 &&
-                 !value_type->Is(Type::Unsigned32())) {
-        value = graph()->NewNode(simplified()->NumberToUint32(), value);
-      }
-      // Check if we can avoid the bounds check.
-      if (key_type->Min() >= 0 && key_type->Max() < array->length()->Number()) {
-        node->set_op(simplified()->StoreElement(
-            AccessBuilder::ForTypedArrayElement(array->type(), true)));
+        // Check if we can avoid the bounds check.
+        if (key_type->Min() >= 0 && key_type->Max() < array->length_value()) {
+          RelaxControls(node);
+          node->ReplaceInput(0, buffer);
+          DCHECK_EQ(key, node->InputAt(1));
+          node->ReplaceInput(2, value);
+          node->ReplaceInput(3, effect);
+          node->ReplaceInput(4, control);
+          node->TrimInputCount(5);
+          NodeProperties::ChangeOp(
+              node,
+              simplified()->StoreElement(
+                  AccessBuilder::ForTypedArrayElement(array->type(), true)));
+          return Changed(node);
+        }
+        // Compute byte offset.
+        Node* offset = Word32Shl(key, static_cast<int>(k));
+        // Turn into a StoreBuffer operation.
+        RelaxControls(node);
         node->ReplaceInput(0, buffer);
-        DCHECK_EQ(key, node->InputAt(1));
-        node->ReplaceInput(2, value);
-        node->ReplaceInput(3, effect);
-        node->ReplaceInput(4, control);
-        node->TrimInputCount(5);
+        node->ReplaceInput(1, offset);
+        node->ReplaceInput(2, length);
+        node->ReplaceInput(3, value);
+        node->ReplaceInput(4, effect);
+        node->ReplaceInput(5, control);
+        node->TrimInputCount(6);
+        NodeProperties::ChangeOp(node, simplified()->StoreBuffer(access));
         return Changed(node);
       }
-      // Compute byte offset.
-      Node* offset = Word32Shl(key, static_cast<int>(k));
-      // Turn into a StoreBuffer operation.
-      node->set_op(simplified()->StoreBuffer(access));
-      node->ReplaceInput(0, buffer);
-      node->ReplaceInput(1, offset);
-      node->ReplaceInput(2, length);
-      node->ReplaceInput(3, value);
-      node->ReplaceInput(4, effect);
-      DCHECK_EQ(control, node->InputAt(5));
-      DCHECK_EQ(6, node->InputCount());
-      return Changed(node);
     }
   }
   return NoChange();
 }
 
 
+Reduction JSTypedLowering::ReduceJSInstanceOf(Node* node) {
+  DCHECK_EQ(IrOpcode::kJSInstanceOf, node->opcode());
+  Node* const context = NodeProperties::GetContextInput(node);
+  Node* const frame_state = NodeProperties::GetFrameStateInput(node, 0);
+
+  // If deoptimization is disabled, we cannot optimize.
+  if (!(flags() & kDeoptimizationEnabled) ||
+      (flags() & kDisableBinaryOpReduction)) {
+    return NoChange();
+  }
+
+  // If we are in a try block, don't optimize since the runtime call
+  // in the proxy case can throw.
+  if (NodeProperties::IsExceptionalCall(node)) return NoChange();
+
+  JSBinopReduction r(this, node);
+  Node* effect = r.effect();
+  Node* control = r.control();
+
+  if (!r.right_type()->IsConstant() ||
+      !r.right_type()->AsConstant()->Value()->IsJSFunction()) {
+    return NoChange();
+  }
+
+  Handle<JSFunction> function =
+      Handle<JSFunction>::cast(r.right_type()->AsConstant()->Value());
+  Handle<SharedFunctionInfo> shared(function->shared(), isolate());
+
+  if (!function->IsConstructor() ||
+      function->map()->has_non_instance_prototype()) {
+    return NoChange();
+  }
+
+  JSFunction::EnsureHasInitialMap(function);
+  DCHECK(function->has_initial_map());
+  Handle<Map> initial_map(function->initial_map(), isolate());
+  this->dependencies()->AssumeInitialMapCantChange(initial_map);
+  Node* prototype =
+      jsgraph()->Constant(handle(initial_map->prototype(), isolate()));
+
+  Node* if_is_smi = nullptr;
+  Node* e_is_smi = nullptr;
+  // If the left hand side is an object, no smi check is needed.
+  if (r.left_type()->Maybe(Type::TaggedSigned())) {
+    Node* is_smi = graph()->NewNode(simplified()->ObjectIsSmi(), r.left());
+    Node* branch_is_smi =
+        graph()->NewNode(common()->Branch(BranchHint::kFalse), is_smi, control);
+    if_is_smi = graph()->NewNode(common()->IfTrue(), branch_is_smi);
+    e_is_smi = effect;
+    control = graph()->NewNode(common()->IfFalse(), branch_is_smi);
+  }
+
+  Node* object_map = effect =
+      graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
+                       r.left(), effect, control);
+
+  // Loop through the {object}s prototype chain looking for the {prototype}.
+  Node* loop = control = graph()->NewNode(common()->Loop(2), control, control);
+
+  Node* loop_effect = effect =
+      graph()->NewNode(common()->EffectPhi(2), effect, effect, loop);
+
+  Node* loop_object_map =
+      graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
+                       object_map, r.left(), loop);
+
+  // Check if the lhs needs access checks.
+  Node* map_bit_field = effect =
+      graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMapBitField()),
+                       loop_object_map, loop_effect, control);
+  int is_access_check_needed_bit = 1 << Map::kIsAccessCheckNeeded;
+  Node* is_access_check_needed_num =
+      graph()->NewNode(simplified()->NumberBitwiseAnd(), map_bit_field,
+                       jsgraph()->Uint32Constant(is_access_check_needed_bit));
+  Node* is_access_check_needed =
+      graph()->NewNode(machine()->Word32Equal(), is_access_check_needed_num,
+                       jsgraph()->Uint32Constant(is_access_check_needed_bit));
+
+  Node* branch_is_access_check_needed = graph()->NewNode(
+      common()->Branch(BranchHint::kFalse), is_access_check_needed, control);
+  Node* if_is_access_check_needed =
+      graph()->NewNode(common()->IfTrue(), branch_is_access_check_needed);
+  Node* e_is_access_check_needed = effect;
+
+  control =
+      graph()->NewNode(common()->IfFalse(), branch_is_access_check_needed);
+
+  // Check if the lhs is a proxy.
+  Node* map_instance_type = effect = graph()->NewNode(
+      simplified()->LoadField(AccessBuilder::ForMapInstanceType()),
+      loop_object_map, loop_effect, control);
+  Node* is_proxy = graph()->NewNode(machine()->Word32Equal(), map_instance_type,
+                                    jsgraph()->Uint32Constant(JS_PROXY_TYPE));
+  Node* branch_is_proxy =
+      graph()->NewNode(common()->Branch(BranchHint::kFalse), is_proxy, control);
+  Node* if_is_proxy = graph()->NewNode(common()->IfTrue(), branch_is_proxy);
+  Node* e_is_proxy = effect;
+
+
+  Node* runtime_has_in_proto_chain = control = graph()->NewNode(
+      common()->Merge(2), if_is_access_check_needed, if_is_proxy);
+  effect = graph()->NewNode(common()->EffectPhi(2), e_is_access_check_needed,
+                            e_is_proxy, control);
+
+  // If we need an access check or the object is a Proxy, make a runtime call
+  // to finish the lowering.
+  Node* bool_result_runtime_has_in_proto_chain_case = graph()->NewNode(
+      javascript()->CallRuntime(Runtime::kHasInPrototypeChain, 2), r.left(),
+      prototype, context, frame_state, effect, control);
+
+  control = graph()->NewNode(common()->IfFalse(), branch_is_proxy);
+
+  Node* object_prototype = effect = graph()->NewNode(
+      simplified()->LoadField(AccessBuilder::ForMapPrototype()),
+      loop_object_map, loop_effect, control);
+
+  // Check if object prototype is equal to function prototype.
+  Node* eq_proto =
+      graph()->NewNode(simplified()->ReferenceEqual(r.right_type()),
+                       object_prototype, prototype);
+  Node* branch_eq_proto =
+      graph()->NewNode(common()->Branch(BranchHint::kFalse), eq_proto, control);
+  Node* if_eq_proto = graph()->NewNode(common()->IfTrue(), branch_eq_proto);
+  Node* e_eq_proto = effect;
+
+  control = graph()->NewNode(common()->IfFalse(), branch_eq_proto);
+
+  // If not, check if object prototype is the null prototype.
+  Node* null_proto =
+      graph()->NewNode(simplified()->ReferenceEqual(r.right_type()),
+                       object_prototype, jsgraph()->NullConstant());
+  Node* branch_null_proto = graph()->NewNode(
+      common()->Branch(BranchHint::kFalse), null_proto, control);
+  Node* if_null_proto = graph()->NewNode(common()->IfTrue(), branch_null_proto);
+  Node* e_null_proto = effect;
+
+  control = graph()->NewNode(common()->IfFalse(), branch_null_proto);
+  Node* load_object_map = effect =
+      graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
+                       object_prototype, effect, control);
+  // Close the loop.
+  loop_effect->ReplaceInput(1, effect);
+  loop_object_map->ReplaceInput(1, load_object_map);
+  loop->ReplaceInput(1, control);
+
+  control = graph()->NewNode(common()->Merge(3), runtime_has_in_proto_chain,
+                             if_eq_proto, if_null_proto);
+  effect = graph()->NewNode(common()->EffectPhi(3),
+                            bool_result_runtime_has_in_proto_chain_case,
+                            e_eq_proto, e_null_proto, control);
+
+  Node* result = graph()->NewNode(
+      common()->Phi(MachineRepresentation::kTagged, 3),
+      bool_result_runtime_has_in_proto_chain_case, jsgraph()->TrueConstant(),
+      jsgraph()->FalseConstant(), control);
+
+  if (if_is_smi != nullptr) {
+    DCHECK_NOT_NULL(e_is_smi);
+    control = graph()->NewNode(common()->Merge(2), if_is_smi, control);
+    effect =
+        graph()->NewNode(common()->EffectPhi(2), e_is_smi, effect, control);
+    result = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
+                              jsgraph()->FalseConstant(), result, control);
+  }
+
+  ReplaceWithValue(node, result, effect, control);
+  return Changed(result);
+}
+
+
 Reduction JSTypedLowering::ReduceJSLoadContext(Node* node) {
   DCHECK_EQ(IrOpcode::kJSLoadContext, node->opcode());
   ContextAccess const& access = ContextAccessOf(node->op());
-  Node* const effect = NodeProperties::GetEffectInput(node);
-  Node* const control = graph()->start();
+  Node* effect = NodeProperties::GetEffectInput(node);
+  Node* control = graph()->start();
   for (size_t i = 0; i < access.depth(); ++i) {
-    node->ReplaceInput(
-        0, graph()->NewNode(
-               simplified()->LoadField(
-                   AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX)),
-               NodeProperties::GetValueInput(node, 0), effect, control));
+    Node* previous = effect = graph()->NewNode(
+        simplified()->LoadField(
+            AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX)),
+        NodeProperties::GetValueInput(node, 0), effect, control);
+    node->ReplaceInput(0, previous);
   }
-  node->set_op(
-      simplified()->LoadField(AccessBuilder::ForContextSlot(access.index())));
   node->ReplaceInput(1, effect);
   node->ReplaceInput(2, control);
-  DCHECK_EQ(3, node->InputCount());
+  NodeProperties::ChangeOp(
+      node,
+      simplified()->LoadField(AccessBuilder::ForContextSlot(access.index())));
   return Changed(node);
 }
 
@@ -818,53 +1308,1276 @@
 Reduction JSTypedLowering::ReduceJSStoreContext(Node* node) {
   DCHECK_EQ(IrOpcode::kJSStoreContext, node->opcode());
   ContextAccess const& access = ContextAccessOf(node->op());
-  Node* const effect = NodeProperties::GetEffectInput(node);
-  Node* const control = graph()->start();
+  Node* effect = NodeProperties::GetEffectInput(node);
+  Node* control = graph()->start();
   for (size_t i = 0; i < access.depth(); ++i) {
-    node->ReplaceInput(
-        0, graph()->NewNode(
-               simplified()->LoadField(
-                   AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX)),
-               NodeProperties::GetValueInput(node, 0), effect, control));
+    Node* previous = effect = graph()->NewNode(
+        simplified()->LoadField(
+            AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX)),
+        NodeProperties::GetValueInput(node, 0), effect, control);
+    node->ReplaceInput(0, previous);
   }
-  node->set_op(
-      simplified()->StoreField(AccessBuilder::ForContextSlot(access.index())));
   node->RemoveInput(2);
-  DCHECK_EQ(4, node->InputCount());
+  node->ReplaceInput(2, effect);
+  NodeProperties::ChangeOp(
+      node,
+      simplified()->StoreField(AccessBuilder::ForContextSlot(access.index())));
   return Changed(node);
 }
 
 
+Reduction JSTypedLowering::ReduceJSConvertReceiver(Node* node) {
+  DCHECK_EQ(IrOpcode::kJSConvertReceiver, node->opcode());
+  ConvertReceiverMode mode = ConvertReceiverModeOf(node->op());
+  Node* receiver = NodeProperties::GetValueInput(node, 0);
+  Type* receiver_type = NodeProperties::GetType(receiver);
+  Node* context = NodeProperties::GetContextInput(node);
+  Type* context_type = NodeProperties::GetType(context);
+  Node* frame_state = NodeProperties::GetFrameStateInput(node, 0);
+  Node* effect = NodeProperties::GetEffectInput(node);
+  Node* control = NodeProperties::GetControlInput(node);
+  if (!receiver_type->Is(Type::Receiver())) {
+    if (receiver_type->Is(Type::NullOrUndefined()) ||
+        mode == ConvertReceiverMode::kNullOrUndefined) {
+      if (context_type->IsConstant()) {
+        Handle<JSObject> global_proxy(
+            Handle<Context>::cast(context_type->AsConstant()->Value())
+                ->global_proxy(),
+            isolate());
+        receiver = jsgraph()->Constant(global_proxy);
+      } else {
+        Node* native_context = effect = graph()->NewNode(
+            javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true),
+            context, context, effect);
+        receiver = effect = graph()->NewNode(
+            javascript()->LoadContext(0, Context::GLOBAL_PROXY_INDEX, true),
+            native_context, native_context, effect);
+      }
+    } else if (!receiver_type->Maybe(Type::NullOrUndefined()) ||
+               mode == ConvertReceiverMode::kNotNullOrUndefined) {
+      receiver = effect =
+          graph()->NewNode(javascript()->ToObject(), receiver, context,
+                           frame_state, effect, control);
+    } else {
+      // Check {receiver} for undefined.
+      Node* check0 =
+          graph()->NewNode(simplified()->ReferenceEqual(receiver_type),
+                           receiver, jsgraph()->UndefinedConstant());
+      Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
+                                       check0, control);
+      Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
+      Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
+
+      // Check {receiver} for null.
+      Node* check1 =
+          graph()->NewNode(simplified()->ReferenceEqual(receiver_type),
+                           receiver, jsgraph()->NullConstant());
+      Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
+                                       check1, if_false0);
+      Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
+      Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
+
+      // Convert {receiver} using ToObject.
+      Node* if_convert = if_false1;
+      Node* econvert = effect;
+      Node* rconvert;
+      {
+        rconvert = econvert =
+            graph()->NewNode(javascript()->ToObject(), receiver, context,
+                             frame_state, econvert, if_convert);
+      }
+
+      // Replace {receiver} with global proxy of {context}.
+      Node* if_global =
+          graph()->NewNode(common()->Merge(2), if_true0, if_true1);
+      Node* eglobal = effect;
+      Node* rglobal;
+      {
+        if (context_type->IsConstant()) {
+          Handle<JSObject> global_proxy(
+              Handle<Context>::cast(context_type->AsConstant()->Value())
+                  ->global_proxy(),
+              isolate());
+          rglobal = jsgraph()->Constant(global_proxy);
+        } else {
+          Node* native_context = eglobal = graph()->NewNode(
+              javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true),
+              context, context, eglobal);
+          rglobal = eglobal = graph()->NewNode(
+              javascript()->LoadContext(0, Context::GLOBAL_PROXY_INDEX, true),
+              native_context, native_context, eglobal);
+        }
+      }
+
+      control = graph()->NewNode(common()->Merge(2), if_convert, if_global);
+      effect =
+          graph()->NewNode(common()->EffectPhi(2), econvert, eglobal, control);
+      receiver =
+          graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
+                           rconvert, rglobal, control);
+    }
+  }
+  ReplaceWithValue(node, receiver, effect, control);
+  return Changed(receiver);
+}
+
+
+namespace {
+
+// Maximum instance size for which allocations will be inlined.
+const int kMaxInlineInstanceSize = 64 * kPointerSize;
+
+
+// Checks whether allocation using the given constructor can be inlined.
+bool IsAllocationInlineable(Handle<JSFunction> constructor) {
+  // TODO(bmeurer): Further relax restrictions on inlining, i.e.
+  // instance type and maybe instance size (inobject properties
+  // are limited anyways by the runtime).
+  return constructor->has_initial_map() &&
+         constructor->initial_map()->instance_type() == JS_OBJECT_TYPE &&
+         constructor->initial_map()->instance_size() < kMaxInlineInstanceSize;
+}
+
+}  // namespace
+
+
+Reduction JSTypedLowering::ReduceJSCreate(Node* node) {
+  DCHECK_EQ(IrOpcode::kJSCreate, node->opcode());
+  Node* const target = NodeProperties::GetValueInput(node, 0);
+  Type* const target_type = NodeProperties::GetType(target);
+  Node* const new_target = NodeProperties::GetValueInput(node, 1);
+  Node* const effect = NodeProperties::GetEffectInput(node);
+  // TODO(turbofan): Add support for NewTarget passed to JSCreate.
+  if (target != new_target) return NoChange();
+  // Extract constructor function.
+  if (target_type->IsConstant() &&
+      target_type->AsConstant()->Value()->IsJSFunction()) {
+    Handle<JSFunction> constructor =
+        Handle<JSFunction>::cast(target_type->AsConstant()->Value());
+    DCHECK(constructor->IsConstructor());
+    // Force completion of inobject slack tracking before
+    // generating code to finalize the instance size.
+    constructor->CompleteInobjectSlackTrackingIfActive();
+
+    // TODO(bmeurer): We fall back to the runtime in case we cannot inline
+    // the allocation here, which is sort of expensive. We should think about
+    // a soft fallback to some NewObjectCodeStub.
+    if (IsAllocationInlineable(constructor)) {
+      // Compute instance size from initial map of {constructor}.
+      Handle<Map> initial_map(constructor->initial_map(), isolate());
+      int const instance_size = initial_map->instance_size();
+
+      // Add a dependency on the {initial_map} to make sure that this code is
+      // deoptimized whenever the {initial_map} of the {constructor} changes.
+      dependencies()->AssumeInitialMapCantChange(initial_map);
+
+      // Emit code to allocate the JSObject instance for the {constructor}.
+      AllocationBuilder a(jsgraph(), effect, graph()->start());
+      a.Allocate(instance_size);
+      a.Store(AccessBuilder::ForMap(), initial_map);
+      a.Store(AccessBuilder::ForJSObjectProperties(),
+              jsgraph()->EmptyFixedArrayConstant());
+      a.Store(AccessBuilder::ForJSObjectElements(),
+              jsgraph()->EmptyFixedArrayConstant());
+      for (int i = 0; i < initial_map->GetInObjectProperties(); ++i) {
+        a.Store(AccessBuilder::ForJSObjectInObjectProperty(initial_map, i),
+                jsgraph()->UndefinedConstant());
+      }
+      a.FinishAndChange(node);
+      return Changed(node);
+    }
+  }
+  return NoChange();
+}
+
+
+namespace {
+
+// Retrieves the frame state holding actual argument values.
+Node* GetArgumentsFrameState(Node* frame_state) {
+  Node* const outer_state = frame_state->InputAt(kFrameStateOuterStateInput);
+  FrameStateInfo outer_state_info = OpParameter<FrameStateInfo>(outer_state);
+  return outer_state_info.type() == FrameStateType::kArgumentsAdaptor
+             ? outer_state
+             : frame_state;
+}
+
+}  // namespace
+
+
+Reduction JSTypedLowering::ReduceJSCreateArguments(Node* node) {
+  DCHECK_EQ(IrOpcode::kJSCreateArguments, node->opcode());
+  CreateArgumentsParameters const& p = CreateArgumentsParametersOf(node->op());
+  Node* const frame_state = NodeProperties::GetFrameStateInput(node, 0);
+  Node* const outer_state = frame_state->InputAt(kFrameStateOuterStateInput);
+  FrameStateInfo state_info = OpParameter<FrameStateInfo>(frame_state);
+
+  // Use the ArgumentsAccessStub for materializing both mapped and unmapped
+  // arguments object, but only for non-inlined (i.e. outermost) frames.
+  if (outer_state->opcode() != IrOpcode::kFrameState) {
+    Isolate* isolate = jsgraph()->isolate();
+    int parameter_count = state_info.parameter_count() - 1;
+    int parameter_offset = parameter_count * kPointerSize;
+    int offset = StandardFrameConstants::kCallerSPOffset + parameter_offset;
+    Node* parameter_pointer = graph()->NewNode(
+        machine()->IntAdd(), graph()->NewNode(machine()->LoadFramePointer()),
+        jsgraph()->IntPtrConstant(offset));
+
+    if (p.type() != CreateArgumentsParameters::kRestArray) {
+      Handle<SharedFunctionInfo> shared;
+      if (!state_info.shared_info().ToHandle(&shared)) return NoChange();
+      bool unmapped = p.type() == CreateArgumentsParameters::kUnmappedArguments;
+      Callable callable = CodeFactory::ArgumentsAccess(
+          isolate, unmapped, shared->has_duplicate_parameters());
+      CallDescriptor* desc = Linkage::GetStubCallDescriptor(
+          isolate, graph()->zone(), callable.descriptor(), 0,
+          CallDescriptor::kNeedsFrameState);
+      const Operator* new_op = common()->Call(desc);
+      Node* stub_code = jsgraph()->HeapConstant(callable.code());
+      node->InsertInput(graph()->zone(), 0, stub_code);
+      node->InsertInput(graph()->zone(), 2,
+                        jsgraph()->Constant(parameter_count));
+      node->InsertInput(graph()->zone(), 3, parameter_pointer);
+      NodeProperties::ChangeOp(node, new_op);
+      return Changed(node);
+    } else {
+      Callable callable = CodeFactory::RestArgumentsAccess(isolate);
+      CallDescriptor* desc = Linkage::GetStubCallDescriptor(
+          isolate, graph()->zone(), callable.descriptor(), 0,
+          CallDescriptor::kNeedsFrameState);
+      const Operator* new_op = common()->Call(desc);
+      Node* stub_code = jsgraph()->HeapConstant(callable.code());
+      node->InsertInput(graph()->zone(), 0, stub_code);
+      node->ReplaceInput(1, jsgraph()->Constant(parameter_count));
+      node->InsertInput(graph()->zone(), 2, parameter_pointer);
+      node->InsertInput(graph()->zone(), 3,
+                        jsgraph()->Constant(p.start_index()));
+      NodeProperties::ChangeOp(node, new_op);
+      return Changed(node);
+    }
+  } else if (outer_state->opcode() == IrOpcode::kFrameState) {
+    // Use inline allocation for all mapped arguments objects within inlined
+    // (i.e. non-outermost) frames, independent of the object size.
+    if (p.type() == CreateArgumentsParameters::kMappedArguments) {
+      Handle<SharedFunctionInfo> shared;
+      if (!state_info.shared_info().ToHandle(&shared)) return NoChange();
+      Node* const callee = NodeProperties::GetValueInput(node, 0);
+      Node* const control = NodeProperties::GetControlInput(node);
+      Node* const context = NodeProperties::GetContextInput(node);
+      Node* effect = NodeProperties::GetEffectInput(node);
+      // TODO(mstarzinger): Duplicate parameters are not handled yet.
+      if (shared->has_duplicate_parameters()) return NoChange();
+      // Choose the correct frame state and frame state info depending on
+      // whether there conceptually is an arguments adaptor frame in the call
+      // chain.
+      Node* const args_state = GetArgumentsFrameState(frame_state);
+      FrameStateInfo args_state_info = OpParameter<FrameStateInfo>(args_state);
+      // Prepare element backing store to be used by arguments object.
+      bool has_aliased_arguments = false;
+      Node* const elements = AllocateAliasedArguments(
+          effect, control, args_state, context, shared, &has_aliased_arguments);
+      effect = elements->op()->EffectOutputCount() > 0 ? elements : effect;
+      // Load the arguments object map from the current native context.
+      Node* const load_native_context = effect = graph()->NewNode(
+          javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true),
+          context, context, effect);
+      Node* const load_arguments_map = effect = graph()->NewNode(
+          simplified()->LoadField(AccessBuilder::ForContextSlot(
+              has_aliased_arguments ? Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX
+                                    : Context::SLOPPY_ARGUMENTS_MAP_INDEX)),
+          load_native_context, effect, control);
+      // Actually allocate and initialize the arguments object.
+      AllocationBuilder a(jsgraph(), effect, control);
+      Node* properties = jsgraph()->EmptyFixedArrayConstant();
+      int length = args_state_info.parameter_count() - 1;  // Minus receiver.
+      STATIC_ASSERT(Heap::kSloppyArgumentsObjectSize == 5 * kPointerSize);
+      a.Allocate(Heap::kSloppyArgumentsObjectSize);
+      a.Store(AccessBuilder::ForMap(), load_arguments_map);
+      a.Store(AccessBuilder::ForJSObjectProperties(), properties);
+      a.Store(AccessBuilder::ForJSObjectElements(), elements);
+      a.Store(AccessBuilder::ForArgumentsLength(), jsgraph()->Constant(length));
+      a.Store(AccessBuilder::ForArgumentsCallee(), callee);
+      RelaxControls(node);
+      a.FinishAndChange(node);
+      return Changed(node);
+    } else if (p.type() == CreateArgumentsParameters::kUnmappedArguments) {
+      // Use inline allocation for all unmapped arguments objects within inlined
+      // (i.e. non-outermost) frames, independent of the object size.
+      Node* const control = NodeProperties::GetControlInput(node);
+      Node* const context = NodeProperties::GetContextInput(node);
+      Node* effect = NodeProperties::GetEffectInput(node);
+      // Choose the correct frame state and frame state info depending on
+      // whether there conceptually is an arguments adaptor frame in the call
+      // chain.
+      Node* const args_state = GetArgumentsFrameState(frame_state);
+      FrameStateInfo args_state_info = OpParameter<FrameStateInfo>(args_state);
+      // Prepare element backing store to be used by arguments object.
+      Node* const elements = AllocateArguments(effect, control, args_state);
+      effect = elements->op()->EffectOutputCount() > 0 ? elements : effect;
+      // Load the arguments object map from the current native context.
+      Node* const load_native_context = effect = graph()->NewNode(
+          javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true),
+          context, context, effect);
+      Node* const load_arguments_map = effect = graph()->NewNode(
+          simplified()->LoadField(AccessBuilder::ForContextSlot(
+              Context::STRICT_ARGUMENTS_MAP_INDEX)),
+          load_native_context, effect, control);
+      // Actually allocate and initialize the arguments object.
+      AllocationBuilder a(jsgraph(), effect, control);
+      Node* properties = jsgraph()->EmptyFixedArrayConstant();
+      int length = args_state_info.parameter_count() - 1;  // Minus receiver.
+      STATIC_ASSERT(Heap::kStrictArgumentsObjectSize == 4 * kPointerSize);
+      a.Allocate(Heap::kStrictArgumentsObjectSize);
+      a.Store(AccessBuilder::ForMap(), load_arguments_map);
+      a.Store(AccessBuilder::ForJSObjectProperties(), properties);
+      a.Store(AccessBuilder::ForJSObjectElements(), elements);
+      a.Store(AccessBuilder::ForArgumentsLength(), jsgraph()->Constant(length));
+      RelaxControls(node);
+      a.FinishAndChange(node);
+      return Changed(node);
+    } else if (p.type() == CreateArgumentsParameters::kRestArray) {
+      // Use inline allocation for all unmapped arguments objects within inlined
+      // (i.e. non-outermost) frames, independent of the object size.
+      Node* const control = NodeProperties::GetControlInput(node);
+      Node* const context = NodeProperties::GetContextInput(node);
+      Node* effect = NodeProperties::GetEffectInput(node);
+      // Choose the correct frame state and frame state info depending on
+      // whether there conceptually is an arguments adaptor frame in the call
+      // chain.
+      Node* const args_state = GetArgumentsFrameState(frame_state);
+      FrameStateInfo args_state_info = OpParameter<FrameStateInfo>(args_state);
+      // Prepare element backing store to be used by the rest array.
+      Node* const elements =
+          AllocateRestArguments(effect, control, args_state, p.start_index());
+      effect = elements->op()->EffectOutputCount() > 0 ? elements : effect;
+      // Load the JSArray object map from the current native context.
+      Node* const load_native_context = effect = graph()->NewNode(
+          javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true),
+          context, context, effect);
+      Node* const load_jsarray_map = effect = graph()->NewNode(
+          simplified()->LoadField(AccessBuilder::ForContextSlot(
+              Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX)),
+          load_native_context, effect, control);
+      // Actually allocate and initialize the jsarray.
+      AllocationBuilder a(jsgraph(), effect, control);
+      Node* properties = jsgraph()->EmptyFixedArrayConstant();
+
+      // -1 to minus receiver
+      int argument_count = args_state_info.parameter_count() - 1;
+      int length = std::max(0, argument_count - p.start_index());
+      STATIC_ASSERT(JSArray::kSize == 4 * kPointerSize);
+      a.Allocate(JSArray::kSize);
+      a.Store(AccessBuilder::ForMap(), load_jsarray_map);
+      a.Store(AccessBuilder::ForJSObjectProperties(), properties);
+      a.Store(AccessBuilder::ForJSObjectElements(), elements);
+      a.Store(AccessBuilder::ForJSArrayLength(FAST_ELEMENTS),
+              jsgraph()->Constant(length));
+      RelaxControls(node);
+      a.FinishAndChange(node);
+      return Changed(node);
+    }
+  }
+
+  return NoChange();
+}
+
+
+Reduction JSTypedLowering::ReduceNewArray(Node* node, Node* length,
+                                          int capacity,
+                                          Handle<AllocationSite> site) {
+  DCHECK_EQ(IrOpcode::kJSCreateArray, node->opcode());
+  Node* context = NodeProperties::GetContextInput(node);
+  Node* effect = NodeProperties::GetEffectInput(node);
+  Node* control = NodeProperties::GetControlInput(node);
+
+  // Extract transition and tenuring feedback from the {site} and add
+  // appropriate code dependencies on the {site} if deoptimization is
+  // enabled.
+  PretenureFlag pretenure = site->GetPretenureMode();
+  ElementsKind elements_kind = site->GetElementsKind();
+  DCHECK(IsFastElementsKind(elements_kind));
+  if (flags() & kDeoptimizationEnabled) {
+    dependencies()->AssumeTenuringDecision(site);
+    dependencies()->AssumeTransitionStable(site);
+  }
+
+  // Retrieve the initial map for the array from the appropriate native context.
+  Node* native_context = effect = graph()->NewNode(
+      javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true),
+      context, context, effect);
+  Node* js_array_map = effect = graph()->NewNode(
+      javascript()->LoadContext(0, Context::ArrayMapIndex(elements_kind), true),
+      native_context, native_context, effect);
+
+  // Setup elements and properties.
+  Node* elements;
+  if (capacity == 0) {
+    elements = jsgraph()->EmptyFixedArrayConstant();
+  } else {
+    elements = effect =
+        AllocateElements(effect, control, elements_kind, capacity, pretenure);
+  }
+  Node* properties = jsgraph()->EmptyFixedArrayConstant();
+
+  // Perform the allocation of the actual JSArray object.
+  AllocationBuilder a(jsgraph(), effect, control);
+  a.Allocate(JSArray::kSize, pretenure);
+  a.Store(AccessBuilder::ForMap(), js_array_map);
+  a.Store(AccessBuilder::ForJSObjectProperties(), properties);
+  a.Store(AccessBuilder::ForJSObjectElements(), elements);
+  a.Store(AccessBuilder::ForJSArrayLength(elements_kind), length);
+  RelaxControls(node);
+  a.FinishAndChange(node);
+  return Changed(node);
+}
+
+
+Reduction JSTypedLowering::ReduceJSCreateArray(Node* node) {
+  DCHECK_EQ(IrOpcode::kJSCreateArray, node->opcode());
+  CreateArrayParameters const& p = CreateArrayParametersOf(node->op());
+  Node* target = NodeProperties::GetValueInput(node, 0);
+  Node* new_target = NodeProperties::GetValueInput(node, 1);
+
+  // TODO(bmeurer): Optimize the subclassing case.
+  if (target != new_target) return NoChange();
+
+  // Check if we have a feedback {site} on the {node}.
+  Handle<AllocationSite> site = p.site();
+  if (p.site().is_null()) return NoChange();
+
+  // Attempt to inline calls to the Array constructor for the relevant cases
+  // where either no arguments are provided, or exactly one unsigned number
+  // argument is given.
+  if (site->CanInlineCall()) {
+    if (p.arity() == 0) {
+      Node* length = jsgraph()->ZeroConstant();
+      int capacity = JSArray::kPreallocatedArrayElements;
+      return ReduceNewArray(node, length, capacity, site);
+    } else if (p.arity() == 1) {
+      Node* length = NodeProperties::GetValueInput(node, 2);
+      Type* length_type = NodeProperties::GetType(length);
+      if (length_type->Is(type_cache_.kElementLoopUnrollType)) {
+        int capacity = static_cast<int>(length_type->Max());
+        return ReduceNewArray(node, length, capacity, site);
+      }
+    }
+  }
+
+  // Reduce {node} to the appropriate ArrayConstructorStub backend.
+  // Note that these stubs "behave" like JSFunctions, which means they
+  // expect a receiver on the stack, which they remove. We just push
+  // undefined for the receiver.
+  ElementsKind elements_kind = site->GetElementsKind();
+  AllocationSiteOverrideMode override_mode =
+      (AllocationSite::GetMode(elements_kind) == TRACK_ALLOCATION_SITE)
+          ? DISABLE_ALLOCATION_SITES
+          : DONT_OVERRIDE;
+  if (p.arity() == 0) {
+    ArrayNoArgumentConstructorStub stub(isolate(), elements_kind,
+                                        override_mode);
+    CallDescriptor* desc = Linkage::GetStubCallDescriptor(
+        isolate(), graph()->zone(), stub.GetCallInterfaceDescriptor(), 1,
+        CallDescriptor::kNeedsFrameState);
+    node->ReplaceInput(0, jsgraph()->HeapConstant(stub.GetCode()));
+    node->InsertInput(graph()->zone(), 2, jsgraph()->HeapConstant(site));
+    node->InsertInput(graph()->zone(), 3, jsgraph()->UndefinedConstant());
+    NodeProperties::ChangeOp(node, common()->Call(desc));
+    return Changed(node);
+  } else if (p.arity() == 1) {
+    // TODO(bmeurer): Optimize for the 0 length non-holey case?
+    ArraySingleArgumentConstructorStub stub(
+        isolate(), GetHoleyElementsKind(elements_kind), override_mode);
+    CallDescriptor* desc = Linkage::GetStubCallDescriptor(
+        isolate(), graph()->zone(), stub.GetCallInterfaceDescriptor(), 2,
+        CallDescriptor::kNeedsFrameState);
+    node->ReplaceInput(0, jsgraph()->HeapConstant(stub.GetCode()));
+    node->InsertInput(graph()->zone(), 2, jsgraph()->HeapConstant(site));
+    node->InsertInput(graph()->zone(), 3, jsgraph()->Int32Constant(1));
+    node->InsertInput(graph()->zone(), 4, jsgraph()->UndefinedConstant());
+    NodeProperties::ChangeOp(node, common()->Call(desc));
+    return Changed(node);
+  } else {
+    int const arity = static_cast<int>(p.arity());
+    ArrayNArgumentsConstructorStub stub(isolate(), elements_kind,
+                                        override_mode);
+    CallDescriptor* desc = Linkage::GetStubCallDescriptor(
+        isolate(), graph()->zone(), stub.GetCallInterfaceDescriptor(),
+        arity + 1, CallDescriptor::kNeedsFrameState);
+    node->ReplaceInput(0, jsgraph()->HeapConstant(stub.GetCode()));
+    node->InsertInput(graph()->zone(), 2, jsgraph()->HeapConstant(site));
+    node->InsertInput(graph()->zone(), 3, jsgraph()->Int32Constant(arity));
+    node->InsertInput(graph()->zone(), 4, jsgraph()->UndefinedConstant());
+    NodeProperties::ChangeOp(node, common()->Call(desc));
+    return Changed(node);
+  }
+}
+
+
+Reduction JSTypedLowering::ReduceJSCreateClosure(Node* node) {
+  DCHECK_EQ(IrOpcode::kJSCreateClosure, node->opcode());
+  CreateClosureParameters const& p = CreateClosureParametersOf(node->op());
+  Handle<SharedFunctionInfo> shared = p.shared_info();
+
+  // Use the FastNewClosureStub that allocates in new space only for nested
+  // functions that don't need literals cloning.
+  if (p.pretenure() == NOT_TENURED && shared->num_literals() == 0) {
+    Isolate* isolate = jsgraph()->isolate();
+    Callable callable = CodeFactory::FastNewClosure(
+        isolate, shared->language_mode(), shared->kind());
+    CallDescriptor* desc = Linkage::GetStubCallDescriptor(
+        isolate, graph()->zone(), callable.descriptor(), 0,
+        CallDescriptor::kNoFlags);
+    const Operator* new_op = common()->Call(desc);
+    Node* stub_code = jsgraph()->HeapConstant(callable.code());
+    node->InsertInput(graph()->zone(), 0, stub_code);
+    node->InsertInput(graph()->zone(), 1, jsgraph()->HeapConstant(shared));
+    NodeProperties::ChangeOp(node, new_op);
+    return Changed(node);
+  }
+
+  return NoChange();
+}
+
+
+Reduction JSTypedLowering::ReduceJSCreateIterResultObject(Node* node) {
+  DCHECK_EQ(IrOpcode::kJSCreateIterResultObject, node->opcode());
+  Node* value = NodeProperties::GetValueInput(node, 0);
+  Node* done = NodeProperties::GetValueInput(node, 1);
+  Node* context = NodeProperties::GetContextInput(node);
+  Node* effect = NodeProperties::GetEffectInput(node);
+
+  // Load the JSIteratorResult map for the {context}.
+  Node* native_context = effect = graph()->NewNode(
+      javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true),
+      context, context, effect);
+  Node* iterator_result_map = effect = graph()->NewNode(
+      javascript()->LoadContext(0, Context::ITERATOR_RESULT_MAP_INDEX, true),
+      native_context, native_context, effect);
+
+  // Emit code to allocate the JSIteratorResult instance.
+  AllocationBuilder a(jsgraph(), effect, graph()->start());
+  a.Allocate(JSIteratorResult::kSize);
+  a.Store(AccessBuilder::ForMap(), iterator_result_map);
+  a.Store(AccessBuilder::ForJSObjectProperties(),
+          jsgraph()->EmptyFixedArrayConstant());
+  a.Store(AccessBuilder::ForJSObjectElements(),
+          jsgraph()->EmptyFixedArrayConstant());
+  a.Store(AccessBuilder::ForJSIteratorResultValue(), value);
+  a.Store(AccessBuilder::ForJSIteratorResultDone(), done);
+  STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize);
+  a.FinishAndChange(node);
+  return Changed(node);
+}
+
+
+Reduction JSTypedLowering::ReduceJSCreateLiteralArray(Node* node) {
+  DCHECK_EQ(IrOpcode::kJSCreateLiteralArray, node->opcode());
+  CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
+  Handle<FixedArray> const constants = Handle<FixedArray>::cast(p.constant());
+  int const length = constants->length();
+  int const flags = p.flags();
+
+  // Use the FastCloneShallowArrayStub only for shallow boilerplates up to the
+  // initial length limit for arrays with "fast" elements kind.
+  // TODO(rossberg): Teach strong mode to FastCloneShallowArrayStub.
+  if ((flags & ArrayLiteral::kShallowElements) != 0 &&
+      (flags & ArrayLiteral::kIsStrong) == 0 &&
+      length < JSArray::kInitialMaxFastElementArray) {
+    Isolate* isolate = jsgraph()->isolate();
+    Callable callable = CodeFactory::FastCloneShallowArray(isolate);
+    CallDescriptor* desc = Linkage::GetStubCallDescriptor(
+        isolate, graph()->zone(), callable.descriptor(), 0,
+        (OperatorProperties::GetFrameStateInputCount(node->op()) != 0)
+            ? CallDescriptor::kNeedsFrameState
+            : CallDescriptor::kNoFlags);
+    const Operator* new_op = common()->Call(desc);
+    Node* stub_code = jsgraph()->HeapConstant(callable.code());
+    Node* literal_index = jsgraph()->SmiConstant(p.index());
+    Node* constant_elements = jsgraph()->HeapConstant(constants);
+    node->InsertInput(graph()->zone(), 0, stub_code);
+    node->InsertInput(graph()->zone(), 2, literal_index);
+    node->InsertInput(graph()->zone(), 3, constant_elements);
+    NodeProperties::ChangeOp(node, new_op);
+    return Changed(node);
+  }
+
+  return NoChange();
+}
+
+
+Reduction JSTypedLowering::ReduceJSCreateLiteralObject(Node* node) {
+  DCHECK_EQ(IrOpcode::kJSCreateLiteralObject, node->opcode());
+  CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
+  Handle<FixedArray> const constants = Handle<FixedArray>::cast(p.constant());
+  // Constants are pairs, see ObjectLiteral::properties_count().
+  int const length = constants->length() / 2;
+  int const flags = p.flags();
+
+  // Use the FastCloneShallowObjectStub only for shallow boilerplates without
+  // elements up to the number of properties that the stubs can handle.
+  if ((flags & ObjectLiteral::kShallowProperties) != 0 &&
+      length <= FastCloneShallowObjectStub::kMaximumClonedProperties) {
+    Isolate* isolate = jsgraph()->isolate();
+    Callable callable = CodeFactory::FastCloneShallowObject(isolate, length);
+    CallDescriptor* desc = Linkage::GetStubCallDescriptor(
+        isolate, graph()->zone(), callable.descriptor(), 0,
+        (OperatorProperties::GetFrameStateInputCount(node->op()) != 0)
+            ? CallDescriptor::kNeedsFrameState
+            : CallDescriptor::kNoFlags);
+    const Operator* new_op = common()->Call(desc);
+    Node* stub_code = jsgraph()->HeapConstant(callable.code());
+    Node* literal_index = jsgraph()->SmiConstant(p.index());
+    Node* literal_flags = jsgraph()->SmiConstant(flags);
+    Node* constant_elements = jsgraph()->HeapConstant(constants);
+    node->InsertInput(graph()->zone(), 0, stub_code);
+    node->InsertInput(graph()->zone(), 2, literal_index);
+    node->InsertInput(graph()->zone(), 3, constant_elements);
+    node->InsertInput(graph()->zone(), 4, literal_flags);
+    NodeProperties::ChangeOp(node, new_op);
+    return Changed(node);
+  }
+
+  return NoChange();
+}
+
+
+Reduction JSTypedLowering::ReduceJSCreateFunctionContext(Node* node) {
+  DCHECK_EQ(IrOpcode::kJSCreateFunctionContext, node->opcode());
+  int slot_count = OpParameter<int>(node->op());
+  Node* const closure = NodeProperties::GetValueInput(node, 0);
+
+  // Use inline allocation for function contexts up to a size limit.
+  if (slot_count < kFunctionContextAllocationLimit) {
+    // JSCreateFunctionContext[slot_count < limit]](fun)
+    Node* effect = NodeProperties::GetEffectInput(node);
+    Node* control = NodeProperties::GetControlInput(node);
+    Node* context = NodeProperties::GetContextInput(node);
+    Node* extension = jsgraph()->TheHoleConstant();
+    Node* native_context = effect = graph()->NewNode(
+        javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true),
+        context, context, effect);
+    AllocationBuilder a(jsgraph(), effect, control);
+    STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 4);  // Ensure fully covered.
+    int context_length = slot_count + Context::MIN_CONTEXT_SLOTS;
+    a.AllocateArray(context_length, factory()->function_context_map());
+    a.Store(AccessBuilder::ForContextSlot(Context::CLOSURE_INDEX), closure);
+    a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context);
+    a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), extension);
+    a.Store(AccessBuilder::ForContextSlot(Context::NATIVE_CONTEXT_INDEX),
+            native_context);
+    for (int i = Context::MIN_CONTEXT_SLOTS; i < context_length; ++i) {
+      a.Store(AccessBuilder::ForContextSlot(i), jsgraph()->UndefinedConstant());
+    }
+    RelaxControls(node);
+    a.FinishAndChange(node);
+    return Changed(node);
+  }
+
+  // Use the FastNewContextStub only for function contexts up maximum size.
+  if (slot_count <= FastNewContextStub::kMaximumSlots) {
+    Isolate* isolate = jsgraph()->isolate();
+    Callable callable = CodeFactory::FastNewContext(isolate, slot_count);
+    CallDescriptor* desc = Linkage::GetStubCallDescriptor(
+        isolate, graph()->zone(), callable.descriptor(), 0,
+        CallDescriptor::kNoFlags);
+    const Operator* new_op = common()->Call(desc);
+    Node* stub_code = jsgraph()->HeapConstant(callable.code());
+    node->InsertInput(graph()->zone(), 0, stub_code);
+    NodeProperties::ChangeOp(node, new_op);
+    return Changed(node);
+  }
+
+  return NoChange();
+}
+
+
+Reduction JSTypedLowering::ReduceJSCreateWithContext(Node* node) {
+  DCHECK_EQ(IrOpcode::kJSCreateWithContext, node->opcode());
+  Node* object = NodeProperties::GetValueInput(node, 0);
+  Node* closure = NodeProperties::GetValueInput(node, 1);
+  Node* effect = NodeProperties::GetEffectInput(node);
+  Node* control = NodeProperties::GetControlInput(node);
+  Node* context = NodeProperties::GetContextInput(node);
+  Node* native_context = effect = graph()->NewNode(
+      javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true),
+      context, context, effect);
+  AllocationBuilder a(jsgraph(), effect, control);
+  STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 4);  // Ensure fully covered.
+  a.AllocateArray(Context::MIN_CONTEXT_SLOTS, factory()->with_context_map());
+  a.Store(AccessBuilder::ForContextSlot(Context::CLOSURE_INDEX), closure);
+  a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context);
+  a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), object);
+  a.Store(AccessBuilder::ForContextSlot(Context::NATIVE_CONTEXT_INDEX),
+          native_context);
+  RelaxControls(node);
+  a.FinishAndChange(node);
+  return Changed(node);
+}
+
+
+Reduction JSTypedLowering::ReduceJSCreateCatchContext(Node* node) {
+  DCHECK_EQ(IrOpcode::kJSCreateCatchContext, node->opcode());
+  Handle<String> name = OpParameter<Handle<String>>(node);
+  Node* exception = NodeProperties::GetValueInput(node, 0);
+  Node* closure = NodeProperties::GetValueInput(node, 1);
+  Node* effect = NodeProperties::GetEffectInput(node);
+  Node* control = NodeProperties::GetControlInput(node);
+  Node* context = NodeProperties::GetContextInput(node);
+  Node* native_context = effect = graph()->NewNode(
+      javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true),
+      context, context, effect);
+  AllocationBuilder a(jsgraph(), effect, control);
+  STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 4);  // Ensure fully covered.
+  a.AllocateArray(Context::MIN_CONTEXT_SLOTS + 1,
+                  factory()->catch_context_map());
+  a.Store(AccessBuilder::ForContextSlot(Context::CLOSURE_INDEX), closure);
+  a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context);
+  a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), name);
+  a.Store(AccessBuilder::ForContextSlot(Context::NATIVE_CONTEXT_INDEX),
+          native_context);
+  a.Store(AccessBuilder::ForContextSlot(Context::THROWN_OBJECT_INDEX),
+          exception);
+  RelaxControls(node);
+  a.FinishAndChange(node);
+  return Changed(node);
+}
+
+
+Reduction JSTypedLowering::ReduceJSCreateBlockContext(Node* node) {
+  DCHECK_EQ(IrOpcode::kJSCreateBlockContext, node->opcode());
+  Handle<ScopeInfo> scope_info = OpParameter<Handle<ScopeInfo>>(node);
+  int context_length = scope_info->ContextLength();
+  Node* const closure = NodeProperties::GetValueInput(node, 0);
+
+  // Use inline allocation for block contexts up to a size limit.
+  if (context_length < kBlockContextAllocationLimit) {
+    // JSCreateBlockContext[scope[length < limit]](fun)
+    Node* effect = NodeProperties::GetEffectInput(node);
+    Node* control = NodeProperties::GetControlInput(node);
+    Node* context = NodeProperties::GetContextInput(node);
+    Node* extension = jsgraph()->Constant(scope_info);
+    Node* native_context = effect = graph()->NewNode(
+        javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true),
+        context, context, effect);
+    AllocationBuilder a(jsgraph(), effect, control);
+    STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 4);  // Ensure fully covered.
+    a.AllocateArray(context_length, factory()->block_context_map());
+    a.Store(AccessBuilder::ForContextSlot(Context::CLOSURE_INDEX), closure);
+    a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context);
+    a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), extension);
+    a.Store(AccessBuilder::ForContextSlot(Context::NATIVE_CONTEXT_INDEX),
+            native_context);
+    for (int i = Context::MIN_CONTEXT_SLOTS; i < context_length; ++i) {
+      a.Store(AccessBuilder::ForContextSlot(i), jsgraph()->UndefinedConstant());
+    }
+    RelaxControls(node);
+    a.FinishAndChange(node);
+    return Changed(node);
+  }
+
+  return NoChange();
+}
+
+
+Reduction JSTypedLowering::ReduceJSCallConstruct(Node* node) {
+  DCHECK_EQ(IrOpcode::kJSCallConstruct, node->opcode());
+  CallConstructParameters const& p = CallConstructParametersOf(node->op());
+  DCHECK_LE(2u, p.arity());
+  int const arity = static_cast<int>(p.arity() - 2);
+  Node* target = NodeProperties::GetValueInput(node, 0);
+  Type* target_type = NodeProperties::GetType(target);
+  Node* new_target = NodeProperties::GetValueInput(node, arity + 1);
+
+  // Check if {target} is a known JSFunction.
+  if (target_type->IsConstant() &&
+      target_type->AsConstant()->Value()->IsJSFunction()) {
+    Handle<JSFunction> function =
+        Handle<JSFunction>::cast(target_type->AsConstant()->Value());
+    Handle<SharedFunctionInfo> shared(function->shared(), isolate());
+
+    // Remove the eager bailout frame state.
+    NodeProperties::RemoveFrameStateInput(node, 1);
+
+    // Patch {node} to an indirect call via the {function}s construct stub.
+    Callable callable(handle(shared->construct_stub(), isolate()),
+                      ConstructStubDescriptor(isolate()));
+    node->RemoveInput(arity + 1);
+    node->InsertInput(graph()->zone(), 0,
+                      jsgraph()->HeapConstant(callable.code()));
+    node->InsertInput(graph()->zone(), 2, new_target);
+    node->InsertInput(graph()->zone(), 3, jsgraph()->Int32Constant(arity));
+    node->InsertInput(graph()->zone(), 4, jsgraph()->UndefinedConstant());
+    node->InsertInput(graph()->zone(), 5, jsgraph()->UndefinedConstant());
+    NodeProperties::ChangeOp(
+        node, common()->Call(Linkage::GetStubCallDescriptor(
+                  isolate(), graph()->zone(), callable.descriptor(), 1 + arity,
+                  CallDescriptor::kNeedsFrameState)));
+    return Changed(node);
+  }
+
+  // Check if {target} is a JSFunction.
+  if (target_type->Is(Type::Function())) {
+    // Remove the eager bailout frame state.
+    NodeProperties::RemoveFrameStateInput(node, 1);
+
+    // Patch {node} to an indirect call via the ConstructFunction builtin.
+    Callable callable = CodeFactory::ConstructFunction(isolate());
+    node->RemoveInput(arity + 1);
+    node->InsertInput(graph()->zone(), 0,
+                      jsgraph()->HeapConstant(callable.code()));
+    node->InsertInput(graph()->zone(), 2, new_target);
+    node->InsertInput(graph()->zone(), 3, jsgraph()->Int32Constant(arity));
+    node->InsertInput(graph()->zone(), 4, jsgraph()->UndefinedConstant());
+    NodeProperties::ChangeOp(
+        node, common()->Call(Linkage::GetStubCallDescriptor(
+                  isolate(), graph()->zone(), callable.descriptor(), 1 + arity,
+                  CallDescriptor::kNeedsFrameState)));
+    return Changed(node);
+  }
+
+  return NoChange();
+}
+
+
+Reduction JSTypedLowering::ReduceJSCallFunction(Node* node) {
+  DCHECK_EQ(IrOpcode::kJSCallFunction, node->opcode());
+  CallFunctionParameters const& p = CallFunctionParametersOf(node->op());
+  int const arity = static_cast<int>(p.arity() - 2);
+  ConvertReceiverMode convert_mode = p.convert_mode();
+  Node* target = NodeProperties::GetValueInput(node, 0);
+  Type* target_type = NodeProperties::GetType(target);
+  Node* receiver = NodeProperties::GetValueInput(node, 1);
+  Type* receiver_type = NodeProperties::GetType(receiver);
+  Node* frame_state = NodeProperties::GetFrameStateInput(node, 1);
+  Node* effect = NodeProperties::GetEffectInput(node);
+  Node* control = NodeProperties::GetControlInput(node);
+
+  // Try to infer receiver {convert_mode} from {receiver} type.
+  if (receiver_type->Is(Type::NullOrUndefined())) {
+    convert_mode = ConvertReceiverMode::kNullOrUndefined;
+  } else if (!receiver_type->Maybe(Type::NullOrUndefined())) {
+    convert_mode = ConvertReceiverMode::kNotNullOrUndefined;
+  }
+
+  // Check if {target} is a known JSFunction.
+  if (target_type->IsConstant() &&
+      target_type->AsConstant()->Value()->IsJSFunction()) {
+    Handle<JSFunction> function =
+        Handle<JSFunction>::cast(target_type->AsConstant()->Value());
+    Handle<SharedFunctionInfo> shared(function->shared(), isolate());
+
+    // Class constructors are callable, but [[Call]] will raise an exception.
+    // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList ).
+    if (IsClassConstructor(shared->kind())) return NoChange();
+
+    // Load the context from the {target}.
+    Node* context = effect = graph()->NewNode(
+        simplified()->LoadField(AccessBuilder::ForJSFunctionContext()), target,
+        effect, control);
+    NodeProperties::ReplaceContextInput(node, context);
+
+    // Check if we need to convert the {receiver}.
+    if (is_sloppy(shared->language_mode()) && !shared->native() &&
+        !receiver_type->Is(Type::Receiver())) {
+      receiver = effect =
+          graph()->NewNode(javascript()->ConvertReceiver(convert_mode),
+                           receiver, context, frame_state, effect, control);
+      NodeProperties::ReplaceValueInput(node, receiver, 1);
+    }
+
+    // Update the effect dependency for the {node}.
+    NodeProperties::ReplaceEffectInput(node, effect);
+
+    // Remove the eager bailout frame state.
+    NodeProperties::RemoveFrameStateInput(node, 1);
+
+    // Compute flags for the call.
+    CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState;
+    if (p.tail_call_mode() == TailCallMode::kAllow) {
+      flags |= CallDescriptor::kSupportsTailCalls;
+    }
+
+    Node* new_target = jsgraph()->UndefinedConstant();
+    Node* argument_count = jsgraph()->Int32Constant(arity);
+    if (shared->internal_formal_parameter_count() == arity ||
+        shared->internal_formal_parameter_count() ==
+            SharedFunctionInfo::kDontAdaptArgumentsSentinel) {
+      // Patch {node} to a direct call.
+      node->InsertInput(graph()->zone(), arity + 2, new_target);
+      node->InsertInput(graph()->zone(), arity + 3, argument_count);
+      NodeProperties::ChangeOp(node,
+                               common()->Call(Linkage::GetJSCallDescriptor(
+                                   graph()->zone(), false, 1 + arity, flags)));
+    } else {
+      // Patch {node} to an indirect call via the ArgumentsAdaptorTrampoline.
+      Callable callable = CodeFactory::ArgumentAdaptor(isolate());
+      node->InsertInput(graph()->zone(), 0,
+                        jsgraph()->HeapConstant(callable.code()));
+      node->InsertInput(graph()->zone(), 2, new_target);
+      node->InsertInput(graph()->zone(), 3, argument_count);
+      node->InsertInput(
+          graph()->zone(), 4,
+          jsgraph()->Int32Constant(shared->internal_formal_parameter_count()));
+      NodeProperties::ChangeOp(
+          node, common()->Call(Linkage::GetStubCallDescriptor(
+                    isolate(), graph()->zone(), callable.descriptor(),
+                    1 + arity, flags)));
+    }
+    return Changed(node);
+  }
+
+  // Check if {target} is a JSFunction.
+  if (target_type->Is(Type::Function())) {
+    // Remove the eager bailout frame state.
+    NodeProperties::RemoveFrameStateInput(node, 1);
+
+    // Compute flags for the call.
+    CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState;
+    if (p.tail_call_mode() == TailCallMode::kAllow) {
+      flags |= CallDescriptor::kSupportsTailCalls;
+    }
+
+    // Patch {node} to an indirect call via the CallFunction builtin.
+    Callable callable = CodeFactory::CallFunction(isolate(), convert_mode);
+    node->InsertInput(graph()->zone(), 0,
+                      jsgraph()->HeapConstant(callable.code()));
+    node->InsertInput(graph()->zone(), 2, jsgraph()->Int32Constant(arity));
+    NodeProperties::ChangeOp(
+        node, common()->Call(Linkage::GetStubCallDescriptor(
+                  isolate(), graph()->zone(), callable.descriptor(), 1 + arity,
+                  flags)));
+    return Changed(node);
+  }
+
+  // Maybe we did at least learn something about the {receiver}.
+  if (p.convert_mode() != convert_mode) {
+    NodeProperties::ChangeOp(
+        node,
+        javascript()->CallFunction(p.arity(), p.language_mode(), p.feedback(),
+                                   convert_mode, p.tail_call_mode()));
+    return Changed(node);
+  }
+
+  return NoChange();
+}
+
+
+Reduction JSTypedLowering::ReduceJSForInDone(Node* node) {
+  DCHECK_EQ(IrOpcode::kJSForInDone, node->opcode());
+  node->TrimInputCount(2);
+  NodeProperties::ChangeOp(node, machine()->Word32Equal());
+  return Changed(node);
+}
+
+
+Reduction JSTypedLowering::ReduceJSForInPrepare(Node* node) {
+  DCHECK_EQ(IrOpcode::kJSForInPrepare, node->opcode());
+  Node* receiver = NodeProperties::GetValueInput(node, 0);
+  Node* context = NodeProperties::GetContextInput(node);
+  Node* frame_state = NodeProperties::GetFrameStateInput(node, 0);
+  Node* effect = NodeProperties::GetEffectInput(node);
+  Node* control = NodeProperties::GetControlInput(node);
+
+  // Get the set of properties to enumerate.
+  Node* cache_type = effect = graph()->NewNode(
+      javascript()->CallRuntime(Runtime::kGetPropertyNamesFast, 1), receiver,
+      context, frame_state, effect, control);
+  control = graph()->NewNode(common()->IfSuccess(), cache_type);
+
+  Node* receiver_map = effect =
+      graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
+                       receiver, effect, control);
+  Node* cache_type_map = effect =
+      graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
+                       cache_type, effect, control);
+  Node* meta_map = jsgraph()->HeapConstant(factory()->meta_map());
+
+  // If we got a map from the GetPropertyNamesFast runtime call, we can do a
+  // fast modification check. Otherwise, we got a fixed array, and we have to
+  // perform a slow check on every iteration.
+  Node* check0 = graph()->NewNode(simplified()->ReferenceEqual(Type::Any()),
+                                  cache_type_map, meta_map);
+  Node* branch0 =
+      graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
+
+  Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
+  Node* cache_array_true0;
+  Node* cache_length_true0;
+  Node* cache_type_true0;
+  Node* etrue0;
+  {
+    // Enum cache case.
+    Node* cache_type_enum_length = etrue0 = graph()->NewNode(
+        simplified()->LoadField(AccessBuilder::ForMapBitField3()), cache_type,
+        effect, if_true0);
+    cache_length_true0 = graph()->NewNode(
+        simplified()->NumberBitwiseAnd(), cache_type_enum_length,
+        jsgraph()->Int32Constant(Map::EnumLengthBits::kMask));
+
+    Node* check1 =
+        graph()->NewNode(machine()->Word32Equal(), cache_length_true0,
+                         jsgraph()->Int32Constant(0));
+    Node* branch1 =
+        graph()->NewNode(common()->Branch(BranchHint::kTrue), check1, if_true0);
+
+    Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
+    Node* cache_array_true1;
+    Node* etrue1;
+    {
+      // No properties to enumerate.
+      cache_array_true1 =
+          jsgraph()->HeapConstant(factory()->empty_fixed_array());
+      etrue1 = etrue0;
+    }
+
+    Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
+    Node* cache_array_false1;
+    Node* efalse1;
+    {
+      // Load the enumeration cache from the instance descriptors of {receiver}.
+      Node* receiver_map_descriptors = efalse1 = graph()->NewNode(
+          simplified()->LoadField(AccessBuilder::ForMapDescriptors()),
+          receiver_map, etrue0, if_false1);
+      Node* object_map_enum_cache = efalse1 = graph()->NewNode(
+          simplified()->LoadField(AccessBuilder::ForDescriptorArrayEnumCache()),
+          receiver_map_descriptors, efalse1, if_false1);
+      cache_array_false1 = efalse1 = graph()->NewNode(
+          simplified()->LoadField(
+              AccessBuilder::ForDescriptorArrayEnumCacheBridgeCache()),
+          object_map_enum_cache, efalse1, if_false1);
+    }
+
+    if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
+    etrue0 =
+        graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_true0);
+    cache_array_true0 =
+        graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
+                         cache_array_true1, cache_array_false1, if_true0);
+
+    cache_type_true0 = cache_type;
+  }
+
+  Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
+  Node* cache_array_false0;
+  Node* cache_length_false0;
+  Node* cache_type_false0;
+  Node* efalse0;
+  {
+    // FixedArray case.
+    cache_type_false0 = jsgraph()->OneConstant();  // Smi means slow check
+    cache_array_false0 = cache_type;
+    cache_length_false0 = efalse0 = graph()->NewNode(
+        simplified()->LoadField(AccessBuilder::ForFixedArrayLength()),
+        cache_array_false0, effect, if_false0);
+  }
+
+  control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
+  effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
+  Node* cache_array =
+      graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
+                       cache_array_true0, cache_array_false0, control);
+  Node* cache_length =
+      graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
+                       cache_length_true0, cache_length_false0, control);
+  cache_type =
+      graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
+                       cache_type_true0, cache_type_false0, control);
+
+  for (auto edge : node->use_edges()) {
+    Node* const use = edge.from();
+    if (NodeProperties::IsEffectEdge(edge)) {
+      edge.UpdateTo(effect);
+      Revisit(use);
+    } else {
+      if (NodeProperties::IsControlEdge(edge)) {
+        if (use->opcode() == IrOpcode::kIfSuccess) {
+          Replace(use, control);
+        } else if (use->opcode() == IrOpcode::kIfException) {
+          edge.UpdateTo(cache_type_true0);
+          continue;
+        } else {
+          UNREACHABLE();
+        }
+      } else {
+        DCHECK(NodeProperties::IsValueEdge(edge));
+        DCHECK_EQ(IrOpcode::kProjection, use->opcode());
+        switch (ProjectionIndexOf(use->op())) {
+          case 0:
+            Replace(use, cache_type);
+            break;
+          case 1:
+            Replace(use, cache_array);
+            break;
+          case 2:
+            Replace(use, cache_length);
+            break;
+          default:
+            UNREACHABLE();
+            break;
+        }
+      }
+      use->Kill();
+    }
+  }
+  return NoChange();  // All uses were replaced already above.
+}
+
+
+Reduction JSTypedLowering::ReduceJSForInNext(Node* node) {
+  DCHECK_EQ(IrOpcode::kJSForInNext, node->opcode());
+  Node* receiver = NodeProperties::GetValueInput(node, 0);
+  Node* cache_array = NodeProperties::GetValueInput(node, 1);
+  Node* cache_type = NodeProperties::GetValueInput(node, 2);
+  Node* index = NodeProperties::GetValueInput(node, 3);
+  Node* context = NodeProperties::GetContextInput(node);
+  Node* frame_state = NodeProperties::GetFrameStateInput(node, 0);
+  Node* effect = NodeProperties::GetEffectInput(node);
+  Node* control = NodeProperties::GetControlInput(node);
+
+  // Load the next {key} from the {cache_array}.
+  Node* key = effect = graph()->NewNode(
+      simplified()->LoadElement(AccessBuilder::ForFixedArrayElement()),
+      cache_array, index, effect, control);
+
+  // Load the map of the {receiver}.
+  Node* receiver_map = effect =
+      graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
+                       receiver, effect, control);
+
+  // Check if the expected map still matches that of the {receiver}.
+  Node* check0 = graph()->NewNode(simplified()->ReferenceEqual(Type::Any()),
+                                  receiver_map, cache_type);
+  Node* branch0 =
+      graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
+
+  Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
+  Node* etrue0;
+  Node* vtrue0;
+  {
+    // Don't need filtering since expected map still matches that of the
+    // {receiver}.
+    etrue0 = effect;
+    vtrue0 = key;
+  }
+
+  Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
+  Node* efalse0;
+  Node* vfalse0;
+  {
+    // Check if the {cache_type} is zero, which indicates proxy.
+    Node* check1 = graph()->NewNode(simplified()->ReferenceEqual(Type::Any()),
+                                    cache_type, jsgraph()->ZeroConstant());
+    Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
+                                     check1, if_false0);
+
+    Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
+    Node* etrue1;
+    Node* vtrue1;
+    {
+      // Don't do filtering for proxies.
+      etrue1 = effect;
+      vtrue1 = key;
+    }
+
+    Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
+    Node* efalse1;
+    Node* vfalse1;
+    {
+      // Filter the {key} to check if it's still a valid property of the
+      // {receiver} (does the ToName conversion implicitly).
+      vfalse1 = efalse1 = graph()->NewNode(
+          javascript()->CallRuntime(Runtime::kForInFilter, 2), receiver, key,
+          context, frame_state, effect, if_false1);
+      if_false1 = graph()->NewNode(common()->IfSuccess(), vfalse1);
+    }
+
+    if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
+    efalse0 =
+        graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_false0);
+    vfalse0 = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
+                               vtrue1, vfalse1, if_false0);
+  }
+
+  control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
+  effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
+  ReplaceWithValue(node, node, effect, control);
+  node->ReplaceInput(0, vtrue0);
+  node->ReplaceInput(1, vfalse0);
+  node->ReplaceInput(2, control);
+  node->TrimInputCount(3);
+  NodeProperties::ChangeOp(node,
+                           common()->Phi(MachineRepresentation::kTagged, 2));
+  return Changed(node);
+}
+
+
+Reduction JSTypedLowering::ReduceJSForInStep(Node* node) {
+  DCHECK_EQ(IrOpcode::kJSForInStep, node->opcode());
+  node->ReplaceInput(1, jsgraph()->Int32Constant(1));
+  NodeProperties::ChangeOp(node, machine()->Int32Add());
+  return Changed(node);
+}
+
+
+Reduction JSTypedLowering::ReduceSelect(Node* node) {
+  DCHECK_EQ(IrOpcode::kSelect, node->opcode());
+  Node* const condition = NodeProperties::GetValueInput(node, 0);
+  Type* const condition_type = NodeProperties::GetType(condition);
+  Node* const vtrue = NodeProperties::GetValueInput(node, 1);
+  Type* const vtrue_type = NodeProperties::GetType(vtrue);
+  Node* const vfalse = NodeProperties::GetValueInput(node, 2);
+  Type* const vfalse_type = NodeProperties::GetType(vfalse);
+  if (condition_type->Is(true_type_)) {
+    // Select(condition:true, vtrue, vfalse) => vtrue
+    return Replace(vtrue);
+  }
+  if (condition_type->Is(false_type_)) {
+    // Select(condition:false, vtrue, vfalse) => vfalse
+    return Replace(vfalse);
+  }
+  if (vtrue_type->Is(true_type_) && vfalse_type->Is(false_type_)) {
+    // Select(condition, vtrue:true, vfalse:false) => condition
+    return Replace(condition);
+  }
+  if (vtrue_type->Is(false_type_) && vfalse_type->Is(true_type_)) {
+    // Select(condition, vtrue:false, vfalse:true) => BooleanNot(condition)
+    node->TrimInputCount(1);
+    NodeProperties::ChangeOp(node, simplified()->BooleanNot());
+    return Changed(node);
+  }
+  return NoChange();
+}
+
+
 Reduction JSTypedLowering::Reduce(Node* node) {
   // Check if the output type is a singleton.  In that case we already know the
   // result value and can simply replace the node if it's eliminable.
-  if (NodeProperties::IsTyped(node) &&
-      !IrOpcode::IsLeafOpcode(node->opcode()) &&
+  if (!NodeProperties::IsConstant(node) && NodeProperties::IsTyped(node) &&
       node->op()->HasProperty(Operator::kEliminatable)) {
-    Type* upper = NodeProperties::GetBounds(node).upper;
+    Type* upper = NodeProperties::GetType(node);
     if (upper->IsConstant()) {
       Node* replacement = jsgraph()->Constant(upper->AsConstant()->Value());
-      NodeProperties::ReplaceWithValue(node, replacement);
+      ReplaceWithValue(node, replacement);
       return Changed(replacement);
     } else if (upper->Is(Type::MinusZero())) {
       Node* replacement = jsgraph()->Constant(factory()->minus_zero_value());
-      NodeProperties::ReplaceWithValue(node, replacement);
+      ReplaceWithValue(node, replacement);
       return Changed(replacement);
     } else if (upper->Is(Type::NaN())) {
       Node* replacement = jsgraph()->NaNConstant();
-      NodeProperties::ReplaceWithValue(node, replacement);
+      ReplaceWithValue(node, replacement);
       return Changed(replacement);
     } else if (upper->Is(Type::Null())) {
       Node* replacement = jsgraph()->NullConstant();
-      NodeProperties::ReplaceWithValue(node, replacement);
+      ReplaceWithValue(node, replacement);
       return Changed(replacement);
     } else if (upper->Is(Type::PlainNumber()) && upper->Min() == upper->Max()) {
       Node* replacement = jsgraph()->Constant(upper->Min());
-      NodeProperties::ReplaceWithValue(node, replacement);
+      ReplaceWithValue(node, replacement);
       return Changed(replacement);
     } else if (upper->Is(Type::Undefined())) {
       Node* replacement = jsgraph()->UndefinedConstant();
-      NodeProperties::ReplaceWithValue(node, replacement);
+      ReplaceWithValue(node, replacement);
       return Changed(replacement);
     }
   }
@@ -883,43 +2596,86 @@
     case IrOpcode::kJSGreaterThanOrEqual:
       return ReduceJSComparison(node);
     case IrOpcode::kJSBitwiseOr:
-      return ReduceJSBitwiseOr(node);
+      return ReduceInt32Binop(node, simplified()->NumberBitwiseOr());
     case IrOpcode::kJSBitwiseXor:
-      return ReduceInt32Binop(node, machine()->Word32Xor());
+      return ReduceInt32Binop(node, simplified()->NumberBitwiseXor());
     case IrOpcode::kJSBitwiseAnd:
-      return ReduceInt32Binop(node, machine()->Word32And());
+      return ReduceInt32Binop(node, simplified()->NumberBitwiseAnd());
     case IrOpcode::kJSShiftLeft:
-      return ReduceUI32Shift(node, kSigned, machine()->Word32Shl());
+      return ReduceUI32Shift(node, kSigned, simplified()->NumberShiftLeft());
     case IrOpcode::kJSShiftRight:
-      return ReduceUI32Shift(node, kSigned, machine()->Word32Sar());
+      return ReduceUI32Shift(node, kSigned, simplified()->NumberShiftRight());
     case IrOpcode::kJSShiftRightLogical:
-      return ReduceUI32Shift(node, kUnsigned, machine()->Word32Shr());
+      return ReduceUI32Shift(node, kUnsigned,
+                             simplified()->NumberShiftRightLogical());
     case IrOpcode::kJSAdd:
       return ReduceJSAdd(node);
     case IrOpcode::kJSSubtract:
       return ReduceNumberBinop(node, simplified()->NumberSubtract());
     case IrOpcode::kJSMultiply:
-      return ReduceJSMultiply(node);
+      return ReduceNumberBinop(node, simplified()->NumberMultiply());
     case IrOpcode::kJSDivide:
       return ReduceNumberBinop(node, simplified()->NumberDivide());
     case IrOpcode::kJSModulus:
-      return ReduceNumberBinop(node, simplified()->NumberModulus());
-    case IrOpcode::kJSUnaryNot:
-      return ReduceJSUnaryNot(node);
+      return ReduceJSModulus(node);
     case IrOpcode::kJSToBoolean:
       return ReduceJSToBoolean(node);
     case IrOpcode::kJSToNumber:
       return ReduceJSToNumber(node);
     case IrOpcode::kJSToString:
       return ReduceJSToString(node);
+    case IrOpcode::kJSToObject:
+      return ReduceJSToObject(node);
+    case IrOpcode::kJSLoadNamed:
+      return ReduceJSLoadNamed(node);
     case IrOpcode::kJSLoadProperty:
       return ReduceJSLoadProperty(node);
     case IrOpcode::kJSStoreProperty:
       return ReduceJSStoreProperty(node);
+    case IrOpcode::kJSInstanceOf:
+      return ReduceJSInstanceOf(node);
     case IrOpcode::kJSLoadContext:
       return ReduceJSLoadContext(node);
     case IrOpcode::kJSStoreContext:
       return ReduceJSStoreContext(node);
+    case IrOpcode::kJSConvertReceiver:
+      return ReduceJSConvertReceiver(node);
+    case IrOpcode::kJSCreate:
+      return ReduceJSCreate(node);
+    case IrOpcode::kJSCreateArguments:
+      return ReduceJSCreateArguments(node);
+    case IrOpcode::kJSCreateArray:
+      return ReduceJSCreateArray(node);
+    case IrOpcode::kJSCreateClosure:
+      return ReduceJSCreateClosure(node);
+    case IrOpcode::kJSCreateIterResultObject:
+      return ReduceJSCreateIterResultObject(node);
+    case IrOpcode::kJSCreateLiteralArray:
+      return ReduceJSCreateLiteralArray(node);
+    case IrOpcode::kJSCreateLiteralObject:
+      return ReduceJSCreateLiteralObject(node);
+    case IrOpcode::kJSCreateFunctionContext:
+      return ReduceJSCreateFunctionContext(node);
+    case IrOpcode::kJSCreateWithContext:
+      return ReduceJSCreateWithContext(node);
+    case IrOpcode::kJSCreateCatchContext:
+      return ReduceJSCreateCatchContext(node);
+    case IrOpcode::kJSCreateBlockContext:
+      return ReduceJSCreateBlockContext(node);
+    case IrOpcode::kJSCallConstruct:
+      return ReduceJSCallConstruct(node);
+    case IrOpcode::kJSCallFunction:
+      return ReduceJSCallFunction(node);
+    case IrOpcode::kJSForInDone:
+      return ReduceJSForInDone(node);
+    case IrOpcode::kJSForInNext:
+      return ReduceJSForInNext(node);
+    case IrOpcode::kJSForInPrepare:
+      return ReduceJSForInPrepare(node);
+    case IrOpcode::kJSForInStep:
+      return ReduceJSForInStep(node);
+    case IrOpcode::kSelect:
+      return ReduceSelect(node);
     default:
       break;
   }
@@ -927,42 +2683,6 @@
 }
 
 
-Node* JSTypedLowering::ConvertToNumber(Node* input) {
-  DCHECK(NodeProperties::GetBounds(input).upper->Is(Type::PlainPrimitive()));
-  // Avoid inserting too many eager ToNumber() operations.
-  Reduction const reduction = ReduceJSToNumberInput(input);
-  if (reduction.Changed()) return reduction.replacement();
-  Node* const conversion = graph()->NewNode(javascript()->ToNumber(), input,
-                                            jsgraph()->NoContextConstant(),
-                                            graph()->start(), graph()->start());
-  InsertConversion(conversion);
-  return conversion;
-}
-
-
-template <IrOpcode::Value kOpcode>
-Node* JSTypedLowering::FindConversion(Node* input) {
-  size_t const input_id = input->id();
-  if (input_id < conversions_.size()) {
-    Node* const conversion = conversions_[input_id];
-    if (conversion && conversion->opcode() == kOpcode) {
-      return conversion;
-    }
-  }
-  return nullptr;
-}
-
-
-void JSTypedLowering::InsertConversion(Node* conversion) {
-  DCHECK(conversion->opcode() == IrOpcode::kJSToNumber);
-  size_t const input_id = conversion->InputAt(0)->id();
-  if (input_id >= conversions_.size()) {
-    conversions_.resize(2 * input_id + 1);
-  }
-  conversions_[input_id] = conversion;
-}
-
-
 Node* JSTypedLowering::Word32Shl(Node* const lhs, int32_t const rhs) {
   if (rhs == 0) return lhs;
   return graph()->NewNode(machine()->Word32Shl(), lhs,
@@ -970,12 +2690,148 @@
 }
 
 
+// Helper that allocates a FixedArray holding argument values recorded in the
+// given {frame_state}. Serves as backing store for JSCreateArguments nodes.
+Node* JSTypedLowering::AllocateArguments(Node* effect, Node* control,
+                                         Node* frame_state) {
+  FrameStateInfo state_info = OpParameter<FrameStateInfo>(frame_state);
+  int argument_count = state_info.parameter_count() - 1;  // Minus receiver.
+  if (argument_count == 0) return jsgraph()->EmptyFixedArrayConstant();
+
+  // Prepare an iterator over argument values recorded in the frame state.
+  Node* const parameters = frame_state->InputAt(kFrameStateParametersInput);
+  StateValuesAccess parameters_access(parameters);
+  auto parameters_it = ++parameters_access.begin();
+
+  // Actually allocate the backing store.
+  AllocationBuilder a(jsgraph(), effect, control);
+  a.AllocateArray(argument_count, factory()->fixed_array_map());
+  for (int i = 0; i < argument_count; ++i, ++parameters_it) {
+    a.Store(AccessBuilder::ForFixedArraySlot(i), (*parameters_it).node);
+  }
+  return a.Finish();
+}
+
+
+// Helper that allocates a FixedArray holding argument values recorded in the
+// given {frame_state}. Serves as backing store for JSCreateArguments nodes.
+Node* JSTypedLowering::AllocateRestArguments(Node* effect, Node* control,
+                                             Node* frame_state,
+                                             int start_index) {
+  FrameStateInfo state_info = OpParameter<FrameStateInfo>(frame_state);
+  int argument_count = state_info.parameter_count() - 1;  // Minus receiver.
+  int num_elements = std::max(0, argument_count - start_index);
+  if (num_elements == 0) return jsgraph()->EmptyFixedArrayConstant();
+
+  // Prepare an iterator over argument values recorded in the frame state.
+  Node* const parameters = frame_state->InputAt(kFrameStateParametersInput);
+  StateValuesAccess parameters_access(parameters);
+  auto parameters_it = ++parameters_access.begin();
+
+  // Skip unused arguments.
+  for (int i = 0; i < start_index; i++) {
+    ++parameters_it;
+  }
+
+  // Actually allocate the backing store.
+  AllocationBuilder a(jsgraph(), effect, control);
+  a.AllocateArray(num_elements, factory()->fixed_array_map());
+  for (int i = 0; i < num_elements; ++i, ++parameters_it) {
+    a.Store(AccessBuilder::ForFixedArraySlot(i), (*parameters_it).node);
+  }
+  return a.Finish();
+}
+
+
+// Helper that allocates a FixedArray serving as a parameter map for values
+// recorded in the given {frame_state}. Some elements map to slots within the
+// given {context}. Serves as backing store for JSCreateArguments nodes.
+Node* JSTypedLowering::AllocateAliasedArguments(
+    Node* effect, Node* control, Node* frame_state, Node* context,
+    Handle<SharedFunctionInfo> shared, bool* has_aliased_arguments) {
+  FrameStateInfo state_info = OpParameter<FrameStateInfo>(frame_state);
+  int argument_count = state_info.parameter_count() - 1;  // Minus receiver.
+  if (argument_count == 0) return jsgraph()->EmptyFixedArrayConstant();
+
+  // If there is no aliasing, the arguments object elements are not special in
+  // any way, we can just return an unmapped backing store instead.
+  int parameter_count = shared->internal_formal_parameter_count();
+  if (parameter_count == 0) {
+    return AllocateArguments(effect, control, frame_state);
+  }
+
+  // Calculate number of argument values being aliased/mapped.
+  int mapped_count = Min(argument_count, parameter_count);
+  *has_aliased_arguments = true;
+
+  // Prepare an iterator over argument values recorded in the frame state.
+  Node* const parameters = frame_state->InputAt(kFrameStateParametersInput);
+  StateValuesAccess parameters_access(parameters);
+  auto paratemers_it = ++parameters_access.begin();
+
+  // The unmapped argument values recorded in the frame state are stored yet
+  // another indirection away and then linked into the parameter map below,
+  // whereas mapped argument values are replaced with a hole instead.
+  AllocationBuilder aa(jsgraph(), effect, control);
+  aa.AllocateArray(argument_count, factory()->fixed_array_map());
+  for (int i = 0; i < mapped_count; ++i, ++paratemers_it) {
+    aa.Store(AccessBuilder::ForFixedArraySlot(i), jsgraph()->TheHoleConstant());
+  }
+  for (int i = mapped_count; i < argument_count; ++i, ++paratemers_it) {
+    aa.Store(AccessBuilder::ForFixedArraySlot(i), (*paratemers_it).node);
+  }
+  Node* arguments = aa.Finish();
+
+  // Actually allocate the backing store.
+  AllocationBuilder a(jsgraph(), arguments, control);
+  a.AllocateArray(mapped_count + 2, factory()->sloppy_arguments_elements_map());
+  a.Store(AccessBuilder::ForFixedArraySlot(0), context);
+  a.Store(AccessBuilder::ForFixedArraySlot(1), arguments);
+  for (int i = 0; i < mapped_count; ++i) {
+    int idx = Context::MIN_CONTEXT_SLOTS + parameter_count - 1 - i;
+    a.Store(AccessBuilder::ForFixedArraySlot(i + 2), jsgraph()->Constant(idx));
+  }
+  return a.Finish();
+}
+
+
+Node* JSTypedLowering::AllocateElements(Node* effect, Node* control,
+                                        ElementsKind elements_kind,
+                                        int capacity, PretenureFlag pretenure) {
+  DCHECK_LE(1, capacity);
+  DCHECK_LE(capacity, JSArray::kInitialMaxFastElementArray);
+
+  Handle<Map> elements_map = IsFastDoubleElementsKind(elements_kind)
+                                 ? factory()->fixed_double_array_map()
+                                 : factory()->fixed_array_map();
+  ElementAccess access = IsFastDoubleElementsKind(elements_kind)
+                             ? AccessBuilder::ForFixedDoubleArrayElement()
+                             : AccessBuilder::ForFixedArrayElement();
+  Node* value =
+      IsFastDoubleElementsKind(elements_kind)
+          ? jsgraph()->Float64Constant(bit_cast<double>(kHoleNanInt64))
+          : jsgraph()->TheHoleConstant();
+
+  // Actually allocate the backing store.
+  AllocationBuilder a(jsgraph(), effect, control);
+  a.AllocateArray(capacity, elements_map, pretenure);
+  for (int i = 0; i < capacity; ++i) {
+    Node* index = jsgraph()->Constant(i);
+    a.Store(access, index, value);
+  }
+  return a.Finish();
+}
+
+
 Factory* JSTypedLowering::factory() const { return jsgraph()->factory(); }
 
 
 Graph* JSTypedLowering::graph() const { return jsgraph()->graph(); }
 
 
+Isolate* JSTypedLowering::isolate() const { return jsgraph()->isolate(); }
+
+
 JSOperatorBuilder* JSTypedLowering::javascript() const {
   return jsgraph()->javascript();
 }
@@ -986,10 +2842,20 @@
 }
 
 
+SimplifiedOperatorBuilder* JSTypedLowering::simplified() const {
+  return jsgraph()->simplified();
+}
+
+
 MachineOperatorBuilder* JSTypedLowering::machine() const {
   return jsgraph()->machine();
 }
 
+
+CompilationDependencies* JSTypedLowering::dependencies() const {
+  return dependencies_;
+}
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/src/compiler/js-typed-lowering.h b/src/compiler/js-typed-lowering.h
index 838085e..68ce74e 100644
--- a/src/compiler/js-typed-lowering.h
+++ b/src/compiler/js-typed-lowering.h
@@ -5,11 +5,19 @@
 #ifndef V8_COMPILER_JS_TYPED_LOWERING_H_
 #define V8_COMPILER_JS_TYPED_LOWERING_H_
 
+#include "src/base/flags.h"
 #include "src/compiler/graph-reducer.h"
-#include "src/compiler/simplified-operator.h"
+#include "src/compiler/opcodes.h"
 
 namespace v8 {
 namespace internal {
+
+// Forward declarations.
+class CompilationDependencies;
+class Factory;
+class TypeCache;
+
+
 namespace compiler {
 
 // Forward declarations.
@@ -17,65 +25,112 @@
 class JSGraph;
 class JSOperatorBuilder;
 class MachineOperatorBuilder;
+class SimplifiedOperatorBuilder;
 
 
 // Lowers JS-level operators to simplified operators based on types.
-class JSTypedLowering FINAL : public Reducer {
+class JSTypedLowering final : public AdvancedReducer {
  public:
-  JSTypedLowering(JSGraph* jsgraph, Zone* zone);
-  ~JSTypedLowering() FINAL {}
+  // Flags that control the mode of operation.
+  enum Flag {
+    kNoFlags = 0u,
+    kDeoptimizationEnabled = 1u << 0,
+    kDisableBinaryOpReduction = 1u << 1,
+  };
+  typedef base::Flags<Flag> Flags;
 
-  Reduction Reduce(Node* node) FINAL;
+  JSTypedLowering(Editor* editor, CompilationDependencies* dependencies,
+                  Flags flags, JSGraph* jsgraph, Zone* zone);
+  ~JSTypedLowering() final {}
+
+  Reduction Reduce(Node* node) final;
 
  private:
   friend class JSBinopReduction;
 
-  Reduction ReplaceEagerly(Node* old, Node* node);
   Reduction ReduceJSAdd(Node* node);
+  Reduction ReduceJSModulus(Node* node);
   Reduction ReduceJSBitwiseOr(Node* node);
   Reduction ReduceJSMultiply(Node* node);
   Reduction ReduceJSComparison(Node* node);
+  Reduction ReduceJSLoadNamed(Node* node);
   Reduction ReduceJSLoadProperty(Node* node);
   Reduction ReduceJSStoreProperty(Node* node);
+  Reduction ReduceJSInstanceOf(Node* node);
   Reduction ReduceJSLoadContext(Node* node);
   Reduction ReduceJSStoreContext(Node* node);
   Reduction ReduceJSEqual(Node* node, bool invert);
   Reduction ReduceJSStrictEqual(Node* node, bool invert);
-  Reduction ReduceJSUnaryNot(Node* node);
   Reduction ReduceJSToBoolean(Node* node);
   Reduction ReduceJSToNumberInput(Node* input);
   Reduction ReduceJSToNumber(Node* node);
   Reduction ReduceJSToStringInput(Node* input);
   Reduction ReduceJSToString(Node* node);
+  Reduction ReduceJSToObject(Node* node);
+  Reduction ReduceJSConvertReceiver(Node* node);
+  Reduction ReduceJSCreate(Node* node);
+  Reduction ReduceJSCreateArguments(Node* node);
+  Reduction ReduceJSCreateArray(Node* node);
+  Reduction ReduceJSCreateClosure(Node* node);
+  Reduction ReduceJSCreateIterResultObject(Node* node);
+  Reduction ReduceJSCreateLiteralArray(Node* node);
+  Reduction ReduceJSCreateLiteralObject(Node* node);
+  Reduction ReduceJSCreateFunctionContext(Node* node);
+  Reduction ReduceJSCreateWithContext(Node* node);
+  Reduction ReduceJSCreateCatchContext(Node* node);
+  Reduction ReduceJSCreateBlockContext(Node* node);
+  Reduction ReduceJSCallConstruct(Node* node);
+  Reduction ReduceJSCallFunction(Node* node);
+  Reduction ReduceJSForInDone(Node* node);
+  Reduction ReduceJSForInNext(Node* node);
+  Reduction ReduceJSForInPrepare(Node* node);
+  Reduction ReduceJSForInStep(Node* node);
+  Reduction ReduceSelect(Node* node);
   Reduction ReduceNumberBinop(Node* node, const Operator* numberOp);
   Reduction ReduceInt32Binop(Node* node, const Operator* intOp);
   Reduction ReduceUI32Shift(Node* node, Signedness left_signedness,
                             const Operator* shift_op);
-
-  Node* ConvertToNumber(Node* input);
-  template <IrOpcode::Value>
-  Node* FindConversion(Node* input);
-  void InsertConversion(Node* conversion);
+  Reduction ReduceNewArray(Node* node, Node* length, int capacity,
+                           Handle<AllocationSite> site);
 
   Node* Word32Shl(Node* const lhs, int32_t const rhs);
+  Node* AllocateArguments(Node* effect, Node* control, Node* frame_state);
+  Node* AllocateRestArguments(Node* effect, Node* control, Node* frame_state,
+                              int start_index);
+  Node* AllocateAliasedArguments(Node* effect, Node* control, Node* frame_state,
+                                 Node* context, Handle<SharedFunctionInfo>,
+                                 bool* has_aliased_arguments);
+  Node* AllocateElements(Node* effect, Node* control,
+                         ElementsKind elements_kind, int capacity,
+                         PretenureFlag pretenure);
 
   Factory* factory() const;
   Graph* graph() const;
   JSGraph* jsgraph() const { return jsgraph_; }
+  Isolate* isolate() const;
   JSOperatorBuilder* javascript() const;
   CommonOperatorBuilder* common() const;
-  SimplifiedOperatorBuilder* simplified() { return &simplified_; }
+  SimplifiedOperatorBuilder* simplified() const;
   MachineOperatorBuilder* machine() const;
+  CompilationDependencies* dependencies() const;
+  Flags flags() const { return flags_; }
 
+  // Limits up to which context allocations are inlined.
+  static const int kFunctionContextAllocationLimit = 16;
+  static const int kBlockContextAllocationLimit = 16;
+
+  CompilationDependencies* dependencies_;
+  Flags flags_;
   JSGraph* jsgraph_;
-  SimplifiedOperatorBuilder simplified_;
-  ZoneVector<Node*> conversions_;  // Cache inserted JSToXXX() conversions.
-  Type* zero_range_;
-  Type* one_range_;
-  Type* zero_thirtyone_range_;
   Type* shifted_int32_ranges_[4];
+  Type* const true_type_;
+  Type* const false_type_;
+  Type* const the_hole_type_;
+  TypeCache const& type_cache_;
 };
 
+DEFINE_OPERATORS_FOR_FLAGS(JSTypedLowering::Flags)
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/src/compiler/jump-threading.cc b/src/compiler/jump-threading.cc
index f0bb731..7b53b5c 100644
--- a/src/compiler/jump-threading.cc
+++ b/src/compiler/jump-threading.cc
@@ -9,10 +9,10 @@
 namespace internal {
 namespace compiler {
 
-typedef BasicBlock::RpoNumber RpoNumber;
-
-#define TRACE(x) \
-  if (FLAG_trace_turbo_jt) PrintF x
+#define TRACE(...)                                \
+  do {                                            \
+    if (FLAG_trace_turbo_jt) PrintF(__VA_ARGS__); \
+  } while (false)
 
 struct JumpThreadingState {
   bool forwarded;
@@ -31,19 +31,19 @@
     RpoNumber to_to = result[to.ToInt()];
     bool pop = true;
     if (to == from) {
-      TRACE(("  xx %d\n", from.ToInt()));
+      TRACE("  xx %d\n", from.ToInt());
       result[from.ToInt()] = from;
     } else if (to_to == unvisited()) {
-      TRACE(("  fw %d -> %d (recurse)\n", from.ToInt(), to.ToInt()));
+      TRACE("  fw %d -> %d (recurse)\n", from.ToInt(), to.ToInt());
       stack.push(to);
       result[to.ToInt()] = onstack();
       pop = false;  // recurse.
     } else if (to_to == onstack()) {
-      TRACE(("  fw %d -> %d (cycle)\n", from.ToInt(), to.ToInt()));
+      TRACE("  fw %d -> %d (cycle)\n", from.ToInt(), to.ToInt());
       result[from.ToInt()] = to;  // break the cycle.
       forwarded = true;
     } else {
-      TRACE(("  fw %d -> %d (forward)\n", from.ToInt(), to.ToInt()));
+      TRACE("  fw %d -> %d (forward)\n", from.ToInt(), to.ToInt());
       result[from.ToInt()] = to_to;  // forward the block.
       forwarded = true;
     }
@@ -70,36 +70,32 @@
     while (!state.stack.empty()) {
       InstructionBlock* block = code->InstructionBlockAt(state.stack.top());
       // Process the instructions in a block up to a non-empty instruction.
-      TRACE(("jt [%d] B%d RPO%d\n", static_cast<int>(stack.size()),
-             block->id().ToInt(), block->rpo_number().ToInt()));
+      TRACE("jt [%d] B%d\n", static_cast<int>(stack.size()),
+            block->rpo_number().ToInt());
       bool fallthru = true;
       RpoNumber fw = block->rpo_number();
       for (int i = block->code_start(); i < block->code_end(); ++i) {
         Instruction* instr = code->InstructionAt(i);
-        if (instr->IsGapMoves() && GapInstruction::cast(instr)->IsRedundant()) {
-          // skip redundant gap moves.
-          TRACE(("  nop gap\n"));
-          continue;
-        } else if (instr->IsSourcePosition()) {
-          // skip source positions.
-          TRACE(("  src pos\n"));
-          continue;
+        if (!instr->AreMovesRedundant()) {
+          // can't skip instructions with non redundant moves.
+          TRACE("  parallel move\n");
+          fallthru = false;
         } else if (FlagsModeField::decode(instr->opcode()) != kFlags_none) {
           // can't skip instructions with flags continuations.
-          TRACE(("  flags\n"));
+          TRACE("  flags\n");
           fallthru = false;
         } else if (instr->IsNop()) {
           // skip nops.
-          TRACE(("  nop\n"));
+          TRACE("  nop\n");
           continue;
         } else if (instr->arch_opcode() == kArchJmp) {
           // try to forward the jump instruction.
-          TRACE(("  jmp\n"));
+          TRACE("  jmp\n");
           fw = code->InputRpo(instr, 0);
           fallthru = false;
         } else {
           // can't skip other instructions.
-          TRACE(("  other\n"));
+          TRACE("  other\n");
           fallthru = false;
         }
         break;
@@ -120,14 +116,12 @@
 
   if (FLAG_trace_turbo_jt) {
     for (int i = 0; i < static_cast<int>(result.size()); i++) {
-      TRACE(("RPO%d B%d ", i,
-             code->InstructionBlockAt(RpoNumber::FromInt(i))->id().ToInt()));
+      TRACE("B%d ", i);
       int to = result[i].ToInt();
       if (i != to) {
-        TRACE(("-> B%d\n",
-               code->InstructionBlockAt(RpoNumber::FromInt(to))->id().ToInt()));
+        TRACE("-> B%d\n", to);
       } else {
-        TRACE(("\n"));
+        TRACE("\n");
       }
     }
   }
@@ -140,7 +134,7 @@
                                     InstructionSequence* code) {
   if (!FLAG_turbo_jt) return;
 
-  Zone local_zone(code->zone()->isolate());
+  Zone local_zone;
   ZoneVector<bool> skip(static_cast<int>(result.size()), false, &local_zone);
 
   // Skip empty blocks when the previous block doesn't fall through.
@@ -157,7 +151,7 @@
       } else if (instr->arch_opcode() == kArchJmp) {
         if (skip[block_num]) {
           // Overwrite a redundant jump with a nop.
-          TRACE(("jt-fw nop @%d\n", i));
+          TRACE("jt-fw nop @%d\n", i);
           instr->OverwriteWithNop();
         }
         fallthru = false;  // jumps don't fall through to the next block.
diff --git a/src/compiler/jump-threading.h b/src/compiler/jump-threading.h
index b801fec..fa74ee9 100644
--- a/src/compiler/jump-threading.h
+++ b/src/compiler/jump-threading.h
@@ -17,13 +17,12 @@
  public:
   // Compute the forwarding map of basic blocks to their ultimate destination.
   // Returns {true} if there is at least one block that is forwarded.
-  static bool ComputeForwarding(Zone* local_zone,
-                                ZoneVector<BasicBlock::RpoNumber>& result,
+  static bool ComputeForwarding(Zone* local_zone, ZoneVector<RpoNumber>& result,
                                 InstructionSequence* code);
 
   // Rewrite the instructions to forward jumps and branches.
   // May also negate some branches.
-  static void ApplyForwarding(ZoneVector<BasicBlock::RpoNumber>& forwarding,
+  static void ApplyForwarding(ZoneVector<RpoNumber>& forwarding,
                               InstructionSequence* code);
 };
 
diff --git a/src/compiler/linkage-impl.h b/src/compiler/linkage-impl.h
deleted file mode 100644
index c13bd74..0000000
--- a/src/compiler/linkage-impl.h
+++ /dev/null
@@ -1,233 +0,0 @@
-// 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.
-
-#ifndef V8_COMPILER_LINKAGE_IMPL_H_
-#define V8_COMPILER_LINKAGE_IMPL_H_
-
-#include "src/code-stubs.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-// TODO(titzer): replace uses of int with size_t in LinkageHelper.
-template <typename LinkageTraits>
-class LinkageHelper {
- public:
-  static const RegList kNoCalleeSaved = 0;
-
-  static void AddReturnLocations(LocationSignature::Builder* locations) {
-    DCHECK(locations->return_count_ <= 2);
-    if (locations->return_count_ > 0) {
-      locations->AddReturn(regloc(LinkageTraits::ReturnValueReg()));
-    }
-    if (locations->return_count_ > 1) {
-      locations->AddReturn(regloc(LinkageTraits::ReturnValue2Reg()));
-    }
-  }
-
-  // TODO(turbofan): cache call descriptors for JSFunction calls.
-  static CallDescriptor* GetJSCallDescriptor(Zone* zone, int js_parameter_count,
-                                             CallDescriptor::Flags flags) {
-    const size_t return_count = 1;
-    const size_t context_count = 1;
-    const size_t parameter_count = js_parameter_count + context_count;
-
-    LocationSignature::Builder locations(zone, return_count, parameter_count);
-    MachineSignature::Builder types(zone, return_count, parameter_count);
-
-    // Add returns.
-    AddReturnLocations(&locations);
-    for (size_t i = 0; i < return_count; i++) {
-      types.AddReturn(kMachAnyTagged);
-    }
-
-    // All parameters to JS calls go on the stack.
-    for (int i = 0; i < js_parameter_count; i++) {
-      int spill_slot_index = i - js_parameter_count;
-      locations.AddParam(stackloc(spill_slot_index));
-      types.AddParam(kMachAnyTagged);
-    }
-    // Add context.
-    locations.AddParam(regloc(LinkageTraits::ContextReg()));
-    types.AddParam(kMachAnyTagged);
-
-    // The target for JS function calls is the JSFunction object.
-    MachineType target_type = kMachAnyTagged;
-    LinkageLocation target_loc = regloc(LinkageTraits::JSCallFunctionReg());
-    return new (zone) CallDescriptor(     // --
-        CallDescriptor::kCallJSFunction,  // kind
-        target_type,                      // target MachineType
-        target_loc,                       // target location
-        types.Build(),                    // machine_sig
-        locations.Build(),                // location_sig
-        js_parameter_count,               // js_parameter_count
-        Operator::kNoProperties,          // properties
-        kNoCalleeSaved,                   // callee-saved
-        flags,                            // flags
-        "js-call");
-  }
-
-
-  // TODO(turbofan): cache call descriptors for runtime calls.
-  static CallDescriptor* GetRuntimeCallDescriptor(
-      Zone* zone, Runtime::FunctionId function_id, int js_parameter_count,
-      Operator::Properties properties) {
-    const size_t function_count = 1;
-    const size_t num_args_count = 1;
-    const size_t context_count = 1;
-    const size_t parameter_count = function_count +
-                                   static_cast<size_t>(js_parameter_count) +
-                                   num_args_count + context_count;
-
-    const Runtime::Function* function = Runtime::FunctionForId(function_id);
-    const size_t return_count = static_cast<size_t>(function->result_size);
-
-    LocationSignature::Builder locations(zone, return_count, parameter_count);
-    MachineSignature::Builder types(zone, return_count, parameter_count);
-
-    // Add returns.
-    AddReturnLocations(&locations);
-    for (size_t i = 0; i < return_count; i++) {
-      types.AddReturn(kMachAnyTagged);
-    }
-
-    // All parameters to the runtime call go on the stack.
-    for (int i = 0; i < js_parameter_count; i++) {
-      locations.AddParam(stackloc(i - js_parameter_count));
-      types.AddParam(kMachAnyTagged);
-    }
-    // Add runtime function itself.
-    locations.AddParam(regloc(LinkageTraits::RuntimeCallFunctionReg()));
-    types.AddParam(kMachAnyTagged);
-
-    // Add runtime call argument count.
-    locations.AddParam(regloc(LinkageTraits::RuntimeCallArgCountReg()));
-    types.AddParam(kMachPtr);
-
-    // Add context.
-    locations.AddParam(regloc(LinkageTraits::ContextReg()));
-    types.AddParam(kMachAnyTagged);
-
-    CallDescriptor::Flags flags = Linkage::NeedsFrameState(function_id)
-                                      ? CallDescriptor::kNeedsFrameState
-                                      : CallDescriptor::kNoFlags;
-
-    // The target for runtime calls is a code object.
-    MachineType target_type = kMachAnyTagged;
-    LinkageLocation target_loc = LinkageLocation::AnyRegister();
-    return new (zone) CallDescriptor(     // --
-        CallDescriptor::kCallCodeObject,  // kind
-        target_type,                      // target MachineType
-        target_loc,                       // target location
-        types.Build(),                    // machine_sig
-        locations.Build(),                // location_sig
-        js_parameter_count,               // js_parameter_count
-        properties,                       // properties
-        kNoCalleeSaved,                   // callee-saved
-        flags,                            // flags
-        function->name);                  // debug name
-  }
-
-
-  // TODO(turbofan): cache call descriptors for code stub calls.
-  static CallDescriptor* GetStubCallDescriptor(
-      Zone* zone, const CallInterfaceDescriptor& descriptor,
-      int stack_parameter_count, CallDescriptor::Flags flags,
-      Operator::Properties properties) {
-    const int register_parameter_count =
-        descriptor.GetEnvironmentParameterCount();
-    const int js_parameter_count =
-        register_parameter_count + stack_parameter_count;
-    const int context_count = 1;
-    const size_t return_count = 1;
-    const size_t parameter_count =
-        static_cast<size_t>(js_parameter_count + context_count);
-
-    LocationSignature::Builder locations(zone, return_count, parameter_count);
-    MachineSignature::Builder types(zone, return_count, parameter_count);
-
-    // Add return location.
-    AddReturnLocations(&locations);
-    types.AddReturn(kMachAnyTagged);
-
-    // Add parameters in registers and on the stack.
-    for (int i = 0; i < js_parameter_count; i++) {
-      if (i < register_parameter_count) {
-        // The first parameters go in registers.
-        Register reg = descriptor.GetEnvironmentParameterRegister(i);
-        locations.AddParam(regloc(reg));
-      } else {
-        // The rest of the parameters go on the stack.
-        int stack_slot = i - register_parameter_count - stack_parameter_count;
-        locations.AddParam(stackloc(stack_slot));
-      }
-      types.AddParam(kMachAnyTagged);
-    }
-    // Add context.
-    locations.AddParam(regloc(LinkageTraits::ContextReg()));
-    types.AddParam(kMachAnyTagged);
-
-    // The target for stub calls is a code object.
-    MachineType target_type = kMachAnyTagged;
-    LinkageLocation target_loc = LinkageLocation::AnyRegister();
-    return new (zone) CallDescriptor(     // --
-        CallDescriptor::kCallCodeObject,  // kind
-        target_type,                      // target MachineType
-        target_loc,                       // target location
-        types.Build(),                    // machine_sig
-        locations.Build(),                // location_sig
-        js_parameter_count,               // js_parameter_count
-        properties,                       // properties
-        kNoCalleeSaved,                   // callee-saved registers
-        flags,                            // flags
-        descriptor.DebugName(zone->isolate()));
-  }
-
-  static CallDescriptor* GetSimplifiedCDescriptor(Zone* zone,
-                                                  MachineSignature* msig) {
-    LocationSignature::Builder locations(zone, msig->return_count(),
-                                         msig->parameter_count());
-    // Add return location(s).
-    AddReturnLocations(&locations);
-
-    // Add register and/or stack parameter(s).
-    const int parameter_count = static_cast<int>(msig->parameter_count());
-    for (int i = 0; i < parameter_count; i++) {
-      if (i < LinkageTraits::CRegisterParametersLength()) {
-        locations.AddParam(regloc(LinkageTraits::CRegisterParameter(i)));
-      } else {
-        locations.AddParam(stackloc(-1 - i));
-      }
-    }
-
-    // The target for C calls is always an address (i.e. machine pointer).
-    MachineType target_type = kMachPtr;
-    LinkageLocation target_loc = LinkageLocation::AnyRegister();
-    return new (zone) CallDescriptor(  // --
-        CallDescriptor::kCallAddress,  // kind
-        target_type,                   // target MachineType
-        target_loc,                    // target location
-        msig,                          // machine_sig
-        locations.Build(),             // location_sig
-        0,                             // js_parameter_count
-        Operator::kNoProperties,       // properties
-        LinkageTraits::CCalleeSaveRegisters(), CallDescriptor::kNoFlags,
-        "c-call");
-  }
-
-  static LinkageLocation regloc(Register reg) {
-    return LinkageLocation(Register::ToAllocationIndex(reg));
-  }
-
-  static LinkageLocation stackloc(int i) {
-    DCHECK_LT(i, 0);
-    return LinkageLocation(i);
-  }
-};
-}  // namespace compiler
-}  // namespace internal
-}  // namespace v8
-
-#endif  // V8_COMPILER_LINKAGE_IMPL_H_
diff --git a/src/compiler/linkage.cc b/src/compiler/linkage.cc
index fc6b19e..2eef929 100644
--- a/src/compiler/linkage.cc
+++ b/src/compiler/linkage.cc
@@ -2,17 +2,55 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "src/ast/scopes.h"
 #include "src/code-stubs.h"
 #include "src/compiler.h"
+#include "src/compiler/common-operator.h"
+#include "src/compiler/frame.h"
 #include "src/compiler/linkage.h"
 #include "src/compiler/node.h"
+#include "src/compiler/osr.h"
 #include "src/compiler/pipeline.h"
-#include "src/scopes.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
+namespace {
+LinkageLocation regloc(Register reg) {
+  return LinkageLocation::ForRegister(reg.code());
+}
+
+
+MachineType reptyp(Representation representation) {
+  switch (representation.kind()) {
+    case Representation::kInteger8:
+      return MachineType::Int8();
+    case Representation::kUInteger8:
+      return MachineType::Uint8();
+    case Representation::kInteger16:
+      return MachineType::Int16();
+    case Representation::kUInteger16:
+      return MachineType::Uint16();
+    case Representation::kInteger32:
+      return MachineType::Int32();
+    case Representation::kSmi:
+    case Representation::kTagged:
+    case Representation::kHeapObject:
+      return MachineType::AnyTagged();
+    case Representation::kDouble:
+      return MachineType::Float64();
+    case Representation::kExternal:
+      return MachineType::Pointer();
+    case Representation::kNone:
+    case Representation::kNumRepresentations:
+      break;
+  }
+  UNREACHABLE();
+  return MachineType::None();
+}
+}  // namespace
+
 
 std::ostream& operator<<(std::ostream& os, const CallDescriptor::Kind& k) {
   switch (k) {
@@ -25,6 +63,9 @@
     case CallDescriptor::kCallAddress:
       os << "Addr";
       break;
+    case CallDescriptor::kLazyBailout:
+      os << "LazyBail";
+      break;
   }
   return os;
 }
@@ -33,226 +74,466 @@
 std::ostream& operator<<(std::ostream& os, const CallDescriptor& d) {
   // TODO(svenpanne) Output properties etc. and be less cryptic.
   return os << d.kind() << ":" << d.debug_name() << ":r" << d.ReturnCount()
-            << "j" << d.JSParameterCount() << "i" << d.InputCount() << "f"
-            << d.FrameStateCount();
+            << "s" << d.StackParameterCount() << "i" << d.InputCount() << "f"
+            << d.FrameStateCount() << "t" << d.SupportsTailCalls();
+}
+
+
+bool CallDescriptor::HasSameReturnLocationsAs(
+    const CallDescriptor* other) const {
+  if (ReturnCount() != other->ReturnCount()) return false;
+  for (size_t i = 0; i < ReturnCount(); ++i) {
+    if (GetReturnLocation(i) != other->GetReturnLocation(i)) return false;
+  }
+  return true;
+}
+
+
+bool CallDescriptor::CanTailCall(const Node* node,
+                                 int* stack_param_delta) const {
+  CallDescriptor const* other = OpParameter<CallDescriptor const*>(node);
+  size_t current_input = 0;
+  size_t other_input = 0;
+  *stack_param_delta = 0;
+  bool more_other = true;
+  bool more_this = true;
+  while (more_other || more_this) {
+    if (other_input < other->InputCount()) {
+      if (!other->GetInputLocation(other_input).IsRegister()) {
+        (*stack_param_delta)--;
+      }
+    } else {
+      more_other = false;
+    }
+    if (current_input < InputCount()) {
+      if (!GetInputLocation(current_input).IsRegister()) {
+        (*stack_param_delta)++;
+      }
+    } else {
+      more_this = false;
+    }
+    ++current_input;
+    ++other_input;
+  }
+  return HasSameReturnLocationsAs(OpParameter<CallDescriptor const*>(node));
 }
 
 
 CallDescriptor* Linkage::ComputeIncoming(Zone* zone, CompilationInfo* info) {
-  if (info->function() != NULL) {
+  if (info->code_stub() != nullptr) {
+    // Use the code stub interface descriptor.
+    CodeStub* stub = info->code_stub();
+    CallInterfaceDescriptor descriptor = stub->GetCallInterfaceDescriptor();
+    return GetStubCallDescriptor(
+        info->isolate(), zone, descriptor, stub->GetStackParameterCount(),
+        CallDescriptor::kNoFlags, Operator::kNoProperties);
+  }
+  if (info->has_literal()) {
     // If we already have the function literal, use the number of parameters
     // plus the receiver.
-    return GetJSCallDescriptor(1 + info->function()->parameter_count(), zone,
+    return GetJSCallDescriptor(zone, info->is_osr(),
+                               1 + info->literal()->parameter_count(),
                                CallDescriptor::kNoFlags);
   }
   if (!info->closure().is_null()) {
     // If we are compiling a JS function, use a JS call descriptor,
     // plus the receiver.
     SharedFunctionInfo* shared = info->closure()->shared();
-    return GetJSCallDescriptor(1 + shared->formal_parameter_count(), zone,
+    return GetJSCallDescriptor(zone, info->is_osr(),
+                               1 + shared->internal_formal_parameter_count(),
                                CallDescriptor::kNoFlags);
   }
-  if (info->code_stub() != NULL) {
-    // Use the code stub interface descriptor.
-    CallInterfaceDescriptor descriptor =
-        info->code_stub()->GetCallInterfaceDescriptor();
-    return GetStubCallDescriptor(descriptor, 0, CallDescriptor::kNoFlags,
-                                 Operator::kNoProperties, zone);
-  }
-  return NULL;  // TODO(titzer): ?
-}
-
-
-FrameOffset Linkage::GetFrameOffset(int spill_slot, Frame* frame,
-                                    int extra) const {
-  if (frame->GetSpillSlotCount() > 0 || incoming_->IsJSFunctionCall() ||
-      incoming_->kind() == CallDescriptor::kCallAddress) {
-    int offset;
-    int register_save_area_size = frame->GetRegisterSaveAreaSize();
-    if (spill_slot >= 0) {
-      // Local or spill slot. Skip the frame pointer, function, and
-      // context in the fixed part of the frame.
-      offset =
-          -(spill_slot + 1) * kPointerSize - register_save_area_size + extra;
-    } else {
-      // Incoming parameter. Skip the return address.
-      offset = -(spill_slot + 1) * kPointerSize + kFPOnStackSize +
-               kPCOnStackSize + extra;
-    }
-    return FrameOffset::FromFramePointer(offset);
-  } else {
-    // No frame. Retrieve all parameters relative to stack pointer.
-    DCHECK(spill_slot < 0);  // Must be a parameter.
-    int register_save_area_size = frame->GetRegisterSaveAreaSize();
-    int offset = register_save_area_size - (spill_slot + 1) * kPointerSize +
-                 kPCOnStackSize + extra;
-    return FrameOffset::FromStackPointer(offset);
-  }
-}
-
-
-CallDescriptor* Linkage::GetJSCallDescriptor(
-    int parameter_count, CallDescriptor::Flags flags) const {
-  return GetJSCallDescriptor(parameter_count, zone_, flags);
-}
-
-
-CallDescriptor* Linkage::GetRuntimeCallDescriptor(
-    Runtime::FunctionId function, int parameter_count,
-    Operator::Properties properties) const {
-  return GetRuntimeCallDescriptor(function, parameter_count, properties, zone_);
-}
-
-
-CallDescriptor* Linkage::GetStubCallDescriptor(
-    const CallInterfaceDescriptor& descriptor, int stack_parameter_count,
-    CallDescriptor::Flags flags, Operator::Properties properties) const {
-  return GetStubCallDescriptor(descriptor, stack_parameter_count, flags,
-                               properties, zone_);
+  return nullptr;  // TODO(titzer): ?
 }
 
 
 // static
-bool Linkage::NeedsFrameState(Runtime::FunctionId function) {
-  if (!FLAG_turbo_deoptimization) {
-    return false;
-  }
-  // TODO(jarin) At the moment, we only add frame state for
-  // few chosen runtime functions.
+int Linkage::FrameStateInputCount(Runtime::FunctionId function) {
+  // Most runtime functions need a FrameState. A few chosen ones that we know
+  // not to call into arbitrary JavaScript, not to throw, and not to deoptimize
+  // are blacklisted here and can be called without a FrameState.
   switch (function) {
-    case Runtime::kApply:
-    case Runtime::kArrayBufferNeuter:
-    case Runtime::kArrayConcat:
-    case Runtime::kBasicJSONStringify:
-    case Runtime::kCheckExecutionState:
-    case Runtime::kCollectStackTrace:
-    case Runtime::kCompileLazy:
-    case Runtime::kCompileOptimized:
-    case Runtime::kCompileString:
-    case Runtime::kCreateObjectLiteral:
-    case Runtime::kDebugBreak:
-    case Runtime::kDataViewSetInt8:
-    case Runtime::kDataViewSetUint8:
-    case Runtime::kDataViewSetInt16:
-    case Runtime::kDataViewSetUint16:
-    case Runtime::kDataViewSetInt32:
-    case Runtime::kDataViewSetUint32:
-    case Runtime::kDataViewSetFloat32:
-    case Runtime::kDataViewSetFloat64:
-    case Runtime::kDataViewGetInt8:
-    case Runtime::kDataViewGetUint8:
-    case Runtime::kDataViewGetInt16:
-    case Runtime::kDataViewGetUint16:
-    case Runtime::kDataViewGetInt32:
-    case Runtime::kDataViewGetUint32:
-    case Runtime::kDataViewGetFloat32:
-    case Runtime::kDataViewGetFloat64:
-    case Runtime::kDebugEvaluate:
-    case Runtime::kDebugEvaluateGlobal:
-    case Runtime::kDebugGetLoadedScripts:
-    case Runtime::kDebugGetPropertyDetails:
-    case Runtime::kDebugPromiseEvent:
-    case Runtime::kDefineAccessorPropertyUnchecked:
-    case Runtime::kDefineDataPropertyUnchecked:
-    case Runtime::kDeleteProperty:
-    case Runtime::kDeoptimizeFunction:
-    case Runtime::kFunctionBindArguments:
-    case Runtime::kGetDefaultReceiver:
-    case Runtime::kGetFrameCount:
-    case Runtime::kGetOwnProperty:
-    case Runtime::kGetOwnPropertyNames:
-    case Runtime::kGetPropertyNamesFast:
-    case Runtime::kGetPrototype:
+    case Runtime::kAllocateInTargetSpace:
+    case Runtime::kCreateIterResultObject:
+    case Runtime::kDefineClassMethod:              // TODO(jarin): Is it safe?
+    case Runtime::kDefineGetterPropertyUnchecked:  // TODO(jarin): Is it safe?
+    case Runtime::kDefineSetterPropertyUnchecked:  // TODO(jarin): Is it safe?
+    case Runtime::kFinalizeClassDefinition:        // TODO(conradw): Is it safe?
+    case Runtime::kForInDone:
+    case Runtime::kForInStep:
+    case Runtime::kGetSuperConstructor:
+    case Runtime::kNewClosure:
+    case Runtime::kNewClosure_Tenured:
+    case Runtime::kNewFunctionContext:
+    case Runtime::kPushBlockContext:
+    case Runtime::kPushCatchContext:
+    case Runtime::kReThrow:
+    case Runtime::kStringCompare:
+    case Runtime::kStringEquals:
+    case Runtime::kToFastProperties:  // TODO(jarin): Is it safe?
+    case Runtime::kTraceEnter:
+    case Runtime::kTraceExit:
+      return 0;
     case Runtime::kInlineArguments:
-    case Runtime::kInlineCallFunction:
-    case Runtime::kInlineDateField:
+    case Runtime::kInlineArgumentsLength:
+    case Runtime::kInlineGetPrototype:
+    case Runtime::kInlineRegExpConstructResult:
     case Runtime::kInlineRegExpExec:
-    case Runtime::kInternalSetPrototype:
-    case Runtime::kInterrupt:
-    case Runtime::kIsPropertyEnumerable:
-    case Runtime::kIsSloppyModeFunction:
-    case Runtime::kLiveEditGatherCompileInfo:
-    case Runtime::kLoadLookupSlot:
-    case Runtime::kLoadLookupSlotNoReferenceError:
-    case Runtime::kMaterializeRegExpLiteral:
-    case Runtime::kNewObject:
-    case Runtime::kNewObjectFromBound:
-    case Runtime::kNewObjectWithAllocationSite:
-    case Runtime::kObjectFreeze:
-    case Runtime::kOwnKeys:
-    case Runtime::kParseJson:
-    case Runtime::kPrepareStep:
-    case Runtime::kPreventExtensions:
-    case Runtime::kPromiseRejectEvent:
-    case Runtime::kPromiseRevokeReject:
-    case Runtime::kRegExpInitializeAndCompile:
-    case Runtime::kRegExpExecMultiple:
-    case Runtime::kResolvePossiblyDirectEval:
-    case Runtime::kRunMicrotasks:
-    case Runtime::kSetPrototype:
-    case Runtime::kSetScriptBreakPoint:
-    case Runtime::kSparseJoinWithSeparator:
-    case Runtime::kStackGuard:
-    case Runtime::kStoreKeyedToSuper_Sloppy:
-    case Runtime::kStoreKeyedToSuper_Strict:
-    case Runtime::kStoreToSuper_Sloppy:
-    case Runtime::kStoreToSuper_Strict:
-    case Runtime::kStoreLookupSlot:
-    case Runtime::kStringBuilderConcat:
-    case Runtime::kStringBuilderJoin:
-    case Runtime::kStringMatch:
-    case Runtime::kStringReplaceGlobalRegExpWithString:
-    case Runtime::kThrowNonMethodError:
-    case Runtime::kThrowNotDateError:
-    case Runtime::kThrowReferenceError:
-    case Runtime::kThrowUnsupportedSuperError:
-    case Runtime::kThrow:
-    case Runtime::kTypedArraySetFastCases:
-    case Runtime::kTypedArrayInitializeFromArrayLike:
-#ifdef V8_I18N_SUPPORT
-    case Runtime::kGetImplFromInitializedIntlObject:
-#endif
-      return true;
+    case Runtime::kInlineSubString:
+    case Runtime::kInlineToInteger:
+    case Runtime::kInlineToLength:
+    case Runtime::kInlineToName:
+    case Runtime::kInlineToNumber:
+    case Runtime::kInlineToObject:
+    case Runtime::kInlineToPrimitive_Number:
+    case Runtime::kInlineToPrimitive_String:
+    case Runtime::kInlineToPrimitive:
+    case Runtime::kInlineToString:
+      return 1;
+    case Runtime::kInlineCall:
+    case Runtime::kInlineTailCall:
+    case Runtime::kInlineDeoptimizeNow:
+    case Runtime::kInlineThrowNotDateError:
+      return 2;
     default:
-      return false;
+      break;
   }
+
+  // Most inlined runtime functions (except the ones listed above) can be called
+  // without a FrameState or will be lowered by JSIntrinsicLowering internally.
+  const Runtime::Function* const f = Runtime::FunctionForId(function);
+  if (f->intrinsic_type == Runtime::IntrinsicType::INLINE) return 0;
+
+  return 1;
 }
 
 
-//==============================================================================
-// Provide unimplemented methods on unsupported architectures, to at least link.
-//==============================================================================
-#if !V8_TURBOFAN_BACKEND
-CallDescriptor* Linkage::GetJSCallDescriptor(int parameter_count, Zone* zone,
-                                             CallDescriptor::Flags flags) {
-  UNIMPLEMENTED();
-  return NULL;
+bool CallDescriptor::UsesOnlyRegisters() const {
+  for (size_t i = 0; i < InputCount(); ++i) {
+    if (!GetInputLocation(i).IsRegister()) return false;
+  }
+  for (size_t i = 0; i < ReturnCount(); ++i) {
+    if (!GetReturnLocation(i).IsRegister()) return false;
+  }
+  return true;
 }
 
 
 CallDescriptor* Linkage::GetRuntimeCallDescriptor(
-    Runtime::FunctionId function, int parameter_count,
-    Operator::Properties properties, Zone* zone) {
-  UNIMPLEMENTED();
-  return NULL;
+    Zone* zone, Runtime::FunctionId function_id, int js_parameter_count,
+    Operator::Properties properties, CallDescriptor::Flags flags) {
+  const size_t function_count = 1;
+  const size_t num_args_count = 1;
+  const size_t context_count = 1;
+  const size_t parameter_count = function_count +
+                                 static_cast<size_t>(js_parameter_count) +
+                                 num_args_count + context_count;
+
+  const Runtime::Function* function = Runtime::FunctionForId(function_id);
+  const size_t return_count = static_cast<size_t>(function->result_size);
+
+  LocationSignature::Builder locations(zone, return_count, parameter_count);
+  MachineSignature::Builder types(zone, return_count, parameter_count);
+
+  // Add returns.
+  if (locations.return_count_ > 0) {
+    locations.AddReturn(regloc(kReturnRegister0));
+  }
+  if (locations.return_count_ > 1) {
+    locations.AddReturn(regloc(kReturnRegister1));
+  }
+  for (size_t i = 0; i < return_count; i++) {
+    types.AddReturn(MachineType::AnyTagged());
+  }
+
+  // All parameters to the runtime call go on the stack.
+  for (int i = 0; i < js_parameter_count; i++) {
+    locations.AddParam(
+        LinkageLocation::ForCallerFrameSlot(i - js_parameter_count));
+    types.AddParam(MachineType::AnyTagged());
+  }
+  // Add runtime function itself.
+  locations.AddParam(regloc(kRuntimeCallFunctionRegister));
+  types.AddParam(MachineType::AnyTagged());
+
+  // Add runtime call argument count.
+  locations.AddParam(regloc(kRuntimeCallArgCountRegister));
+  types.AddParam(MachineType::Pointer());
+
+  // Add context.
+  locations.AddParam(regloc(kContextRegister));
+  types.AddParam(MachineType::AnyTagged());
+
+  if (Linkage::FrameStateInputCount(function_id) == 0) {
+    flags = static_cast<CallDescriptor::Flags>(
+        flags & ~CallDescriptor::kNeedsFrameState);
+  }
+
+  // The target for runtime calls is a code object.
+  MachineType target_type = MachineType::AnyTagged();
+  LinkageLocation target_loc = LinkageLocation::ForAnyRegister();
+  return new (zone) CallDescriptor(     // --
+      CallDescriptor::kCallCodeObject,  // kind
+      target_type,                      // target MachineType
+      target_loc,                       // target location
+      types.Build(),                    // machine_sig
+      locations.Build(),                // location_sig
+      js_parameter_count,               // stack_parameter_count
+      properties,                       // properties
+      kNoCalleeSaved,                   // callee-saved
+      kNoCalleeSaved,                   // callee-saved fp
+      flags,                            // flags
+      function->name);                  // debug name
 }
 
 
+CallDescriptor* Linkage::GetLazyBailoutDescriptor(Zone* zone) {
+  const size_t return_count = 0;
+  const size_t parameter_count = 0;
+
+  LocationSignature::Builder locations(zone, return_count, parameter_count);
+  MachineSignature::Builder types(zone, return_count, parameter_count);
+
+  // The target is ignored, but we need to give some values here.
+  MachineType target_type = MachineType::AnyTagged();
+  LinkageLocation target_loc = regloc(kJSFunctionRegister);
+  return new (zone) CallDescriptor(      // --
+      CallDescriptor::kLazyBailout,      // kind
+      target_type,                       // target MachineType
+      target_loc,                        // target location
+      types.Build(),                     // machine_sig
+      locations.Build(),                 // location_sig
+      0,                                 // stack_parameter_count
+      Operator::kNoThrow,                // properties
+      kNoCalleeSaved,                    // callee-saved
+      kNoCalleeSaved,                    // callee-saved fp
+      CallDescriptor::kNeedsFrameState,  // flags
+      "lazy-bailout");
+}
+
+
+CallDescriptor* Linkage::GetJSCallDescriptor(Zone* zone, bool is_osr,
+                                             int js_parameter_count,
+                                             CallDescriptor::Flags flags) {
+  const size_t return_count = 1;
+  const size_t context_count = 1;
+  const size_t new_target_count = 1;
+  const size_t num_args_count = 1;
+  const size_t parameter_count =
+      js_parameter_count + new_target_count + num_args_count + context_count;
+
+  LocationSignature::Builder locations(zone, return_count, parameter_count);
+  MachineSignature::Builder types(zone, return_count, parameter_count);
+
+  // All JS calls have exactly one return value.
+  locations.AddReturn(regloc(kReturnRegister0));
+  types.AddReturn(MachineType::AnyTagged());
+
+  // All parameters to JS calls go on the stack.
+  for (int i = 0; i < js_parameter_count; i++) {
+    int spill_slot_index = i - js_parameter_count;
+    locations.AddParam(LinkageLocation::ForCallerFrameSlot(spill_slot_index));
+    types.AddParam(MachineType::AnyTagged());
+  }
+
+  // Add JavaScript call new target value.
+  locations.AddParam(regloc(kJavaScriptCallNewTargetRegister));
+  types.AddParam(MachineType::AnyTagged());
+
+  // Add JavaScript call argument count.
+  locations.AddParam(regloc(kJavaScriptCallArgCountRegister));
+  types.AddParam(MachineType::Int32());
+
+  // Add context.
+  locations.AddParam(regloc(kContextRegister));
+  types.AddParam(MachineType::AnyTagged());
+
+  // The target for JS function calls is the JSFunction object.
+  MachineType target_type = MachineType::AnyTagged();
+  // TODO(titzer): When entering into an OSR function from unoptimized code,
+  // the JSFunction is not in a register, but it is on the stack in an
+  // unaddressable spill slot. We hack this in the OSR prologue. Fix.
+  LinkageLocation target_loc = regloc(kJSFunctionRegister);
+  return new (zone) CallDescriptor(     // --
+      CallDescriptor::kCallJSFunction,  // kind
+      target_type,                      // target MachineType
+      target_loc,                       // target location
+      types.Build(),                    // machine_sig
+      locations.Build(),                // location_sig
+      js_parameter_count,               // stack_parameter_count
+      Operator::kNoProperties,          // properties
+      kNoCalleeSaved,                   // callee-saved
+      kNoCalleeSaved,                   // callee-saved fp
+      CallDescriptor::kCanUseRoots |    // flags
+          flags,                        // flags
+      "js-call");
+}
+
+
+CallDescriptor* Linkage::GetInterpreterDispatchDescriptor(Zone* zone) {
+  MachineSignature::Builder types(zone, 0, 6);
+  LocationSignature::Builder locations(zone, 0, 6);
+
+  // Add registers for fixed parameters passed via interpreter dispatch.
+  STATIC_ASSERT(0 == Linkage::kInterpreterAccumulatorParameter);
+  types.AddParam(MachineType::AnyTagged());
+  locations.AddParam(regloc(kInterpreterAccumulatorRegister));
+
+  STATIC_ASSERT(1 == Linkage::kInterpreterRegisterFileParameter);
+  types.AddParam(MachineType::Pointer());
+  locations.AddParam(regloc(kInterpreterRegisterFileRegister));
+
+  STATIC_ASSERT(2 == Linkage::kInterpreterBytecodeOffsetParameter);
+  types.AddParam(MachineType::IntPtr());
+  locations.AddParam(regloc(kInterpreterBytecodeOffsetRegister));
+
+  STATIC_ASSERT(3 == Linkage::kInterpreterBytecodeArrayParameter);
+  types.AddParam(MachineType::AnyTagged());
+  locations.AddParam(regloc(kInterpreterBytecodeArrayRegister));
+
+  STATIC_ASSERT(4 == Linkage::kInterpreterDispatchTableParameter);
+  types.AddParam(MachineType::Pointer());
+#if defined(V8_TARGET_ARCH_IA32) || defined(V8_TARGET_ARCH_X87)
+  // TODO(rmcilroy): Make the context param the one spilled to the stack once
+  // Turbofan supports modified stack arguments in tail calls.
+  locations.AddParam(
+      LinkageLocation::ForCallerFrameSlot(kInterpreterDispatchTableSpillSlot));
+#else
+  locations.AddParam(regloc(kInterpreterDispatchTableRegister));
+#endif
+
+  STATIC_ASSERT(5 == Linkage::kInterpreterContextParameter);
+  types.AddParam(MachineType::AnyTagged());
+  locations.AddParam(regloc(kContextRegister));
+
+  LinkageLocation target_loc = LinkageLocation::ForAnyRegister();
+  return new (zone) CallDescriptor(         // --
+      CallDescriptor::kCallCodeObject,      // kind
+      MachineType::None(),                  // target MachineType
+      target_loc,                           // target location
+      types.Build(),                        // machine_sig
+      locations.Build(),                    // location_sig
+      0,                                    // stack_parameter_count
+      Operator::kNoProperties,              // properties
+      kNoCalleeSaved,                       // callee-saved registers
+      kNoCalleeSaved,                       // callee-saved fp regs
+      CallDescriptor::kSupportsTailCalls |  // flags
+          CallDescriptor::kCanUseRoots,     // flags
+      "interpreter-dispatch");
+}
+
+
+// TODO(all): Add support for return representations/locations to
+// CallInterfaceDescriptor.
+// TODO(turbofan): cache call descriptors for code stub calls.
 CallDescriptor* Linkage::GetStubCallDescriptor(
-    const CallInterfaceDescriptor& descriptor, int stack_parameter_count,
-    CallDescriptor::Flags flags, Operator::Properties properties,
-    Zone* zone) {
-  UNIMPLEMENTED();
-  return NULL;
+    Isolate* isolate, Zone* zone, const CallInterfaceDescriptor& descriptor,
+    int stack_parameter_count, CallDescriptor::Flags flags,
+    Operator::Properties properties, MachineType return_type,
+    size_t return_count) {
+  const int register_parameter_count = descriptor.GetRegisterParameterCount();
+  const int js_parameter_count =
+      register_parameter_count + stack_parameter_count;
+  const int context_count = 1;
+  const size_t parameter_count =
+      static_cast<size_t>(js_parameter_count + context_count);
+
+  LocationSignature::Builder locations(zone, return_count, parameter_count);
+  MachineSignature::Builder types(zone, return_count, parameter_count);
+
+  // Add returns.
+  if (locations.return_count_ > 0) {
+    locations.AddReturn(regloc(kReturnRegister0));
+  }
+  if (locations.return_count_ > 1) {
+    locations.AddReturn(regloc(kReturnRegister1));
+  }
+  for (size_t i = 0; i < return_count; i++) {
+    types.AddReturn(return_type);
+  }
+
+  // Add parameters in registers and on the stack.
+  for (int i = 0; i < js_parameter_count; i++) {
+    if (i < register_parameter_count) {
+      // The first parameters go in registers.
+      Register reg = descriptor.GetRegisterParameter(i);
+      Representation rep =
+          RepresentationFromType(descriptor.GetParameterType(i));
+      locations.AddParam(regloc(reg));
+      types.AddParam(reptyp(rep));
+    } else {
+      // The rest of the parameters go on the stack.
+      int stack_slot = i - register_parameter_count - stack_parameter_count;
+      locations.AddParam(LinkageLocation::ForCallerFrameSlot(stack_slot));
+      types.AddParam(MachineType::AnyTagged());
+    }
+  }
+  // Add context.
+  locations.AddParam(regloc(kContextRegister));
+  types.AddParam(MachineType::AnyTagged());
+
+  // The target for stub calls is a code object.
+  MachineType target_type = MachineType::AnyTagged();
+  LinkageLocation target_loc = LinkageLocation::ForAnyRegister();
+  return new (zone) CallDescriptor(     // --
+      CallDescriptor::kCallCodeObject,  // kind
+      target_type,                      // target MachineType
+      target_loc,                       // target location
+      types.Build(),                    // machine_sig
+      locations.Build(),                // location_sig
+      stack_parameter_count,            // stack_parameter_count
+      properties,                       // properties
+      kNoCalleeSaved,                   // callee-saved registers
+      kNoCalleeSaved,                   // callee-saved fp
+      flags,                            // flags
+      descriptor.DebugName(isolate));
 }
 
 
-CallDescriptor* Linkage::GetSimplifiedCDescriptor(Zone* zone,
-                                                  MachineSignature* sig) {
-  UNIMPLEMENTED();
-  return NULL;
+LinkageLocation Linkage::GetOsrValueLocation(int index) const {
+  CHECK(incoming_->IsJSFunctionCall());
+  int parameter_count = static_cast<int>(incoming_->JSParameterCount() - 1);
+  int first_stack_slot = OsrHelper::FirstStackSlotIndex(parameter_count);
+
+  if (index == kOsrContextSpillSlotIndex) {
+    // Context. Use the parameter location of the context spill slot.
+    // Parameter (arity + 2) is special for the context of the function frame.
+    // >> context_index = target + receiver + params + new_target + #args
+    int context_index = 1 + 1 + parameter_count + 1 + 1;
+    return incoming_->GetInputLocation(context_index);
+  } else if (index >= first_stack_slot) {
+    // Local variable stored in this (callee) stack.
+    int spill_index =
+        index - first_stack_slot + StandardFrameConstants::kFixedSlotCount;
+    return LinkageLocation::ForCalleeFrameSlot(spill_index);
+  } else {
+    // Parameter. Use the assigned location from the incoming call descriptor.
+    int parameter_index = 1 + index;  // skip index 0, which is the target.
+    return incoming_->GetInputLocation(parameter_index);
+  }
 }
-#endif  // !V8_TURBOFAN_BACKEND
+
+
+bool Linkage::ParameterHasSecondaryLocation(int index) const {
+  if (incoming_->kind() != CallDescriptor::kCallJSFunction) return false;
+  LinkageLocation loc = GetParameterLocation(index);
+  return (loc == regloc(kJSFunctionRegister) ||
+          loc == regloc(kContextRegister));
 }
+
+LinkageLocation Linkage::GetParameterSecondaryLocation(int index) const {
+  DCHECK(ParameterHasSecondaryLocation(index));
+  LinkageLocation loc = GetParameterLocation(index);
+
+  if (loc == regloc(kJSFunctionRegister)) {
+    return LinkageLocation::ForCalleeFrameSlot(Frame::kJSFunctionSlot);
+  } else {
+    DCHECK(loc == regloc(kContextRegister));
+    return LinkageLocation::ForCalleeFrameSlot(Frame::kContextSlot);
+  }
 }
-}  // namespace v8::internal::compiler
+
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/linkage.h b/src/compiler/linkage.h
index 0ad0761..252f044 100644
--- a/src/compiler/linkage.h
+++ b/src/compiler/linkage.h
@@ -7,68 +7,175 @@
 
 #include "src/base/flags.h"
 #include "src/compiler/frame.h"
-#include "src/compiler/machine-type.h"
 #include "src/compiler/operator.h"
+#include "src/frames.h"
+#include "src/machine-type.h"
+#include "src/runtime/runtime.h"
 #include "src/zone.h"
 
 namespace v8 {
 namespace internal {
 
 class CallInterfaceDescriptor;
+class CompilationInfo;
 
 namespace compiler {
 
+const RegList kNoCalleeSaved = 0;
+
+class Node;
+class OsrHelper;
+
 // Describes the location for a parameter or a return value to a call.
 class LinkageLocation {
  public:
-  explicit LinkageLocation(int location) : location_(location) {}
+  bool operator==(const LinkageLocation& other) const {
+    return bit_field_ == other.bit_field_;
+  }
 
-  static const int16_t ANY_REGISTER = 32767;
+  bool operator!=(const LinkageLocation& other) const {
+    return !(*this == other);
+  }
 
-  static LinkageLocation AnyRegister() { return LinkageLocation(ANY_REGISTER); }
+  static LinkageLocation ForAnyRegister() {
+    return LinkageLocation(REGISTER, ANY_REGISTER);
+  }
+
+  static LinkageLocation ForRegister(int32_t reg) {
+    DCHECK(reg >= 0);
+    return LinkageLocation(REGISTER, reg);
+  }
+
+  static LinkageLocation ForCallerFrameSlot(int32_t slot) {
+    DCHECK(slot < 0);
+    return LinkageLocation(STACK_SLOT, slot);
+  }
+
+  static LinkageLocation ForCalleeFrameSlot(int32_t slot) {
+    // TODO(titzer): bailout instead of crashing here.
+    DCHECK(slot >= 0 && slot < LinkageLocation::MAX_STACK_SLOT);
+    return LinkageLocation(STACK_SLOT, slot);
+  }
+
+  static LinkageLocation ForSavedCallerReturnAddress() {
+    return ForCalleeFrameSlot((StandardFrameConstants::kCallerPCOffset -
+                               StandardFrameConstants::kCallerPCOffset) /
+                              kPointerSize);
+  }
+
+  static LinkageLocation ForSavedCallerFramePtr() {
+    return ForCalleeFrameSlot((StandardFrameConstants::kCallerPCOffset -
+                               StandardFrameConstants::kCallerFPOffset) /
+                              kPointerSize);
+  }
+
+  static LinkageLocation ForSavedCallerConstantPool() {
+    DCHECK(V8_EMBEDDED_CONSTANT_POOL);
+    return ForCalleeFrameSlot((StandardFrameConstants::kCallerPCOffset -
+                               StandardFrameConstants::kConstantPoolOffset) /
+                              kPointerSize);
+  }
+
+  static LinkageLocation ConvertToTailCallerLocation(
+      LinkageLocation caller_location, int stack_param_delta) {
+    if (!caller_location.IsRegister()) {
+      return LinkageLocation(STACK_SLOT,
+                             caller_location.GetLocation() - stack_param_delta);
+    }
+    return caller_location;
+  }
 
  private:
   friend class CallDescriptor;
   friend class OperandGenerator;
-  int16_t location_;  // >= 0 implies register, otherwise stack slot.
+
+  enum LocationType { REGISTER, STACK_SLOT };
+
+  class TypeField : public BitField<LocationType, 0, 1> {};
+  class LocationField : public BitField<int32_t, TypeField::kNext, 31> {};
+
+  static const int32_t ANY_REGISTER = -1;
+  static const int32_t MAX_STACK_SLOT = 32767;
+
+  LinkageLocation(LocationType type, int32_t location) {
+    bit_field_ = TypeField::encode(type) |
+                 ((location << LocationField::kShift) & LocationField::kMask);
+  }
+
+  int32_t GetLocation() const {
+    return static_cast<int32_t>(bit_field_ & LocationField::kMask) >>
+           LocationField::kShift;
+  }
+
+  bool IsRegister() const { return TypeField::decode(bit_field_) == REGISTER; }
+  bool IsAnyRegister() const {
+    return IsRegister() && GetLocation() == ANY_REGISTER;
+  }
+  bool IsCallerFrameSlot() const { return !IsRegister() && GetLocation() < 0; }
+  bool IsCalleeFrameSlot() const { return !IsRegister() && GetLocation() >= 0; }
+
+  int32_t AsRegister() const {
+    DCHECK(IsRegister());
+    return GetLocation();
+  }
+  int32_t AsCallerFrameSlot() const {
+    DCHECK(IsCallerFrameSlot());
+    return GetLocation();
+  }
+  int32_t AsCalleeFrameSlot() const {
+    DCHECK(IsCalleeFrameSlot());
+    return GetLocation();
+  }
+
+  int32_t bit_field_;
 };
 
 typedef Signature<LinkageLocation> LocationSignature;
 
 // Describes a call to various parts of the compiler. Every call has the notion
 // of a "target", which is the first input to the call.
-class CallDescriptor FINAL : public ZoneObject {
+class CallDescriptor final : public ZoneObject {
  public:
   // Describes the kind of this call, which determines the target.
   enum Kind {
     kCallCodeObject,  // target is a Code object
     kCallJSFunction,  // target is a JSFunction object
-    kCallAddress      // target is a machine pointer
+    kCallAddress,     // target is a machine pointer
+    kLazyBailout      // the call is no-op, only used for lazy bailout
   };
 
   enum Flag {
-    // TODO(jarin) kLazyDeoptimization and kNeedsFrameState should be unified.
     kNoFlags = 0u,
     kNeedsFrameState = 1u << 0,
     kPatchableCallSite = 1u << 1,
     kNeedsNopAfterCall = 1u << 2,
+    kHasExceptionHandler = 1u << 3,
+    kHasLocalCatchHandler = 1u << 4,
+    kSupportsTailCalls = 1u << 5,
+    kCanUseRoots = 1u << 6,
+    // Indicates that the native stack should be used for a code object. This
+    // information is important for native calls on arm64.
+    kUseNativeStack = 1u << 7,
     kPatchableCallSiteWithNop = kPatchableCallSite | kNeedsNopAfterCall
   };
   typedef base::Flags<Flag> Flags;
 
   CallDescriptor(Kind kind, MachineType target_type, LinkageLocation target_loc,
-                 MachineSignature* machine_sig, LocationSignature* location_sig,
-                 size_t js_param_count, Operator::Properties properties,
-                 RegList callee_saved_registers, Flags flags,
+                 const MachineSignature* machine_sig,
+                 LocationSignature* location_sig, size_t stack_param_count,
+                 Operator::Properties properties,
+                 RegList callee_saved_registers,
+                 RegList callee_saved_fp_registers, Flags flags,
                  const char* debug_name = "")
       : kind_(kind),
         target_type_(target_type),
         target_loc_(target_loc),
         machine_sig_(machine_sig),
         location_sig_(location_sig),
-        js_param_count_(js_param_count),
+        stack_param_count_(stack_param_count),
         properties_(properties),
         callee_saved_registers_(callee_saved_registers),
+        callee_saved_fp_registers_(callee_saved_fp_registers),
         flags_(flags),
         debug_name_(debug_name) {
     DCHECK(machine_sig->return_count() == location_sig->return_count());
@@ -78,15 +185,30 @@
   // Returns the kind of this call.
   Kind kind() const { return kind_; }
 
+  // Returns {true} if this descriptor is a call to a C function.
+  bool IsCFunctionCall() const { return kind_ == kCallAddress; }
+
   // Returns {true} if this descriptor is a call to a JSFunction.
   bool IsJSFunctionCall() const { return kind_ == kCallJSFunction; }
 
+  bool RequiresFrameAsIncoming() const {
+    return IsCFunctionCall() || IsJSFunctionCall();
+  }
+
   // The number of return values from this call.
   size_t ReturnCount() const { return machine_sig_->return_count(); }
 
-  // The number of JavaScript parameters to this call, including the receiver
-  // object.
-  size_t JSParameterCount() const { return js_param_count_; }
+  // The number of C parameters to this call.
+  size_t CParameterCount() const { return machine_sig_->parameter_count(); }
+
+  // The number of stack parameters to the call.
+  size_t StackParameterCount() const { return stack_param_count_; }
+
+  // The number of parameters to the JS function call.
+  size_t JSParameterCount() const {
+    DCHECK(IsJSFunctionCall());
+    return stack_param_count_;
+  }
 
   // The total number of inputs to this call, which includes the target,
   // receiver, context, etc.
@@ -98,6 +220,8 @@
   Flags flags() const { return flags_; }
 
   bool NeedsFrameState() const { return flags() & kNeedsFrameState; }
+  bool SupportsTailCalls() const { return flags() & kSupportsTailCalls; }
+  bool UseNativeStack() const { return flags() & kUseNativeStack; }
 
   LinkageLocation GetReturnLocation(size_t index) const {
     return location_sig_->GetReturn(index);
@@ -125,8 +249,17 @@
   // Get the callee-saved registers, if any, across this call.
   RegList CalleeSavedRegisters() const { return callee_saved_registers_; }
 
+  // Get the callee-saved FP registers, if any, across this call.
+  RegList CalleeSavedFPRegisters() const { return callee_saved_fp_registers_; }
+
   const char* debug_name() const { return debug_name_; }
 
+  bool UsesOnlyRegisters() const;
+
+  bool HasSameReturnLocationsAs(const CallDescriptor* other) const;
+
+  bool CanTailCall(const Node* call, int* stack_param_delta) const;
+
  private:
   friend class Linkage;
 
@@ -135,9 +268,10 @@
   const LinkageLocation target_loc_;
   const MachineSignature* const machine_sig_;
   const LocationSignature* const location_sig_;
-  const size_t js_param_count_;
+  const size_t stack_param_count_;
   const Operator::Properties properties_;
   const RegList callee_saved_registers_;
+  const RegList callee_saved_fp_registers_;
   const Flags flags_;
   const char* const debug_name_;
 
@@ -156,49 +290,49 @@
 // Can be used to translate {arg_index} (i.e. index of the call node input) as
 // well as {param_index} (i.e. as stored in parameter nodes) into an operator
 // representing the architecture-specific location. The following call node
-// layouts are supported (where {n} is the number value inputs):
+// layouts are supported (where {n} is the number of value inputs):
 //
 //                  #0          #1     #2     #3     [...]             #n
 // Call[CodeStub]   code,       arg 1, arg 2, arg 3, [...],            context
-// Call[JSFunction] function,   rcvr,  arg 1, arg 2, [...],            context
+// Call[JSFunction] function,   rcvr,  arg 1, arg 2, [...], new, #arg, context
 // Call[Runtime]    CEntryStub, arg 1, arg 2, arg 3, [...], fun, #arg, context
 class Linkage : public ZoneObject {
  public:
-  Linkage(Zone* zone, CompilationInfo* info)
-      : zone_(zone), incoming_(ComputeIncoming(zone, info)) {}
-  Linkage(Zone* zone, CallDescriptor* incoming)
-      : zone_(zone), incoming_(incoming) {}
+  explicit Linkage(CallDescriptor* incoming) : incoming_(incoming) {}
 
   static CallDescriptor* ComputeIncoming(Zone* zone, CompilationInfo* info);
 
   // The call descriptor for this compilation unit describes the locations
   // of incoming parameters and the outgoing return value(s).
   CallDescriptor* GetIncomingDescriptor() const { return incoming_; }
-  CallDescriptor* GetJSCallDescriptor(int parameter_count,
-                                      CallDescriptor::Flags flags) const;
-  static CallDescriptor* GetJSCallDescriptor(int parameter_count, Zone* zone,
+  static CallDescriptor* GetJSCallDescriptor(Zone* zone, bool is_osr,
+                                             int parameter_count,
                                              CallDescriptor::Flags flags);
-  CallDescriptor* GetRuntimeCallDescriptor(
-      Runtime::FunctionId function, int parameter_count,
-      Operator::Properties properties) const;
-  static CallDescriptor* GetRuntimeCallDescriptor(
-      Runtime::FunctionId function, int parameter_count,
-      Operator::Properties properties, Zone* zone);
 
-  CallDescriptor* GetStubCallDescriptor(
-      const CallInterfaceDescriptor& descriptor, int stack_parameter_count = 0,
-      CallDescriptor::Flags flags = CallDescriptor::kNoFlags,
-      Operator::Properties properties = Operator::kNoProperties) const;
+  static CallDescriptor* GetRuntimeCallDescriptor(
+      Zone* zone, Runtime::FunctionId function, int parameter_count,
+      Operator::Properties properties, CallDescriptor::Flags flags);
+
+  static CallDescriptor* GetLazyBailoutDescriptor(Zone* zone);
+
   static CallDescriptor* GetStubCallDescriptor(
-      const CallInterfaceDescriptor& descriptor, int stack_parameter_count,
-      CallDescriptor::Flags flags, Operator::Properties properties, Zone* zone);
+      Isolate* isolate, Zone* zone, const CallInterfaceDescriptor& descriptor,
+      int stack_parameter_count, CallDescriptor::Flags flags,
+      Operator::Properties properties = Operator::kNoProperties,
+      MachineType return_type = MachineType::AnyTagged(),
+      size_t return_count = 1);
 
   // Creates a call descriptor for simplified C calls that is appropriate
   // for the host platform. This simplified calling convention only supports
   // integers and pointers of one word size each, i.e. no floating point,
   // structs, pointers to members, etc.
   static CallDescriptor* GetSimplifiedCDescriptor(Zone* zone,
-                                                  MachineSignature* sig);
+                                                  const MachineSignature* sig);
+
+  // Creates a call descriptor for interpreter handler code stubs. These are not
+  // intended to be called directly but are instead dispatched to by the
+  // interpreter.
+  static CallDescriptor* GetInterpreterDispatchDescriptor(Zone* zone);
 
   // Get the location of an (incoming) parameter to this function.
   LinkageLocation GetParameterLocation(int index) const {
@@ -211,24 +345,54 @@
   }
 
   // Get the location where this function should place its return value.
-  LinkageLocation GetReturnLocation() const {
-    return incoming_->GetReturnLocation(0);
+  LinkageLocation GetReturnLocation(size_t index = 0) const {
+    return incoming_->GetReturnLocation(index);
   }
 
   // Get the machine type of this function's return value.
-  MachineType GetReturnType() const { return incoming_->GetReturnType(0); }
+  MachineType GetReturnType(size_t index = 0) const {
+    return incoming_->GetReturnType(index);
+  }
 
-  // Get the frame offset for a given spill slot. The location depends on the
-  // calling convention and the specific frame layout, and may thus be
-  // architecture-specific. Negative spill slots indicate arguments on the
-  // caller's frame. The {extra} parameter indicates an additional offset from
-  // the frame offset, e.g. to index into part of a double slot.
-  FrameOffset GetFrameOffset(int spill_slot, Frame* frame, int extra = 0) const;
+  bool ParameterHasSecondaryLocation(int index) const;
+  LinkageLocation GetParameterSecondaryLocation(int index) const;
 
-  static bool NeedsFrameState(Runtime::FunctionId function);
+  static int FrameStateInputCount(Runtime::FunctionId function);
+
+  // Get the location where an incoming OSR value is stored.
+  LinkageLocation GetOsrValueLocation(int index) const;
+
+  // A special {Parameter} index for JSCalls that represents the new target.
+  static int GetJSCallNewTargetParamIndex(int parameter_count) {
+    return parameter_count + 0;  // Parameter (arity + 0) is special.
+  }
+
+  // A special {Parameter} index for JSCalls that represents the argument count.
+  static int GetJSCallArgCountParamIndex(int parameter_count) {
+    return parameter_count + 1;  // Parameter (arity + 1) is special.
+  }
+
+  // A special {Parameter} index for JSCalls that represents the context.
+  static int GetJSCallContextParamIndex(int parameter_count) {
+    return parameter_count + 2;  // Parameter (arity + 2) is special.
+  }
+
+  // A special {Parameter} index for JSCalls that represents the closure.
+  static const int kJSCallClosureParamIndex = -1;
+
+  // A special {OsrValue} index to indicate the context spill slot.
+  static const int kOsrContextSpillSlotIndex = -1;
+
+  // Special parameter indices used to pass fixed register data through
+  // interpreter dispatches.
+  static const int kInterpreterAccumulatorParameter = 0;
+  static const int kInterpreterRegisterFileParameter = 1;
+  static const int kInterpreterBytecodeOffsetParameter = 2;
+  static const int kInterpreterBytecodeArrayParameter = 3;
+  static const int kInterpreterDispatchTableParameter = 4;
+  static const int kInterpreterContextParameter = 5;
 
  private:
-  Zone* const zone_;
   CallDescriptor* const incoming_;
 
   DISALLOW_COPY_AND_ASSIGN(Linkage);
diff --git a/src/compiler/live-range-separator.cc b/src/compiler/live-range-separator.cc
new file mode 100644
index 0000000..980c944
--- /dev/null
+++ b/src/compiler/live-range-separator.cc
@@ -0,0 +1,159 @@
+// Copyright 2015 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/live-range-separator.h"
+#include "src/compiler/register-allocator.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+
+#define TRACE(...)                             \
+  do {                                         \
+    if (FLAG_trace_alloc) PrintF(__VA_ARGS__); \
+  } while (false)
+
+
+namespace {
+
+
+void CreateSplinter(TopLevelLiveRange *range, RegisterAllocationData *data,
+                    LifetimePosition first_cut, LifetimePosition last_cut) {
+  DCHECK(!range->IsSplinter());
+  // We can ignore ranges that live solely in deferred blocks.
+  // If a range ends right at the end of a deferred block, it is marked by
+  // the range builder as ending at gap start of the next block - since the
+  // end is a position where the variable isn't live. We need to take that
+  // into consideration.
+  LifetimePosition max_allowed_end = last_cut.NextFullStart();
+
+  if (first_cut <= range->Start() && max_allowed_end >= range->End()) {
+    return;
+  }
+
+  LifetimePosition start = Max(first_cut, range->Start());
+  LifetimePosition end = Min(last_cut, range->End());
+
+  if (start < end) {
+    // Ensure the original range has a spill range associated, before it gets
+    // splintered. Splinters will point to it. This way, when attempting to
+    // reuse spill slots of splinters, during allocation, we avoid clobbering
+    // such slots.
+    if (range->MayRequireSpillRange()) {
+      data->CreateSpillRangeForLiveRange(range);
+    }
+    if (range->splinter() == nullptr) {
+      TopLevelLiveRange *splinter =
+          data->NextLiveRange(range->representation());
+      DCHECK_NULL(data->live_ranges()[splinter->vreg()]);
+      data->live_ranges()[splinter->vreg()] = splinter;
+      range->SetSplinter(splinter);
+    }
+    Zone *zone = data->allocation_zone();
+    TRACE("creating splinter for range %d between %d and %d\n", range->vreg(),
+          start.ToInstructionIndex(), end.ToInstructionIndex());
+    range->Splinter(start, end, zone);
+  }
+}
+
+
+void SplinterLiveRange(TopLevelLiveRange *range, RegisterAllocationData *data) {
+  const InstructionSequence *code = data->code();
+  UseInterval *interval = range->first_interval();
+
+  LifetimePosition first_cut = LifetimePosition::Invalid();
+  LifetimePosition last_cut = LifetimePosition::Invalid();
+
+  while (interval != nullptr) {
+    UseInterval *next_interval = interval->next();
+    const InstructionBlock *first_block =
+        code->GetInstructionBlock(interval->FirstGapIndex());
+    const InstructionBlock *last_block =
+        code->GetInstructionBlock(interval->LastGapIndex());
+    int first_block_nr = first_block->rpo_number().ToInt();
+    int last_block_nr = last_block->rpo_number().ToInt();
+    for (int block_id = first_block_nr; block_id <= last_block_nr; ++block_id) {
+      const InstructionBlock *current_block =
+          code->InstructionBlockAt(RpoNumber::FromInt(block_id));
+      if (current_block->IsDeferred()) {
+        if (!first_cut.IsValid()) {
+          first_cut = LifetimePosition::GapFromInstructionIndex(
+              current_block->first_instruction_index());
+        }
+        last_cut = LifetimePosition::GapFromInstructionIndex(
+            current_block->last_instruction_index());
+      } else {
+        if (first_cut.IsValid()) {
+          CreateSplinter(range, data, first_cut, last_cut);
+          first_cut = LifetimePosition::Invalid();
+          last_cut = LifetimePosition::Invalid();
+        }
+      }
+    }
+    interval = next_interval;
+  }
+  // When the range ends in deferred blocks, first_cut will be valid here.
+  // Splinter from there to the last instruction that was in a deferred block.
+  if (first_cut.IsValid()) {
+    CreateSplinter(range, data, first_cut, last_cut);
+  }
+}
+}  // namespace
+
+
+void LiveRangeSeparator::Splinter() {
+  size_t virt_reg_count = data()->live_ranges().size();
+  for (size_t vreg = 0; vreg < virt_reg_count; ++vreg) {
+    TopLevelLiveRange *range = data()->live_ranges()[vreg];
+    if (range == nullptr || range->IsEmpty() || range->IsSplinter()) {
+      continue;
+    }
+    int first_instr = range->first_interval()->FirstGapIndex();
+    if (!data()->code()->GetInstructionBlock(first_instr)->IsDeferred()) {
+      SplinterLiveRange(range, data());
+    }
+  }
+}
+
+
+void LiveRangeMerger::MarkRangesSpilledInDeferredBlocks() {
+  for (TopLevelLiveRange *top : data()->live_ranges()) {
+    if (top == nullptr || top->IsEmpty() || top->splinter() == nullptr) {
+      continue;
+    }
+
+    LiveRange *child = top;
+    for (; child != nullptr; child = child->next()) {
+      if (child->spilled() ||
+          child->NextSlotPosition(child->Start()) != nullptr) {
+        break;
+      }
+    }
+    if (child == nullptr) top->MarkSpilledInDeferredBlock();
+  }
+}
+
+
+void LiveRangeMerger::Merge() {
+  MarkRangesSpilledInDeferredBlocks();
+
+  int live_range_count = static_cast<int>(data()->live_ranges().size());
+  for (int i = 0; i < live_range_count; ++i) {
+    TopLevelLiveRange *range = data()->live_ranges()[i];
+    if (range == nullptr || range->IsEmpty() || !range->IsSplinter()) {
+      continue;
+    }
+    TopLevelLiveRange *splinter_parent = range->splintered_from();
+
+    int to_remove = range->vreg();
+    splinter_parent->Merge(range, data()->allocation_zone());
+    data()->live_ranges()[to_remove] = nullptr;
+  }
+}
+
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/live-range-separator.h b/src/compiler/live-range-separator.h
new file mode 100644
index 0000000..57bc982
--- /dev/null
+++ b/src/compiler/live-range-separator.h
@@ -0,0 +1,65 @@
+// Copyright 2015 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.
+
+#ifndef V8_LIVE_RANGE_SEPARATOR_H_
+#define V8_LIVE_RANGE_SEPARATOR_H_
+
+
+#include <src/zone.h>
+namespace v8 {
+namespace internal {
+
+class Zone;
+
+namespace compiler {
+
+class RegisterAllocationData;
+
+
+// A register allocation pair of transformations: splinter and merge live ranges
+class LiveRangeSeparator final : public ZoneObject {
+ public:
+  LiveRangeSeparator(RegisterAllocationData* data, Zone* zone)
+      : data_(data), zone_(zone) {}
+
+  void Splinter();
+
+ private:
+  RegisterAllocationData* data() const { return data_; }
+  Zone* zone() const { return zone_; }
+
+  RegisterAllocationData* const data_;
+  Zone* const zone_;
+
+  DISALLOW_COPY_AND_ASSIGN(LiveRangeSeparator);
+};
+
+
+class LiveRangeMerger final : public ZoneObject {
+ public:
+  LiveRangeMerger(RegisterAllocationData* data, Zone* zone)
+      : data_(data), zone_(zone) {}
+
+  void Merge();
+
+ private:
+  RegisterAllocationData* data() const { return data_; }
+  Zone* zone() const { return zone_; }
+
+  // Mark ranges spilled in deferred blocks, that also cover non-deferred code.
+  // We do nothing special for ranges fully contained in deferred blocks,
+  // because they would "spill in deferred blocks" anyway.
+  void MarkRangesSpilledInDeferredBlocks();
+
+  RegisterAllocationData* const data_;
+  Zone* const zone_;
+
+  DISALLOW_COPY_AND_ASSIGN(LiveRangeMerger);
+};
+
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+#endif  // V8_LIVE_RANGE_SEPARATOR_H_
diff --git a/src/compiler/liveness-analyzer.cc b/src/compiler/liveness-analyzer.cc
new file mode 100644
index 0000000..fe458b8
--- /dev/null
+++ b/src/compiler/liveness-analyzer.cc
@@ -0,0 +1,200 @@
+// 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/base/adapters.h"
+#include "src/compiler/js-graph.h"
+#include "src/compiler/liveness-analyzer.h"
+#include "src/compiler/node.h"
+#include "src/compiler/node-matchers.h"
+#include "src/compiler/state-values-utils.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+
+LivenessAnalyzer::LivenessAnalyzer(size_t local_count, Zone* zone)
+    : zone_(zone), blocks_(zone), local_count_(local_count), queue_(zone) {}
+
+
+void LivenessAnalyzer::Print(std::ostream& os) {
+  for (auto block : blocks_) {
+    block->Print(os);
+    os << std::endl;
+  }
+}
+
+
+LivenessAnalyzerBlock* LivenessAnalyzer::NewBlock() {
+  LivenessAnalyzerBlock* result =
+      new (zone()->New(sizeof(LivenessAnalyzerBlock)))
+          LivenessAnalyzerBlock(blocks_.size(), local_count_, zone());
+  blocks_.push_back(result);
+  return result;
+}
+
+
+LivenessAnalyzerBlock* LivenessAnalyzer::NewBlock(
+    LivenessAnalyzerBlock* predecessor) {
+  LivenessAnalyzerBlock* result = NewBlock();
+  result->AddPredecessor(predecessor);
+  return result;
+}
+
+
+void LivenessAnalyzer::Queue(LivenessAnalyzerBlock* block) {
+  if (!block->IsQueued()) {
+    block->SetQueued();
+    queue_.push(block);
+  }
+}
+
+
+void LivenessAnalyzer::Run(NonLiveFrameStateSlotReplacer* replacer) {
+  if (local_count_ == 0) {
+    // No local variables => nothing to do.
+    return;
+  }
+
+  // Put all blocks into the queue.
+  DCHECK(queue_.empty());
+  for (auto block : blocks_) {
+    Queue(block);
+  }
+
+  // Compute the fix-point.
+  BitVector working_area(static_cast<int>(local_count_), zone_);
+  while (!queue_.empty()) {
+    LivenessAnalyzerBlock* block = queue_.front();
+    queue_.pop();
+    block->Process(&working_area, nullptr);
+
+    for (auto i = block->pred_begin(); i != block->pred_end(); i++) {
+      if ((*i)->UpdateLive(&working_area)) {
+        Queue(*i);
+      }
+    }
+  }
+
+  // Update the frame states according to the liveness.
+  for (auto block : blocks_) {
+    block->Process(&working_area, replacer);
+  }
+}
+
+LivenessAnalyzerBlock::LivenessAnalyzerBlock(size_t id, size_t local_count,
+                                             Zone* zone)
+    : entries_(zone),
+      predecessors_(zone),
+      live_(local_count == 0 ? 1 : static_cast<int>(local_count), zone),
+      queued_(false),
+      id_(id) {}
+
+void LivenessAnalyzerBlock::Process(BitVector* result,
+                                    NonLiveFrameStateSlotReplacer* replacer) {
+  queued_ = false;
+
+  // Copy the bitvector to the target bit vector.
+  result->CopyFrom(live_);
+
+  for (auto entry : base::Reversed(entries_)) {
+    switch (entry.kind()) {
+      case Entry::kLookup:
+        result->Add(entry.var());
+        break;
+      case Entry::kBind:
+        result->Remove(entry.var());
+        break;
+      case Entry::kCheckpoint:
+        if (replacer != nullptr) {
+          replacer->ClearNonLiveFrameStateSlots(entry.node(), result);
+        }
+        break;
+    }
+  }
+}
+
+
+bool LivenessAnalyzerBlock::UpdateLive(BitVector* working_area) {
+  return live_.UnionIsChanged(*working_area);
+}
+
+
+void NonLiveFrameStateSlotReplacer::ClearNonLiveFrameStateSlots(
+    Node* frame_state, BitVector* liveness) {
+  DCHECK_EQ(frame_state->opcode(), IrOpcode::kFrameState);
+  Node* locals_state = frame_state->InputAt(1);
+  DCHECK_EQ(locals_state->opcode(), IrOpcode::kStateValues);
+  int count = static_cast<int>(StateValuesAccess(locals_state).size());
+  DCHECK_EQ(count == 0 ? 1 : count, liveness->length());
+  for (int i = 0; i < count; i++) {
+    bool live = liveness->Contains(i) || permanently_live_.Contains(i);
+    if (!live || locals_state->InputAt(i) != replacement_node_) {
+      Node* new_values = ClearNonLiveStateValues(locals_state, liveness);
+      frame_state->ReplaceInput(1, new_values);
+      break;
+    }
+  }
+}
+
+
+Node* NonLiveFrameStateSlotReplacer::ClearNonLiveStateValues(
+    Node* values, BitVector* liveness) {
+  DCHECK(inputs_buffer_.empty());
+  for (StateValuesAccess::TypedNode node : StateValuesAccess(values)) {
+    // Index of the next variable is its furure index in the inputs buffer,
+    // i.e., the buffer's size.
+    int var = static_cast<int>(inputs_buffer_.size());
+    bool live = liveness->Contains(var) || permanently_live_.Contains(var);
+    inputs_buffer_.push_back(live ? node.node : replacement_node_);
+  }
+  Node* result = state_values_cache()->GetNodeForValues(
+      inputs_buffer_.empty() ? nullptr : &(inputs_buffer_.front()),
+      inputs_buffer_.size());
+  inputs_buffer_.clear();
+  return result;
+}
+
+
+void LivenessAnalyzerBlock::Print(std::ostream& os) {
+  os << "Block " << id();
+  bool first = true;
+  for (LivenessAnalyzerBlock* pred : predecessors_) {
+    if (!first) {
+      os << ", ";
+    } else {
+      os << "; predecessors: ";
+      first = false;
+    }
+    os << pred->id();
+  }
+  os << std::endl;
+
+  for (auto entry : entries_) {
+    os << "    ";
+    switch (entry.kind()) {
+      case Entry::kLookup:
+        os << "- Lookup " << entry.var() << std::endl;
+        break;
+      case Entry::kBind:
+        os << "- Bind " << entry.var() << std::endl;
+        break;
+      case Entry::kCheckpoint:
+        os << "- Checkpoint " << entry.node()->id() << std::endl;
+        break;
+    }
+  }
+
+  if (live_.length() > 0) {
+    os << "    Live set: ";
+    for (int i = 0; i < live_.length(); i++) {
+      os << (live_.Contains(i) ? "L" : ".");
+    }
+    os << std::endl;
+  }
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/liveness-analyzer.h b/src/compiler/liveness-analyzer.h
new file mode 100644
index 0000000..1e2f85b
--- /dev/null
+++ b/src/compiler/liveness-analyzer.h
@@ -0,0 +1,146 @@
+// Copyright 2015 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.
+
+#ifndef V8_COMPILER_LIVENESS_ANAYZER_H_
+#define V8_COMPILER_LIVENESS_ANAYZER_H_
+
+#include "src/bit-vector.h"
+#include "src/compiler/node.h"
+#include "src/zone-containers.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+class LivenessAnalyzerBlock;
+class Node;
+class StateValuesCache;
+
+
+class NonLiveFrameStateSlotReplacer {
+ public:
+  void ClearNonLiveFrameStateSlots(Node* frame_state, BitVector* liveness);
+  NonLiveFrameStateSlotReplacer(StateValuesCache* state_values_cache,
+                                Node* replacement, size_t local_count,
+                                Zone* local_zone)
+      : replacement_node_(replacement),
+        state_values_cache_(state_values_cache),
+        local_zone_(local_zone),
+        permanently_live_(local_count == 0 ? 1 : static_cast<int>(local_count),
+                          local_zone),
+        inputs_buffer_(local_zone) {}
+
+  void MarkPermanentlyLive(int var) { permanently_live_.Add(var); }
+
+ private:
+  Node* ClearNonLiveStateValues(Node* frame_state, BitVector* liveness);
+
+  StateValuesCache* state_values_cache() { return state_values_cache_; }
+  Zone* local_zone() { return local_zone_; }
+
+  // Node that replaces dead values.
+  Node* replacement_node_;
+  // Reference to state values cache so that we can create state values
+  // nodes.
+  StateValuesCache* state_values_cache_;
+
+  Zone* local_zone_;
+  BitVector permanently_live_;
+  NodeVector inputs_buffer_;
+};
+
+
+class LivenessAnalyzer {
+ public:
+  LivenessAnalyzer(size_t local_count, Zone* zone);
+
+  LivenessAnalyzerBlock* NewBlock();
+  LivenessAnalyzerBlock* NewBlock(LivenessAnalyzerBlock* predecessor);
+
+  void Run(NonLiveFrameStateSlotReplacer* relaxer);
+
+  Zone* zone() { return zone_; }
+
+  void Print(std::ostream& os);
+
+  size_t local_count() { return local_count_; }
+
+ private:
+  void Queue(LivenessAnalyzerBlock* block);
+
+  Zone* zone_;
+  ZoneDeque<LivenessAnalyzerBlock*> blocks_;
+  size_t local_count_;
+
+  ZoneQueue<LivenessAnalyzerBlock*> queue_;
+};
+
+
+class LivenessAnalyzerBlock {
+ public:
+  friend class LivenessAnalyzer;
+
+  void Lookup(int var) { entries_.push_back(Entry(Entry::kLookup, var)); }
+  void Bind(int var) { entries_.push_back(Entry(Entry::kBind, var)); }
+  void Checkpoint(Node* node) { entries_.push_back(Entry(node)); }
+  void AddPredecessor(LivenessAnalyzerBlock* b) { predecessors_.push_back(b); }
+
+ private:
+  class Entry {
+   public:
+    enum Kind { kBind, kLookup, kCheckpoint };
+
+    Kind kind() const { return kind_; }
+    Node* node() const {
+      DCHECK(kind() == kCheckpoint);
+      return node_;
+    }
+    int var() const {
+      DCHECK(kind() != kCheckpoint);
+      return var_;
+    }
+
+    explicit Entry(Node* node) : kind_(kCheckpoint), var_(-1), node_(node) {}
+    Entry(Kind kind, int var) : kind_(kind), var_(var), node_(nullptr) {
+      DCHECK(kind != kCheckpoint);
+    }
+
+   private:
+    Kind kind_;
+    int var_;
+    Node* node_;
+  };
+
+  LivenessAnalyzerBlock(size_t id, size_t local_count, Zone* zone);
+  void Process(BitVector* result, NonLiveFrameStateSlotReplacer* relaxer);
+  bool UpdateLive(BitVector* working_area);
+
+  void SetQueued() { queued_ = true; }
+  bool IsQueued() { return queued_; }
+
+  ZoneDeque<LivenessAnalyzerBlock*>::const_iterator pred_begin() {
+    return predecessors_.begin();
+  }
+  ZoneDeque<LivenessAnalyzerBlock*>::const_iterator pred_end() {
+    return predecessors_.end();
+  }
+
+  size_t id() { return id_; }
+  void Print(std::ostream& os);
+
+  ZoneDeque<Entry> entries_;
+  ZoneDeque<LivenessAnalyzerBlock*> predecessors_;
+
+  BitVector live_;
+  bool queued_;
+
+  size_t id_;
+};
+
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_AST_GRAPH_BUILDER_H_
diff --git a/src/compiler/load-elimination.cc b/src/compiler/load-elimination.cc
index fe0714e..97f1ab0 100644
--- a/src/compiler/load-elimination.cc
+++ b/src/compiler/load-elimination.cc
@@ -4,7 +4,7 @@
 
 #include "src/compiler/load-elimination.h"
 
-#include "src/compiler/node-properties-inl.h"
+#include "src/compiler/node-properties.h"
 #include "src/compiler/simplified-operator.h"
 
 namespace v8 {
@@ -28,7 +28,7 @@
 Reduction LoadElimination::ReduceLoadField(Node* node) {
   DCHECK_EQ(IrOpcode::kLoadField, node->opcode());
   FieldAccess const access = FieldAccessOf(node->op());
-  Node* const object = NodeProperties::GetValueInput(node, 0);
+  Node* object = NodeProperties::GetValueInput(node, 0);
   for (Node* effect = NodeProperties::GetEffectInput(node);;
        effect = NodeProperties::GetEffectInput(effect)) {
     switch (effect->opcode()) {
@@ -36,7 +36,7 @@
         if (object == NodeProperties::GetValueInput(effect, 0) &&
             access == FieldAccessOf(effect->op())) {
           Node* const value = effect;
-          NodeProperties::ReplaceWithValue(node, value);
+          ReplaceWithValue(node, value);
           return Replace(value);
         }
         break;
@@ -45,7 +45,7 @@
         if (access == FieldAccessOf(effect->op())) {
           if (object == NodeProperties::GetValueInput(effect, 0)) {
             Node* const value = NodeProperties::GetValueInput(effect, 1);
-            NodeProperties::ReplaceWithValue(node, value);
+            ReplaceWithValue(node, value);
             return Replace(value);
           }
           // TODO(turbofan): Alias analysis to the rescue?
@@ -53,11 +53,24 @@
         }
         break;
       }
+      case IrOpcode::kBeginRegion:
       case IrOpcode::kStoreBuffer:
       case IrOpcode::kStoreElement: {
         // These can never interfere with field loads.
         break;
       }
+      case IrOpcode::kFinishRegion: {
+        // "Look through" FinishRegion nodes to make LoadElimination capable
+        // of looking into atomic regions.
+        if (object == effect) object = NodeProperties::GetValueInput(effect, 0);
+        break;
+      }
+      case IrOpcode::kAllocate: {
+        // Allocations don't interfere with field loads. In case we see the
+        // actual allocation for the {object} we can abort.
+        if (object == effect) return NoChange();
+        break;
+      }
       default: {
         if (!effect->op()->HasProperty(Operator::kNoWrite) ||
             effect->op()->EffectInputCount() != 1) {
diff --git a/src/compiler/load-elimination.h b/src/compiler/load-elimination.h
index 6917ce3..db87d9a 100644
--- a/src/compiler/load-elimination.h
+++ b/src/compiler/load-elimination.h
@@ -11,12 +11,12 @@
 namespace internal {
 namespace compiler {
 
-class LoadElimination FINAL : public Reducer {
+class LoadElimination final : public AdvancedReducer {
  public:
-  LoadElimination() {}
-  ~LoadElimination() FINAL;
+  explicit LoadElimination(Editor* editor) : AdvancedReducer(editor) {}
+  ~LoadElimination() final;
 
-  Reduction Reduce(Node* node) FINAL;
+  Reduction Reduce(Node* node) final;
 
  private:
   Reduction ReduceLoadField(Node* node);
diff --git a/src/compiler/loop-analysis.cc b/src/compiler/loop-analysis.cc
index e1b703e..d52c7c7 100644
--- a/src/compiler/loop-analysis.cc
+++ b/src/compiler/loop-analysis.cc
@@ -1,61 +1,27 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
+// 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/graph.h"
 #include "src/compiler/loop-analysis.h"
+
+#include "src/compiler/graph.h"
 #include "src/compiler/node.h"
-#include "src/compiler/node-properties-inl.h"
+#include "src/compiler/node-marker.h"
+#include "src/compiler/node-properties.h"
 #include "src/zone.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
-typedef uint32_t LoopMarks;
-
-
-// TODO(titzer): don't assume entry edges have a particular index.
-// TODO(titzer): use a BitMatrix to generalize this algorithm.
-static const size_t kMaxLoops = 31;
-static const int kAssumedLoopEntryIndex = 0;  // assume loops are entered here.
-static const LoopMarks kVisited = 1;          // loop #0 is reserved.
-
+#define OFFSET(x) ((x)&0x1f)
+#define BIT(x) (1u << OFFSET(x))
+#define INDEX(x) ((x) >> 5)
 
 // Temporary information for each node during marking.
 struct NodeInfo {
   Node* node;
   NodeInfo* next;       // link in chaining loop members
-  LoopMarks forward;    // accumulated marks in the forward direction
-  LoopMarks backward;   // accumulated marks in the backward direction
-  LoopMarks loop_mark;  // loop mark for header nodes; encodes loop_num
-
-  bool MarkBackward(LoopMarks bw) {
-    LoopMarks prev = backward;
-    LoopMarks next = backward | bw;
-    backward = next;
-    return prev != next;
-  }
-
-  bool MarkForward(LoopMarks fw) {
-    LoopMarks prev = forward;
-    LoopMarks next = forward | fw;
-    forward = next;
-    return prev != next;
-  }
-
-  bool IsInLoop(size_t loop_num) {
-    DCHECK(loop_num > 0 && loop_num <= 31);
-    return forward & backward & (1 << loop_num);
-  }
-
-  bool IsLoopHeader() { return loop_mark != 0; }
-  bool IsInAnyLoop() { return (forward & backward) > kVisited; }
-
-  bool IsInHeaderForLoop(size_t loop_num) {
-    DCHECK(loop_num > 0);
-    return loop_mark == (kVisited | (1 << loop_num));
-  }
 };
 
 
@@ -68,9 +34,6 @@
 };
 
 
-static const NodeInfo kEmptyNodeInfo = {nullptr, nullptr, 0, 0, 0};
-
-
 // Encapsulation of the loop finding algorithm.
 // -----------------------------------------------------------------------------
 // Conceptually, the contents of a loop are those nodes that are "between" the
@@ -88,13 +51,18 @@
 class LoopFinderImpl {
  public:
   LoopFinderImpl(Graph* graph, LoopTree* loop_tree, Zone* zone)
-      : end_(graph->end()),
+      : zone_(zone),
+        end_(graph->end()),
         queue_(zone),
         queued_(graph, 2),
-        info_(graph->NodeCount(), kEmptyNodeInfo, zone),
+        info_(graph->NodeCount(), {nullptr, nullptr}, zone),
         loops_(zone),
+        loop_num_(graph->NodeCount(), -1, zone),
         loop_tree_(loop_tree),
-        loops_found_(0) {}
+        loops_found_(0),
+        width_(0),
+        backward_(nullptr),
+        forward_(nullptr) {}
 
   void Run() {
     PropagateBackward();
@@ -106,12 +74,15 @@
     // Print out the results.
     for (NodeInfo& ni : info_) {
       if (ni.node == nullptr) continue;
-      for (size_t i = 1; i <= loops_.size(); i++) {
-        if (ni.IsInLoop(i)) {
+      for (int i = 1; i <= loops_found_; i++) {
+        int index = ni.node->id() * width_ + INDEX(i);
+        bool marked_forward = forward_[index] & BIT(i);
+        bool marked_backward = backward_[index] & BIT(i);
+        if (marked_forward && marked_backward) {
           PrintF("X");
-        } else if (ni.forward & (1 << i)) {
+        } else if (marked_forward) {
           PrintF("/");
-        } else if (ni.backward & (1 << i)) {
+        } else if (marked_backward) {
           PrintF("\\");
         } else {
           PrintF(" ");
@@ -132,157 +103,246 @@
   }
 
  private:
+  Zone* zone_;
   Node* end_;
   NodeDeque queue_;
   NodeMarker<bool> queued_;
   ZoneVector<NodeInfo> info_;
   ZoneVector<LoopInfo> loops_;
+  ZoneVector<int> loop_num_;
   LoopTree* loop_tree_;
-  size_t loops_found_;
+  int loops_found_;
+  int width_;
+  uint32_t* backward_;
+  uint32_t* forward_;
+
+  int num_nodes() {
+    return static_cast<int>(loop_tree_->node_to_loop_num_.size());
+  }
+
+  // Tb = Tb | (Fb - loop_filter)
+  bool PropagateBackwardMarks(Node* from, Node* to, int loop_filter) {
+    if (from == to) return false;
+    uint32_t* fp = &backward_[from->id() * width_];
+    uint32_t* tp = &backward_[to->id() * width_];
+    bool change = false;
+    for (int i = 0; i < width_; i++) {
+      uint32_t mask = i == INDEX(loop_filter) ? ~BIT(loop_filter) : 0xFFFFFFFF;
+      uint32_t prev = tp[i];
+      uint32_t next = prev | (fp[i] & mask);
+      tp[i] = next;
+      if (!change && (prev != next)) change = true;
+    }
+    return change;
+  }
+
+  // Tb = Tb | B
+  bool SetBackwardMark(Node* to, int loop_num) {
+    uint32_t* tp = &backward_[to->id() * width_ + INDEX(loop_num)];
+    uint32_t prev = tp[0];
+    uint32_t next = prev | BIT(loop_num);
+    tp[0] = next;
+    return next != prev;
+  }
+
+  // Tf = Tf | B
+  bool SetForwardMark(Node* to, int loop_num) {
+    uint32_t* tp = &forward_[to->id() * width_ + INDEX(loop_num)];
+    uint32_t prev = tp[0];
+    uint32_t next = prev | BIT(loop_num);
+    tp[0] = next;
+    return next != prev;
+  }
+
+  // Tf = Tf | (Ff & Tb)
+  bool PropagateForwardMarks(Node* from, Node* to) {
+    if (from == to) return false;
+    bool change = false;
+    int findex = from->id() * width_;
+    int tindex = to->id() * width_;
+    for (int i = 0; i < width_; i++) {
+      uint32_t marks = backward_[tindex + i] & forward_[findex + i];
+      uint32_t prev = forward_[tindex + i];
+      uint32_t next = prev | marks;
+      forward_[tindex + i] = next;
+      if (!change && (prev != next)) change = true;
+    }
+    return change;
+  }
+
+  bool IsInLoop(Node* node, int loop_num) {
+    int offset = node->id() * width_ + INDEX(loop_num);
+    return backward_[offset] & forward_[offset] & BIT(loop_num);
+  }
 
   // Propagate marks backward from loop headers.
   void PropagateBackward() {
-    PropagateBackward(end_, kVisited);
+    ResizeBackwardMarks();
+    SetBackwardMark(end_, 0);
+    Queue(end_);
 
     while (!queue_.empty()) {
       Node* node = queue_.front();
+      info(node);
       queue_.pop_front();
       queued_.Set(node, false);
 
+      int loop_num = -1;
       // Setup loop headers first.
       if (node->opcode() == IrOpcode::kLoop) {
         // found the loop node first.
-        CreateLoopInfo(node);
-      } else if (node->opcode() == IrOpcode::kPhi ||
-                 node->opcode() == IrOpcode::kEffectPhi) {
+        loop_num = CreateLoopInfo(node);
+      } else if (NodeProperties::IsPhi(node)) {
         // found a phi first.
         Node* merge = node->InputAt(node->InputCount() - 1);
-        if (merge->opcode() == IrOpcode::kLoop) CreateLoopInfo(merge);
+        if (merge->opcode() == IrOpcode::kLoop) {
+          loop_num = CreateLoopInfo(merge);
+        }
       }
 
-      // Propagate reachability marks backwards from this node.
-      NodeInfo& ni = info(node);
-      if (ni.IsLoopHeader()) {
-        // Handle edges from loop header nodes specially.
-        for (int i = 0; i < node->InputCount(); i++) {
-          if (i == kAssumedLoopEntryIndex) {
-            // Don't propagate the loop mark backwards on the entry edge.
-            PropagateBackward(node->InputAt(0),
-                              kVisited | (ni.backward & ~ni.loop_mark));
-          } else {
-            // Only propagate the loop mark on backedges.
-            PropagateBackward(node->InputAt(i), ni.loop_mark);
-          }
-        }
-      } else {
-        // Propagate all loop marks backwards for a normal node.
-        for (Node* const input : node->inputs()) {
-          PropagateBackward(input, ni.backward);
+      // Propagate marks backwards from this node.
+      for (int i = 0; i < node->InputCount(); i++) {
+        Node* input = node->InputAt(i);
+        if (loop_num > 0 && i != kAssumedLoopEntryIndex) {
+          // Only propagate the loop mark on backedges.
+          if (SetBackwardMark(input, loop_num)) Queue(input);
+        } else {
+          // Entry or normal edge. Propagate all marks except loop_num.
+          if (PropagateBackwardMarks(node, input, loop_num)) Queue(input);
         }
       }
     }
   }
 
-  // Make a new loop header for the given node.
-  void CreateLoopInfo(Node* node) {
-    NodeInfo& ni = info(node);
-    if (ni.IsLoopHeader()) return;  // loop already set up.
+  // Make a new loop if necessary for the given node.
+  int CreateLoopInfo(Node* node) {
+    int loop_num = LoopNum(node);
+    if (loop_num > 0) return loop_num;
 
-    loops_found_++;
-    size_t loop_num = loops_.size() + 1;
-    CHECK(loops_found_ <= kMaxLoops);  // TODO(titzer): don't crash.
+    loop_num = ++loops_found_;
+    if (INDEX(loop_num) >= width_) ResizeBackwardMarks();
+
     // Create a new loop.
     loops_.push_back({node, nullptr, nullptr, nullptr});
     loop_tree_->NewLoop();
-    LoopMarks loop_mark = kVisited | (1 << loop_num);
-    ni.node = node;
-    ni.loop_mark = loop_mark;
+    SetBackwardMark(node, loop_num);
+    loop_tree_->node_to_loop_num_[node->id()] = loop_num;
 
     // Setup loop mark for phis attached to loop header.
     for (Node* use : node->uses()) {
-      if (use->opcode() == IrOpcode::kPhi ||
-          use->opcode() == IrOpcode::kEffectPhi) {
-        info(use).loop_mark = loop_mark;
+      if (NodeProperties::IsPhi(use)) {
+        info(use);  // create the NodeInfo
+        SetBackwardMark(use, loop_num);
+        loop_tree_->node_to_loop_num_[use->id()] = loop_num;
       }
     }
+
+    return loop_num;
+  }
+
+  void ResizeBackwardMarks() {
+    int new_width = width_ + 1;
+    int max = num_nodes();
+    uint32_t* new_backward = zone_->NewArray<uint32_t>(new_width * max);
+    memset(new_backward, 0, new_width * max * sizeof(uint32_t));
+    if (width_ > 0) {  // copy old matrix data.
+      for (int i = 0; i < max; i++) {
+        uint32_t* np = &new_backward[i * new_width];
+        uint32_t* op = &backward_[i * width_];
+        for (int j = 0; j < width_; j++) np[j] = op[j];
+      }
+    }
+    width_ = new_width;
+    backward_ = new_backward;
+  }
+
+  void ResizeForwardMarks() {
+    int max = num_nodes();
+    forward_ = zone_->NewArray<uint32_t>(width_ * max);
+    memset(forward_, 0, width_ * max * sizeof(uint32_t));
   }
 
   // Propagate marks forward from loops.
   void PropagateForward() {
+    ResizeForwardMarks();
     for (LoopInfo& li : loops_) {
-      queued_.Set(li.header, true);
-      queue_.push_back(li.header);
-      NodeInfo& ni = info(li.header);
-      ni.forward = ni.loop_mark;
+      SetForwardMark(li.header, LoopNum(li.header));
+      Queue(li.header);
     }
     // Propagate forward on paths that were backward reachable from backedges.
     while (!queue_.empty()) {
       Node* node = queue_.front();
       queue_.pop_front();
       queued_.Set(node, false);
-      NodeInfo& ni = info(node);
       for (Edge edge : node->use_edges()) {
         Node* use = edge.from();
-        NodeInfo& ui = info(use);
-        if (IsBackedge(use, ui, edge)) continue;  // skip backedges.
-        LoopMarks both = ni.forward & ui.backward;
-        if (ui.MarkForward(both) && !queued_.Get(use)) {
-          queued_.Set(use, true);
-          queue_.push_back(use);
+        if (!IsBackedge(use, edge)) {
+          if (PropagateForwardMarks(node, use)) Queue(use);
         }
       }
     }
   }
 
-  bool IsBackedge(Node* use, NodeInfo& ui, Edge& edge) {
-    // TODO(titzer): checking for backedges here is ugly.
-    if (!ui.IsLoopHeader()) return false;
+  bool IsBackedge(Node* use, Edge& edge) {
+    if (LoopNum(use) <= 0) return false;
     if (edge.index() == kAssumedLoopEntryIndex) return false;
-    if (use->opcode() == IrOpcode::kPhi ||
-        use->opcode() == IrOpcode::kEffectPhi) {
+    if (NodeProperties::IsPhi(use)) {
       return !NodeProperties::IsControlEdge(edge);
     }
     return true;
   }
 
+  int LoopNum(Node* node) { return loop_tree_->node_to_loop_num_[node->id()]; }
+
   NodeInfo& info(Node* node) {
     NodeInfo& i = info_[node->id()];
     if (i.node == nullptr) i.node = node;
     return i;
   }
 
-  void PropagateBackward(Node* node, LoopMarks marks) {
-    if (info(node).MarkBackward(marks) && !queued_.Get(node)) {
+  void Queue(Node* node) {
+    if (!queued_.Get(node)) {
       queue_.push_back(node);
       queued_.Set(node, true);
     }
   }
 
   void FinishLoopTree() {
-    // Degenerate cases.
-    if (loops_.size() == 0) return;
-    if (loops_.size() == 1) return FinishSingleLoop();
+    DCHECK(loops_found_ == static_cast<int>(loops_.size()));
+    DCHECK(loops_found_ == static_cast<int>(loop_tree_->all_loops_.size()));
 
-    for (size_t i = 1; i <= loops_.size(); i++) ConnectLoopTree(i);
+    // Degenerate cases.
+    if (loops_found_ == 0) return;
+    if (loops_found_ == 1) return FinishSingleLoop();
+
+    for (int i = 1; i <= loops_found_; i++) ConnectLoopTree(i);
 
     size_t count = 0;
     // Place the node into the innermost nested loop of which it is a member.
     for (NodeInfo& ni : info_) {
-      if (ni.node == nullptr || !ni.IsInAnyLoop()) continue;
+      if (ni.node == nullptr) continue;
 
       LoopInfo* innermost = nullptr;
-      size_t index = 0;
-      for (size_t i = 1; i <= loops_.size(); i++) {
-        if (ni.IsInLoop(i)) {
-          LoopInfo* loop = &loops_[i - 1];
-          if (innermost == nullptr ||
-              loop->loop->depth_ > innermost->loop->depth_) {
-            innermost = loop;
-            index = i;
+      int innermost_index = 0;
+      int pos = ni.node->id() * width_;
+      // Search the marks word by word.
+      for (int i = 0; i < width_; i++) {
+        uint32_t marks = backward_[pos + i] & forward_[pos + i];
+        for (int j = 0; j < 32; j++) {
+          if (marks & (1u << j)) {
+            int loop_num = i * 32 + j;
+            if (loop_num == 0) continue;
+            LoopInfo* loop = &loops_[loop_num - 1];
+            if (innermost == nullptr ||
+                loop->loop->depth_ > innermost->loop->depth_) {
+              innermost = loop;
+              innermost_index = loop_num;
+            }
           }
         }
       }
-      if (ni.IsInHeaderForLoop(index)) {
+      if (innermost == nullptr) continue;
+      if (LoopNum(ni.node) == innermost_index) {
         ni.next = innermost->header_list;
         innermost->header_list = &ni;
       } else {
@@ -301,18 +361,14 @@
 
   // Handle the simpler case of a single loop (no checks for nesting necessary).
   void FinishSingleLoop() {
-    DCHECK(loops_.size() == 1);
-    DCHECK(loop_tree_->all_loops_.size() == 1);
-
     // Place nodes into the loop header and body.
     LoopInfo* li = &loops_[0];
     li->loop = &loop_tree_->all_loops_[0];
     loop_tree_->SetParent(nullptr, li->loop);
     size_t count = 0;
     for (NodeInfo& ni : info_) {
-      if (ni.node == nullptr || !ni.IsInAnyLoop()) continue;
-      DCHECK(ni.IsInLoop(1));
-      if (ni.IsInHeaderForLoop(1)) {
+      if (ni.node == nullptr || !IsInLoop(ni.node, 1)) continue;
+      if (LoopNum(ni.node) == 1) {
         ni.next = li->header_list;
         li->header_list = &ni;
       } else {
@@ -330,25 +386,21 @@
   // Recursively serialize the list of header nodes and body nodes
   // so that nested loops occupy nested intervals.
   void SerializeLoop(LoopTree::Loop* loop) {
-    size_t loop_num = loop_tree_->LoopNum(loop);
+    int loop_num = loop_tree_->LoopNum(loop);
     LoopInfo& li = loops_[loop_num - 1];
 
     // Serialize the header.
     loop->header_start_ = static_cast<int>(loop_tree_->loop_nodes_.size());
     for (NodeInfo* ni = li.header_list; ni != nullptr; ni = ni->next) {
       loop_tree_->loop_nodes_.push_back(ni->node);
-      // TODO(titzer): lift loop count restriction.
-      loop_tree_->node_to_loop_num_[ni->node->id()] =
-          static_cast<uint8_t>(loop_num);
+      loop_tree_->node_to_loop_num_[ni->node->id()] = loop_num;
     }
 
     // Serialize the body.
     loop->body_start_ = static_cast<int>(loop_tree_->loop_nodes_.size());
     for (NodeInfo* ni = li.body_list; ni != nullptr; ni = ni->next) {
       loop_tree_->loop_nodes_.push_back(ni->node);
-      // TODO(titzer): lift loop count restriction.
-      loop_tree_->node_to_loop_num_[ni->node->id()] =
-          static_cast<uint8_t>(loop_num);
+      loop_tree_->node_to_loop_num_[ni->node->id()] = loop_num;
     }
 
     // Serialize nested loops.
@@ -358,15 +410,15 @@
   }
 
   // Connect the LoopTree loops to their parents recursively.
-  LoopTree::Loop* ConnectLoopTree(size_t loop_num) {
+  LoopTree::Loop* ConnectLoopTree(int loop_num) {
     LoopInfo& li = loops_[loop_num - 1];
     if (li.loop != nullptr) return li.loop;
 
     NodeInfo& ni = info(li.header);
     LoopTree::Loop* parent = nullptr;
-    for (size_t i = 1; i <= loops_.size(); i++) {
+    for (int i = 1; i <= loops_found_; i++) {
       if (i == loop_num) continue;
-      if (ni.IsInLoop(i)) {
+      if (IsInLoop(ni.node, i)) {
         // recursively create potential parent loops first.
         LoopTree::Loop* upper = ConnectLoopTree(i);
         if (parent == nullptr || upper->depth_ > parent->depth_) {
@@ -406,6 +458,16 @@
   return loop_tree;
 }
 
+
+Node* LoopTree::HeaderNode(Loop* loop) {
+  Node* first = *HeaderNodes(loop).begin();
+  if (first->opcode() == IrOpcode::kLoop) return first;
+  DCHECK(IrOpcode::IsPhiOpcode(first->opcode()));
+  Node* header = NodeProperties::GetControlInput(first);
+  DCHECK_EQ(IrOpcode::kLoop, header->opcode());
+  return header;
+}
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/src/compiler/loop-analysis.h b/src/compiler/loop-analysis.h
index 8c8d19a..2ed5bc2 100644
--- a/src/compiler/loop-analysis.h
+++ b/src/compiler/loop-analysis.h
@@ -14,6 +14,9 @@
 namespace internal {
 namespace compiler {
 
+// TODO(titzer): don't assume entry edges have a particular index.
+static const int kAssumedLoopEntryIndex = 0;  // assume loops are entered here.
+
 class LoopFinderImpl;
 
 typedef base::iterator_range<Node**> NodeRange;
@@ -25,7 +28,7 @@
       : zone_(zone),
         outer_loops_(zone),
         all_loops_(zone),
-        node_to_loop_num_(static_cast<int>(num_nodes), 0, zone),
+        node_to_loop_num_(static_cast<int>(num_nodes), -1, zone),
         loop_nodes_(zone) {}
 
   // Represents a loop in the tree of loops, including the header nodes,
@@ -37,6 +40,7 @@
     size_t HeaderSize() const { return body_start_ - header_start_; }
     size_t BodySize() const { return body_end_ - body_start_; }
     size_t TotalSize() const { return body_end_ - header_start_; }
+    size_t depth() const { return static_cast<size_t>(depth_); }
 
    private:
     friend class LoopTree;
@@ -59,9 +63,8 @@
 
   // Return the innermost nested loop, if any, that contains {node}.
   Loop* ContainingLoop(Node* node) {
-    if (node->id() >= static_cast<int>(node_to_loop_num_.size()))
-      return nullptr;
-    uint8_t num = node_to_loop_num_[node->id()];
+    if (node->id() >= node_to_loop_num_.size()) return nullptr;
+    int num = node_to_loop_num_[node->id()];
     return num > 0 ? &all_loops_[num - 1] : nullptr;
   }
 
@@ -88,12 +91,31 @@
                      &loop_nodes_[0] + loop->body_start_);
   }
 
+  // Return the header control node for a loop.
+  Node* HeaderNode(Loop* loop);
+
   // Return a range which can iterate over the body nodes of {loop}.
   NodeRange BodyNodes(Loop* loop) {
     return NodeRange(&loop_nodes_[0] + loop->body_start_,
                      &loop_nodes_[0] + loop->body_end_);
   }
 
+  // Return a range which can iterate over the nodes of {loop}.
+  NodeRange LoopNodes(Loop* loop) {
+    return NodeRange(&loop_nodes_[0] + loop->header_start_,
+                     &loop_nodes_[0] + loop->body_end_);
+  }
+
+  // Return the node that represents the control, i.e. the loop node itself.
+  Node* GetLoopControl(Loop* loop) {
+    // TODO(turbofan): make the loop control node always first?
+    for (Node* node : HeaderNodes(loop)) {
+      if (node->opcode() == IrOpcode::kLoop) return node;
+    }
+    UNREACHABLE();
+    return nullptr;
+  }
+
  private:
   friend class LoopFinderImpl;
 
@@ -116,18 +138,17 @@
   Zone* zone_;
   ZoneVector<Loop*> outer_loops_;
   ZoneVector<Loop> all_loops_;
-  // TODO(titzer): lift loop count restriction.
-  ZoneVector<uint8_t> node_to_loop_num_;
+  ZoneVector<int> node_to_loop_num_;
   ZoneVector<Node*> loop_nodes_;
 };
 
-
 class LoopFinder {
  public:
   // Build a loop tree for the entire graph.
   static LoopTree* BuildLoopTree(Graph* graph, Zone* temp_zone);
 };
 
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/src/compiler/loop-peeling.cc b/src/compiler/loop-peeling.cc
new file mode 100644
index 0000000..b553a9f
--- /dev/null
+++ b/src/compiler/loop-peeling.cc
@@ -0,0 +1,334 @@
+// Copyright 2015 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/common-operator.h"
+#include "src/compiler/graph.h"
+#include "src/compiler/loop-peeling.h"
+#include "src/compiler/node.h"
+#include "src/compiler/node-marker.h"
+#include "src/compiler/node-properties.h"
+#include "src/zone.h"
+
+// Loop peeling is an optimization that copies the body of a loop, creating
+// a new copy of the body called the "peeled iteration" that represents the
+// first iteration. Beginning with a loop as follows:
+
+//             E
+//             |                 A
+//             |                 |                     (backedges)
+//             | +---------------|---------------------------------+
+//             | | +-------------|-------------------------------+ |
+//             | | |             | +--------+                    | |
+//             | | |             | | +----+ |                    | |
+//             | | |             | | |    | |                    | |
+//           ( Loop )<-------- ( phiA )   | |                    | |
+//              |                 |       | |                    | |
+//      ((======P=================U=======|=|=====))             | |
+//      ((                                | |     ))             | |
+//      ((        X <---------------------+ |     ))             | |
+//      ((                                  |     ))             | |
+//      ((     body                         |     ))             | |
+//      ((                                  |     ))             | |
+//      ((        Y <-----------------------+     ))             | |
+//      ((                                        ))             | |
+//      ((===K====L====M==========================))             | |
+//           |    |    |                                         | |
+//           |    |    +-----------------------------------------+ |
+//           |    +------------------------------------------------+
+//           |
+//          exit
+
+// The body of the loop is duplicated so that all nodes considered "inside"
+// the loop (e.g. {P, U, X, Y, K, L, M}) have a corresponding copies in the
+// peeled iteration (e.g. {P', U', X', Y', K', L', M'}). What were considered
+// backedges of the loop correspond to edges from the peeled iteration to
+// the main loop body, with multiple backedges requiring a merge.
+
+// Similarly, any exits from the loop body need to be merged with "exits"
+// from the peeled iteration, resulting in the graph as follows:
+
+//             E
+//             |                 A
+//             |                 |
+//      ((=====P'================U'===============))
+//      ((                                        ))
+//      ((        X'<-------------+               ))
+//      ((                        |               ))
+//      ((   peeled iteration     |               ))
+//      ((                        |               ))
+//      ((        Y'<-----------+ |               ))
+//      ((                      | |               ))
+//      ((===K'===L'====M'======|=|===============))
+//           |    |     |       | |
+//  +--------+    +-+ +-+       | |
+//  |               | |         | |
+//  |              Merge <------phi
+//  |                |           |
+//  |          +-----+           |
+//  |          |                 |                     (backedges)
+//  |          | +---------------|---------------------------------+
+//  |          | | +-------------|-------------------------------+ |
+//  |          | | |             | +--------+                    | |
+//  |          | | |             | | +----+ |                    | |
+//  |          | | |             | | |    | |                    | |
+//  |        ( Loop )<-------- ( phiA )   | |                    | |
+//  |           |                 |       | |                    | |
+//  |   ((======P=================U=======|=|=====))             | |
+//  |   ((                                | |     ))             | |
+//  |   ((        X <---------------------+ |     ))             | |
+//  |   ((                                  |     ))             | |
+//  |   ((     body                         |     ))             | |
+//  |   ((                                  |     ))             | |
+//  |   ((        Y <-----------------------+     ))             | |
+//  |   ((                                        ))             | |
+//  |   ((===K====L====M==========================))             | |
+//  |        |    |    |                                         | |
+//  |        |    |    +-----------------------------------------+ |
+//  |        |    +------------------------------------------------+
+//  |        |
+//  |        |
+//  +----+ +-+
+//       | |
+//      Merge
+//        |
+//      exit
+
+// Note that the boxes ((===)) above are not explicitly represented in the
+// graph, but are instead computed by the {LoopFinder}.
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+struct Peeling {
+  // Maps a node to its index in the {pairs} vector.
+  NodeMarker<size_t> node_map;
+  // The vector which contains the mapped nodes.
+  NodeVector* pairs;
+
+  Peeling(Graph* graph, Zone* tmp_zone, size_t max, NodeVector* p)
+      : node_map(graph, static_cast<uint32_t>(max)), pairs(p) {}
+
+  Node* map(Node* node) {
+    if (node_map.Get(node) == 0) return node;
+    return pairs->at(node_map.Get(node));
+  }
+
+  void Insert(Node* original, Node* copy) {
+    node_map.Set(original, 1 + pairs->size());
+    pairs->push_back(original);
+    pairs->push_back(copy);
+  }
+
+  void CopyNodes(Graph* graph, Zone* tmp_zone, Node* dead, NodeRange nodes) {
+    NodeVector inputs(tmp_zone);
+    // Copy all the nodes first.
+    for (Node* node : nodes) {
+      inputs.clear();
+      for (Node* input : node->inputs()) inputs.push_back(map(input));
+      Insert(node, graph->NewNode(node->op(), node->InputCount(), &inputs[0]));
+    }
+
+    // Fix remaining inputs of the copies.
+    for (Node* original : nodes) {
+      Node* copy = pairs->at(node_map.Get(original));
+      for (int i = 0; i < copy->InputCount(); i++) {
+        copy->ReplaceInput(i, map(original->InputAt(i)));
+      }
+    }
+  }
+
+  bool Marked(Node* node) { return node_map.Get(node) > 0; }
+};
+
+
+class PeeledIterationImpl : public PeeledIteration {
+ public:
+  NodeVector node_pairs_;
+  explicit PeeledIterationImpl(Zone* zone) : node_pairs_(zone) {}
+};
+
+
+Node* PeeledIteration::map(Node* node) {
+  // TODO(turbofan): we use a simple linear search, since the peeled iteration
+  // is really only used in testing.
+  PeeledIterationImpl* impl = static_cast<PeeledIterationImpl*>(this);
+  for (size_t i = 0; i < impl->node_pairs_.size(); i += 2) {
+    if (impl->node_pairs_[i] == node) return impl->node_pairs_[i + 1];
+  }
+  return node;
+}
+
+
+static void FindLoopExits(LoopTree* loop_tree, LoopTree::Loop* loop,
+                          NodeVector& exits, NodeVector& rets) {
+  // Look for returns and if projections that are outside the loop but whose
+  // control input is inside the loop.
+  for (Node* node : loop_tree->LoopNodes(loop)) {
+    for (Node* use : node->uses()) {
+      if (!loop_tree->Contains(loop, use)) {
+        if (IrOpcode::IsIfProjectionOpcode(use->opcode())) {
+          // This is a branch from inside the loop to outside the loop.
+          exits.push_back(use);
+        } else if (use->opcode() == IrOpcode::kReturn &&
+                   loop_tree->Contains(loop,
+                                       NodeProperties::GetControlInput(use))) {
+          // This is a return from inside the loop.
+          rets.push_back(use);
+        }
+      }
+    }
+  }
+}
+
+
+bool LoopPeeler::CanPeel(LoopTree* loop_tree, LoopTree::Loop* loop) {
+  Zone zone;
+  NodeVector exits(&zone);
+  NodeVector rets(&zone);
+  FindLoopExits(loop_tree, loop, exits, rets);
+  return exits.size() <= 1u;
+}
+
+
+PeeledIteration* LoopPeeler::Peel(Graph* graph, CommonOperatorBuilder* common,
+                                  LoopTree* loop_tree, LoopTree::Loop* loop,
+                                  Zone* tmp_zone) {
+  //============================================================================
+  // Find the loop exit region to determine if this loop can be peeled.
+  //============================================================================
+  NodeVector exits(tmp_zone);
+  NodeVector rets(tmp_zone);
+  FindLoopExits(loop_tree, loop, exits, rets);
+
+  if (exits.size() != 1) return nullptr;  // not peelable currently.
+
+  //============================================================================
+  // Construct the peeled iteration.
+  //============================================================================
+  PeeledIterationImpl* iter = new (tmp_zone) PeeledIterationImpl(tmp_zone);
+  size_t estimated_peeled_size =
+      5 + (loop->TotalSize() + exits.size() + rets.size()) * 2;
+  Peeling peeling(graph, tmp_zone, estimated_peeled_size, &iter->node_pairs_);
+
+  Node* dead = graph->NewNode(common->Dead());
+
+  // Map the loop header nodes to their entry values.
+  for (Node* node : loop_tree->HeaderNodes(loop)) {
+    peeling.Insert(node, node->InputAt(kAssumedLoopEntryIndex));
+  }
+
+  // Copy all the nodes of loop body for the peeled iteration.
+  peeling.CopyNodes(graph, tmp_zone, dead, loop_tree->BodyNodes(loop));
+
+  //============================================================================
+  // Replace the entry to the loop with the output of the peeled iteration.
+  //============================================================================
+  Node* loop_node = loop_tree->GetLoopControl(loop);
+  Node* new_entry;
+  int backedges = loop_node->InputCount() - 1;
+  if (backedges > 1) {
+    // Multiple backedges from original loop, therefore multiple output edges
+    // from the peeled iteration.
+    NodeVector inputs(tmp_zone);
+    for (int i = 1; i < loop_node->InputCount(); i++) {
+      inputs.push_back(peeling.map(loop_node->InputAt(i)));
+    }
+    Node* merge =
+        graph->NewNode(common->Merge(backedges), backedges, &inputs[0]);
+
+    // Merge values from the multiple output edges of the peeled iteration.
+    for (Node* node : loop_tree->HeaderNodes(loop)) {
+      if (node->opcode() == IrOpcode::kLoop) continue;  // already done.
+      inputs.clear();
+      for (int i = 0; i < backedges; i++) {
+        inputs.push_back(peeling.map(node->InputAt(1 + i)));
+      }
+      for (Node* input : inputs) {
+        if (input != inputs[0]) {  // Non-redundant phi.
+          inputs.push_back(merge);
+          const Operator* op = common->ResizeMergeOrPhi(node->op(), backedges);
+          Node* phi = graph->NewNode(op, backedges + 1, &inputs[0]);
+          node->ReplaceInput(0, phi);
+          break;
+        }
+      }
+    }
+    new_entry = merge;
+  } else {
+    // Only one backedge, simply replace the input to loop with output of
+    // peeling.
+    for (Node* node : loop_tree->HeaderNodes(loop)) {
+      node->ReplaceInput(0, peeling.map(node->InputAt(0)));
+    }
+    new_entry = peeling.map(loop_node->InputAt(1));
+  }
+  loop_node->ReplaceInput(0, new_entry);
+
+  //============================================================================
+  // Duplicate the loop exit region and add a merge.
+  //============================================================================
+
+  // Currently we are limited to peeling loops with a single exit. The exit is
+  // the postdominator of the loop (ignoring returns).
+  Node* postdom = exits[0];
+  for (Node* node : rets) exits.push_back(node);
+  for (Node* use : postdom->uses()) {
+    if (NodeProperties::IsPhi(use)) exits.push_back(use);
+  }
+
+  NodeRange exit_range(&exits[0], &exits[0] + exits.size());
+  peeling.CopyNodes(graph, tmp_zone, dead, exit_range);
+
+  Node* merge = graph->NewNode(common->Merge(2), postdom, peeling.map(postdom));
+  postdom->ReplaceUses(merge);
+  merge->ReplaceInput(0, postdom);  // input 0 overwritten by above line.
+
+  // Find and update all the edges into either the loop or exit region.
+  for (int i = 0; i < 2; i++) {
+    NodeRange range = i == 0 ? loop_tree->LoopNodes(loop) : exit_range;
+    ZoneVector<Edge> value_edges(tmp_zone);
+    ZoneVector<Edge> effect_edges(tmp_zone);
+
+    for (Node* node : range) {
+      // Gather value and effect edges from outside the region.
+      for (Edge edge : node->use_edges()) {
+        if (!peeling.Marked(edge.from())) {
+          // Edge from outside the loop into the region.
+          if (NodeProperties::IsValueEdge(edge) ||
+              NodeProperties::IsContextEdge(edge)) {
+            value_edges.push_back(edge);
+          } else if (NodeProperties::IsEffectEdge(edge)) {
+            effect_edges.push_back(edge);
+          } else {
+            // don't do anything for control edges.
+            // TODO(titzer): should update control edges to peeled?
+          }
+        }
+      }
+
+      // Update all the value and effect edges at once.
+      if (!value_edges.empty()) {
+        // TODO(titzer): machine type is wrong here.
+        Node* phi =
+            graph->NewNode(common->Phi(MachineRepresentation::kTagged, 2), node,
+                           peeling.map(node), merge);
+        for (Edge edge : value_edges) edge.UpdateTo(phi);
+        value_edges.clear();
+      }
+      if (!effect_edges.empty()) {
+        Node* effect_phi = graph->NewNode(common->EffectPhi(2), node,
+                                          peeling.map(node), merge);
+        for (Edge edge : effect_edges) edge.UpdateTo(effect_phi);
+        effect_edges.clear();
+      }
+    }
+  }
+
+  return iter;
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/loop-peeling.h b/src/compiler/loop-peeling.h
new file mode 100644
index 0000000..ea963b0
--- /dev/null
+++ b/src/compiler/loop-peeling.h
@@ -0,0 +1,43 @@
+// Copyright 2015 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.
+
+#ifndef V8_COMPILER_LOOP_PEELING_H_
+#define V8_COMPILER_LOOP_PEELING_H_
+
+#include "src/compiler/loop-analysis.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+// Represents the output of peeling a loop, which is basically the mapping
+// from the body of the loop to the corresponding nodes in the peeled
+// iteration.
+class PeeledIteration : public ZoneObject {
+ public:
+  // Maps {node} to its corresponding copy in the peeled iteration, if
+  // the node was part of the body of the loop. Returns {node} otherwise.
+  Node* map(Node* node);
+
+ protected:
+  PeeledIteration() {}
+};
+
+class CommonOperatorBuilder;
+
+// Implements loop peeling.
+class LoopPeeler {
+ public:
+  static bool CanPeel(LoopTree* loop_tree, LoopTree::Loop* loop);
+  static PeeledIteration* Peel(Graph* graph, CommonOperatorBuilder* common,
+                               LoopTree* loop_tree, LoopTree::Loop* loop,
+                               Zone* tmp_zone);
+};
+
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_LOOP_PEELING_H_
diff --git a/src/compiler/machine-operator-reducer.cc b/src/compiler/machine-operator-reducer.cc
index c3e45a1..19ea062 100644
--- a/src/compiler/machine-operator-reducer.cc
+++ b/src/compiler/machine-operator-reducer.cc
@@ -75,7 +75,9 @@
 
 
 Node* MachineOperatorReducer::Int32Sub(Node* lhs, Node* rhs) {
-  return graph()->NewNode(machine()->Int32Sub(), lhs, rhs);
+  Node* const node = graph()->NewNode(machine()->Int32Sub(), lhs, rhs);
+  Reduction const reduction = ReduceInt32Sub(node);
+  return reduction.Changed() ? reduction.replacement() : node;
 }
 
 
@@ -101,13 +103,19 @@
 
 
 Node* MachineOperatorReducer::Uint32Div(Node* dividend, uint32_t divisor) {
-  DCHECK_LT(0, divisor);
+  DCHECK_LT(0u, divisor);
+  // If the divisor is even, we can avoid using the expensive fixup by shifting
+  // the dividend upfront.
+  unsigned const shift = base::bits::CountTrailingZeros32(divisor);
+  dividend = Word32Shr(dividend, shift);
+  divisor >>= shift;
+  // Compute the magic number for the (shifted) divisor.
   base::MagicNumbersForDivision<uint32_t> const mag =
-      base::UnsignedDivisionByConstant(bit_cast<uint32_t>(divisor));
+      base::UnsignedDivisionByConstant(divisor, shift);
   Node* quotient = graph()->NewNode(machine()->Uint32MulHigh(), dividend,
                                     Uint32Constant(mag.multiplier));
   if (mag.add) {
-    DCHECK_LE(1, mag.shift);
+    DCHECK_LE(1u, mag.shift);
     quotient = Word32Shr(
         Int32Add(Word32Shr(Int32Sub(dividend, quotient), 1), quotient),
         mag.shift - 1);
@@ -122,7 +130,7 @@
 Reduction MachineOperatorReducer::Reduce(Node* node) {
   switch (node->opcode()) {
     case IrOpcode::kProjection:
-      return ReduceProjection(OpParameter<size_t>(node), node->InputAt(0));
+      return ReduceProjection(ProjectionIndexOf(node->op()), node->InputAt(0));
     case IrOpcode::kWord32And:
       return ReduceWord32And(node);
     case IrOpcode::kWord32Or:
@@ -152,29 +160,8 @@
       }
       return ReduceWord32Shifts(node);
     }
-    case IrOpcode::kWord32Sar: {
-      Int32BinopMatcher m(node);
-      if (m.right().Is(0)) return Replace(m.left().node());  // x >> 0 => x
-      if (m.IsFoldable()) {                                  // K >> K => K
-        return ReplaceInt32(m.left().Value() >> m.right().Value());
-      }
-      if (m.left().IsWord32Shl()) {
-        Int32BinopMatcher mleft(m.left().node());
-        if (mleft.left().IsLoad()) {
-          LoadRepresentation const rep =
-              OpParameter<LoadRepresentation>(mleft.left().node());
-          if (m.right().Is(24) && mleft.right().Is(24) && rep == kMachInt8) {
-            // Load[kMachInt8] << 24 >> 24 => Load[kMachInt8]
-            return Replace(mleft.left().node());
-          }
-          if (m.right().Is(16) && mleft.right().Is(16) && rep == kMachInt16) {
-            // Load[kMachInt16] << 16 >> 16 => Load[kMachInt8]
-            return Replace(mleft.left().node());
-          }
-        }
-      }
-      return ReduceWord32Shifts(node);
-    }
+    case IrOpcode::kWord32Sar:
+      return ReduceWord32Sar(node);
     case IrOpcode::kWord32Ror: {
       Int32BinopMatcher m(node);
       if (m.right().Is(0)) return Replace(m.left().node());  // x ror 0 => x
@@ -216,16 +203,8 @@
     }
     case IrOpcode::kInt32Add:
       return ReduceInt32Add(node);
-    case IrOpcode::kInt32Sub: {
-      Int32BinopMatcher m(node);
-      if (m.right().Is(0)) return Replace(m.left().node());  // x - 0 => x
-      if (m.IsFoldable()) {                                  // K - K => K
-        return ReplaceInt32(static_cast<uint32_t>(m.left().Value()) -
-                            static_cast<uint32_t>(m.right().Value()));
-      }
-      if (m.LeftEqualsRight()) return ReplaceInt32(0);  // x - x => 0
-      break;
-    }
+    case IrOpcode::kInt32Sub:
+      return ReduceInt32Sub(node);
     case IrOpcode::kInt32Mul: {
       Int32BinopMatcher m(node);
       if (m.right().Is(0)) return Replace(m.right().node());  // x * 0 => 0
@@ -234,14 +213,14 @@
         return ReplaceInt32(m.left().Value() * m.right().Value());
       }
       if (m.right().Is(-1)) {  // x * -1 => 0 - x
-        node->set_op(machine()->Int32Sub());
         node->ReplaceInput(0, Int32Constant(0));
         node->ReplaceInput(1, m.left().node());
+        NodeProperties::ChangeOp(node, machine()->Int32Sub());
         return Changed(node);
       }
       if (m.right().IsPowerOf2()) {  // x * 2^n => x << n
-        node->set_op(machine()->Word32Shl());
         node->ReplaceInput(1, Int32Constant(WhichPowerOf2(m.right().Value())));
+        NodeProperties::ChangeOp(node, machine()->Word32Shl());
         Reduction reduction = ReduceWord32Shl(node);
         return reduction.Changed() ? reduction : Changed(node);
       }
@@ -359,9 +338,9 @@
     case IrOpcode::kFloat64Mul: {
       Float64BinopMatcher m(node);
       if (m.right().Is(-1)) {  // x * -1.0 => -0.0 - x
-        node->set_op(machine()->Float64Sub());
         node->ReplaceInput(0, Float64Constant(-0.0));
         node->ReplaceInput(1, m.left().node());
+        NodeProperties::ChangeOp(node, machine()->Float64Sub());
         return Changed(node);
       }
       if (m.right().Is(1)) return Replace(m.left().node());  // x * 1.0 => x
@@ -390,7 +369,7 @@
     case IrOpcode::kFloat64Mod: {
       Float64BinopMatcher m(node);
       if (m.right().Is(0)) {  // x % 0 => NaN
-        return ReplaceFloat64(base::OS::nan_value());
+        return ReplaceFloat64(std::numeric_limits<double>::quiet_NaN());
       }
       if (m.right().IsNaN()) {  // x % NaN => NaN
         return Replace(m.right().node());
@@ -454,8 +433,16 @@
       if (m.IsChangeFloat32ToFloat64()) return Replace(m.node()->InputAt(0));
       break;
     }
+    case IrOpcode::kFloat64InsertLowWord32:
+      return ReduceFloat64InsertLowWord32(node);
+    case IrOpcode::kFloat64InsertHighWord32:
+      return ReduceFloat64InsertHighWord32(node);
     case IrOpcode::kStore:
       return ReduceStore(node);
+    case IrOpcode::kFloat64Equal:
+    case IrOpcode::kFloat64LessThan:
+    case IrOpcode::kFloat64LessThanOrEqual:
+      return ReduceFloat64Compare(node);
     default:
       break;
   }
@@ -471,6 +458,44 @@
     return ReplaceUint32(bit_cast<uint32_t>(m.left().Value()) +
                          bit_cast<uint32_t>(m.right().Value()));
   }
+  if (m.left().IsInt32Sub()) {
+    Int32BinopMatcher mleft(m.left().node());
+    if (mleft.left().Is(0)) {  // (0 - x) + y => y - x
+      node->ReplaceInput(0, m.right().node());
+      node->ReplaceInput(1, mleft.right().node());
+      NodeProperties::ChangeOp(node, machine()->Int32Sub());
+      Reduction const reduction = ReduceInt32Sub(node);
+      return reduction.Changed() ? reduction : Changed(node);
+    }
+  }
+  if (m.right().IsInt32Sub()) {
+    Int32BinopMatcher mright(m.right().node());
+    if (mright.left().Is(0)) {  // y + (0 - x) => y - x
+      node->ReplaceInput(1, mright.right().node());
+      NodeProperties::ChangeOp(node, machine()->Int32Sub());
+      Reduction const reduction = ReduceInt32Sub(node);
+      return reduction.Changed() ? reduction : Changed(node);
+    }
+  }
+  return NoChange();
+}
+
+
+Reduction MachineOperatorReducer::ReduceInt32Sub(Node* node) {
+  DCHECK_EQ(IrOpcode::kInt32Sub, node->opcode());
+  Int32BinopMatcher m(node);
+  if (m.right().Is(0)) return Replace(m.left().node());  // x - 0 => x
+  if (m.IsFoldable()) {                                  // K - K => K
+    return ReplaceInt32(static_cast<uint32_t>(m.left().Value()) -
+                        static_cast<uint32_t>(m.right().Value()));
+  }
+  if (m.LeftEqualsRight()) return ReplaceInt32(0);  // x - x => 0
+  if (m.right().HasValue()) {                       // x - K => x + -K
+    node->ReplaceInput(1, Int32Constant(-m.right().Value()));
+    NodeProperties::ChangeOp(node, machine()->Int32Add());
+    Reduction const reduction = ReduceInt32Add(node);
+    return reduction.Changed() ? reduction : Changed(node);
+  }
   return NoChange();
 }
 
@@ -489,10 +514,10 @@
     return Replace(Word32Equal(Word32Equal(m.left().node(), zero), zero));
   }
   if (m.right().Is(-1)) {  // x / -1 => 0 - x
-    node->set_op(machine()->Int32Sub());
     node->ReplaceInput(0, Int32Constant(0));
     node->ReplaceInput(1, m.left().node());
     node->TrimInputCount(2);
+    NodeProperties::ChangeOp(node, machine()->Int32Sub());
     return Changed(node);
   }
   if (m.right().HasValue()) {
@@ -501,7 +526,7 @@
     Node* quotient = dividend;
     if (base::bits::IsPowerOfTwo32(Abs(divisor))) {
       uint32_t const shift = WhichPowerOf2Abs(divisor);
-      DCHECK_NE(0, shift);
+      DCHECK_NE(0u, shift);
       if (shift > 1) {
         quotient = Word32Sar(quotient, 31);
       }
@@ -511,10 +536,10 @@
       quotient = Int32Div(quotient, Abs(divisor));
     }
     if (divisor < 0) {
-      node->set_op(machine()->Int32Sub());
       node->ReplaceInput(0, Int32Constant(0));
       node->ReplaceInput(1, quotient);
       node->TrimInputCount(2);
+      NodeProperties::ChangeOp(node, machine()->Int32Sub());
       return Changed(node);
     }
     return Replace(quotient);
@@ -540,9 +565,9 @@
     Node* const dividend = m.left().node();
     uint32_t const divisor = m.right().Value();
     if (base::bits::IsPowerOfTwo32(divisor)) {  // x / 2^n => x >> n
-      node->set_op(machine()->Word32Shr());
       node->ReplaceInput(1, Uint32Constant(WhichPowerOf2(m.right().Value())));
       node->TrimInputCount(2);
+      NodeProperties::ChangeOp(node, machine()->Word32Shr());
       return Changed(node);
     } else {
       return Replace(Uint32Div(dividend, divisor));
@@ -569,18 +594,20 @@
     if (base::bits::IsPowerOfTwo32(divisor)) {
       uint32_t const mask = divisor - 1;
       Node* const zero = Int32Constant(0);
-      node->set_op(common()->Select(kMachInt32, BranchHint::kFalse));
       node->ReplaceInput(
           0, graph()->NewNode(machine()->Int32LessThan(), dividend, zero));
       node->ReplaceInput(
           1, Int32Sub(zero, Word32And(Int32Sub(zero, dividend), mask)));
       node->ReplaceInput(2, Word32And(dividend, mask));
+      NodeProperties::ChangeOp(
+          node,
+          common()->Select(MachineRepresentation::kWord32, BranchHint::kFalse));
     } else {
       Node* quotient = Int32Div(dividend, divisor);
-      node->set_op(machine()->Int32Sub());
       DCHECK_EQ(dividend, node->InputAt(0));
       node->ReplaceInput(1, Int32Mul(quotient, Int32Constant(divisor)));
       node->TrimInputCount(2);
+      NodeProperties::ChangeOp(node, machine()->Int32Sub());
     }
     return Changed(node);
   }
@@ -602,15 +629,16 @@
     Node* const dividend = m.left().node();
     uint32_t const divisor = m.right().Value();
     if (base::bits::IsPowerOfTwo32(divisor)) {  // x % 2^n => x & 2^n-1
-      node->set_op(machine()->Word32And());
       node->ReplaceInput(1, Uint32Constant(m.right().Value() - 1));
+      node->TrimInputCount(2);
+      NodeProperties::ChangeOp(node, machine()->Word32And());
     } else {
       Node* quotient = Uint32Div(dividend, divisor);
-      node->set_op(machine()->Int32Sub());
       DCHECK_EQ(dividend, node->InputAt(0));
       node->ReplaceInput(1, Int32Mul(quotient, Uint32Constant(divisor)));
+      node->TrimInputCount(2);
+      NodeProperties::ChangeOp(node, machine()->Int32Sub());
     }
-    node->TrimInputCount(2);
     return Changed(node);
   }
   return NoChange();
@@ -623,23 +651,24 @@
   if (m.IsChangeInt32ToFloat64()) return Replace(m.node()->InputAt(0));
   if (m.IsPhi()) {
     Node* const phi = m.node();
-    DCHECK_EQ(kRepFloat64, RepresentationOf(OpParameter<MachineType>(phi)));
+    DCHECK_EQ(MachineRepresentation::kFloat64, PhiRepresentationOf(phi->op()));
     if (phi->OwnedBy(node)) {
-      // TruncateFloat64ToInt32(Phi[Float64](x1,...,xn))
-      //   => Phi[Int32](TruncateFloat64ToInt32(x1),
+      // TruncateFloat64ToInt32[mode](Phi[Float64](x1,...,xn))
+      //   => Phi[Int32](TruncateFloat64ToInt32[mode](x1),
       //                 ...,
-      //                 TruncateFloat64ToInt32(xn))
+      //                 TruncateFloat64ToInt32[mode](xn))
       const int value_input_count = phi->InputCount() - 1;
       for (int i = 0; i < value_input_count; ++i) {
-        Node* input = graph()->NewNode(machine()->TruncateFloat64ToInt32(),
-                                       phi->InputAt(i));
+        Node* input = graph()->NewNode(node->op(), phi->InputAt(i));
         // TODO(bmeurer): Reschedule input for reduction once we have Revisit()
         // instead of recursing into ReduceTruncateFloat64ToInt32() here.
         Reduction reduction = ReduceTruncateFloat64ToInt32(input);
         if (reduction.Changed()) input = reduction.replacement();
         phi->ReplaceInput(i, input);
       }
-      phi->set_op(common()->Phi(kMachInt32, value_input_count));
+      NodeProperties::ChangeOp(
+          phi,
+          common()->Phi(MachineRepresentation::kWord32, value_input_count));
       return Replace(phi);
     }
   }
@@ -648,15 +677,16 @@
 
 
 Reduction MachineOperatorReducer::ReduceStore(Node* node) {
-  MachineType const rep =
-      RepresentationOf(StoreRepresentationOf(node->op()).machine_type());
+  MachineRepresentation const rep =
+      StoreRepresentationOf(node->op()).representation();
   Node* const value = node->InputAt(2);
   switch (value->opcode()) {
     case IrOpcode::kWord32And: {
       Uint32BinopMatcher m(value);
-      if (m.right().HasValue() &&
-          ((rep == kRepWord8 && (m.right().Value() & 0xff) == 0xff) ||
-           (rep == kRepWord16 && (m.right().Value() & 0xffff) == 0xffff))) {
+      if (m.right().HasValue() && ((rep == MachineRepresentation::kWord8 &&
+                                    (m.right().Value() & 0xff) == 0xff) ||
+                                   (rep == MachineRepresentation::kWord16 &&
+                                    (m.right().Value() & 0xffff) == 0xffff))) {
         node->ReplaceInput(2, m.left().node());
         return Changed(node);
       }
@@ -664,9 +694,10 @@
     }
     case IrOpcode::kWord32Sar: {
       Int32BinopMatcher m(value);
-      if (m.left().IsWord32Shl() &&
-          ((rep == kRepWord8 && m.right().IsInRange(1, 24)) ||
-           (rep == kRepWord16 && m.right().IsInRange(1, 16)))) {
+      if (m.left().IsWord32Shl() && ((rep == MachineRepresentation::kWord8 &&
+                                      m.right().IsInRange(1, 24)) ||
+                                     (rep == MachineRepresentation::kWord16 &&
+                                      m.right().IsInRange(1, 16)))) {
         Int32BinopMatcher mleft(m.left().node());
         if (mleft.right().Is(m.right().Value())) {
           node->ReplaceInput(2, mleft.left().node());
@@ -752,10 +783,10 @@
     if (m.left().IsWord32Sar() || m.left().IsWord32Shr()) {
       Int32BinopMatcher mleft(m.left().node());
       if (mleft.right().Is(m.right().Value())) {
-        node->set_op(machine()->Word32And());
         node->ReplaceInput(0, mleft.left().node());
         node->ReplaceInput(1,
                            Uint32Constant(~((1U << m.right().Value()) - 1U)));
+        NodeProperties::ChangeOp(node, machine()->Word32And());
         Reduction reduction = ReduceWord32And(node);
         return reduction.Changed() ? reduction : Changed(node);
       }
@@ -765,11 +796,50 @@
 }
 
 
+Reduction MachineOperatorReducer::ReduceWord32Sar(Node* node) {
+  Int32BinopMatcher m(node);
+  if (m.right().Is(0)) return Replace(m.left().node());  // x >> 0 => x
+  if (m.IsFoldable()) {                                  // K >> K => K
+    return ReplaceInt32(m.left().Value() >> m.right().Value());
+  }
+  if (m.left().IsWord32Shl()) {
+    Int32BinopMatcher mleft(m.left().node());
+    if (mleft.left().IsComparison()) {
+      if (m.right().Is(31) && mleft.right().Is(31)) {
+        // Comparison << 31 >> 31 => 0 - Comparison
+        node->ReplaceInput(0, Int32Constant(0));
+        node->ReplaceInput(1, mleft.left().node());
+        NodeProperties::ChangeOp(node, machine()->Int32Sub());
+        Reduction const reduction = ReduceInt32Sub(node);
+        return reduction.Changed() ? reduction : Changed(node);
+      }
+    } else if (mleft.left().IsLoad()) {
+      LoadRepresentation const rep =
+          LoadRepresentationOf(mleft.left().node()->op());
+      if (m.right().Is(24) && mleft.right().Is(24) &&
+          rep == MachineType::Int8()) {
+        // Load[kMachInt8] << 24 >> 24 => Load[kMachInt8]
+        return Replace(mleft.left().node());
+      }
+      if (m.right().Is(16) && mleft.right().Is(16) &&
+          rep == MachineType::Int16()) {
+        // Load[kMachInt16] << 16 >> 16 => Load[kMachInt8]
+        return Replace(mleft.left().node());
+      }
+    }
+  }
+  return ReduceWord32Shifts(node);
+}
+
+
 Reduction MachineOperatorReducer::ReduceWord32And(Node* node) {
   DCHECK_EQ(IrOpcode::kWord32And, node->opcode());
   Int32BinopMatcher m(node);
   if (m.right().Is(0)) return Replace(m.right().node());  // x & 0  => 0
   if (m.right().Is(-1)) return Replace(m.left().node());  // x & -1 => x
+  if (m.left().IsComparison() && m.right().Is(1)) {       // CMP & 1 => CMP
+    return Replace(m.left().node());
+  }
   if (m.IsFoldable()) {                                   // K & K  => K
     return ReplaceInt32(m.left().Value() & m.right().Value());
   }
@@ -784,63 +854,79 @@
       return reduction.Changed() ? reduction : Changed(node);
     }
   }
-  if (m.left().IsInt32Add() && m.right().IsNegativePowerOf2()) {
-    Int32BinopMatcher mleft(m.left().node());
-    if (mleft.right().HasValue() &&
-        (mleft.right().Value() & m.right().Value()) == mleft.right().Value()) {
-      // (x + (K << L)) & (-1 << L) => (x & (-1 << L)) + (K << L)
-      node->set_op(machine()->Int32Add());
-      node->ReplaceInput(0, Word32And(mleft.left().node(), m.right().node()));
-      node->ReplaceInput(1, mleft.right().node());
-      Reduction const reduction = ReduceInt32Add(node);
-      return reduction.Changed() ? reduction : Changed(node);
-    }
-    if (mleft.left().IsInt32Mul()) {
-      Int32BinopMatcher mleftleft(mleft.left().node());
-      if (mleftleft.right().IsMultipleOf(-m.right().Value())) {
-        // (y * (K << L) + x) & (-1 << L) => (x & (-1 << L)) + y * (K << L)
-        node->set_op(machine()->Int32Add());
-        node->ReplaceInput(0,
-                           Word32And(mleft.right().node(), m.right().node()));
-        node->ReplaceInput(1, mleftleft.node());
-        Reduction const reduction = ReduceInt32Add(node);
-        return reduction.Changed() ? reduction : Changed(node);
+  if (m.right().IsNegativePowerOf2()) {
+    int32_t const mask = m.right().Value();
+    if (m.left().IsWord32Shl()) {
+      Uint32BinopMatcher mleft(m.left().node());
+      if (mleft.right().HasValue() &&
+          mleft.right().Value() >= base::bits::CountTrailingZeros32(mask)) {
+        // (x << L) & (-1 << K) => x << L iff K >= L
+        return Replace(mleft.node());
       }
-    }
-    if (mleft.right().IsInt32Mul()) {
-      Int32BinopMatcher mleftright(mleft.right().node());
-      if (mleftright.right().IsMultipleOf(-m.right().Value())) {
-        // (x + y * (K << L)) & (-1 << L) => (x & (-1 << L)) + y * (K << L)
-        node->set_op(machine()->Int32Add());
+    } else if (m.left().IsInt32Add()) {
+      Int32BinopMatcher mleft(m.left().node());
+      if (mleft.right().HasValue() &&
+          (mleft.right().Value() & mask) == mleft.right().Value()) {
+        // (x + (K << L)) & (-1 << L) => (x & (-1 << L)) + (K << L)
         node->ReplaceInput(0, Word32And(mleft.left().node(), m.right().node()));
-        node->ReplaceInput(1, mleftright.node());
+        node->ReplaceInput(1, mleft.right().node());
+        NodeProperties::ChangeOp(node, machine()->Int32Add());
         Reduction const reduction = ReduceInt32Add(node);
         return reduction.Changed() ? reduction : Changed(node);
       }
-    }
-    if (mleft.left().IsWord32Shl()) {
-      Int32BinopMatcher mleftleft(mleft.left().node());
-      if (mleftleft.right().Is(
-              base::bits::CountTrailingZeros32(m.right().Value()))) {
-        // (y << L + x) & (-1 << L) => (x & (-1 << L)) + y << L
-        node->set_op(machine()->Int32Add());
-        node->ReplaceInput(0,
-                           Word32And(mleft.right().node(), m.right().node()));
-        node->ReplaceInput(1, mleftleft.node());
-        Reduction const reduction = ReduceInt32Add(node);
-        return reduction.Changed() ? reduction : Changed(node);
+      if (mleft.left().IsInt32Mul()) {
+        Int32BinopMatcher mleftleft(mleft.left().node());
+        if (mleftleft.right().IsMultipleOf(-mask)) {
+          // (y * (K << L) + x) & (-1 << L) => (x & (-1 << L)) + y * (K << L)
+          node->ReplaceInput(0,
+                             Word32And(mleft.right().node(), m.right().node()));
+          node->ReplaceInput(1, mleftleft.node());
+          NodeProperties::ChangeOp(node, machine()->Int32Add());
+          Reduction const reduction = ReduceInt32Add(node);
+          return reduction.Changed() ? reduction : Changed(node);
+        }
       }
-    }
-    if (mleft.right().IsWord32Shl()) {
-      Int32BinopMatcher mleftright(mleft.right().node());
-      if (mleftright.right().Is(
-              base::bits::CountTrailingZeros32(m.right().Value()))) {
-        // (x + y << L) & (-1 << L) => (x & (-1 << L)) + y << L
-        node->set_op(machine()->Int32Add());
-        node->ReplaceInput(0, Word32And(mleft.left().node(), m.right().node()));
-        node->ReplaceInput(1, mleftright.node());
-        Reduction const reduction = ReduceInt32Add(node);
-        return reduction.Changed() ? reduction : Changed(node);
+      if (mleft.right().IsInt32Mul()) {
+        Int32BinopMatcher mleftright(mleft.right().node());
+        if (mleftright.right().IsMultipleOf(-mask)) {
+          // (x + y * (K << L)) & (-1 << L) => (x & (-1 << L)) + y * (K << L)
+          node->ReplaceInput(0,
+                             Word32And(mleft.left().node(), m.right().node()));
+          node->ReplaceInput(1, mleftright.node());
+          NodeProperties::ChangeOp(node, machine()->Int32Add());
+          Reduction const reduction = ReduceInt32Add(node);
+          return reduction.Changed() ? reduction : Changed(node);
+        }
+      }
+      if (mleft.left().IsWord32Shl()) {
+        Int32BinopMatcher mleftleft(mleft.left().node());
+        if (mleftleft.right().Is(base::bits::CountTrailingZeros32(mask))) {
+          // (y << L + x) & (-1 << L) => (x & (-1 << L)) + y << L
+          node->ReplaceInput(0,
+                             Word32And(mleft.right().node(), m.right().node()));
+          node->ReplaceInput(1, mleftleft.node());
+          NodeProperties::ChangeOp(node, machine()->Int32Add());
+          Reduction const reduction = ReduceInt32Add(node);
+          return reduction.Changed() ? reduction : Changed(node);
+        }
+      }
+      if (mleft.right().IsWord32Shl()) {
+        Int32BinopMatcher mleftright(mleft.right().node());
+        if (mleftright.right().Is(base::bits::CountTrailingZeros32(mask))) {
+          // (x + y << L) & (-1 << L) => (x & (-1 << L)) + y << L
+          node->ReplaceInput(0,
+                             Word32And(mleft.left().node(), m.right().node()));
+          node->ReplaceInput(1, mleftright.node());
+          NodeProperties::ChangeOp(node, machine()->Int32Add());
+          Reduction const reduction = ReduceInt32Add(node);
+          return reduction.Changed() ? reduction : Changed(node);
+        }
+      }
+    } else if (m.left().IsInt32Mul()) {
+      Int32BinopMatcher mleft(m.left().node());
+      if (mleft.right().IsMultipleOf(-mask)) {
+        // (x * (K << L)) & (-1 << L) => x * (K << L)
+        return Replace(mleft.node());
       }
     }
   }
@@ -858,8 +944,8 @@
   }
   if (m.LeftEqualsRight()) return Replace(m.left().node());  // x | x => x
 
-  Node* shl = NULL;
-  Node* shr = NULL;
+  Node* shl = nullptr;
+  Node* shr = nullptr;
   // Recognize rotation, we are matching either:
   //  * x << y | x >>> (32 - y) => x ror (32 - y), i.e  x rol y
   //  * x << (32 - y) | x >>> y => x ror y
@@ -882,8 +968,8 @@
     // Case where y is a constant.
     if (mshl.right().Value() + mshr.right().Value() != 32) return NoChange();
   } else {
-    Node* sub = NULL;
-    Node* y = NULL;
+    Node* sub = nullptr;
+    Node* y = nullptr;
     if (mshl.right().IsInt32Sub()) {
       sub = mshl.right().node();
       y = mshr.right().node();
@@ -898,13 +984,96 @@
     if (!msub.left().Is(32) || msub.right().node() != y) return NoChange();
   }
 
-  node->set_op(machine()->Word32Ror());
   node->ReplaceInput(0, mshl.left().node());
   node->ReplaceInput(1, mshr.right().node());
+  NodeProperties::ChangeOp(node, machine()->Word32Ror());
   return Changed(node);
 }
 
 
+Reduction MachineOperatorReducer::ReduceFloat64InsertLowWord32(Node* node) {
+  DCHECK_EQ(IrOpcode::kFloat64InsertLowWord32, node->opcode());
+  Float64Matcher mlhs(node->InputAt(0));
+  Uint32Matcher mrhs(node->InputAt(1));
+  if (mlhs.HasValue() && mrhs.HasValue()) {
+    return ReplaceFloat64(bit_cast<double>(
+        (bit_cast<uint64_t>(mlhs.Value()) & V8_UINT64_C(0xFFFFFFFF00000000)) |
+        mrhs.Value()));
+  }
+  return NoChange();
+}
+
+
+Reduction MachineOperatorReducer::ReduceFloat64InsertHighWord32(Node* node) {
+  DCHECK_EQ(IrOpcode::kFloat64InsertHighWord32, node->opcode());
+  Float64Matcher mlhs(node->InputAt(0));
+  Uint32Matcher mrhs(node->InputAt(1));
+  if (mlhs.HasValue() && mrhs.HasValue()) {
+    return ReplaceFloat64(bit_cast<double>(
+        (bit_cast<uint64_t>(mlhs.Value()) & V8_UINT64_C(0xFFFFFFFF)) |
+        (static_cast<uint64_t>(mrhs.Value()) << 32)));
+  }
+  return NoChange();
+}
+
+
+namespace {
+
+bool IsFloat64RepresentableAsFloat32(const Float64Matcher& m) {
+  if (m.HasValue()) {
+    double v = m.Value();
+    float fv = static_cast<float>(v);
+    return static_cast<double>(fv) == v;
+  }
+  return false;
+}
+
+}  // namespace
+
+
+Reduction MachineOperatorReducer::ReduceFloat64Compare(Node* node) {
+  DCHECK((IrOpcode::kFloat64Equal == node->opcode()) ||
+         (IrOpcode::kFloat64LessThan == node->opcode()) ||
+         (IrOpcode::kFloat64LessThanOrEqual == node->opcode()));
+  // As all Float32 values have an exact representation in Float64, comparing
+  // two Float64 values both converted from Float32 is equivalent to comparing
+  // the original Float32s, so we can ignore the conversions. We can also reduce
+  // comparisons of converted Float64 values against constants that can be
+  // represented exactly as Float32.
+  Float64BinopMatcher m(node);
+  if ((m.left().IsChangeFloat32ToFloat64() &&
+       m.right().IsChangeFloat32ToFloat64()) ||
+      (m.left().IsChangeFloat32ToFloat64() &&
+       IsFloat64RepresentableAsFloat32(m.right())) ||
+      (IsFloat64RepresentableAsFloat32(m.left()) &&
+       m.right().IsChangeFloat32ToFloat64())) {
+    switch (node->opcode()) {
+      case IrOpcode::kFloat64Equal:
+        NodeProperties::ChangeOp(node, machine()->Float32Equal());
+        break;
+      case IrOpcode::kFloat64LessThan:
+        NodeProperties::ChangeOp(node, machine()->Float32LessThan());
+        break;
+      case IrOpcode::kFloat64LessThanOrEqual:
+        NodeProperties::ChangeOp(node, machine()->Float32LessThanOrEqual());
+        break;
+      default:
+        return NoChange();
+    }
+    node->ReplaceInput(
+        0, m.left().HasValue()
+               ? Float32Constant(static_cast<float>(m.left().Value()))
+               : m.left().InputAt(0));
+    node->ReplaceInput(
+        1, m.right().HasValue()
+               ? Float32Constant(static_cast<float>(m.right().Value()))
+               : m.right().InputAt(0));
+    return Changed(node);
+  }
+  return NoChange();
+}
+
+
 CommonOperatorBuilder* MachineOperatorReducer::common() const {
   return jsgraph()->common();
 }
diff --git a/src/compiler/machine-operator-reducer.h b/src/compiler/machine-operator-reducer.h
index 8200abb..7f8ff1a 100644
--- a/src/compiler/machine-operator-reducer.h
+++ b/src/compiler/machine-operator-reducer.h
@@ -19,12 +19,12 @@
 
 // Performs constant folding and strength reduction on nodes that have
 // machine operators.
-class MachineOperatorReducer FINAL : public Reducer {
+class MachineOperatorReducer final : public Reducer {
  public:
   explicit MachineOperatorReducer(JSGraph* jsgraph);
   ~MachineOperatorReducer();
 
-  Reduction Reduce(Node* node) OVERRIDE;
+  Reduction Reduce(Node* node) override;
 
  private:
   Node* Float32Constant(volatile float value);
@@ -65,6 +65,7 @@
   }
 
   Reduction ReduceInt32Add(Node* node);
+  Reduction ReduceInt32Sub(Node* node);
   Reduction ReduceInt32Div(Node* node);
   Reduction ReduceUint32Div(Node* node);
   Reduction ReduceInt32Mod(Node* node);
@@ -74,8 +75,12 @@
   Reduction ReduceProjection(size_t index, Node* node);
   Reduction ReduceWord32Shifts(Node* node);
   Reduction ReduceWord32Shl(Node* node);
+  Reduction ReduceWord32Sar(Node* node);
   Reduction ReduceWord32And(Node* node);
   Reduction ReduceWord32Or(Node* node);
+  Reduction ReduceFloat64InsertLowWord32(Node* node);
+  Reduction ReduceFloat64InsertHighWord32(Node* node);
+  Reduction ReduceFloat64Compare(Node* node);
 
   Graph* graph() const;
   JSGraph* jsgraph() const { return jsgraph_; }
diff --git a/src/compiler/machine-operator.cc b/src/compiler/machine-operator.cc
index eb034e9..511a10d 100644
--- a/src/compiler/machine-operator.cc
+++ b/src/compiler/machine-operator.cc
@@ -7,17 +7,37 @@
 #include "src/base/lazy-instance.h"
 #include "src/compiler/opcodes.h"
 #include "src/compiler/operator.h"
-#include "src/v8.h"
-#include "src/zone-inl.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
+std::ostream& operator<<(std::ostream& os, TruncationMode mode) {
+  switch (mode) {
+    case TruncationMode::kJavaScript:
+      return os << "JavaScript";
+    case TruncationMode::kRoundToZero:
+      return os << "RoundToZero";
+  }
+  UNREACHABLE();
+  return os;
+}
+
+
+TruncationMode TruncationModeOf(Operator const* op) {
+  DCHECK_EQ(IrOpcode::kTruncateFloat64ToInt32, op->opcode());
+  return OpParameter<TruncationMode>(op);
+}
+
+
 std::ostream& operator<<(std::ostream& os, WriteBarrierKind kind) {
   switch (kind) {
     case kNoWriteBarrier:
       return os << "NoWriteBarrier";
+    case kMapWriteBarrier:
+      return os << "MapWriteBarrier";
+    case kPointerWriteBarrier:
+      return os << "PointerWriteBarrier";
     case kFullWriteBarrier:
       return os << "FullWriteBarrier";
   }
@@ -27,7 +47,7 @@
 
 
 bool operator==(StoreRepresentation lhs, StoreRepresentation rhs) {
-  return lhs.machine_type() == rhs.machine_type() &&
+  return lhs.representation() == rhs.representation() &&
          lhs.write_barrier_kind() == rhs.write_barrier_kind();
 }
 
@@ -38,16 +58,22 @@
 
 
 size_t hash_value(StoreRepresentation rep) {
-  return base::hash_combine(rep.machine_type(), rep.write_barrier_kind());
+  return base::hash_combine(rep.representation(), rep.write_barrier_kind());
 }
 
 
 std::ostream& operator<<(std::ostream& os, StoreRepresentation rep) {
-  return os << "(" << rep.machine_type() << " : " << rep.write_barrier_kind()
+  return os << "(" << rep.representation() << " : " << rep.write_barrier_kind()
             << ")";
 }
 
 
+LoadRepresentation LoadRepresentationOf(Operator const* op) {
+  DCHECK_EQ(IrOpcode::kLoad, op->opcode());
+  return OpParameter<LoadRepresentation>(op);
+}
+
+
 StoreRepresentation const& StoreRepresentationOf(Operator const* op) {
   DCHECK_EQ(IrOpcode::kStore, op->opcode());
   return OpParameter<StoreRepresentation>(op);
@@ -75,6 +101,7 @@
   V(Word32Sar, Operator::kNoProperties, 2, 0, 1)                              \
   V(Word32Ror, Operator::kNoProperties, 2, 0, 1)                              \
   V(Word32Equal, Operator::kCommutative, 2, 0, 1)                             \
+  V(Word32Clz, Operator::kNoProperties, 1, 0, 1)                              \
   V(Word64And, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)      \
   V(Word64Or, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)       \
   V(Word64Xor, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)      \
@@ -82,6 +109,7 @@
   V(Word64Shr, Operator::kNoProperties, 2, 0, 1)                              \
   V(Word64Sar, Operator::kNoProperties, 2, 0, 1)                              \
   V(Word64Ror, Operator::kNoProperties, 2, 0, 1)                              \
+  V(Word64Clz, Operator::kNoProperties, 1, 0, 1)                              \
   V(Word64Equal, Operator::kCommutative, 2, 0, 1)                             \
   V(Int32Add, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)       \
   V(Int32AddWithOverflow, Operator::kAssociative | Operator::kCommutative, 2, \
@@ -100,67 +128,115 @@
   V(Uint32Mod, Operator::kNoProperties, 2, 1, 1)                              \
   V(Uint32MulHigh, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)  \
   V(Int64Add, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)       \
+  V(Int64AddWithOverflow, Operator::kAssociative | Operator::kCommutative, 2, \
+    0, 2)                                                                     \
   V(Int64Sub, Operator::kNoProperties, 2, 0, 1)                               \
+  V(Int64SubWithOverflow, Operator::kNoProperties, 2, 0, 2)                   \
   V(Int64Mul, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)       \
-  V(Int64Div, Operator::kNoProperties, 2, 0, 1)                               \
-  V(Int64Mod, Operator::kNoProperties, 2, 0, 1)                               \
+  V(Int64Div, Operator::kNoProperties, 2, 1, 1)                               \
+  V(Int64Mod, Operator::kNoProperties, 2, 1, 1)                               \
   V(Int64LessThan, Operator::kNoProperties, 2, 0, 1)                          \
   V(Int64LessThanOrEqual, Operator::kNoProperties, 2, 0, 1)                   \
-  V(Uint64Div, Operator::kNoProperties, 2, 0, 1)                              \
+  V(Uint64Div, Operator::kNoProperties, 2, 1, 1)                              \
+  V(Uint64Mod, Operator::kNoProperties, 2, 1, 1)                              \
   V(Uint64LessThan, Operator::kNoProperties, 2, 0, 1)                         \
-  V(Uint64Mod, Operator::kNoProperties, 2, 0, 1)                              \
+  V(Uint64LessThanOrEqual, Operator::kNoProperties, 2, 0, 1)                  \
   V(ChangeFloat32ToFloat64, Operator::kNoProperties, 1, 0, 1)                 \
   V(ChangeFloat64ToInt32, Operator::kNoProperties, 1, 0, 1)                   \
   V(ChangeFloat64ToUint32, Operator::kNoProperties, 1, 0, 1)                  \
+  V(TryTruncateFloat32ToInt64, Operator::kNoProperties, 1, 0, 2)              \
+  V(TryTruncateFloat64ToInt64, Operator::kNoProperties, 1, 0, 2)              \
+  V(TryTruncateFloat32ToUint64, Operator::kNoProperties, 1, 0, 2)             \
+  V(TryTruncateFloat64ToUint64, Operator::kNoProperties, 1, 0, 2)             \
   V(ChangeInt32ToFloat64, Operator::kNoProperties, 1, 0, 1)                   \
+  V(RoundInt64ToFloat32, Operator::kNoProperties, 1, 0, 1)                    \
+  V(RoundInt64ToFloat64, Operator::kNoProperties, 1, 0, 1)                    \
+  V(RoundUint64ToFloat32, Operator::kNoProperties, 1, 0, 1)                   \
+  V(RoundUint64ToFloat64, Operator::kNoProperties, 1, 0, 1)                   \
   V(ChangeInt32ToInt64, Operator::kNoProperties, 1, 0, 1)                     \
   V(ChangeUint32ToFloat64, Operator::kNoProperties, 1, 0, 1)                  \
   V(ChangeUint32ToUint64, Operator::kNoProperties, 1, 0, 1)                   \
   V(TruncateFloat64ToFloat32, Operator::kNoProperties, 1, 0, 1)               \
-  V(TruncateFloat64ToInt32, Operator::kNoProperties, 1, 0, 1)                 \
   V(TruncateInt64ToInt32, Operator::kNoProperties, 1, 0, 1)                   \
+  V(BitcastFloat32ToInt32, Operator::kNoProperties, 1, 0, 1)                  \
+  V(BitcastFloat64ToInt64, Operator::kNoProperties, 1, 0, 1)                  \
+  V(BitcastInt32ToFloat32, Operator::kNoProperties, 1, 0, 1)                  \
+  V(BitcastInt64ToFloat64, Operator::kNoProperties, 1, 0, 1)                  \
+  V(Float32Abs, Operator::kNoProperties, 1, 0, 1)                             \
+  V(Float32Add, Operator::kCommutative, 2, 0, 1)                              \
+  V(Float32Sub, Operator::kNoProperties, 2, 0, 1)                             \
+  V(Float32Mul, Operator::kCommutative, 2, 0, 1)                              \
+  V(Float32Div, Operator::kNoProperties, 2, 0, 1)                             \
+  V(Float32Sqrt, Operator::kNoProperties, 1, 0, 1)                            \
+  V(Float64Abs, Operator::kNoProperties, 1, 0, 1)                             \
   V(Float64Add, Operator::kCommutative, 2, 0, 1)                              \
   V(Float64Sub, Operator::kNoProperties, 2, 0, 1)                             \
   V(Float64Mul, Operator::kCommutative, 2, 0, 1)                              \
   V(Float64Div, Operator::kNoProperties, 2, 0, 1)                             \
   V(Float64Mod, Operator::kNoProperties, 2, 0, 1)                             \
   V(Float64Sqrt, Operator::kNoProperties, 1, 0, 1)                            \
-  V(Float64Ceil, Operator::kNoProperties, 1, 0, 1)                            \
-  V(Float64Floor, Operator::kNoProperties, 1, 0, 1)                           \
-  V(Float64RoundTruncate, Operator::kNoProperties, 1, 0, 1)                   \
-  V(Float64RoundTiesAway, Operator::kNoProperties, 1, 0, 1)                   \
+  V(Float32Equal, Operator::kCommutative, 2, 0, 1)                            \
+  V(Float32LessThan, Operator::kNoProperties, 2, 0, 1)                        \
+  V(Float32LessThanOrEqual, Operator::kNoProperties, 2, 0, 1)                 \
   V(Float64Equal, Operator::kCommutative, 2, 0, 1)                            \
   V(Float64LessThan, Operator::kNoProperties, 2, 0, 1)                        \
   V(Float64LessThanOrEqual, Operator::kNoProperties, 2, 0, 1)                 \
-  V(LoadStackPointer, Operator::kNoProperties, 0, 0, 1)
+  V(Float64ExtractLowWord32, Operator::kNoProperties, 1, 0, 1)                \
+  V(Float64ExtractHighWord32, Operator::kNoProperties, 1, 0, 1)               \
+  V(Float64InsertLowWord32, Operator::kNoProperties, 2, 0, 1)                 \
+  V(Float64InsertHighWord32, Operator::kNoProperties, 2, 0, 1)                \
+  V(LoadStackPointer, Operator::kNoProperties, 0, 0, 1)                       \
+  V(LoadFramePointer, Operator::kNoProperties, 0, 0, 1)
+
+#define PURE_OPTIONAL_OP_LIST(V)                            \
+  V(Word32Ctz, Operator::kNoProperties, 1, 0, 1)            \
+  V(Word64Ctz, Operator::kNoProperties, 1, 0, 1)            \
+  V(Word32Popcnt, Operator::kNoProperties, 1, 0, 1)         \
+  V(Word64Popcnt, Operator::kNoProperties, 1, 0, 1)         \
+  V(Float32Max, Operator::kNoProperties, 2, 0, 1)           \
+  V(Float32Min, Operator::kNoProperties, 2, 0, 1)           \
+  V(Float64Max, Operator::kNoProperties, 2, 0, 1)           \
+  V(Float64Min, Operator::kNoProperties, 2, 0, 1)           \
+  V(Float32RoundDown, Operator::kNoProperties, 1, 0, 1)     \
+  V(Float64RoundDown, Operator::kNoProperties, 1, 0, 1)     \
+  V(Float32RoundUp, Operator::kNoProperties, 1, 0, 1)       \
+  V(Float64RoundUp, Operator::kNoProperties, 1, 0, 1)       \
+  V(Float32RoundTruncate, Operator::kNoProperties, 1, 0, 1) \
+  V(Float64RoundTruncate, Operator::kNoProperties, 1, 0, 1) \
+  V(Float64RoundTiesAway, Operator::kNoProperties, 1, 0, 1) \
+  V(Float32RoundTiesEven, Operator::kNoProperties, 1, 0, 1) \
+  V(Float64RoundTiesEven, Operator::kNoProperties, 1, 0, 1)
 
 
 #define MACHINE_TYPE_LIST(V) \
-  V(MachFloat32)             \
-  V(MachFloat64)             \
-  V(MachInt8)                \
-  V(MachUint8)               \
-  V(MachInt16)               \
-  V(MachUint16)              \
-  V(MachInt32)               \
-  V(MachUint32)              \
-  V(MachInt64)               \
-  V(MachUint64)              \
-  V(MachAnyTagged)           \
-  V(RepBit)                  \
-  V(RepWord8)                \
-  V(RepWord16)               \
-  V(RepWord32)               \
-  V(RepWord64)               \
-  V(RepFloat32)              \
-  V(RepFloat64)              \
-  V(RepTagged)
+  V(Float32)                 \
+  V(Float64)                 \
+  V(Int8)                    \
+  V(Uint8)                   \
+  V(Int16)                   \
+  V(Uint16)                  \
+  V(Int32)                   \
+  V(Uint32)                  \
+  V(Int64)                   \
+  V(Uint64)                  \
+  V(Pointer)                 \
+  V(AnyTagged)
+
+
+#define MACHINE_REPRESENTATION_LIST(V) \
+  V(kFloat32)                          \
+  V(kFloat64)                          \
+  V(kWord8)                            \
+  V(kWord16)                           \
+  V(kWord32)                           \
+  V(kWord64)                           \
+  V(kTagged)
 
 
 struct MachineOperatorGlobalCache {
 #define PURE(Name, properties, value_input_count, control_input_count,         \
              output_count)                                                     \
-  struct Name##Operator FINAL : public Operator {                              \
+  struct Name##Operator final : public Operator {                              \
     Name##Operator()                                                           \
         : Operator(IrOpcode::k##Name, Operator::kPure | properties, #Name,     \
                    value_input_count, 0, control_input_count, output_count, 0, \
@@ -168,21 +244,35 @@
   };                                                                           \
   Name##Operator k##Name;
   PURE_OP_LIST(PURE)
+  PURE_OPTIONAL_OP_LIST(PURE)
 #undef PURE
 
+  template <TruncationMode kMode>
+  struct TruncateFloat64ToInt32Operator final
+      : public Operator1<TruncationMode> {
+    TruncateFloat64ToInt32Operator()
+        : Operator1<TruncationMode>(IrOpcode::kTruncateFloat64ToInt32,
+                                    Operator::kPure, "TruncateFloat64ToInt32",
+                                    1, 0, 0, 1, 0, 0, kMode) {}
+  };
+  TruncateFloat64ToInt32Operator<TruncationMode::kJavaScript>
+      kTruncateFloat64ToInt32JavaScript;
+  TruncateFloat64ToInt32Operator<TruncationMode::kRoundToZero>
+      kTruncateFloat64ToInt32RoundToZero;
+
 #define LOAD(Type)                                                             \
-  struct Load##Type##Operator FINAL : public Operator1<LoadRepresentation> {   \
+  struct Load##Type##Operator final : public Operator1<LoadRepresentation> {   \
     Load##Type##Operator()                                                     \
         : Operator1<LoadRepresentation>(                                       \
               IrOpcode::kLoad, Operator::kNoThrow | Operator::kNoWrite,        \
-              "Load", 2, 1, 1, 1, 1, 0, k##Type) {}                            \
+              "Load", 2, 1, 1, 1, 1, 0, MachineType::Type()) {}                \
   };                                                                           \
-  struct CheckedLoad##Type##Operator FINAL                                     \
+  struct CheckedLoad##Type##Operator final                                     \
       : public Operator1<CheckedLoadRepresentation> {                          \
     CheckedLoad##Type##Operator()                                              \
         : Operator1<CheckedLoadRepresentation>(                                \
               IrOpcode::kCheckedLoad, Operator::kNoThrow | Operator::kNoWrite, \
-              "CheckedLoad", 3, 1, 1, 1, 1, 0, k##Type) {}                     \
+              "CheckedLoad", 3, 1, 1, 1, 1, 0, MachineType::Type()) {}         \
   };                                                                           \
   Load##Type##Operator kLoad##Type;                                            \
   CheckedLoad##Type##Operator kCheckedLoad##Type;
@@ -195,29 +285,44 @@
         : Operator1<StoreRepresentation>(                                      \
               IrOpcode::kStore, Operator::kNoRead | Operator::kNoThrow,        \
               "Store", 3, 1, 1, 0, 1, 0,                                       \
-              StoreRepresentation(k##Type, write_barrier_kind)) {}             \
+              StoreRepresentation(MachineRepresentation::Type,                 \
+                                  write_barrier_kind)) {}                      \
   };                                                                           \
-  struct Store##Type##NoWriteBarrier##Operator FINAL                           \
+  struct Store##Type##NoWriteBarrier##Operator final                           \
       : public Store##Type##Operator {                                         \
     Store##Type##NoWriteBarrier##Operator()                                    \
         : Store##Type##Operator(kNoWriteBarrier) {}                            \
   };                                                                           \
-  struct Store##Type##FullWriteBarrier##Operator FINAL                         \
+  struct Store##Type##MapWriteBarrier##Operator final                          \
+      : public Store##Type##Operator {                                         \
+    Store##Type##MapWriteBarrier##Operator()                                   \
+        : Store##Type##Operator(kMapWriteBarrier) {}                           \
+  };                                                                           \
+  struct Store##Type##PointerWriteBarrier##Operator final                      \
+      : public Store##Type##Operator {                                         \
+    Store##Type##PointerWriteBarrier##Operator()                               \
+        : Store##Type##Operator(kPointerWriteBarrier) {}                       \
+  };                                                                           \
+  struct Store##Type##FullWriteBarrier##Operator final                         \
       : public Store##Type##Operator {                                         \
     Store##Type##FullWriteBarrier##Operator()                                  \
         : Store##Type##Operator(kFullWriteBarrier) {}                          \
   };                                                                           \
-  struct CheckedStore##Type##Operator FINAL                                    \
+  struct CheckedStore##Type##Operator final                                    \
       : public Operator1<CheckedStoreRepresentation> {                         \
     CheckedStore##Type##Operator()                                             \
         : Operator1<CheckedStoreRepresentation>(                               \
               IrOpcode::kCheckedStore, Operator::kNoRead | Operator::kNoThrow, \
-              "CheckedStore", 4, 1, 1, 0, 1, 0, k##Type) {}                    \
+              "CheckedStore", 4, 1, 1, 0, 1, 0, MachineRepresentation::Type) { \
+    }                                                                          \
   };                                                                           \
   Store##Type##NoWriteBarrier##Operator kStore##Type##NoWriteBarrier;          \
+  Store##Type##MapWriteBarrier##Operator kStore##Type##MapWriteBarrier;        \
+  Store##Type##PointerWriteBarrier##Operator                                   \
+      kStore##Type##PointerWriteBarrier;                                       \
   Store##Type##FullWriteBarrier##Operator kStore##Type##FullWriteBarrier;      \
   CheckedStore##Type##Operator kCheckedStore##Type;
-  MACHINE_TYPE_LIST(STORE)
+  MACHINE_REPRESENTATION_LIST(STORE)
 #undef STORE
 };
 
@@ -226,10 +331,12 @@
     LAZY_INSTANCE_INITIALIZER;
 
 
-MachineOperatorBuilder::MachineOperatorBuilder(Zone* zone, MachineType word,
+MachineOperatorBuilder::MachineOperatorBuilder(Zone* zone,
+                                               MachineRepresentation word,
                                                Flags flags)
-    : zone_(zone), cache_(kCache.Get()), word_(word), flags_(flags) {
-  DCHECK(word == kRepWord32 || word == kRepWord64);
+    : cache_(kCache.Get()), word_(word), flags_(flags) {
+  DCHECK(word == MachineRepresentation::kWord32 ||
+         word == MachineRepresentation::kWord64);
 }
 
 
@@ -239,81 +346,93 @@
 PURE_OP_LIST(PURE)
 #undef PURE
 
-
-const Operator* MachineOperatorBuilder::Load(LoadRepresentation rep) {
-  switch (rep) {
-#define LOAD(Type) \
-  case k##Type:    \
-    return &cache_.kLoad##Type;
-    MACHINE_TYPE_LIST(LOAD)
-#undef LOAD
-    default:
-      break;
+#define PURE(Name, properties, value_input_count, control_input_count,     \
+             output_count)                                                 \
+  const OptionalOperator MachineOperatorBuilder::Name() {                  \
+    return OptionalOperator(flags_ & k##Name ? &cache_.k##Name : nullptr); \
   }
-  // Uncached.
-  return new (zone_) Operator1<LoadRepresentation>(  // --
-      IrOpcode::kLoad, Operator::kNoThrow | Operator::kNoWrite, "Load", 2, 1, 1,
-      1, 1, 0, rep);
+PURE_OPTIONAL_OP_LIST(PURE)
+#undef PURE
+
+
+const Operator* MachineOperatorBuilder::TruncateFloat64ToInt32(
+    TruncationMode mode) {
+  switch (mode) {
+    case TruncationMode::kJavaScript:
+      return &cache_.kTruncateFloat64ToInt32JavaScript;
+    case TruncationMode::kRoundToZero:
+      return &cache_.kTruncateFloat64ToInt32RoundToZero;
+  }
+  UNREACHABLE();
+  return nullptr;
 }
 
 
-const Operator* MachineOperatorBuilder::Store(StoreRepresentation rep) {
-  switch (rep.machine_type()) {
-#define STORE(Type)                                      \
-  case k##Type:                                          \
-    switch (rep.write_barrier_kind()) {                  \
-      case kNoWriteBarrier:                              \
-        return &cache_.k##Store##Type##NoWriteBarrier;   \
-      case kFullWriteBarrier:                            \
-        return &cache_.k##Store##Type##FullWriteBarrier; \
-    }                                                    \
-    break;
-    MACHINE_TYPE_LIST(STORE)
-#undef STORE
+const Operator* MachineOperatorBuilder::Load(LoadRepresentation rep) {
+#define LOAD(Type)                  \
+  if (rep == MachineType::Type()) { \
+    return &cache_.kLoad##Type;     \
+  }
+    MACHINE_TYPE_LIST(LOAD)
+#undef LOAD
+  UNREACHABLE();
+  return nullptr;
+}
 
-    default:
+
+const Operator* MachineOperatorBuilder::Store(StoreRepresentation store_rep) {
+  switch (store_rep.representation()) {
+#define STORE(kRep)                                         \
+  case MachineRepresentation::kRep:                         \
+    switch (store_rep.write_barrier_kind()) {               \
+      case kNoWriteBarrier:                                 \
+        return &cache_.k##Store##kRep##NoWriteBarrier;      \
+      case kMapWriteBarrier:                                \
+        return &cache_.k##Store##kRep##MapWriteBarrier;     \
+      case kPointerWriteBarrier:                            \
+        return &cache_.k##Store##kRep##PointerWriteBarrier; \
+      case kFullWriteBarrier:                               \
+        return &cache_.k##Store##kRep##FullWriteBarrier;    \
+    }                                                       \
+    break;
+    MACHINE_REPRESENTATION_LIST(STORE)
+#undef STORE
+    case MachineRepresentation::kBit:
+    case MachineRepresentation::kNone:
       break;
   }
-  // Uncached.
-  return new (zone_) Operator1<StoreRepresentation>(  // --
-      IrOpcode::kStore, Operator::kNoRead | Operator::kNoThrow, "Store", 3, 1,
-      1, 0, 1, 0, rep);
+  UNREACHABLE();
+  return nullptr;
 }
 
 
 const Operator* MachineOperatorBuilder::CheckedLoad(
     CheckedLoadRepresentation rep) {
-  switch (rep) {
-#define LOAD(Type) \
-  case k##Type:    \
-    return &cache_.kCheckedLoad##Type;
+#define LOAD(Type)                     \
+  if (rep == MachineType::Type()) {    \
+    return &cache_.kCheckedLoad##Type; \
+  }
     MACHINE_TYPE_LIST(LOAD)
 #undef LOAD
-    default:
-      break;
-  }
-  // Uncached.
-  return new (zone_) Operator1<CheckedLoadRepresentation>(
-      IrOpcode::kCheckedLoad, Operator::kNoThrow | Operator::kNoWrite,
-      "CheckedLoad", 3, 1, 1, 1, 1, 0, rep);
+  UNREACHABLE();
+  return nullptr;
 }
 
 
 const Operator* MachineOperatorBuilder::CheckedStore(
     CheckedStoreRepresentation rep) {
   switch (rep) {
-#define STORE(Type) \
-  case k##Type:     \
-    return &cache_.kCheckedStore##Type;
-    MACHINE_TYPE_LIST(STORE)
+#define STORE(kRep)                 \
+  case MachineRepresentation::kRep: \
+    return &cache_.kCheckedStore##kRep;
+    MACHINE_REPRESENTATION_LIST(STORE)
 #undef STORE
-    default:
+    case MachineRepresentation::kBit:
+    case MachineRepresentation::kNone:
       break;
   }
-  // Uncached.
-  return new (zone_) Operator1<CheckedStoreRepresentation>(
-      IrOpcode::kCheckedStore, Operator::kNoRead | Operator::kNoThrow,
-      "CheckedStore", 4, 1, 1, 0, 1, 0, rep);
+  UNREACHABLE();
+  return nullptr;
 }
 
 }  // namespace compiler
diff --git a/src/compiler/machine-operator.h b/src/compiler/machine-operator.h
index 42f3130..00fefe3 100644
--- a/src/compiler/machine-operator.h
+++ b/src/compiler/machine-operator.h
@@ -6,7 +6,7 @@
 #define V8_COMPILER_MACHINE_OPERATOR_H_
 
 #include "src/base/flags.h"
-#include "src/compiler/machine-type.h"
+#include "src/machine-type.h"
 
 namespace v8 {
 namespace internal {
@@ -17,8 +17,44 @@
 class Operator;
 
 
+// For operators that are not supported on all platforms.
+class OptionalOperator final {
+ public:
+  explicit OptionalOperator(const Operator* op) : op_(op) {}
+
+  bool IsSupported() const { return op_ != nullptr; }
+  const Operator* op() const {
+    DCHECK_NOT_NULL(op_);
+    return op_;
+  }
+
+ private:
+  const Operator* const op_;
+};
+
+
+// Supported float64 to int32 truncation modes.
+enum class TruncationMode : uint8_t {
+  kJavaScript,  // ES6 section 7.1.5
+  kRoundToZero  // Round towards zero. Implementation defined for NaN and ovf.
+};
+
+V8_INLINE size_t hash_value(TruncationMode mode) {
+  return static_cast<uint8_t>(mode);
+}
+
+std::ostream& operator<<(std::ostream&, TruncationMode);
+
+TruncationMode TruncationModeOf(Operator const*);
+
+
 // Supported write barrier modes.
-enum WriteBarrierKind { kNoWriteBarrier, kFullWriteBarrier };
+enum WriteBarrierKind {
+  kNoWriteBarrier,
+  kMapWriteBarrier,
+  kPointerWriteBarrier,
+  kFullWriteBarrier
+};
 
 std::ostream& operator<<(std::ostream& os, WriteBarrierKind);
 
@@ -26,20 +62,22 @@
 // A Load needs a MachineType.
 typedef MachineType LoadRepresentation;
 
+LoadRepresentation LoadRepresentationOf(Operator const*);
 
 // A Store needs a MachineType and a WriteBarrierKind in order to emit the
 // correct write barrier.
-class StoreRepresentation FINAL {
+class StoreRepresentation final {
  public:
-  StoreRepresentation(MachineType machine_type,
+  StoreRepresentation(MachineRepresentation representation,
                       WriteBarrierKind write_barrier_kind)
-      : machine_type_(machine_type), write_barrier_kind_(write_barrier_kind) {}
+      : representation_(representation),
+        write_barrier_kind_(write_barrier_kind) {}
 
-  MachineType machine_type() const { return machine_type_; }
+  MachineRepresentation representation() const { return representation_; }
   WriteBarrierKind write_barrier_kind() const { return write_barrier_kind_; }
 
  private:
-  MachineType machine_type_;
+  MachineRepresentation representation_;
   WriteBarrierKind write_barrier_kind_;
 };
 
@@ -60,7 +98,7 @@
 
 
 // A CheckedStore needs a MachineType.
-typedef MachineType CheckedStoreRepresentation;
+typedef MachineRepresentation CheckedStoreRepresentation;
 
 CheckedStoreRepresentation CheckedStoreRepresentationOf(Operator const*);
 
@@ -68,24 +106,47 @@
 // Interface for building machine-level operators. These operators are
 // machine-level but machine-independent and thus define a language suitable
 // for generating code to run on architectures such as ia32, x64, arm, etc.
-class MachineOperatorBuilder FINAL : public ZoneObject {
+class MachineOperatorBuilder final : public ZoneObject {
  public:
   // Flags that specify which operations are available. This is useful
   // for operations that are unsupported by some back-ends.
   enum Flag {
     kNoFlags = 0u,
-    kFloat64Floor = 1u << 0,
-    kFloat64Ceil = 1u << 1,
-    kFloat64RoundTruncate = 1u << 2,
-    kFloat64RoundTiesAway = 1u << 3,
-    kInt32DivIsSafe = 1u << 4,
-    kUint32DivIsSafe = 1u << 5,
-    kWord32ShiftIsSafe = 1u << 6
+    // Note that Float*Max behaves like `(b < a) ? a : b`, not like Math.max().
+    // Note that Float*Min behaves like `(a < b) ? a : b`, not like Math.min().
+    kFloat32Max = 1u << 0,
+    kFloat32Min = 1u << 1,
+    kFloat64Max = 1u << 2,
+    kFloat64Min = 1u << 3,
+    kFloat32RoundDown = 1u << 4,
+    kFloat64RoundDown = 1u << 5,
+    kFloat32RoundUp = 1u << 6,
+    kFloat64RoundUp = 1u << 7,
+    kFloat32RoundTruncate = 1u << 8,
+    kFloat64RoundTruncate = 1u << 9,
+    kFloat32RoundTiesEven = 1u << 10,
+    kFloat64RoundTiesEven = 1u << 11,
+    kFloat64RoundTiesAway = 1u << 12,
+    kInt32DivIsSafe = 1u << 13,
+    kUint32DivIsSafe = 1u << 14,
+    kWord32ShiftIsSafe = 1u << 15,
+    kWord32Ctz = 1u << 16,
+    kWord64Ctz = 1u << 17,
+    kWord32Popcnt = 1u << 18,
+    kWord64Popcnt = 1u << 19,
+    kAllOptionalOps = kFloat32Max | kFloat32Min | kFloat64Max | kFloat64Min |
+                      kFloat32RoundDown | kFloat64RoundDown | kFloat32RoundUp |
+                      kFloat64RoundUp | kFloat32RoundTruncate |
+                      kFloat64RoundTruncate | kFloat64RoundTiesAway |
+                      kFloat32RoundTiesEven | kFloat64RoundTiesEven |
+                      kWord32Ctz | kWord64Ctz | kWord32Popcnt | kWord64Popcnt
   };
   typedef base::Flags<Flag, unsigned> Flags;
 
-  explicit MachineOperatorBuilder(Zone* zone, MachineType word = kMachPtr,
-                                  Flags supportedOperators = kNoFlags);
+  explicit MachineOperatorBuilder(
+      Zone* zone,
+      MachineRepresentation word = MachineType::PointerRepresentation(),
+      Flags supportedOperators = kNoFlags);
 
   const Operator* Word32And();
   const Operator* Word32Or();
@@ -95,6 +156,10 @@
   const Operator* Word32Sar();
   const Operator* Word32Ror();
   const Operator* Word32Equal();
+  const Operator* Word32Clz();
+  const OptionalOperator Word32Ctz();
+  const OptionalOperator Word32Popcnt();
+  const OptionalOperator Word64Popcnt();
   bool Word32ShiftIsSafe() const { return flags_ & kWord32ShiftIsSafe; }
 
   const Operator* Word64And();
@@ -104,6 +169,8 @@
   const Operator* Word64Shr();
   const Operator* Word64Sar();
   const Operator* Word64Ror();
+  const Operator* Word64Clz();
+  const OptionalOperator Word64Ctz();
   const Operator* Word64Equal();
 
   const Operator* Int32Add();
@@ -125,7 +192,9 @@
   bool Uint32DivIsSafe() const { return flags_ & kUint32DivIsSafe; }
 
   const Operator* Int64Add();
+  const Operator* Int64AddWithOverflow();
   const Operator* Int64Sub();
+  const Operator* Int64SubWithOverflow();
   const Operator* Int64Mul();
   const Operator* Int64Div();
   const Operator* Int64Mod();
@@ -133,6 +202,7 @@
   const Operator* Int64LessThanOrEqual();
   const Operator* Uint64Div();
   const Operator* Uint64LessThan();
+  const Operator* Uint64LessThanOrEqual();
   const Operator* Uint64Mod();
 
   // These operators change the representation of numbers while preserving the
@@ -143,18 +213,42 @@
   const Operator* ChangeFloat32ToFloat64();
   const Operator* ChangeFloat64ToInt32();   // narrowing
   const Operator* ChangeFloat64ToUint32();  // narrowing
+  const Operator* TryTruncateFloat32ToInt64();
+  const Operator* TryTruncateFloat64ToInt64();
+  const Operator* TryTruncateFloat32ToUint64();
+  const Operator* TryTruncateFloat64ToUint64();
   const Operator* ChangeInt32ToFloat64();
   const Operator* ChangeInt32ToInt64();
   const Operator* ChangeUint32ToFloat64();
   const Operator* ChangeUint32ToUint64();
 
-  // These operators truncate numbers, both changing the representation of
-  // the number and mapping multiple input values onto the same output value.
+  // These operators truncate or round numbers, both changing the representation
+  // of the number and mapping multiple input values onto the same output value.
   const Operator* TruncateFloat64ToFloat32();
-  const Operator* TruncateFloat64ToInt32();  // JavaScript semantics.
+  const Operator* TruncateFloat64ToInt32(TruncationMode);
   const Operator* TruncateInt64ToInt32();
+  const Operator* RoundInt64ToFloat32();
+  const Operator* RoundInt64ToFloat64();
+  const Operator* RoundUint64ToFloat32();
+  const Operator* RoundUint64ToFloat64();
 
-  // Floating point operators always operate with IEEE 754 round-to-nearest.
+  // These operators reinterpret the bits of a floating point number as an
+  // integer and vice versa.
+  const Operator* BitcastFloat32ToInt32();
+  const Operator* BitcastFloat64ToInt64();
+  const Operator* BitcastInt32ToFloat32();
+  const Operator* BitcastInt64ToFloat64();
+
+  // Floating point operators always operate with IEEE 754 round-to-nearest
+  // (single-precision).
+  const Operator* Float32Add();
+  const Operator* Float32Sub();
+  const Operator* Float32Mul();
+  const Operator* Float32Div();
+  const Operator* Float32Sqrt();
+
+  // Floating point operators always operate with IEEE 754 round-to-nearest
+  // (double-precision).
   const Operator* Float64Add();
   const Operator* Float64Sub();
   const Operator* Float64Mul();
@@ -162,20 +256,46 @@
   const Operator* Float64Mod();
   const Operator* Float64Sqrt();
 
-  // Floating point comparisons complying to IEEE 754.
+  // Floating point comparisons complying to IEEE 754 (single-precision).
+  const Operator* Float32Equal();
+  const Operator* Float32LessThan();
+  const Operator* Float32LessThanOrEqual();
+
+  // Floating point comparisons complying to IEEE 754 (double-precision).
   const Operator* Float64Equal();
   const Operator* Float64LessThan();
   const Operator* Float64LessThanOrEqual();
 
+  // Floating point min/max complying to IEEE 754 (single-precision).
+  const OptionalOperator Float32Max();
+  const OptionalOperator Float32Min();
+
+  // Floating point min/max complying to IEEE 754 (double-precision).
+  const OptionalOperator Float64Max();
+  const OptionalOperator Float64Min();
+
+  // Floating point abs complying to IEEE 754 (single-precision).
+  const Operator* Float32Abs();
+
+  // Floating point abs complying to IEEE 754 (double-precision).
+  const Operator* Float64Abs();
+
   // Floating point rounding.
-  const Operator* Float64Floor();
-  const Operator* Float64Ceil();
-  const Operator* Float64RoundTruncate();
-  const Operator* Float64RoundTiesAway();
-  bool HasFloat64Floor() { return flags_ & kFloat64Floor; }
-  bool HasFloat64Ceil() { return flags_ & kFloat64Ceil; }
-  bool HasFloat64RoundTruncate() { return flags_ & kFloat64RoundTruncate; }
-  bool HasFloat64RoundTiesAway() { return flags_ & kFloat64RoundTiesAway; }
+  const OptionalOperator Float32RoundDown();
+  const OptionalOperator Float64RoundDown();
+  const OptionalOperator Float32RoundUp();
+  const OptionalOperator Float64RoundUp();
+  const OptionalOperator Float32RoundTruncate();
+  const OptionalOperator Float64RoundTruncate();
+  const OptionalOperator Float64RoundTiesAway();
+  const OptionalOperator Float32RoundTiesEven();
+  const OptionalOperator Float64RoundTiesEven();
+
+  // Floating point bit representation.
+  const Operator* Float64ExtractLowWord32();
+  const Operator* Float64ExtractHighWord32();
+  const Operator* Float64InsertLowWord32();
+  const Operator* Float64InsertHighWord32();
 
   // load [base + index]
   const Operator* Load(LoadRepresentation rep);
@@ -185,6 +305,7 @@
 
   // Access to the machine stack.
   const Operator* LoadStackPointer();
+  const Operator* LoadFramePointer();
 
   // checked-load heap, index, length
   const Operator* CheckedLoad(CheckedLoadRepresentation);
@@ -192,9 +313,9 @@
   const Operator* CheckedStore(CheckedStoreRepresentation);
 
   // Target machine word-size assumed by this builder.
-  bool Is32() const { return word() == kRepWord32; }
-  bool Is64() const { return word() == kRepWord64; }
-  MachineType word() const { return word_; }
+  bool Is32() const { return word() == MachineRepresentation::kWord32; }
+  bool Is64() const { return word() == MachineRepresentation::kWord64; }
+  MachineRepresentation word() const { return word_; }
 
 // Pseudo operators that translate to 32/64-bit operators depending on the
 // word-size of the target machine assumed by this builder.
@@ -226,10 +347,9 @@
 #undef PSEUDO_OP_LIST
 
  private:
-  Zone* zone_;
-  const MachineOperatorGlobalCache& cache_;
-  const MachineType word_;
-  const Flags flags_;
+  MachineOperatorGlobalCache const& cache_;
+  MachineRepresentation const word_;
+  Flags const flags_;
 
   DISALLOW_COPY_AND_ASSIGN(MachineOperatorBuilder);
 };
diff --git a/src/compiler/machine-type.cc b/src/compiler/machine-type.cc
deleted file mode 100644
index 7475a03..0000000
--- a/src/compiler/machine-type.cc
+++ /dev/null
@@ -1,46 +0,0 @@
-// 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/machine-type.h"
-#include "src/ostreams.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-#define PRINT(bit)         \
-  if (type & bit) {        \
-    if (before) os << "|"; \
-    os << #bit;            \
-    before = true;         \
-  }
-
-
-std::ostream& operator<<(std::ostream& os, const MachineType& type) {
-  bool before = false;
-  PRINT(kRepBit);
-  PRINT(kRepWord8);
-  PRINT(kRepWord16);
-  PRINT(kRepWord32);
-  PRINT(kRepWord64);
-  PRINT(kRepFloat32);
-  PRINT(kRepFloat64);
-  PRINT(kRepTagged);
-
-  PRINT(kTypeBool);
-  PRINT(kTypeInt32);
-  PRINT(kTypeUint32);
-  PRINT(kTypeInt64);
-  PRINT(kTypeUint64);
-  PRINT(kTypeNumber);
-  PRINT(kTypeAny);
-  return os;
-}
-
-
-#undef PRINT
-
-}  // namespace compiler
-}  // namespace internal
-}  // namespace v8
diff --git a/src/compiler/machine-type.h b/src/compiler/machine-type.h
deleted file mode 100644
index 4c51a9f..0000000
--- a/src/compiler/machine-type.h
+++ /dev/null
@@ -1,183 +0,0 @@
-// 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.
-
-#ifndef V8_COMPILER_MACHINE_TYPE_H_
-#define V8_COMPILER_MACHINE_TYPE_H_
-
-#include <iosfwd>
-
-#include "src/base/bits.h"
-#include "src/globals.h"
-#include "src/zone.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-// Machine-level types and representations.
-// TODO(titzer): Use the real type system instead of MachineType.
-enum MachineType {
-  // Representations.
-  kRepBit = 1 << 0,
-  kRepWord8 = 1 << 1,
-  kRepWord16 = 1 << 2,
-  kRepWord32 = 1 << 3,
-  kRepWord64 = 1 << 4,
-  kRepFloat32 = 1 << 5,
-  kRepFloat64 = 1 << 6,
-  kRepTagged = 1 << 7,
-
-  // Types.
-  kTypeBool = 1 << 8,
-  kTypeInt32 = 1 << 9,
-  kTypeUint32 = 1 << 10,
-  kTypeInt64 = 1 << 11,
-  kTypeUint64 = 1 << 12,
-  kTypeNumber = 1 << 13,
-  kTypeAny = 1 << 14,
-
-  // Machine types.
-  kMachNone = 0,
-  kMachBool = kRepBit | kTypeBool,
-  kMachFloat32 = kRepFloat32 | kTypeNumber,
-  kMachFloat64 = kRepFloat64 | kTypeNumber,
-  kMachInt8 = kRepWord8 | kTypeInt32,
-  kMachUint8 = kRepWord8 | kTypeUint32,
-  kMachInt16 = kRepWord16 | kTypeInt32,
-  kMachUint16 = kRepWord16 | kTypeUint32,
-  kMachInt32 = kRepWord32 | kTypeInt32,
-  kMachUint32 = kRepWord32 | kTypeUint32,
-  kMachInt64 = kRepWord64 | kTypeInt64,
-  kMachUint64 = kRepWord64 | kTypeUint64,
-  kMachIntPtr = (kPointerSize == 4) ? kMachInt32 : kMachInt64,
-  kMachUintPtr = (kPointerSize == 4) ? kMachUint32 : kMachUint64,
-  kMachPtr = (kPointerSize == 4) ? kRepWord32 : kRepWord64,
-  kMachAnyTagged = kRepTagged | kTypeAny
-};
-
-std::ostream& operator<<(std::ostream& os, const MachineType& type);
-
-typedef uint16_t MachineTypeUnion;
-
-// Globally useful machine types and constants.
-const MachineTypeUnion kRepMask = kRepBit | kRepWord8 | kRepWord16 |
-                                  kRepWord32 | kRepWord64 | kRepFloat32 |
-                                  kRepFloat64 | kRepTagged;
-const MachineTypeUnion kTypeMask = kTypeBool | kTypeInt32 | kTypeUint32 |
-                                   kTypeInt64 | kTypeUint64 | kTypeNumber |
-                                   kTypeAny;
-
-// Gets only the type of the given type.
-inline MachineType TypeOf(MachineType machine_type) {
-  int result = machine_type & kTypeMask;
-  return static_cast<MachineType>(result);
-}
-
-// Gets only the representation of the given type.
-inline MachineType RepresentationOf(MachineType machine_type) {
-  int result = machine_type & kRepMask;
-  CHECK(base::bits::IsPowerOfTwo32(result));
-  return static_cast<MachineType>(result);
-}
-
-// Gets the log2 of the element size in bytes of the machine type.
-inline int ElementSizeLog2Of(MachineType machine_type) {
-  switch (RepresentationOf(machine_type)) {
-    case kRepBit:
-    case kRepWord8:
-      return 0;
-    case kRepWord16:
-      return 1;
-    case kRepWord32:
-    case kRepFloat32:
-      return 2;
-    case kRepWord64:
-    case kRepFloat64:
-      return 3;
-    case kRepTagged:
-      return kPointerSizeLog2;
-    default:
-      break;
-  }
-  UNREACHABLE();
-  return -1;
-}
-
-// Gets the element size in bytes of the machine type.
-inline int ElementSizeOf(MachineType machine_type) {
-  const int shift = ElementSizeLog2Of(machine_type);
-  DCHECK_NE(-1, shift);
-  return 1 << shift;
-}
-
-// Describes the inputs and outputs of a function or call.
-template <typename T>
-class Signature : public ZoneObject {
- public:
-  Signature(size_t return_count, size_t parameter_count, T* reps)
-      : return_count_(return_count),
-        parameter_count_(parameter_count),
-        reps_(reps) {}
-
-  size_t return_count() const { return return_count_; }
-  size_t parameter_count() const { return parameter_count_; }
-
-  T GetParam(size_t index) const {
-    DCHECK(index < parameter_count_);
-    return reps_[return_count_ + index];
-  }
-
-  T GetReturn(size_t index = 0) const {
-    DCHECK(index < return_count_);
-    return reps_[index];
-  }
-
-  // For incrementally building signatures.
-  class Builder {
-   public:
-    Builder(Zone* zone, size_t return_count, size_t parameter_count)
-        : return_count_(return_count),
-          parameter_count_(parameter_count),
-          zone_(zone),
-          rcursor_(0),
-          pcursor_(0),
-          buffer_(zone->NewArray<T>(
-              static_cast<int>(return_count + parameter_count))) {}
-
-    const size_t return_count_;
-    const size_t parameter_count_;
-
-    void AddReturn(T val) {
-      DCHECK(rcursor_ < return_count_);
-      buffer_[rcursor_++] = val;
-    }
-    void AddParam(T val) {
-      DCHECK(pcursor_ < parameter_count_);
-      buffer_[return_count_ + pcursor_++] = val;
-    }
-    Signature<T>* Build() {
-      DCHECK(rcursor_ == return_count_);
-      DCHECK(pcursor_ == parameter_count_);
-      return new (zone_) Signature<T>(return_count_, parameter_count_, buffer_);
-    }
-
-   private:
-    Zone* zone_;
-    size_t rcursor_;
-    size_t pcursor_;
-    T* buffer_;
-  };
-
- protected:
-  size_t return_count_;
-  size_t parameter_count_;
-  T* reps_;
-};
-
-typedef Signature<MachineType> MachineSignature;
-}  // namespace compiler
-}  // namespace internal
-}  // namespace v8
-
-#endif  // V8_COMPILER_MACHINE_TYPE_H_
diff --git a/src/compiler/mips/OWNERS b/src/compiler/mips/OWNERS
index 5508ba6..89455a4 100644
--- a/src/compiler/mips/OWNERS
+++ b/src/compiler/mips/OWNERS
@@ -3,3 +3,4 @@
 akos.palfi@imgtec.com
 balazs.kilvady@imgtec.com
 dusan.milosavljevic@imgtec.com
+ivica.bogosavljevic@imgtec.com
diff --git a/src/compiler/mips/code-generator-mips.cc b/src/compiler/mips/code-generator-mips.cc
index dd92837..75e4b9e 100644
--- a/src/compiler/mips/code-generator-mips.cc
+++ b/src/compiler/mips/code-generator-mips.cc
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "src/ast/scopes.h"
 #include "src/compiler/code-generator.h"
 #include "src/compiler/code-generator-impl.h"
 #include "src/compiler/gap-resolver.h"
 #include "src/compiler/node-matchers.h"
-#include "src/compiler/node-properties-inl.h"
+#include "src/compiler/osr.h"
 #include "src/mips/macro-assembler-mips.h"
-#include "src/scopes.h"
 
 namespace v8 {
 namespace internal {
@@ -35,16 +35,16 @@
 
 
 // Adds Mips-specific methods to convert InstructionOperands.
-class MipsOperandConverter FINAL : public InstructionOperandConverter {
+class MipsOperandConverter final : public InstructionOperandConverter {
  public:
   MipsOperandConverter(CodeGenerator* gen, Instruction* instr)
       : InstructionOperandConverter(gen, instr) {}
 
-  FloatRegister OutputSingleRegister(int index = 0) {
+  FloatRegister OutputSingleRegister(size_t index = 0) {
     return ToSingleRegister(instr_->OutputAt(index));
   }
 
-  FloatRegister InputSingleRegister(int index) {
+  FloatRegister InputSingleRegister(size_t index) {
     return ToSingleRegister(instr_->InputAt(index));
   }
 
@@ -54,7 +54,19 @@
     return ToDoubleRegister(op);
   }
 
-  Operand InputImmediate(int index) {
+  DoubleRegister InputOrZeroDoubleRegister(size_t index) {
+    if (instr_->InputAt(index)->IsImmediate()) return kDoubleRegZero;
+
+    return InputDoubleRegister(index);
+  }
+
+  DoubleRegister InputOrZeroSingleRegister(size_t index) {
+    if (instr_->InputAt(index)->IsImmediate()) return kDoubleRegZero;
+
+    return InputSingleRegister(index);
+  }
+
+  Operand InputImmediate(size_t index) {
     Constant constant = ToConstant(instr_->InputAt(index));
     switch (constant.type()) {
       case Constant::kInt32:
@@ -79,7 +91,7 @@
     return Operand(zero_reg);
   }
 
-  Operand InputOperand(int index) {
+  Operand InputOperand(size_t index) {
     InstructionOperand* op = instr_->InputAt(index);
     if (op->IsRegister()) {
       return Operand(ToRegister(op));
@@ -87,8 +99,8 @@
     return InputImmediate(index);
   }
 
-  MemOperand MemoryOperand(int* first_index) {
-    const int index = *first_index;
+  MemOperand MemoryOperand(size_t* first_index) {
+    const size_t index = *first_index;
     switch (AddressingModeField::decode(instr_->opcode())) {
       case kMode_None:
         break;
@@ -103,33 +115,31 @@
     return MemOperand(no_reg);
   }
 
-  MemOperand MemoryOperand(int index = 0) { return MemoryOperand(&index); }
+  MemOperand MemoryOperand(size_t index = 0) { return MemoryOperand(&index); }
 
   MemOperand ToMemOperand(InstructionOperand* op) const {
-    DCHECK(op != NULL);
-    DCHECK(!op->IsRegister());
-    DCHECK(!op->IsDoubleRegister());
+    DCHECK_NOT_NULL(op);
     DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot());
-    // The linkage computes where all spill slots are located.
-    FrameOffset offset = linkage()->GetFrameOffset(op->index(), frame(), 0);
+    FrameOffset offset = frame_access_state()->GetFrameOffset(
+        AllocatedOperand::cast(op)->index());
     return MemOperand(offset.from_stack_pointer() ? sp : fp, offset.offset());
   }
 };
 
 
-static inline bool HasRegisterInput(Instruction* instr, int index) {
+static inline bool HasRegisterInput(Instruction* instr, size_t index) {
   return instr->InputAt(index)->IsRegister();
 }
 
 
 namespace {
 
-class OutOfLineLoadSingle FINAL : public OutOfLineCode {
+class OutOfLineLoadSingle final : public OutOfLineCode {
  public:
   OutOfLineLoadSingle(CodeGenerator* gen, FloatRegister result)
       : OutOfLineCode(gen), result_(result) {}
 
-  void Generate() FINAL {
+  void Generate() final {
     __ Move(result_, std::numeric_limits<float>::quiet_NaN());
   }
 
@@ -138,12 +148,12 @@
 };
 
 
-class OutOfLineLoadDouble FINAL : public OutOfLineCode {
+class OutOfLineLoadDouble final : public OutOfLineCode {
  public:
   OutOfLineLoadDouble(CodeGenerator* gen, DoubleRegister result)
       : OutOfLineCode(gen), result_(result) {}
 
-  void Generate() FINAL {
+  void Generate() final {
     __ Move(result_, std::numeric_limits<double>::quiet_NaN());
   }
 
@@ -152,12 +162,12 @@
 };
 
 
-class OutOfLineLoadInteger FINAL : public OutOfLineCode {
+class OutOfLineLoadInteger final : public OutOfLineCode {
  public:
   OutOfLineLoadInteger(CodeGenerator* gen, Register result)
       : OutOfLineCode(gen), result_(result) {}
 
-  void Generate() FINAL { __ mov(result_, zero_reg); }
+  void Generate() final { __ mov(result_, zero_reg); }
 
  private:
   Register const result_;
@@ -169,7 +179,7 @@
   OutOfLineRound(CodeGenerator* gen, DoubleRegister result)
       : OutOfLineCode(gen), result_(result) {}
 
-  void Generate() FINAL {
+  void Generate() final {
     // Handle rounding to zero case where sign has to be preserved.
     // High bits of double input already in kScratchReg.
     __ srl(at, kScratchReg, 31);
@@ -182,25 +192,145 @@
 };
 
 
-class OutOfLineTruncate FINAL : public OutOfLineRound {
+class OutOfLineRound32 : public OutOfLineCode {
  public:
-  OutOfLineTruncate(CodeGenerator* gen, DoubleRegister result)
-      : OutOfLineRound(gen, result) {}
+  OutOfLineRound32(CodeGenerator* gen, DoubleRegister result)
+      : OutOfLineCode(gen), result_(result) {}
+
+  void Generate() final {
+    // Handle rounding to zero case where sign has to be preserved.
+    // High bits of float input already in kScratchReg.
+    __ srl(at, kScratchReg, 31);
+    __ sll(at, at, 31);
+    __ mtc1(at, result_);
+  }
+
+ private:
+  DoubleRegister const result_;
 };
 
 
-class OutOfLineFloor FINAL : public OutOfLineRound {
+class OutOfLineRecordWrite final : public OutOfLineCode {
  public:
-  OutOfLineFloor(CodeGenerator* gen, DoubleRegister result)
-      : OutOfLineRound(gen, result) {}
+  OutOfLineRecordWrite(CodeGenerator* gen, Register object, Register index,
+                       Register value, Register scratch0, Register scratch1,
+                       RecordWriteMode mode)
+      : OutOfLineCode(gen),
+        object_(object),
+        index_(index),
+        value_(value),
+        scratch0_(scratch0),
+        scratch1_(scratch1),
+        mode_(mode) {}
+
+  void Generate() final {
+    if (mode_ > RecordWriteMode::kValueIsPointer) {
+      __ JumpIfSmi(value_, exit());
+    }
+    if (mode_ > RecordWriteMode::kValueIsMap) {
+      __ CheckPageFlag(value_, scratch0_,
+                       MemoryChunk::kPointersToHereAreInterestingMask, eq,
+                       exit());
+    }
+    SaveFPRegsMode const save_fp_mode =
+        frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs;
+    // TODO(turbofan): Once we get frame elision working, we need to save
+    // and restore lr properly here if the frame was elided.
+    RecordWriteStub stub(isolate(), object_, scratch0_, scratch1_,
+                         EMIT_REMEMBERED_SET, save_fp_mode);
+    __ Addu(scratch1_, object_, index_);
+    __ CallStub(&stub);
+  }
+
+ private:
+  Register const object_;
+  Register const index_;
+  Register const value_;
+  Register const scratch0_;
+  Register const scratch1_;
+  RecordWriteMode const mode_;
 };
 
 
-class OutOfLineCeil FINAL : public OutOfLineRound {
- public:
-  OutOfLineCeil(CodeGenerator* gen, DoubleRegister result)
-      : OutOfLineRound(gen, result) {}
-};
+Condition FlagsConditionToConditionCmp(FlagsCondition condition) {
+  switch (condition) {
+    case kEqual:
+      return eq;
+    case kNotEqual:
+      return ne;
+    case kSignedLessThan:
+      return lt;
+    case kSignedGreaterThanOrEqual:
+      return ge;
+    case kSignedLessThanOrEqual:
+      return le;
+    case kSignedGreaterThan:
+      return gt;
+    case kUnsignedLessThan:
+      return lo;
+    case kUnsignedGreaterThanOrEqual:
+      return hs;
+    case kUnsignedLessThanOrEqual:
+      return ls;
+    case kUnsignedGreaterThan:
+      return hi;
+    case kUnorderedEqual:
+    case kUnorderedNotEqual:
+      break;
+    default:
+      break;
+  }
+  UNREACHABLE();
+  return kNoCondition;
+}
+
+
+Condition FlagsConditionToConditionTst(FlagsCondition condition) {
+  switch (condition) {
+    case kNotEqual:
+      return ne;
+    case kEqual:
+      return eq;
+    default:
+      break;
+  }
+  UNREACHABLE();
+  return kNoCondition;
+}
+
+
+FPUCondition FlagsConditionToConditionCmpFPU(bool& predicate,
+                                             FlagsCondition condition) {
+  switch (condition) {
+    case kEqual:
+      predicate = true;
+      return EQ;
+    case kNotEqual:
+      predicate = false;
+      return EQ;
+    case kUnsignedLessThan:
+      predicate = true;
+      return OLT;
+    case kUnsignedGreaterThanOrEqual:
+      predicate = false;
+      return ULT;
+    case kUnsignedLessThanOrEqual:
+      predicate = true;
+      return OLE;
+    case kUnsignedGreaterThan:
+      predicate = false;
+      return ULE;
+    case kUnorderedEqual:
+    case kUnorderedNotEqual:
+      predicate = true;
+      break;
+    default:
+      predicate = true;
+      break;
+  }
+  UNREACHABLE();
+  return kNoFPUCondition;
+}
 
 }  // namespace
 
@@ -212,8 +342,8 @@
     if (instr->InputAt(0)->IsRegister()) {                                    \
       auto offset = i.InputRegister(0);                                       \
       __ Branch(USE_DELAY_SLOT, ool->entry(), hs, offset, i.InputOperand(1)); \
-      __ addu(at, i.InputRegister(2), offset);                                \
-      __ asm_instr(result, MemOperand(at, 0));                                \
+      __ addu(kScratchReg, i.InputRegister(2), offset);                       \
+      __ asm_instr(result, MemOperand(kScratchReg, 0));                       \
     } else {                                                                  \
       auto offset = i.InputOperand(0).immediate();                            \
       __ Branch(ool->entry(), ls, i.InputRegister(1), Operand(offset));       \
@@ -230,8 +360,8 @@
     if (instr->InputAt(0)->IsRegister()) {                                    \
       auto offset = i.InputRegister(0);                                       \
       __ Branch(USE_DELAY_SLOT, ool->entry(), hs, offset, i.InputOperand(1)); \
-      __ addu(at, i.InputRegister(2), offset);                                \
-      __ asm_instr(result, MemOperand(at, 0));                                \
+      __ addu(kScratchReg, i.InputRegister(2), offset);                       \
+      __ asm_instr(result, MemOperand(kScratchReg, 0));                       \
     } else {                                                                  \
       auto offset = i.InputOperand(0).immediate();                            \
       __ Branch(ool->entry(), ls, i.InputRegister(1), Operand(offset));       \
@@ -248,8 +378,8 @@
       auto offset = i.InputRegister(0);                                \
       auto value = i.Input##width##Register(2);                        \
       __ Branch(USE_DELAY_SLOT, &done, hs, offset, i.InputOperand(1)); \
-      __ addu(at, i.InputRegister(3), offset);                         \
-      __ asm_instr(value, MemOperand(at, 0));                          \
+      __ addu(kScratchReg, i.InputRegister(3), offset);                \
+      __ asm_instr(value, MemOperand(kScratchReg, 0));                 \
     } else {                                                           \
       auto offset = i.InputOperand(0).immediate();                     \
       auto value = i.Input##width##Register(2);                        \
@@ -267,8 +397,8 @@
       auto offset = i.InputRegister(0);                                \
       auto value = i.InputRegister(2);                                 \
       __ Branch(USE_DELAY_SLOT, &done, hs, offset, i.InputOperand(1)); \
-      __ addu(at, i.InputRegister(3), offset);                         \
-      __ asm_instr(value, MemOperand(at, 0));                          \
+      __ addu(kScratchReg, i.InputRegister(3), offset);                \
+      __ asm_instr(value, MemOperand(kScratchReg, 0));                 \
     } else {                                                           \
       auto offset = i.InputOperand(0).immediate();                     \
       auto value = i.InputRegister(2);                                 \
@@ -279,10 +409,15 @@
   } while (0)
 
 
-#define ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(asm_instr, operation)                  \
-  do {                                                                         \
-    auto ool =                                                                 \
-        new (zone()) OutOfLine##operation(this, i.OutputDoubleRegister());     \
+#define ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(mode)                                  \
+  if (IsMipsArchVariant(kMips32r6)) {                                          \
+    __ cfc1(kScratchReg, FCSR);                                                \
+    __ li(at, Operand(mode_##mode));                                           \
+    __ ctc1(at, FCSR);                                                         \
+    __ rint_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0));             \
+    __ ctc1(kScratchReg, FCSR);                                                \
+  } else {                                                                     \
+    auto ool = new (zone()) OutOfLineRound(this, i.OutputDoubleRegister());    \
     Label done;                                                                \
     __ Mfhc1(kScratchReg, i.InputDoubleRegister(0));                           \
     __ Ext(at, kScratchReg, HeapNumber::kExponentShift,                        \
@@ -290,14 +425,63 @@
     __ Branch(USE_DELAY_SLOT, &done, hs, at,                                   \
               Operand(HeapNumber::kExponentBias + HeapNumber::kMantissaBits)); \
     __ mov_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0));              \
-    __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0));          \
+    __ mode##_l_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0));         \
     __ Move(at, kScratchReg2, i.OutputDoubleRegister());                       \
     __ or_(at, at, kScratchReg2);                                              \
     __ Branch(USE_DELAY_SLOT, ool->entry(), eq, at, Operand(zero_reg));        \
     __ cvt_d_l(i.OutputDoubleRegister(), i.OutputDoubleRegister());            \
     __ bind(ool->exit());                                                      \
     __ bind(&done);                                                            \
-  } while (0)
+  }
+
+
+#define ASSEMBLE_ROUND_FLOAT_TO_FLOAT(mode)                                   \
+  if (IsMipsArchVariant(kMips32r6)) {                                         \
+    __ cfc1(kScratchReg, FCSR);                                               \
+    __ li(at, Operand(mode_##mode));                                          \
+    __ ctc1(at, FCSR);                                                        \
+    __ rint_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0));            \
+    __ ctc1(kScratchReg, FCSR);                                               \
+  } else {                                                                    \
+    int32_t kFloat32ExponentBias = 127;                                       \
+    int32_t kFloat32MantissaBits = 23;                                        \
+    int32_t kFloat32ExponentBits = 8;                                         \
+    auto ool = new (zone()) OutOfLineRound32(this, i.OutputDoubleRegister()); \
+    Label done;                                                               \
+    __ mfc1(kScratchReg, i.InputDoubleRegister(0));                           \
+    __ Ext(at, kScratchReg, kFloat32MantissaBits, kFloat32ExponentBits);      \
+    __ Branch(USE_DELAY_SLOT, &done, hs, at,                                  \
+              Operand(kFloat32ExponentBias + kFloat32MantissaBits));          \
+    __ mov_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0));             \
+    __ mode##_w_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0));        \
+    __ mfc1(at, i.OutputDoubleRegister());                                    \
+    __ Branch(USE_DELAY_SLOT, ool->entry(), eq, at, Operand(zero_reg));       \
+    __ cvt_s_w(i.OutputDoubleRegister(), i.OutputDoubleRegister());           \
+    __ bind(ool->exit());                                                     \
+    __ bind(&done);                                                           \
+  }
+
+void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) {
+  int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta);
+  if (sp_slot_delta > 0) {
+    __ addiu(sp, sp, sp_slot_delta * kPointerSize);
+  }
+  frame_access_state()->SetFrameAccessToDefault();
+}
+
+
+void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) {
+  int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta);
+  if (sp_slot_delta < 0) {
+    __ Subu(sp, sp, Operand(-sp_slot_delta * kPointerSize));
+    frame_access_state()->IncreaseSPDelta(-sp_slot_delta);
+  }
+  if (frame()->needs_frame()) {
+    __ lw(ra, MemOperand(fp, StandardFrameConstants::kCallerPCOffset));
+    __ lw(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
+  }
+  frame_access_state()->SetFrameAccessToSP();
+}
 
 
 // Assembles an instruction after register allocation, producing machine code.
@@ -315,7 +499,21 @@
         __ addiu(at, i.InputRegister(0), Code::kHeaderSize - kHeapObjectTag);
         __ Call(at);
       }
-      AddSafepointAndDeopt(instr);
+      RecordCallPosition(instr);
+      frame_access_state()->ClearSPDelta();
+      break;
+    }
+    case kArchTailCallCodeObject: {
+      int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
+      AssembleDeconstructActivationRecord(stack_param_delta);
+      if (instr->InputAt(0)->IsImmediate()) {
+        __ Jump(Handle<Code>::cast(i.InputHeapObject(0)),
+                RelocInfo::CODE_TARGET);
+      } else {
+        __ addiu(at, i.InputRegister(0), Code::kHeaderSize - kHeapObjectTag);
+        __ Jump(at);
+      }
+      frame_access_state()->ClearSPDelta();
       break;
     }
     case kArchCallJSFunction: {
@@ -329,37 +527,115 @@
 
       __ lw(at, FieldMemOperand(func, JSFunction::kCodeEntryOffset));
       __ Call(at);
-      AddSafepointAndDeopt(instr);
+      RecordCallPosition(instr);
+      frame_access_state()->ClearSPDelta();
+      break;
+    }
+    case kArchTailCallJSFunction: {
+      Register func = i.InputRegister(0);
+      if (FLAG_debug_code) {
+        // Check the function's context matches the context argument.
+        __ lw(kScratchReg, FieldMemOperand(func, JSFunction::kContextOffset));
+        __ Assert(eq, kWrongFunctionContext, cp, Operand(kScratchReg));
+      }
+
+      int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
+      AssembleDeconstructActivationRecord(stack_param_delta);
+      __ lw(at, FieldMemOperand(func, JSFunction::kCodeEntryOffset));
+      __ Jump(at);
+      frame_access_state()->ClearSPDelta();
+      break;
+    }
+    case kArchLazyBailout: {
+      EnsureSpaceForLazyDeopt();
+      RecordCallPosition(instr);
+      break;
+    }
+    case kArchPrepareCallCFunction: {
+      int const num_parameters = MiscField::decode(instr->opcode());
+      __ PrepareCallCFunction(num_parameters, kScratchReg);
+      // Frame alignment requires using FP-relative frame addressing.
+      frame_access_state()->SetFrameAccessToFP();
+      break;
+    }
+    case kArchPrepareTailCall:
+      AssemblePrepareTailCall(i.InputInt32(instr->InputCount() - 1));
+      break;
+    case kArchCallCFunction: {
+      int const num_parameters = MiscField::decode(instr->opcode());
+      if (instr->InputAt(0)->IsImmediate()) {
+        ExternalReference ref = i.InputExternalReference(0);
+        __ CallCFunction(ref, num_parameters);
+      } else {
+        Register func = i.InputRegister(0);
+        __ CallCFunction(func, num_parameters);
+      }
+      frame_access_state()->SetFrameAccessToDefault();
+      frame_access_state()->ClearSPDelta();
       break;
     }
     case kArchJmp:
       AssembleArchJump(i.InputRpo(0));
       break;
+    case kArchLookupSwitch:
+      AssembleArchLookupSwitch(instr);
+      break;
+    case kArchTableSwitch:
+      AssembleArchTableSwitch(instr);
+      break;
     case kArchNop:
+    case kArchThrowTerminator:
       // don't emit code for nops.
       break;
+    case kArchDeoptimize: {
+      int deopt_state_id =
+          BuildTranslation(instr, -1, 0, OutputFrameStateCombine::Ignore());
+      Deoptimizer::BailoutType bailout_type =
+          Deoptimizer::BailoutType(MiscField::decode(instr->opcode()));
+      AssembleDeoptimizerCall(deopt_state_id, bailout_type);
+      break;
+    }
     case kArchRet:
       AssembleReturn();
       break;
     case kArchStackPointer:
       __ mov(i.OutputRegister(), sp);
       break;
+    case kArchFramePointer:
+      __ mov(i.OutputRegister(), fp);
+      break;
     case kArchTruncateDoubleToI:
       __ TruncateDoubleToI(i.OutputRegister(), i.InputDoubleRegister(0));
       break;
+    case kArchStoreWithWriteBarrier: {
+      RecordWriteMode mode =
+          static_cast<RecordWriteMode>(MiscField::decode(instr->opcode()));
+      Register object = i.InputRegister(0);
+      Register index = i.InputRegister(1);
+      Register value = i.InputRegister(2);
+      Register scratch0 = i.TempRegister(0);
+      Register scratch1 = i.TempRegister(1);
+      auto ool = new (zone()) OutOfLineRecordWrite(this, object, index, value,
+                                                   scratch0, scratch1, mode);
+      __ Addu(at, object, index);
+      __ sw(value, MemOperand(at));
+      __ CheckPageFlag(object, scratch0,
+                       MemoryChunk::kPointersFromHereAreInterestingMask, ne,
+                       ool->entry());
+      __ bind(ool->exit());
+      break;
+    }
     case kMipsAdd:
       __ Addu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
       break;
     case kMipsAddOvf:
-      __ AdduAndCheckForOverflow(i.OutputRegister(), i.InputRegister(0),
-                                 i.InputOperand(1), kCompareReg, kScratchReg);
+      // Pseudo-instruction used for overflow/branch. No opcode emitted here.
       break;
     case kMipsSub:
       __ Subu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
       break;
     case kMipsSubOvf:
-      __ SubuAndCheckForOverflow(i.OutputRegister(), i.InputRegister(0),
-                                 i.InputOperand(1), kCompareReg, kScratchReg);
+      // Pseudo-instruction used for overflow/branch. No opcode emitted here.
       break;
     case kMipsMul:
       __ Mul(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
@@ -372,9 +648,19 @@
       break;
     case kMipsDiv:
       __ Div(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      if (IsMipsArchVariant(kMips32r6)) {
+        __ selnez(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
+      } else {
+        __ Movz(i.OutputRegister(), i.InputRegister(1), i.InputRegister(1));
+      }
       break;
     case kMipsDivU:
       __ Divu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      if (IsMipsArchVariant(kMips32r6)) {
+        __ selnez(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
+      } else {
+        __ Movz(i.OutputRegister(), i.InputRegister(1), i.InputRegister(1));
+      }
       break;
     case kMipsMod:
       __ Mod(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
@@ -388,9 +674,20 @@
     case kMipsOr:
       __ Or(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
       break;
+    case kMipsNor:
+      if (instr->InputAt(1)->IsRegister()) {
+        __ Nor(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      } else {
+        DCHECK(i.InputOperand(1).immediate() == 0);
+        __ Nor(i.OutputRegister(), i.InputRegister(0), zero_reg);
+      }
+      break;
     case kMipsXor:
       __ Xor(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
       break;
+    case kMipsClz:
+      __ Clz(i.OutputRegister(), i.InputRegister(0));
+      break;
     case kMipsShl:
       if (instr->InputAt(1)->IsRegister()) {
         __ sllv(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
@@ -415,6 +712,18 @@
         __ sra(i.OutputRegister(), i.InputRegister(0), imm);
       }
       break;
+    case kMipsExt:
+      __ Ext(i.OutputRegister(), i.InputRegister(0), i.InputInt8(1),
+             i.InputInt8(2));
+      break;
+    case kMipsIns:
+      if (instr->InputAt(1)->IsImmediate() && i.InputInt8(1) == 0) {
+        __ Ins(i.OutputRegister(), zero_reg, i.InputInt8(1), i.InputInt8(2));
+      } else {
+        __ Ins(i.OutputRegister(), i.InputRegister(0), i.InputInt8(1),
+               i.InputInt8(2));
+      }
+      break;
     case kMipsRor:
       __ Ror(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
       break;
@@ -434,6 +743,56 @@
       }
       break;
 
+    case kMipsCmpS:
+      // Psuedo-instruction used for FP cmp/branch. No opcode emitted here.
+      break;
+    case kMipsAddS:
+      // TODO(plind): add special case: combine mult & add.
+      __ add_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+               i.InputDoubleRegister(1));
+      break;
+    case kMipsSubS:
+      __ sub_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+               i.InputDoubleRegister(1));
+      break;
+    case kMipsMulS:
+      // TODO(plind): add special case: right op is -1.0, see arm port.
+      __ mul_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+               i.InputDoubleRegister(1));
+      break;
+    case kMipsDivS:
+      __ div_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+               i.InputDoubleRegister(1));
+      break;
+    case kMipsModS: {
+      // TODO(bmeurer): We should really get rid of this special instruction,
+      // and generate a CallAddress instruction instead.
+      FrameScope scope(masm(), StackFrame::MANUAL);
+      __ PrepareCallCFunction(0, 2, kScratchReg);
+      __ MovToFloatParameters(i.InputDoubleRegister(0),
+                              i.InputDoubleRegister(1));
+      // TODO(balazs.kilvady): implement mod_two_floats_operation(isolate())
+      __ CallCFunction(ExternalReference::mod_two_doubles_operation(isolate()),
+                       0, 2);
+      // Move the result in the double result register.
+      __ MovFromFloatResult(i.OutputSingleRegister());
+      break;
+    }
+    case kMipsAbsS:
+      __ abs_s(i.OutputSingleRegister(), i.InputSingleRegister(0));
+      break;
+    case kMipsSqrtS: {
+      __ sqrt_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
+      break;
+    }
+    case kMipsMaxS:
+      __ max_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+               i.InputDoubleRegister(1));
+      break;
+    case kMipsMinS:
+      __ min_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+               i.InputDoubleRegister(1));
+      break;
     case kMipsCmpD:
       // Psuedo-instruction used for FP cmp/branch. No opcode emitted here.
       break;
@@ -468,20 +827,107 @@
       __ MovFromFloatResult(i.OutputDoubleRegister());
       break;
     }
-    case kMipsFloat64Floor: {
-      ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(floor_l_d, Floor);
+    case kMipsAbsD:
+      __ abs_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
+      break;
+    case kMipsSqrtD: {
+      __ sqrt_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
       break;
     }
-    case kMipsFloat64Ceil: {
-      ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(ceil_l_d, Ceil);
+    case kMipsMaxD:
+      __ max_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+               i.InputDoubleRegister(1));
+      break;
+    case kMipsMinD:
+      __ min_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+               i.InputDoubleRegister(1));
+      break;
+    case kMipsFloat64RoundDown: {
+      ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(floor);
+      break;
+    }
+    case kMipsFloat32RoundDown: {
+      ASSEMBLE_ROUND_FLOAT_TO_FLOAT(floor);
       break;
     }
     case kMipsFloat64RoundTruncate: {
-      ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(trunc_l_d, Truncate);
+      ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(trunc);
       break;
     }
-    case kMipsSqrtD: {
-      __ sqrt_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
+    case kMipsFloat32RoundTruncate: {
+      ASSEMBLE_ROUND_FLOAT_TO_FLOAT(trunc);
+      break;
+    }
+    case kMipsFloat64RoundUp: {
+      ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(ceil);
+      break;
+    }
+    case kMipsFloat32RoundUp: {
+      ASSEMBLE_ROUND_FLOAT_TO_FLOAT(ceil);
+      break;
+    }
+    case kMipsFloat64RoundTiesEven: {
+      ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(round);
+      break;
+    }
+    case kMipsFloat32RoundTiesEven: {
+      ASSEMBLE_ROUND_FLOAT_TO_FLOAT(round);
+      break;
+    }
+    case kMipsFloat64Max: {
+      // (b < a) ? a : b
+      if (IsMipsArchVariant(kMips32r6)) {
+        __ cmp_d(OLT, i.OutputDoubleRegister(), i.InputDoubleRegister(1),
+                 i.InputDoubleRegister(0));
+        __ sel_d(i.OutputDoubleRegister(), i.InputDoubleRegister(1),
+                 i.InputDoubleRegister(0));
+      } else {
+        __ c_d(OLT, i.InputDoubleRegister(0), i.InputDoubleRegister(1));
+        // Left operand is result, passthrough if false.
+        __ movt_d(i.OutputDoubleRegister(), i.InputDoubleRegister(1));
+      }
+      break;
+    }
+    case kMipsFloat64Min: {
+      // (a < b) ? a : b
+      if (IsMipsArchVariant(kMips32r6)) {
+        __ cmp_d(OLT, i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+                 i.InputDoubleRegister(1));
+        __ sel_d(i.OutputDoubleRegister(), i.InputDoubleRegister(1),
+                 i.InputDoubleRegister(0));
+      } else {
+        __ c_d(OLT, i.InputDoubleRegister(1), i.InputDoubleRegister(0));
+        // Right operand is result, passthrough if false.
+        __ movt_d(i.OutputDoubleRegister(), i.InputDoubleRegister(1));
+      }
+      break;
+    }
+    case kMipsFloat32Max: {
+      // (b < a) ? a : b
+      if (IsMipsArchVariant(kMips32r6)) {
+        __ cmp_s(OLT, i.OutputDoubleRegister(), i.InputDoubleRegister(1),
+                 i.InputDoubleRegister(0));
+        __ sel_s(i.OutputDoubleRegister(), i.InputDoubleRegister(1),
+                 i.InputDoubleRegister(0));
+      } else {
+        __ c_s(OLT, i.InputDoubleRegister(0), i.InputDoubleRegister(1));
+        // Left operand is result, passthrough if false.
+        __ movt_s(i.OutputDoubleRegister(), i.InputDoubleRegister(1));
+      }
+      break;
+    }
+    case kMipsFloat32Min: {
+      // (a < b) ? a : b
+      if (IsMipsArchVariant(kMips32r6)) {
+        __ cmp_s(OLT, i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+                 i.InputDoubleRegister(1));
+        __ sel_s(i.OutputDoubleRegister(), i.InputDoubleRegister(1),
+                 i.InputDoubleRegister(0));
+      } else {
+        __ c_s(OLT, i.InputDoubleRegister(1), i.InputDoubleRegister(0));
+        // Right operand is result, passthrough if false.
+        __ movt_s(i.OutputDoubleRegister(), i.InputDoubleRegister(1));
+      }
       break;
     }
     case kMipsCvtSD: {
@@ -498,11 +944,35 @@
       __ cvt_d_w(i.OutputDoubleRegister(), scratch);
       break;
     }
+    case kMipsCvtSW: {
+      FPURegister scratch = kScratchDoubleReg;
+      __ mtc1(i.InputRegister(0), scratch);
+      __ cvt_s_w(i.OutputDoubleRegister(), scratch);
+      break;
+    }
     case kMipsCvtDUw: {
       FPURegister scratch = kScratchDoubleReg;
       __ Cvt_d_uw(i.OutputDoubleRegister(), i.InputRegister(0), scratch);
       break;
     }
+    case kMipsFloorWD: {
+      FPURegister scratch = kScratchDoubleReg;
+      __ floor_w_d(scratch, i.InputDoubleRegister(0));
+      __ mfc1(i.OutputRegister(), scratch);
+      break;
+    }
+    case kMipsCeilWD: {
+      FPURegister scratch = kScratchDoubleReg;
+      __ ceil_w_d(scratch, i.InputDoubleRegister(0));
+      __ mfc1(i.OutputRegister(), scratch);
+      break;
+    }
+    case kMipsRoundWD: {
+      FPURegister scratch = kScratchDoubleReg;
+      __ round_w_d(scratch, i.InputDoubleRegister(0));
+      __ mfc1(i.OutputRegister(), scratch);
+      break;
+    }
     case kMipsTruncWD: {
       FPURegister scratch = kScratchDoubleReg;
       // Other arches use round to zero here, so we follow.
@@ -510,12 +980,48 @@
       __ mfc1(i.OutputRegister(), scratch);
       break;
     }
+    case kMipsFloorWS: {
+      FPURegister scratch = kScratchDoubleReg;
+      __ floor_w_s(scratch, i.InputDoubleRegister(0));
+      __ mfc1(i.OutputRegister(), scratch);
+      break;
+    }
+    case kMipsCeilWS: {
+      FPURegister scratch = kScratchDoubleReg;
+      __ ceil_w_s(scratch, i.InputDoubleRegister(0));
+      __ mfc1(i.OutputRegister(), scratch);
+      break;
+    }
+    case kMipsRoundWS: {
+      FPURegister scratch = kScratchDoubleReg;
+      __ round_w_s(scratch, i.InputDoubleRegister(0));
+      __ mfc1(i.OutputRegister(), scratch);
+      break;
+    }
+    case kMipsTruncWS: {
+      FPURegister scratch = kScratchDoubleReg;
+      __ trunc_w_s(scratch, i.InputDoubleRegister(0));
+      __ mfc1(i.OutputRegister(), scratch);
+      break;
+    }
     case kMipsTruncUwD: {
       FPURegister scratch = kScratchDoubleReg;
       // TODO(plind): Fix wrong param order of Trunc_uw_d() macro-asm function.
       __ Trunc_uw_d(i.InputDoubleRegister(0), i.OutputRegister(), scratch);
       break;
     }
+    case kMipsFloat64ExtractLowWord32:
+      __ FmoveLow(i.OutputRegister(), i.InputDoubleRegister(0));
+      break;
+    case kMipsFloat64ExtractHighWord32:
+      __ FmoveHigh(i.OutputRegister(), i.InputDoubleRegister(0));
+      break;
+    case kMipsFloat64InsertLowWord32:
+      __ FmoveLow(i.OutputDoubleRegister(), i.InputRegister(1));
+      break;
+    case kMipsFloat64InsertHighWord32:
+      __ FmoveHigh(i.OutputDoubleRegister(), i.InputRegister(1));
+      break;
     // ... more basic instructions ...
 
     case kMipsLbu:
@@ -547,7 +1053,7 @@
       break;
     }
     case kMipsSwc1: {
-      int index = 0;
+      size_t index = 0;
       MemOperand operand = i.MemoryOperand(&index);
       __ swc1(i.InputSingleRegister(index), operand);
       break;
@@ -559,28 +1065,26 @@
       __ sdc1(i.InputDoubleRegister(2), i.MemoryOperand());
       break;
     case kMipsPush:
-      __ Push(i.InputRegister(0));
+      if (instr->InputAt(0)->IsDoubleRegister()) {
+        __ sdc1(i.InputDoubleRegister(0), MemOperand(sp, -kDoubleSize));
+        __ Subu(sp, sp, Operand(kDoubleSize));
+        frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize);
+      } else {
+        __ Push(i.InputRegister(0));
+        frame_access_state()->IncreaseSPDelta(1);
+      }
       break;
     case kMipsStackClaim: {
-      int words = MiscField::decode(instr->opcode());
-      __ Subu(sp, sp, Operand(words << kPointerSizeLog2));
+      __ Subu(sp, sp, Operand(i.InputInt32(0)));
+      frame_access_state()->IncreaseSPDelta(i.InputInt32(0) / kPointerSize);
       break;
     }
     case kMipsStoreToStackSlot: {
-      int slot = MiscField::decode(instr->opcode());
-      __ sw(i.InputRegister(0), MemOperand(sp, slot << kPointerSizeLog2));
-      break;
-    }
-    case kMipsStoreWriteBarrier: {
-      Register object = i.InputRegister(0);
-      Register index = i.InputRegister(1);
-      Register value = i.InputRegister(2);
-      __ addu(index, object, index);
-      __ sw(value, MemOperand(index));
-      SaveFPRegsMode mode =
-          frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs;
-      RAStatus ra_status = kRAHasNotBeenSaved;
-      __ RecordWrite(object, index, value, ra_status, mode);
+      if (instr->InputAt(0)->IsDoubleRegister()) {
+        __ sdc1(i.InputDoubleRegister(0), MemOperand(sp, i.InputInt32(1)));
+      } else {
+        __ sw(i.InputRegister(0), MemOperand(sp, i.InputInt32(1)));
+      }
       break;
     }
     case kCheckedLoadInt8:
@@ -619,8 +1123,12 @@
     case kCheckedStoreFloat64:
       ASSEMBLE_CHECKED_STORE_FLOAT(Double, sdc1);
       break;
+    case kCheckedLoadWord64:
+    case kCheckedStoreWord64:
+      UNREACHABLE();  // currently unsupported checked int64 load/store.
+      break;
   }
-}
+}  // NOLINT(readability/fn_size)
 
 
 #define UNSUPPORTED_COND(opcode, condition)                                  \
@@ -628,137 +1136,113 @@
   out << "Unsupported " << #opcode << " condition: \"" << condition << "\""; \
   UNIMPLEMENTED();
 
+static bool convertCondition(FlagsCondition condition, Condition& cc) {
+  switch (condition) {
+    case kEqual:
+      cc = eq;
+      return true;
+    case kNotEqual:
+      cc = ne;
+      return true;
+    case kUnsignedLessThan:
+      cc = lt;
+      return true;
+    case kUnsignedGreaterThanOrEqual:
+      cc = uge;
+      return true;
+    case kUnsignedLessThanOrEqual:
+      cc = le;
+      return true;
+    case kUnsignedGreaterThan:
+      cc = ugt;
+      return true;
+    default:
+      break;
+  }
+  return false;
+}
+
+
 // Assembles branches after an instruction.
 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) {
   MipsOperandConverter i(this, instr);
   Label* tlabel = branch->true_label;
   Label* flabel = branch->false_label;
   Condition cc = kNoCondition;
-
   // MIPS does not have condition code flags, so compare and branch are
   // implemented differently than on the other arch's. The compare operations
   // emit mips pseudo-instructions, which are handled here by branch
   // instructions that do the actual comparison. Essential that the input
   // registers to compare pseudo-op are not modified before this branch op, as
   // they are tested here.
-  // TODO(plind): Add CHECK() to ensure that test/cmp and this branch were
-  //    not separated by other instructions.
 
   if (instr->arch_opcode() == kMipsTst) {
-    switch (branch->condition) {
-      case kNotEqual:
-        cc = ne;
-        break;
-      case kEqual:
-        cc = eq;
-        break;
-      default:
-        UNSUPPORTED_COND(kMipsTst, branch->condition);
-        break;
-    }
+    cc = FlagsConditionToConditionTst(branch->condition);
     __ And(at, i.InputRegister(0), i.InputOperand(1));
     __ Branch(tlabel, cc, at, Operand(zero_reg));
-
-  } else if (instr->arch_opcode() == kMipsAddOvf ||
-             instr->arch_opcode() == kMipsSubOvf) {
-    // kMipsAddOvf, SubOvf emit negative result to 'kCompareReg' on overflow.
+  } else if (instr->arch_opcode() == kMipsAddOvf) {
     switch (branch->condition) {
       case kOverflow:
-        cc = lt;
+        __ AddBranchOvf(i.OutputRegister(), i.InputRegister(0),
+                        i.InputOperand(1), tlabel, flabel);
         break;
       case kNotOverflow:
-        cc = ge;
+        __ AddBranchOvf(i.OutputRegister(), i.InputRegister(0),
+                        i.InputOperand(1), flabel, tlabel);
         break;
       default:
         UNSUPPORTED_COND(kMipsAddOvf, branch->condition);
         break;
     }
-    __ Branch(tlabel, cc, kCompareReg, Operand(zero_reg));
-
+  } else if (instr->arch_opcode() == kMipsSubOvf) {
+    switch (branch->condition) {
+      case kOverflow:
+        __ SubBranchOvf(i.OutputRegister(), i.InputRegister(0),
+                        i.InputOperand(1), tlabel, flabel);
+        break;
+      case kNotOverflow:
+        __ SubBranchOvf(i.OutputRegister(), i.InputRegister(0),
+                        i.InputOperand(1), flabel, tlabel);
+        break;
+      default:
+        UNSUPPORTED_COND(kMipsAddOvf, branch->condition);
+        break;
+    }
   } else if (instr->arch_opcode() == kMipsCmp) {
-    switch (branch->condition) {
-      case kEqual:
-        cc = eq;
-        break;
-      case kNotEqual:
-        cc = ne;
-        break;
-      case kSignedLessThan:
-        cc = lt;
-        break;
-      case kSignedGreaterThanOrEqual:
-        cc = ge;
-        break;
-      case kSignedLessThanOrEqual:
-        cc = le;
-        break;
-      case kSignedGreaterThan:
-        cc = gt;
-        break;
-      case kUnsignedLessThan:
-        cc = lo;
-        break;
-      case kUnsignedGreaterThanOrEqual:
-        cc = hs;
-        break;
-      case kUnsignedLessThanOrEqual:
-        cc = ls;
-        break;
-      case kUnsignedGreaterThan:
-        cc = hi;
-        break;
-      default:
-        UNSUPPORTED_COND(kMipsCmp, branch->condition);
-        break;
-    }
+    cc = FlagsConditionToConditionCmp(branch->condition);
     __ Branch(tlabel, cc, i.InputRegister(0), i.InputOperand(1));
-
-    if (!branch->fallthru) __ Branch(flabel);  // no fallthru to flabel.
-
-  } else if (instr->arch_opcode() == kMipsCmpD) {
-    // TODO(dusmil) optimize unordered checks to use fewer instructions
-    // even if we have to unfold BranchF macro.
-    Label* nan = flabel;
-    switch (branch->condition) {
-      case kUnorderedEqual:
-        cc = eq;
-        break;
-      case kUnorderedNotEqual:
-        cc = ne;
-        nan = tlabel;
-        break;
-      case kUnorderedLessThan:
-        cc = lt;
-        break;
-      case kUnorderedGreaterThanOrEqual:
-        cc = ge;
-        nan = tlabel;
-        break;
-      case kUnorderedLessThanOrEqual:
-        cc = le;
-        break;
-      case kUnorderedGreaterThan:
-        cc = gt;
-        nan = tlabel;
-        break;
-      default:
-        UNSUPPORTED_COND(kMipsCmpD, branch->condition);
-        break;
+  } else if (instr->arch_opcode() == kMipsCmpS) {
+    if (!convertCondition(branch->condition, cc)) {
+      UNSUPPORTED_COND(kMips64CmpS, branch->condition);
     }
-    __ BranchF(tlabel, nan, cc, i.InputDoubleRegister(0),
-               i.InputDoubleRegister(1));
-
-    if (!branch->fallthru) __ Branch(flabel);  // no fallthru to flabel.
-
+    FPURegister left = i.InputOrZeroSingleRegister(0);
+    FPURegister right = i.InputOrZeroSingleRegister(1);
+    if ((left.is(kDoubleRegZero) || right.is(kDoubleRegZero)) &&
+        !__ IsDoubleZeroRegSet()) {
+      __ Move(kDoubleRegZero, 0.0);
+    }
+    __ BranchF32(tlabel, nullptr, cc, left, right);
+  } else if (instr->arch_opcode() == kMipsCmpD) {
+    if (!convertCondition(branch->condition, cc)) {
+      UNSUPPORTED_COND(kMips64CmpD, branch->condition);
+    }
+    FPURegister left = i.InputOrZeroDoubleRegister(0);
+    FPURegister right = i.InputOrZeroDoubleRegister(1);
+    if ((left.is(kDoubleRegZero) || right.is(kDoubleRegZero)) &&
+        !__ IsDoubleZeroRegSet()) {
+      __ Move(kDoubleRegZero, 0.0);
+    }
+    __ BranchF64(tlabel, nullptr, cc, left, right);
   } else {
     PrintF("AssembleArchBranch Unimplemented arch_opcode: %d\n",
            instr->arch_opcode());
     UNIMPLEMENTED();
   }
+  if (!branch->fallthru) __ Branch(flabel);  // no fallthru to flabel.
 }
 
 
-void CodeGenerator::AssembleArchJump(BasicBlock::RpoNumber target) {
+void CodeGenerator::AssembleArchJump(RpoNumber target) {
   if (!IsNextInAssemblyOrder(target)) __ Branch(GetLabel(target));
 }
 
@@ -772,224 +1256,291 @@
   // Materialize a full 32-bit 1 or 0 value. The result register is always the
   // last output of the instruction.
   Label false_value;
-  DCHECK_NE(0, instr->OutputCount());
+  DCHECK_NE(0u, instr->OutputCount());
   Register result = i.OutputRegister(instr->OutputCount() - 1);
   Condition cc = kNoCondition;
-
   // MIPS does not have condition code flags, so compare and branch are
   // implemented differently than on the other arch's. The compare operations
   // emit mips psuedo-instructions, which are checked and handled here.
 
-  // For materializations, we use delay slot to set the result true, and
-  // in the false case, where we fall thru the branch, we reset the result
-  // false.
-
-  // TODO(plind): Add CHECK() to ensure that test/cmp and this branch were
-  //    not separated by other instructions.
   if (instr->arch_opcode() == kMipsTst) {
-    switch (condition) {
-      case kNotEqual:
-        cc = ne;
-        break;
-      case kEqual:
-        cc = eq;
-        break;
-      default:
-        UNSUPPORTED_COND(kMipsTst, condition);
-        break;
+    cc = FlagsConditionToConditionTst(condition);
+    __ And(kScratchReg, i.InputRegister(0), i.InputOperand(1));
+    __ Sltu(result, zero_reg, kScratchReg);
+    if (cc == eq) {
+      // Sltu produces 0 for equality, invert the result.
+      __ xori(result, result, 1);
     }
-    __ And(at, i.InputRegister(0), i.InputOperand(1));
-    __ Branch(USE_DELAY_SLOT, &done, cc, at, Operand(zero_reg));
-    __ li(result, Operand(1));  // In delay slot.
-
+    return;
   } else if (instr->arch_opcode() == kMipsAddOvf ||
              instr->arch_opcode() == kMipsSubOvf) {
-    // kMipsAddOvf, SubOvf emits negative result to 'kCompareReg' on overflow.
-    switch (condition) {
-      case kOverflow:
-        cc = lt;
+    Label flabel, tlabel;
+    switch (instr->arch_opcode()) {
+      case kMipsAddOvf:
+        __ AddBranchNoOvf(i.OutputRegister(), i.InputRegister(0),
+                          i.InputOperand(1), &flabel);
+
         break;
-      case kNotOverflow:
-        cc = ge;
+      case kMipsSubOvf:
+        __ SubBranchNoOvf(i.OutputRegister(), i.InputRegister(0),
+                          i.InputOperand(1), &flabel);
         break;
       default:
-        UNSUPPORTED_COND(kMipsAddOvf, condition);
+        UNREACHABLE();
         break;
     }
-    __ Branch(USE_DELAY_SLOT, &done, cc, kCompareReg, Operand(zero_reg));
-    __ li(result, Operand(1));  // In delay slot.
-
-
+    __ li(result, 1);
+    __ Branch(&tlabel);
+    __ bind(&flabel);
+    __ li(result, 0);
+    __ bind(&tlabel);
   } else if (instr->arch_opcode() == kMipsCmp) {
-    Register left = i.InputRegister(0);
-    Operand right = i.InputOperand(1);
-    switch (condition) {
-      case kEqual:
-        cc = eq;
-        break;
-      case kNotEqual:
-        cc = ne;
-        break;
-      case kSignedLessThan:
-        cc = lt;
-        break;
-      case kSignedGreaterThanOrEqual:
-        cc = ge;
-        break;
-      case kSignedLessThanOrEqual:
-        cc = le;
-        break;
-      case kSignedGreaterThan:
-        cc = gt;
-        break;
-      case kUnsignedLessThan:
-        cc = lo;
-        break;
-      case kUnsignedGreaterThanOrEqual:
-        cc = hs;
-        break;
-      case kUnsignedLessThanOrEqual:
-        cc = ls;
-        break;
-      case kUnsignedGreaterThan:
-        cc = hi;
-        break;
+    cc = FlagsConditionToConditionCmp(condition);
+    switch (cc) {
+      case eq:
+      case ne: {
+        Register left = i.InputRegister(0);
+        Operand right = i.InputOperand(1);
+        Register select;
+        if (instr->InputAt(1)->IsImmediate() && right.immediate() == 0) {
+          // Pass left operand if right is zero.
+          select = left;
+        } else {
+          __ Subu(kScratchReg, left, right);
+          select = kScratchReg;
+        }
+        __ Sltu(result, zero_reg, select);
+        if (cc == eq) {
+          // Sltu produces 0 for equality, invert the result.
+          __ xori(result, result, 1);
+        }
+      } break;
+      case lt:
+      case ge: {
+        Register left = i.InputRegister(0);
+        Operand right = i.InputOperand(1);
+        __ Slt(result, left, right);
+        if (cc == ge) {
+          __ xori(result, result, 1);
+        }
+      } break;
+      case gt:
+      case le: {
+        Register left = i.InputRegister(1);
+        Operand right = i.InputOperand(0);
+        __ Slt(result, left, right);
+        if (cc == le) {
+          __ xori(result, result, 1);
+        }
+      } break;
+      case lo:
+      case hs: {
+        Register left = i.InputRegister(0);
+        Operand right = i.InputOperand(1);
+        __ Sltu(result, left, right);
+        if (cc == hs) {
+          __ xori(result, result, 1);
+        }
+      } break;
+      case hi:
+      case ls: {
+        Register left = i.InputRegister(1);
+        Operand right = i.InputOperand(0);
+        __ Sltu(result, left, right);
+        if (cc == ls) {
+          __ xori(result, result, 1);
+        }
+      } break;
       default:
-        UNSUPPORTED_COND(kMipsCmp, condition);
-        break;
+        UNREACHABLE();
     }
-    __ Branch(USE_DELAY_SLOT, &done, cc, left, right);
-    __ li(result, Operand(1));  // In delay slot.
-
-  } else if (instr->arch_opcode() == kMipsCmpD) {
-    FPURegister left = i.InputDoubleRegister(0);
-    FPURegister right = i.InputDoubleRegister(1);
-    // TODO(plind): Provide NaN-testing macro-asm function without need for
-    // BranchF.
-    FPURegister dummy1 = f0;
-    FPURegister dummy2 = f2;
-    switch (condition) {
-      case kUnorderedEqual:
-        // TODO(plind):  improve the NaN testing throughout this function.
-        __ BranchF(NULL, &false_value, kNoCondition, dummy1, dummy2);
-        cc = eq;
-        break;
-      case kUnorderedNotEqual:
-        __ BranchF(USE_DELAY_SLOT, NULL, &done, kNoCondition, dummy1, dummy2);
-        __ li(result, Operand(1));  // In delay slot - returns 1 on NaN.
-        cc = ne;
-        break;
-      case kUnorderedLessThan:
-        __ BranchF(NULL, &false_value, kNoCondition, dummy1, dummy2);
-        cc = lt;
-        break;
-      case kUnorderedGreaterThanOrEqual:
-        __ BranchF(USE_DELAY_SLOT, NULL, &done, kNoCondition, dummy1, dummy2);
-        __ li(result, Operand(1));  // In delay slot - returns 1 on NaN.
-        cc = ge;
-        break;
-      case kUnorderedLessThanOrEqual:
-        __ BranchF(NULL, &false_value, kNoCondition, dummy1, dummy2);
-        cc = le;
-        break;
-      case kUnorderedGreaterThan:
-        __ BranchF(USE_DELAY_SLOT, NULL, &done, kNoCondition, dummy1, dummy2);
-        __ li(result, Operand(1));  // In delay slot - returns 1 on NaN.
-        cc = gt;
-        break;
-      default:
-        UNSUPPORTED_COND(kMipsCmp, condition);
-        break;
+    return;
+  } else if (instr->arch_opcode() == kMipsCmpD ||
+             instr->arch_opcode() == kMipsCmpS) {
+    FPURegister left = i.InputOrZeroDoubleRegister(0);
+    FPURegister right = i.InputOrZeroDoubleRegister(1);
+    if ((left.is(kDoubleRegZero) || right.is(kDoubleRegZero)) &&
+        !__ IsDoubleZeroRegSet()) {
+      __ Move(kDoubleRegZero, 0.0);
     }
-    __ BranchF(USE_DELAY_SLOT, &done, NULL, cc, left, right);
-    __ li(result, Operand(1));  // In delay slot - branch taken returns 1.
-                                // Fall-thru (branch not taken) returns 0.
-
+    bool predicate;
+    FPUCondition cc = FlagsConditionToConditionCmpFPU(predicate, condition);
+    if (!IsMipsArchVariant(kMips32r6)) {
+      __ li(result, Operand(1));
+      if (instr->arch_opcode() == kMipsCmpD) {
+        __ c(cc, D, left, right);
+      } else {
+        DCHECK(instr->arch_opcode() == kMipsCmpS);
+        __ c(cc, S, left, right);
+      }
+      if (predicate) {
+        __ Movf(result, zero_reg);
+      } else {
+        __ Movt(result, zero_reg);
+      }
+    } else {
+      if (instr->arch_opcode() == kMipsCmpD) {
+        __ cmp(cc, L, kDoubleCompareReg, left, right);
+      } else {
+        DCHECK(instr->arch_opcode() == kMipsCmpS);
+        __ cmp(cc, W, kDoubleCompareReg, left, right);
+      }
+      __ mfc1(result, kDoubleCompareReg);
+      __ andi(result, result, 1);  // Cmp returns all 1's/0's, use only LSB.
+      if (!predicate)          // Toggle result for not equal.
+        __ xori(result, result, 1);
+    }
+    return;
   } else {
     PrintF("AssembleArchBranch Unimplemented arch_opcode is : %d\n",
            instr->arch_opcode());
     TRACE_UNIMPL();
     UNIMPLEMENTED();
   }
-  // Fallthru case is the false materialization.
-  __ bind(&false_value);
-  __ li(result, Operand(0));
-  __ bind(&done);
 }
 
 
-void CodeGenerator::AssembleDeoptimizerCall(int deoptimization_id) {
+void CodeGenerator::AssembleArchLookupSwitch(Instruction* instr) {
+  MipsOperandConverter i(this, instr);
+  Register input = i.InputRegister(0);
+  for (size_t index = 2; index < instr->InputCount(); index += 2) {
+    __ li(at, Operand(i.InputInt32(index + 0)));
+    __ beq(input, at, GetLabel(i.InputRpo(index + 1)));
+  }
+  __ nop();  // Branch delay slot of the last beq.
+  AssembleArchJump(i.InputRpo(1));
+}
+
+
+void CodeGenerator::AssembleArchTableSwitch(Instruction* instr) {
+  MipsOperandConverter i(this, instr);
+  Register input = i.InputRegister(0);
+  size_t const case_count = instr->InputCount() - 2;
+  Label here;
+  __ Branch(GetLabel(i.InputRpo(1)), hs, input, Operand(case_count));
+  __ BlockTrampolinePoolFor(case_count + 6);
+  __ bal(&here);
+  __ sll(at, input, 2);  // Branch delay slot.
+  __ bind(&here);
+  __ addu(at, at, ra);
+  __ lw(at, MemOperand(at, 4 * v8::internal::Assembler::kInstrSize));
+  __ jr(at);
+  __ nop();  // Branch delay slot nop.
+  for (size_t index = 0; index < case_count; ++index) {
+    __ dd(GetLabel(i.InputRpo(index + 2)));
+  }
+}
+
+
+void CodeGenerator::AssembleDeoptimizerCall(
+    int deoptimization_id, Deoptimizer::BailoutType bailout_type) {
   Address deopt_entry = Deoptimizer::GetDeoptimizationEntry(
-      isolate(), deoptimization_id, Deoptimizer::LAZY);
+      isolate(), deoptimization_id, bailout_type);
   __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY);
 }
 
 
 void CodeGenerator::AssemblePrologue() {
   CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
-  if (descriptor->kind() == CallDescriptor::kCallAddress) {
+  int stack_shrink_slots = frame()->GetSpillSlotCount();
+  if (descriptor->IsCFunctionCall()) {
     __ Push(ra, fp);
     __ mov(fp, sp);
-    const RegList saves = descriptor->CalleeSavedRegisters();
-    if (saves != 0) {  // Save callee-saved registers.
-      // TODO(plind): make callee save size const, possibly DCHECK it.
-      int register_save_area_size = 0;
-      for (int i = Register::kNumRegisters - 1; i >= 0; i--) {
-        if (!((1 << i) & saves)) continue;
-        register_save_area_size += kPointerSize;
-      }
-      frame()->SetRegisterSaveAreaSize(register_save_area_size);
-      __ MultiPush(saves);
-    }
   } else if (descriptor->IsJSFunctionCall()) {
-    CompilationInfo* info = this->info();
-    __ Prologue(info->IsCodePreAgingActive());
-    frame()->SetRegisterSaveAreaSize(
-        StandardFrameConstants::kFixedFrameSizeFromFp);
-  } else {
+    __ Prologue(this->info()->GeneratePreagedPrologue());
+  } else if (frame()->needs_frame()) {
     __ StubPrologue();
-    frame()->SetRegisterSaveAreaSize(
-        StandardFrameConstants::kFixedFrameSizeFromFp);
+  } else {
+    frame()->SetElidedFrameSizeInSlots(0);
   }
-  int stack_slots = frame()->GetSpillSlotCount();
-  if (stack_slots > 0) {
-    __ Subu(sp, sp, Operand(stack_slots * kPointerSize));
+  frame_access_state()->SetFrameAccessToDefault();
+
+  if (info()->is_osr()) {
+    // TurboFan OSR-compiled functions cannot be entered directly.
+    __ Abort(kShouldNotDirectlyEnterOsrFunction);
+
+    // Unoptimized code jumps directly to this entrypoint while the unoptimized
+    // frame is still on the stack. Optimized code uses OSR values directly from
+    // the unoptimized frame. Thus, all that needs to be done is to allocate the
+    // remaining stack slots.
+    if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --");
+    osr_pc_offset_ = __ pc_offset();
+    // TODO(titzer): cannot address target function == local #-1
+    __ lw(a1, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
+    stack_shrink_slots -= OsrHelper(info()).UnoptimizedFrameSlots();
+  }
+
+  const RegList saves_fpu = descriptor->CalleeSavedFPRegisters();
+  if (saves_fpu != 0) {
+    stack_shrink_slots += frame()->AlignSavedCalleeRegisterSlots();
+  }
+  if (stack_shrink_slots > 0) {
+    __ Subu(sp, sp, Operand(stack_shrink_slots * kPointerSize));
+  }
+
+  // Save callee-saved FPU registers.
+  if (saves_fpu != 0) {
+    __ MultiPushFPU(saves_fpu);
+    int count = base::bits::CountPopulation32(saves_fpu);
+    DCHECK(kNumCalleeSavedFPU == count);
+    frame()->AllocateSavedCalleeRegisterSlots(count *
+                                              (kDoubleSize / kPointerSize));
+  }
+
+  const RegList saves = descriptor->CalleeSavedRegisters();
+  if (saves != 0) {
+    // Save callee-saved registers.
+    __ MultiPush(saves);
+    // kNumCalleeSaved includes the fp register, but the fp register
+    // is saved separately in TF.
+    int count = base::bits::CountPopulation32(saves);
+    DCHECK(kNumCalleeSaved == count + 1);
+    frame()->AllocateSavedCalleeRegisterSlots(count);
   }
 }
 
 
 void CodeGenerator::AssembleReturn() {
   CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
-  if (descriptor->kind() == CallDescriptor::kCallAddress) {
-    if (frame()->GetRegisterSaveAreaSize() > 0) {
-      // Remove this frame's spill slots first.
-      int stack_slots = frame()->GetSpillSlotCount();
-      if (stack_slots > 0) {
-        __ Addu(sp, sp, Operand(stack_slots * kPointerSize));
-      }
-      // Restore registers.
-      const RegList saves = descriptor->CalleeSavedRegisters();
-      if (saves != 0) {
-        __ MultiPop(saves);
-      }
+  int pop_count = static_cast<int>(descriptor->StackParameterCount());
+
+  // Restore GP registers.
+  const RegList saves = descriptor->CalleeSavedRegisters();
+  if (saves != 0) {
+    __ MultiPop(saves);
+  }
+
+  // Restore FPU registers.
+  const RegList saves_fpu = descriptor->CalleeSavedFPRegisters();
+  if (saves_fpu != 0) {
+    __ MultiPopFPU(saves_fpu);
+  }
+
+  if (descriptor->IsCFunctionCall()) {
+    __ mov(sp, fp);
+    __ Pop(ra, fp);
+  } else if (frame()->needs_frame()) {
+    // Canonicalize JSFunction return sites for now.
+    if (return_label_.is_bound()) {
+      __ Branch(&return_label_);
+      return;
+    } else {
+      __ bind(&return_label_);
+      __ mov(sp, fp);
+      __ Pop(ra, fp);
     }
-    __ mov(sp, fp);
-    __ Pop(ra, fp);
-    __ Ret();
-  } else {
-    __ mov(sp, fp);
-    __ Pop(ra, fp);
-    int pop_count = descriptor->IsJSFunctionCall()
-                        ? static_cast<int>(descriptor->JSParameterCount())
-                        : 0;
+  }
+  if (pop_count != 0) {
     __ DropAndRet(pop_count);
+  } else {
+    __ Ret();
   }
 }
 
 
 void CodeGenerator::AssembleMove(InstructionOperand* source,
                                  InstructionOperand* destination) {
-  MipsOperandConverter g(this, NULL);
+  MipsOperandConverter g(this, nullptr);
   // Dispatch on the source and destination operand kinds.  Not all
   // combinations are possible.
   if (source->IsRegister()) {
@@ -1031,9 +1582,19 @@
         case Constant::kExternalReference:
           __ li(dst, Operand(src.ToExternalReference()));
           break;
-        case Constant::kHeapObject:
-          __ li(dst, src.ToHeapObject());
+        case Constant::kHeapObject: {
+          Handle<HeapObject> src_object = src.ToHeapObject();
+          Heap::RootListIndex index;
+          int offset;
+          if (IsMaterializableFromFrame(src_object, &offset)) {
+            __ lw(dst, MemOperand(fp, offset));
+          } else if (IsMaterializableFromRoot(src_object, &index)) {
+            __ LoadRoot(dst, index);
+          } else {
+            __ li(dst, src_object);
+          }
           break;
+        }
         case Constant::kRpoNumber:
           UNREACHABLE();  // TODO(titzer): loading RPO numbers on mips.
           break;
@@ -1085,7 +1646,7 @@
 
 void CodeGenerator::AssembleSwap(InstructionOperand* source,
                                  InstructionOperand* destination) {
-  MipsOperandConverter g(this, NULL);
+  MipsOperandConverter g(this, nullptr);
   // Dispatch on the source and destination operand kinds.  Not all
   // combinations are possible.
   if (source->IsRegister()) {
@@ -1134,9 +1695,9 @@
     Register temp_0 = kScratchReg;
     FPURegister temp_1 = kScratchDoubleReg;
     MemOperand src0 = g.ToMemOperand(source);
-    MemOperand src1(src0.rm(), src0.offset() + kPointerSize);
+    MemOperand src1(src0.rm(), src0.offset() + kIntSize);
     MemOperand dst0 = g.ToMemOperand(destination);
-    MemOperand dst1(dst0.rm(), dst0.offset() + kPointerSize);
+    MemOperand dst1(dst0.rm(), dst0.offset() + kIntSize);
     __ ldc1(temp_1, dst0);  // Save destination in temp_1.
     __ lw(temp_0, src0);    // Then use temp_0 to copy source to destination.
     __ sw(temp_0, dst0);
@@ -1150,6 +1711,12 @@
 }
 
 
+void CodeGenerator::AssembleJumpTable(Label** targets, size_t target_count) {
+  // On 32-bit MIPS we emit the jump tables inline.
+  UNREACHABLE();
+}
+
+
 void CodeGenerator::AddNopForSmiCodeInlining() {
   // Unused on 32-bit ARM. Still exists on 64-bit arm.
   // TODO(plind): Unclear when this is called now. Understand, fix if needed.
@@ -1158,24 +1725,25 @@
 
 
 void CodeGenerator::EnsureSpaceForLazyDeopt() {
+  if (!info()->ShouldEnsureSpaceForLazyDeopt()) {
+    return;
+  }
+
   int space_needed = Deoptimizer::patch_size();
-  if (!info()->IsStub()) {
-    // Ensure that we have enough space after the previous lazy-bailout
-    // instruction for patching the code here.
-    int current_pc = masm()->pc_offset();
-    if (current_pc < last_lazy_deopt_pc_ + space_needed) {
-      // Block tramoline pool emission for duration of padding.
-      v8::internal::Assembler::BlockTrampolinePoolScope block_trampoline_pool(
-          masm());
-      int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc;
-      DCHECK_EQ(0, padding_size % v8::internal::Assembler::kInstrSize);
-      while (padding_size > 0) {
-        __ nop();
-        padding_size -= v8::internal::Assembler::kInstrSize;
-      }
+  // Ensure that we have enough space after the previous lazy-bailout
+  // instruction for patching the code here.
+  int current_pc = masm()->pc_offset();
+  if (current_pc < last_lazy_deopt_pc_ + space_needed) {
+    // Block tramoline pool emission for duration of padding.
+    v8::internal::Assembler::BlockTrampolinePoolScope block_trampoline_pool(
+        masm());
+    int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc;
+    DCHECK_EQ(0, padding_size % v8::internal::Assembler::kInstrSize);
+    while (padding_size > 0) {
+      __ nop();
+      padding_size -= v8::internal::Assembler::kInstrSize;
     }
   }
-  MarkLazyDeoptSite();
 }
 
 #undef __
diff --git a/src/compiler/mips/instruction-codes-mips.h b/src/compiler/mips/instruction-codes-mips.h
index 3aa508f..c938177 100644
--- a/src/compiler/mips/instruction-codes-mips.h
+++ b/src/compiler/mips/instruction-codes-mips.h
@@ -25,30 +25,60 @@
   V(MipsModU)                      \
   V(MipsAnd)                       \
   V(MipsOr)                        \
+  V(MipsNor)                       \
   V(MipsXor)                       \
+  V(MipsClz)                       \
   V(MipsShl)                       \
   V(MipsShr)                       \
   V(MipsSar)                       \
+  V(MipsExt)                       \
+  V(MipsIns)                       \
   V(MipsRor)                       \
   V(MipsMov)                       \
   V(MipsTst)                       \
   V(MipsCmp)                       \
+  V(MipsCmpS)                      \
+  V(MipsAddS)                      \
+  V(MipsSubS)                      \
+  V(MipsMulS)                      \
+  V(MipsDivS)                      \
+  V(MipsModS)                      \
+  V(MipsAbsS)                      \
+  V(MipsSqrtS)                     \
+  V(MipsMaxS)                      \
+  V(MipsMinS)                      \
   V(MipsCmpD)                      \
   V(MipsAddD)                      \
   V(MipsSubD)                      \
   V(MipsMulD)                      \
   V(MipsDivD)                      \
   V(MipsModD)                      \
+  V(MipsAbsD)                      \
   V(MipsSqrtD)                     \
-  V(MipsFloat64Floor)              \
-  V(MipsFloat64Ceil)               \
+  V(MipsMaxD)                      \
+  V(MipsMinD)                      \
+  V(MipsFloat32RoundDown)          \
+  V(MipsFloat32RoundTruncate)      \
+  V(MipsFloat32RoundUp)            \
+  V(MipsFloat32RoundTiesEven)      \
+  V(MipsFloat64RoundDown)          \
   V(MipsFloat64RoundTruncate)      \
+  V(MipsFloat64RoundUp)            \
+  V(MipsFloat64RoundTiesEven)      \
   V(MipsCvtSD)                     \
   V(MipsCvtDS)                     \
   V(MipsTruncWD)                   \
+  V(MipsRoundWD)                   \
+  V(MipsFloorWD)                   \
+  V(MipsCeilWD)                    \
+  V(MipsTruncWS)                   \
+  V(MipsRoundWS)                   \
+  V(MipsFloorWS)                   \
+  V(MipsCeilWS)                    \
   V(MipsTruncUwD)                  \
   V(MipsCvtDW)                     \
   V(MipsCvtDUw)                    \
+  V(MipsCvtSW)                     \
   V(MipsLb)                        \
   V(MipsLbu)                       \
   V(MipsSb)                        \
@@ -61,10 +91,17 @@
   V(MipsSwc1)                      \
   V(MipsLdc1)                      \
   V(MipsSdc1)                      \
+  V(MipsFloat64ExtractLowWord32)   \
+  V(MipsFloat64ExtractHighWord32)  \
+  V(MipsFloat64InsertLowWord32)    \
+  V(MipsFloat64InsertHighWord32)   \
+  V(MipsFloat64Max)                \
+  V(MipsFloat64Min)                \
+  V(MipsFloat32Max)                \
+  V(MipsFloat32Min)                \
   V(MipsPush)                      \
   V(MipsStoreToStackSlot)          \
-  V(MipsStackClaim)                \
-  V(MipsStoreWriteBarrier)
+  V(MipsStackClaim)
 
 
 // Addressing modes represent the "shape" of inputs to an instruction.
diff --git a/src/compiler/mips/instruction-scheduler-mips.cc b/src/compiler/mips/instruction-scheduler-mips.cc
new file mode 100644
index 0000000..af86a87
--- /dev/null
+++ b/src/compiler/mips/instruction-scheduler-mips.cc
@@ -0,0 +1,26 @@
+// Copyright 2015 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/instruction-scheduler.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+bool InstructionScheduler::SchedulerSupported() { return false; }
+
+
+int InstructionScheduler::GetTargetInstructionFlags(
+    const Instruction* instr) const {
+  UNIMPLEMENTED();
+}
+
+
+int InstructionScheduler::GetInstructionLatency(const Instruction* instr) {
+  UNIMPLEMENTED();
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/mips/instruction-selector-mips.cc b/src/compiler/mips/instruction-selector-mips.cc
index 5e8e3b1..61cea76 100644
--- a/src/compiler/mips/instruction-selector-mips.cc
+++ b/src/compiler/mips/instruction-selector-mips.cc
@@ -2,9 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "src/base/adapters.h"
 #include "src/base/bits.h"
 #include "src/compiler/instruction-selector-impl.h"
 #include "src/compiler/node-matchers.h"
+#include "src/compiler/node-properties.h"
 
 namespace v8 {
 namespace internal {
@@ -17,12 +19,12 @@
 
 
 // Adds Mips-specific methods for generating InstructionOperands.
-class MipsOperandGenerator FINAL : public OperandGenerator {
+class MipsOperandGenerator final : public OperandGenerator {
  public:
   explicit MipsOperandGenerator(InstructionSelector* selector)
       : OperandGenerator(selector) {}
 
-  InstructionOperand* UseOperand(Node* node, InstructionCode opcode) {
+  InstructionOperand UseOperand(Node* node, InstructionCode opcode) {
     if (CanBeImmediate(node, opcode)) {
       return UseImmediate(node);
     }
@@ -42,11 +44,10 @@
         return is_uint16(value);
       case kMipsLdc1:
       case kMipsSdc1:
-      case kCheckedLoadFloat32:
       case kCheckedLoadFloat64:
-      case kCheckedStoreFloat32:
       case kCheckedStoreFloat64:
-        return is_int16(value + kIntSize);
+        return std::numeric_limits<int16_t>::min() <= (value + kIntSize) &&
+               std::numeric_limits<int16_t>::max() >= (value + kIntSize);
       default:
         return is_int16(value);
     }
@@ -90,9 +91,9 @@
                        InstructionCode opcode, FlagsContinuation* cont) {
   MipsOperandGenerator g(selector);
   Int32BinopMatcher m(node);
-  InstructionOperand* inputs[4];
+  InstructionOperand inputs[4];
   size_t input_count = 0;
-  InstructionOperand* outputs[2];
+  InstructionOperand outputs[2];
   size_t output_count = 0;
 
   inputs[input_count++] = g.UseRegister(m.left().node());
@@ -108,14 +109,13 @@
     outputs[output_count++] = g.DefineAsRegister(cont->result());
   }
 
-  DCHECK_NE(0, input_count);
-  DCHECK_NE(0, output_count);
+  DCHECK_NE(0u, input_count);
+  DCHECK_NE(0u, output_count);
   DCHECK_GE(arraysize(inputs), input_count);
   DCHECK_GE(arraysize(outputs), output_count);
 
-  Instruction* instr = selector->Emit(cont->Encode(opcode), output_count,
-                                      outputs, input_count, inputs);
-  if (cont->IsBranch()) instr->MarkAsControl();
+  selector->Emit(cont->Encode(opcode), output_count, outputs, input_count,
+                 inputs);
 }
 
 
@@ -127,32 +127,32 @@
 
 
 void InstructionSelector::VisitLoad(Node* node) {
-  MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node));
-  MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node));
+  LoadRepresentation load_rep = LoadRepresentationOf(node->op());
   MipsOperandGenerator g(this);
   Node* base = node->InputAt(0);
   Node* index = node->InputAt(1);
 
-  ArchOpcode opcode;
-  switch (rep) {
-    case kRepFloat32:
+  ArchOpcode opcode = kArchNop;
+  switch (load_rep.representation()) {
+    case MachineRepresentation::kFloat32:
       opcode = kMipsLwc1;
       break;
-    case kRepFloat64:
+    case MachineRepresentation::kFloat64:
       opcode = kMipsLdc1;
       break;
-    case kRepBit:  // Fall through.
-    case kRepWord8:
-      opcode = typ == kTypeUint32 ? kMipsLbu : kMipsLb;
+    case MachineRepresentation::kBit:  // Fall through.
+    case MachineRepresentation::kWord8:
+      opcode = load_rep.IsUnsigned() ? kMipsLbu : kMipsLb;
       break;
-    case kRepWord16:
-      opcode = typ == kTypeUint32 ? kMipsLhu : kMipsLh;
+    case MachineRepresentation::kWord16:
+      opcode = load_rep.IsUnsigned() ? kMipsLhu : kMipsLh;
       break;
-    case kRepTagged:  // Fall through.
-    case kRepWord32:
+    case MachineRepresentation::kTagged:  // Fall through.
+    case MachineRepresentation::kWord32:
       opcode = kMipsLw;
       break;
-    default:
+    case MachineRepresentation::kWord64:  // Fall through.
+    case MachineRepresentation::kNone:
       UNREACHABLE();
       return;
   }
@@ -161,7 +161,7 @@
     Emit(opcode | AddressingModeField::encode(kMode_MRI),
          g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index));
   } else {
-    InstructionOperand* addr_reg = g.TempRegister();
+    InstructionOperand addr_reg = g.TempRegister();
     Emit(kMipsAdd | AddressingModeField::encode(kMode_None), addr_reg,
          g.UseRegister(index), g.UseRegister(base));
     // Emit desired load opcode, using temp addr_reg.
@@ -177,59 +177,126 @@
   Node* index = node->InputAt(1);
   Node* value = node->InputAt(2);
 
-  StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node);
-  MachineType rep = RepresentationOf(store_rep.machine_type());
-  if (store_rep.write_barrier_kind() == kFullWriteBarrier) {
-    DCHECK(rep == kRepTagged);
-    // TODO(dcarney): refactor RecordWrite function to take temp registers
-    //                and pass them here instead of using fixed regs
-    // TODO(dcarney): handle immediate indices.
-    InstructionOperand* temps[] = {g.TempRegister(t1), g.TempRegister(t2)};
-    Emit(kMipsStoreWriteBarrier, NULL, g.UseFixed(base, t0),
-         g.UseFixed(index, t1), g.UseFixed(value, t2), arraysize(temps), temps);
-    return;
-  }
-  DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind());
+  StoreRepresentation store_rep = StoreRepresentationOf(node->op());
+  WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind();
+  MachineRepresentation rep = store_rep.representation();
 
-  ArchOpcode opcode;
-  switch (rep) {
-    case kRepFloat32:
-      opcode = kMipsSwc1;
-      break;
-    case kRepFloat64:
-      opcode = kMipsSdc1;
-      break;
-    case kRepBit:  // Fall through.
-    case kRepWord8:
-      opcode = kMipsSb;
-      break;
-    case kRepWord16:
-      opcode = kMipsSh;
-      break;
-    case kRepTagged:  // Fall through.
-    case kRepWord32:
-      opcode = kMipsSw;
-      break;
-    default:
-      UNREACHABLE();
-      return;
-  }
-
-  if (g.CanBeImmediate(index, opcode)) {
-    Emit(opcode | AddressingModeField::encode(kMode_MRI), NULL,
-         g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value));
+  // TODO(mips): I guess this could be done in a better way.
+  if (write_barrier_kind != kNoWriteBarrier) {
+    DCHECK_EQ(MachineRepresentation::kTagged, rep);
+    InstructionOperand inputs[3];
+    size_t input_count = 0;
+    inputs[input_count++] = g.UseUniqueRegister(base);
+    inputs[input_count++] = g.UseUniqueRegister(index);
+    inputs[input_count++] = (write_barrier_kind == kMapWriteBarrier)
+                                ? g.UseRegister(value)
+                                : g.UseUniqueRegister(value);
+    RecordWriteMode record_write_mode = RecordWriteMode::kValueIsAny;
+    switch (write_barrier_kind) {
+      case kNoWriteBarrier:
+        UNREACHABLE();
+        break;
+      case kMapWriteBarrier:
+        record_write_mode = RecordWriteMode::kValueIsMap;
+        break;
+      case kPointerWriteBarrier:
+        record_write_mode = RecordWriteMode::kValueIsPointer;
+        break;
+      case kFullWriteBarrier:
+        record_write_mode = RecordWriteMode::kValueIsAny;
+        break;
+    }
+    InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()};
+    size_t const temp_count = arraysize(temps);
+    InstructionCode code = kArchStoreWithWriteBarrier;
+    code |= MiscField::encode(static_cast<int>(record_write_mode));
+    Emit(code, 0, nullptr, input_count, inputs, temp_count, temps);
   } else {
-    InstructionOperand* addr_reg = g.TempRegister();
-    Emit(kMipsAdd | AddressingModeField::encode(kMode_None), addr_reg,
-         g.UseRegister(index), g.UseRegister(base));
-    // Emit desired store opcode, using temp addr_reg.
-    Emit(opcode | AddressingModeField::encode(kMode_MRI), NULL, addr_reg,
-         g.TempImmediate(0), g.UseRegister(value));
+    ArchOpcode opcode = kArchNop;
+    switch (rep) {
+      case MachineRepresentation::kFloat32:
+        opcode = kMipsSwc1;
+        break;
+      case MachineRepresentation::kFloat64:
+        opcode = kMipsSdc1;
+        break;
+      case MachineRepresentation::kBit:  // Fall through.
+      case MachineRepresentation::kWord8:
+        opcode = kMipsSb;
+        break;
+      case MachineRepresentation::kWord16:
+        opcode = kMipsSh;
+        break;
+      case MachineRepresentation::kTagged:  // Fall through.
+      case MachineRepresentation::kWord32:
+        opcode = kMipsSw;
+        break;
+      case MachineRepresentation::kWord64:  // Fall through.
+      case MachineRepresentation::kNone:
+        UNREACHABLE();
+        return;
+    }
+
+    if (g.CanBeImmediate(index, opcode)) {
+      Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
+           g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value));
+    } else {
+      InstructionOperand addr_reg = g.TempRegister();
+      Emit(kMipsAdd | AddressingModeField::encode(kMode_None), addr_reg,
+           g.UseRegister(index), g.UseRegister(base));
+      // Emit desired store opcode, using temp addr_reg.
+      Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
+           addr_reg, g.TempImmediate(0), g.UseRegister(value));
+    }
   }
 }
 
 
 void InstructionSelector::VisitWord32And(Node* node) {
+  MipsOperandGenerator g(this);
+  Int32BinopMatcher m(node);
+  if (m.left().IsWord32Shr() && CanCover(node, m.left().node()) &&
+      m.right().HasValue()) {
+    uint32_t mask = m.right().Value();
+    uint32_t mask_width = base::bits::CountPopulation32(mask);
+    uint32_t mask_msb = base::bits::CountLeadingZeros32(mask);
+    if ((mask_width != 0) && (mask_msb + mask_width == 32)) {
+      // The mask must be contiguous, and occupy the least-significant bits.
+      DCHECK_EQ(0u, base::bits::CountTrailingZeros32(mask));
+
+      // Select Ext for And(Shr(x, imm), mask) where the mask is in the least
+      // significant bits.
+      Int32BinopMatcher mleft(m.left().node());
+      if (mleft.right().HasValue()) {
+        // Any shift value can match; int32 shifts use `value % 32`.
+        uint32_t lsb = mleft.right().Value() & 0x1f;
+
+        // Ext cannot extract bits past the register size, however since
+        // shifting the original value would have introduced some zeros we can
+        // still use Ext with a smaller mask and the remaining bits will be
+        // zeros.
+        if (lsb + mask_width > 32) mask_width = 32 - lsb;
+
+        Emit(kMipsExt, g.DefineAsRegister(node),
+             g.UseRegister(mleft.left().node()), g.TempImmediate(lsb),
+             g.TempImmediate(mask_width));
+        return;
+      }
+      // Other cases fall through to the normal And operation.
+    }
+  }
+  if (m.right().HasValue()) {
+    uint32_t mask = m.right().Value();
+    uint32_t shift = base::bits::CountPopulation32(~mask);
+    uint32_t msb = base::bits::CountLeadingZeros32(~mask);
+    if (shift != 0 && shift != 32 && msb + shift == 32) {
+      // Insert zeros for (x >> K) << K => x & ~(2^K - 1) expression reduction
+      // and remove constant loading of invereted mask.
+      Emit(kMipsIns, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()),
+           g.TempImmediate(0), g.TempImmediate(shift));
+      return;
+    }
+  }
   VisitBinop(this, node, kMipsAnd);
 }
 
@@ -240,16 +307,81 @@
 
 
 void InstructionSelector::VisitWord32Xor(Node* node) {
+  Int32BinopMatcher m(node);
+  if (m.left().IsWord32Or() && CanCover(node, m.left().node()) &&
+      m.right().Is(-1)) {
+    Int32BinopMatcher mleft(m.left().node());
+    if (!mleft.right().HasValue()) {
+      MipsOperandGenerator g(this);
+      Emit(kMipsNor, g.DefineAsRegister(node),
+           g.UseRegister(mleft.left().node()),
+           g.UseRegister(mleft.right().node()));
+      return;
+    }
+  }
+  if (m.right().Is(-1)) {
+    // Use Nor for bit negation and eliminate constant loading for xori.
+    MipsOperandGenerator g(this);
+    Emit(kMipsNor, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
+         g.TempImmediate(0));
+    return;
+  }
   VisitBinop(this, node, kMipsXor);
 }
 
 
 void InstructionSelector::VisitWord32Shl(Node* node) {
+  Int32BinopMatcher m(node);
+  if (m.left().IsWord32And() && CanCover(node, m.left().node()) &&
+      m.right().IsInRange(1, 31)) {
+    MipsOperandGenerator g(this);
+    Int32BinopMatcher mleft(m.left().node());
+    // Match Word32Shl(Word32And(x, mask), imm) to Shl where the mask is
+    // contiguous, and the shift immediate non-zero.
+    if (mleft.right().HasValue()) {
+      uint32_t mask = mleft.right().Value();
+      uint32_t mask_width = base::bits::CountPopulation32(mask);
+      uint32_t mask_msb = base::bits::CountLeadingZeros32(mask);
+      if ((mask_width != 0) && (mask_msb + mask_width == 32)) {
+        uint32_t shift = m.right().Value();
+        DCHECK_EQ(0u, base::bits::CountTrailingZeros32(mask));
+        DCHECK_NE(0u, shift);
+        if ((shift + mask_width) >= 32) {
+          // If the mask is contiguous and reaches or extends beyond the top
+          // bit, only the shift is needed.
+          Emit(kMipsShl, g.DefineAsRegister(node),
+               g.UseRegister(mleft.left().node()),
+               g.UseImmediate(m.right().node()));
+          return;
+        }
+      }
+    }
+  }
   VisitRRO(this, kMipsShl, node);
 }
 
 
 void InstructionSelector::VisitWord32Shr(Node* node) {
+  Int32BinopMatcher m(node);
+  if (m.left().IsWord32And() && m.right().HasValue()) {
+    uint32_t lsb = m.right().Value() & 0x1f;
+    Int32BinopMatcher mleft(m.left().node());
+    if (mleft.right().HasValue()) {
+      // Select Ext for Shr(And(x, mask), imm) where the result of the mask is
+      // shifted into the least-significant bits.
+      uint32_t mask = (mleft.right().Value() >> lsb) << lsb;
+      unsigned mask_width = base::bits::CountPopulation32(mask);
+      unsigned mask_msb = base::bits::CountLeadingZeros32(mask);
+      if ((mask_msb + mask_width + lsb) == 32) {
+        MipsOperandGenerator g(this);
+        DCHECK_EQ(lsb, base::bits::CountTrailingZeros32(mask));
+        Emit(kMipsExt, g.DefineAsRegister(node),
+             g.UseRegister(mleft.left().node()), g.TempImmediate(lsb),
+             g.TempImmediate(mask_width));
+        return;
+      }
+    }
+  }
   VisitRRO(this, kMipsShr, node);
 }
 
@@ -264,6 +396,17 @@
 }
 
 
+void InstructionSelector::VisitWord32Clz(Node* node) {
+  VisitRR(this, kMipsClz, node);
+}
+
+
+void InstructionSelector::VisitWord32Ctz(Node* node) { UNREACHABLE(); }
+
+
+void InstructionSelector::VisitWord32Popcnt(Node* node) { UNREACHABLE(); }
+
+
 void InstructionSelector::VisitInt32Add(Node* node) {
   MipsOperandGenerator g(this);
 
@@ -289,7 +432,7 @@
       return;
     }
     if (base::bits::IsPowerOfTwo32(value - 1)) {
-      InstructionOperand* temp = g.TempRegister();
+      InstructionOperand temp = g.TempRegister();
       Emit(kMipsShl | AddressingModeField::encode(kMode_None), temp,
            g.UseRegister(m.left().node()),
            g.TempImmediate(WhichPowerOf2(value - 1)));
@@ -298,7 +441,7 @@
       return;
     }
     if (base::bits::IsPowerOfTwo32(value + 1)) {
-      InstructionOperand* temp = g.TempRegister();
+      InstructionOperand temp = g.TempRegister();
       Emit(kMipsShl | AddressingModeField::encode(kMode_None), temp,
            g.UseRegister(m.left().node()),
            g.TempImmediate(WhichPowerOf2(value + 1)));
@@ -307,15 +450,12 @@
       return;
     }
   }
-  Emit(kMipsMul, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
-       g.UseRegister(m.right().node()));
+  VisitRRR(this, kMipsMul, node);
 }
 
 
 void InstructionSelector::VisitInt32MulHigh(Node* node) {
-  MipsOperandGenerator g(this);
-  Emit(kMipsMulHigh, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)),
-       g.UseRegister(node->InputAt(1)));
+  VisitRRR(this, kMipsMulHigh, node);
 }
 
 
@@ -329,7 +469,7 @@
 void InstructionSelector::VisitInt32Div(Node* node) {
   MipsOperandGenerator g(this);
   Int32BinopMatcher m(node);
-  Emit(kMipsDiv, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
+  Emit(kMipsDiv, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()),
        g.UseRegister(m.right().node()));
 }
 
@@ -337,7 +477,7 @@
 void InstructionSelector::VisitUint32Div(Node* node) {
   MipsOperandGenerator g(this);
   Int32BinopMatcher m(node);
-  Emit(kMipsDivU, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
+  Emit(kMipsDivU, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()),
        g.UseRegister(m.right().node()));
 }
 
@@ -359,39 +499,130 @@
 
 
 void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) {
-  MipsOperandGenerator g(this);
-  Emit(kMipsCvtDS, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)));
+  VisitRR(this, kMipsCvtDS, node);
 }
 
 
 void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) {
-  MipsOperandGenerator g(this);
-  Emit(kMipsCvtDW, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)));
+  VisitRR(this, kMipsCvtDW, node);
 }
 
 
 void InstructionSelector::VisitChangeUint32ToFloat64(Node* node) {
-  MipsOperandGenerator g(this);
-  Emit(kMipsCvtDUw, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)));
+  VisitRR(this, kMipsCvtDUw, node);
 }
 
 
 void InstructionSelector::VisitChangeFloat64ToInt32(Node* node) {
   MipsOperandGenerator g(this);
-  Emit(kMipsTruncWD, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)));
+  Node* value = node->InputAt(0);
+  // Match ChangeFloat64ToInt32(Float64Round##OP) to corresponding instruction
+  // which does rounding and conversion to integer format.
+  if (CanCover(node, value)) {
+    switch (value->opcode()) {
+      case IrOpcode::kFloat64RoundDown:
+        Emit(kMipsFloorWD, g.DefineAsRegister(node),
+             g.UseRegister(value->InputAt(0)));
+        return;
+      case IrOpcode::kFloat64RoundUp:
+        Emit(kMipsCeilWD, g.DefineAsRegister(node),
+             g.UseRegister(value->InputAt(0)));
+        return;
+      case IrOpcode::kFloat64RoundTiesEven:
+        Emit(kMipsRoundWD, g.DefineAsRegister(node),
+             g.UseRegister(value->InputAt(0)));
+        return;
+      case IrOpcode::kFloat64RoundTruncate:
+        Emit(kMipsTruncWD, g.DefineAsRegister(node),
+             g.UseRegister(value->InputAt(0)));
+        return;
+      default:
+        break;
+    }
+    if (value->opcode() == IrOpcode::kChangeFloat32ToFloat64) {
+      Node* next = value->InputAt(0);
+      if (CanCover(value, next)) {
+        // Match ChangeFloat64ToInt32(ChangeFloat32ToFloat64(Float64Round##OP))
+        switch (next->opcode()) {
+          case IrOpcode::kFloat32RoundDown:
+            Emit(kMipsFloorWS, g.DefineAsRegister(node),
+                 g.UseRegister(next->InputAt(0)));
+            return;
+          case IrOpcode::kFloat32RoundUp:
+            Emit(kMipsCeilWS, g.DefineAsRegister(node),
+                 g.UseRegister(next->InputAt(0)));
+            return;
+          case IrOpcode::kFloat32RoundTiesEven:
+            Emit(kMipsRoundWS, g.DefineAsRegister(node),
+                 g.UseRegister(next->InputAt(0)));
+            return;
+          case IrOpcode::kFloat32RoundTruncate:
+            Emit(kMipsTruncWS, g.DefineAsRegister(node),
+                 g.UseRegister(next->InputAt(0)));
+            return;
+          default:
+            Emit(kMipsTruncWS, g.DefineAsRegister(node),
+                 g.UseRegister(value->InputAt(0)));
+            return;
+        }
+      } else {
+        // Match float32 -> float64 -> int32 representation change path.
+        Emit(kMipsTruncWS, g.DefineAsRegister(node),
+             g.UseRegister(value->InputAt(0)));
+        return;
+      }
+    }
+  }
+  VisitRR(this, kMipsTruncWD, node);
 }
 
 
 void InstructionSelector::VisitChangeFloat64ToUint32(Node* node) {
-  MipsOperandGenerator g(this);
-  Emit(kMipsTruncUwD, g.DefineAsRegister(node),
-       g.UseRegister(node->InputAt(0)));
+  VisitRR(this, kMipsTruncUwD, node);
 }
 
 
 void InstructionSelector::VisitTruncateFloat64ToFloat32(Node* node) {
   MipsOperandGenerator g(this);
-  Emit(kMipsCvtSD, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)));
+  Node* value = node->InputAt(0);
+  // Match TruncateFloat64ToFloat32(ChangeInt32ToFloat64) to corresponding
+  // instruction.
+  if (CanCover(node, value) &&
+      value->opcode() == IrOpcode::kChangeInt32ToFloat64) {
+    Emit(kMipsCvtSW, g.DefineAsRegister(node),
+         g.UseRegister(value->InputAt(0)));
+    return;
+  }
+  VisitRR(this, kMipsCvtSD, node);
+}
+
+
+void InstructionSelector::VisitTruncateFloat64ToInt32(Node* node) {
+  switch (TruncationModeOf(node->op())) {
+    case TruncationMode::kJavaScript:
+      return VisitRR(this, kArchTruncateDoubleToI, node);
+    case TruncationMode::kRoundToZero:
+      return VisitRR(this, kMipsTruncWD, node);
+  }
+  UNREACHABLE();
+}
+
+
+void InstructionSelector::VisitBitcastFloat32ToInt32(Node* node) {
+  VisitRR(this, kMipsFloat64ExtractLowWord32, node);
+}
+
+
+void InstructionSelector::VisitBitcastInt32ToFloat32(Node* node) {
+  MipsOperandGenerator g(this);
+  Emit(kMipsFloat64InsertLowWord32, g.DefineAsRegister(node),
+       ImmediateOperand(ImmediateOperand::INLINE, 0),
+       g.UseRegister(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitFloat32Add(Node* node) {
+  VisitRRR(this, kMipsAddS, node);
 }
 
 
@@ -400,16 +631,45 @@
 }
 
 
+void InstructionSelector::VisitFloat32Sub(Node* node) {
+  VisitRRR(this, kMipsSubS, node);
+}
+
+
 void InstructionSelector::VisitFloat64Sub(Node* node) {
+  MipsOperandGenerator g(this);
+  Float64BinopMatcher m(node);
+  if (m.left().IsMinusZero() && m.right().IsFloat64RoundDown() &&
+      CanCover(m.node(), m.right().node())) {
+    if (m.right().InputAt(0)->opcode() == IrOpcode::kFloat64Sub &&
+        CanCover(m.right().node(), m.right().InputAt(0))) {
+      Float64BinopMatcher mright0(m.right().InputAt(0));
+      if (mright0.left().IsMinusZero()) {
+        Emit(kMipsFloat64RoundUp, g.DefineAsRegister(node),
+             g.UseRegister(mright0.right().node()));
+        return;
+      }
+    }
+  }
   VisitRRR(this, kMipsSubD, node);
 }
 
 
+void InstructionSelector::VisitFloat32Mul(Node* node) {
+  VisitRRR(this, kMipsMulS, node);
+}
+
+
 void InstructionSelector::VisitFloat64Mul(Node* node) {
   VisitRRR(this, kMipsMulD, node);
 }
 
 
+void InstructionSelector::VisitFloat32Div(Node* node) {
+  VisitRRR(this, kMipsDivS, node);
+}
+
+
 void InstructionSelector::VisitFloat64Div(Node* node) {
   VisitRRR(this, kMipsDivD, node);
 }
@@ -422,19 +682,108 @@
 }
 
 
-void InstructionSelector::VisitFloat64Sqrt(Node* node) {
+void InstructionSelector::VisitFloat32Max(Node* node) {
   MipsOperandGenerator g(this);
-  Emit(kMipsSqrtD, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)));
+  if (IsMipsArchVariant(kMips32r6)) {
+    Emit(kMipsFloat32Max, g.DefineAsRegister(node),
+         g.UseUniqueRegister(node->InputAt(0)),
+         g.UseUniqueRegister(node->InputAt(1)));
+
+  } else {
+    // Reverse operands, and use same reg. for result and right operand.
+    Emit(kMipsFloat32Max, g.DefineSameAsFirst(node),
+         g.UseRegister(node->InputAt(1)), g.UseRegister(node->InputAt(0)));
+  }
 }
 
 
-void InstructionSelector::VisitFloat64Floor(Node* node) {
-  VisitRR(this, kMipsFloat64Floor, node);
+void InstructionSelector::VisitFloat64Max(Node* node) {
+  MipsOperandGenerator g(this);
+  if (IsMipsArchVariant(kMips32r6)) {
+    Emit(kMipsFloat64Max, g.DefineAsRegister(node),
+         g.UseUniqueRegister(node->InputAt(0)),
+         g.UseUniqueRegister(node->InputAt(1)));
+
+  } else {
+    // Reverse operands, and use same reg. for result and right operand.
+    Emit(kMipsFloat64Max, g.DefineSameAsFirst(node),
+         g.UseRegister(node->InputAt(1)), g.UseRegister(node->InputAt(0)));
+  }
 }
 
 
-void InstructionSelector::VisitFloat64Ceil(Node* node) {
-  VisitRR(this, kMipsFloat64Ceil, node);
+void InstructionSelector::VisitFloat32Min(Node* node) {
+  MipsOperandGenerator g(this);
+  if (IsMipsArchVariant(kMips32r6)) {
+    Emit(kMipsFloat32Min, g.DefineAsRegister(node),
+         g.UseUniqueRegister(node->InputAt(0)),
+         g.UseUniqueRegister(node->InputAt(1)));
+
+  } else {
+    // Reverse operands, and use same reg. for result and right operand.
+    Emit(kMipsFloat32Min, g.DefineSameAsFirst(node),
+         g.UseRegister(node->InputAt(1)), g.UseRegister(node->InputAt(0)));
+  }
+}
+
+
+void InstructionSelector::VisitFloat64Min(Node* node) {
+  MipsOperandGenerator g(this);
+  if (IsMipsArchVariant(kMips32r6)) {
+    Emit(kMipsFloat64Min, g.DefineAsRegister(node),
+         g.UseUniqueRegister(node->InputAt(0)),
+         g.UseUniqueRegister(node->InputAt(1)));
+
+  } else {
+    // Reverse operands, and use same reg. for result and right operand.
+    Emit(kMipsFloat64Min, g.DefineSameAsFirst(node),
+         g.UseRegister(node->InputAt(1)), g.UseRegister(node->InputAt(0)));
+  }
+}
+
+
+void InstructionSelector::VisitFloat32Abs(Node* node) {
+  VisitRR(this, kMipsAbsS, node);
+}
+
+
+void InstructionSelector::VisitFloat64Abs(Node* node) {
+  VisitRR(this, kMipsAbsD, node);
+}
+
+
+void InstructionSelector::VisitFloat32Sqrt(Node* node) {
+  VisitRR(this, kMipsSqrtS, node);
+}
+
+
+void InstructionSelector::VisitFloat64Sqrt(Node* node) {
+  VisitRR(this, kMipsSqrtD, node);
+}
+
+
+void InstructionSelector::VisitFloat32RoundDown(Node* node) {
+  VisitRR(this, kMipsFloat32RoundDown, node);
+}
+
+
+void InstructionSelector::VisitFloat64RoundDown(Node* node) {
+  VisitRR(this, kMipsFloat64RoundDown, node);
+}
+
+
+void InstructionSelector::VisitFloat32RoundUp(Node* node) {
+  VisitRR(this, kMipsFloat32RoundUp, node);
+}
+
+
+void InstructionSelector::VisitFloat64RoundUp(Node* node) {
+  VisitRR(this, kMipsFloat64RoundUp, node);
+}
+
+
+void InstructionSelector::VisitFloat32RoundTruncate(Node* node) {
+  VisitRR(this, kMipsFloat32RoundTruncate, node);
 }
 
 
@@ -448,96 +797,94 @@
 }
 
 
-void InstructionSelector::VisitCall(Node* node) {
-  MipsOperandGenerator g(this);
-  const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(node);
-
-  FrameStateDescriptor* frame_state_descriptor = NULL;
-  if (descriptor->NeedsFrameState()) {
-    frame_state_descriptor =
-        GetFrameStateDescriptor(node->InputAt(descriptor->InputCount()));
-  }
-
-  CallBuffer buffer(zone(), descriptor, frame_state_descriptor);
-
-  // Compute InstructionOperands for inputs and outputs.
-  InitializeCallBuffer(node, &buffer, true, false);
-  // Possibly align stack here for functions.
-  int push_count = buffer.pushed_nodes.size();
-  if (push_count > 0) {
-    Emit(kMipsStackClaim | MiscField::encode(push_count), NULL);
-  }
-  int slot = buffer.pushed_nodes.size() - 1;
-  for (NodeVectorRIter input = buffer.pushed_nodes.rbegin();
-       input != buffer.pushed_nodes.rend(); input++) {
-    Emit(kMipsStoreToStackSlot | MiscField::encode(slot), NULL,
-         g.UseRegister(*input));
-    slot--;
-  }
-
-  // Select the appropriate opcode based on the call type.
-  InstructionCode opcode;
-  switch (descriptor->kind()) {
-    case CallDescriptor::kCallCodeObject: {
-      opcode = kArchCallCodeObject;
-      break;
-    }
-    case CallDescriptor::kCallJSFunction:
-      opcode = kArchCallJSFunction;
-      break;
-    default:
-      UNREACHABLE();
-      return;
-  }
-  opcode |= MiscField::encode(descriptor->flags());
-
-  // Emit the call instruction.
-  InstructionOperand** first_output =
-      buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL;
-  Instruction* call_instr =
-      Emit(opcode, buffer.outputs.size(), first_output,
-           buffer.instruction_args.size(), &buffer.instruction_args.front());
-  call_instr->MarkAsCall();
+void InstructionSelector::VisitFloat32RoundTiesEven(Node* node) {
+  VisitRR(this, kMipsFloat32RoundTiesEven, node);
 }
 
 
+void InstructionSelector::VisitFloat64RoundTiesEven(Node* node) {
+  VisitRR(this, kMipsFloat64RoundTiesEven, node);
+}
+
+
+void InstructionSelector::EmitPrepareArguments(
+    ZoneVector<PushParameter>* arguments, const CallDescriptor* descriptor,
+    Node* node) {
+  MipsOperandGenerator g(this);
+
+  // Prepare for C function call.
+  if (descriptor->IsCFunctionCall()) {
+    Emit(kArchPrepareCallCFunction |
+             MiscField::encode(static_cast<int>(descriptor->CParameterCount())),
+         0, nullptr, 0, nullptr);
+
+    // Poke any stack arguments.
+    int slot = kCArgSlotCount;
+    for (PushParameter input : (*arguments)) {
+      Emit(kMipsStoreToStackSlot, g.NoOutput(), g.UseRegister(input.node()),
+           g.TempImmediate(slot << kPointerSizeLog2));
+      ++slot;
+    }
+  } else {
+    // Possibly align stack here for functions.
+    int push_count = static_cast<int>(descriptor->StackParameterCount());
+    if (push_count > 0) {
+      Emit(kMipsStackClaim, g.NoOutput(),
+           g.TempImmediate(push_count << kPointerSizeLog2));
+    }
+    for (size_t n = 0; n < arguments->size(); ++n) {
+      PushParameter input = (*arguments)[n];
+      if (input.node()) {
+        Emit(kMipsStoreToStackSlot, g.NoOutput(), g.UseRegister(input.node()),
+             g.TempImmediate(n << kPointerSizeLog2));
+      }
+    }
+  }
+}
+
+
+bool InstructionSelector::IsTailCallAddressImmediate() { return false; }
+
+
 void InstructionSelector::VisitCheckedLoad(Node* node) {
-  MachineType rep = RepresentationOf(OpParameter<MachineType>(node));
-  MachineType typ = TypeOf(OpParameter<MachineType>(node));
+  CheckedLoadRepresentation load_rep = CheckedLoadRepresentationOf(node->op());
   MipsOperandGenerator g(this);
   Node* const buffer = node->InputAt(0);
   Node* const offset = node->InputAt(1);
   Node* const length = node->InputAt(2);
-  ArchOpcode opcode;
-  switch (rep) {
-    case kRepWord8:
-      opcode = typ == kTypeInt32 ? kCheckedLoadInt8 : kCheckedLoadUint8;
+  ArchOpcode opcode = kArchNop;
+  switch (load_rep.representation()) {
+    case MachineRepresentation::kWord8:
+      opcode = load_rep.IsSigned() ? kCheckedLoadInt8 : kCheckedLoadUint8;
       break;
-    case kRepWord16:
-      opcode = typ == kTypeInt32 ? kCheckedLoadInt16 : kCheckedLoadUint16;
+    case MachineRepresentation::kWord16:
+      opcode = load_rep.IsSigned() ? kCheckedLoadInt16 : kCheckedLoadUint16;
       break;
-    case kRepWord32:
+    case MachineRepresentation::kWord32:
       opcode = kCheckedLoadWord32;
       break;
-    case kRepFloat32:
+    case MachineRepresentation::kFloat32:
       opcode = kCheckedLoadFloat32;
       break;
-    case kRepFloat64:
+    case MachineRepresentation::kFloat64:
       opcode = kCheckedLoadFloat64;
       break;
-    default:
+    case MachineRepresentation::kBit:     // Fall through.
+    case MachineRepresentation::kTagged:  // Fall through.
+    case MachineRepresentation::kWord64:  // Fall through.
+    case MachineRepresentation::kNone:
       UNREACHABLE();
       return;
   }
-  InstructionOperand* offset_operand = g.CanBeImmediate(offset, opcode)
-                                           ? g.UseImmediate(offset)
-                                           : g.UseRegister(offset);
+  InstructionOperand offset_operand = g.CanBeImmediate(offset, opcode)
+                                          ? g.UseImmediate(offset)
+                                          : g.UseRegister(offset);
 
-  InstructionOperand* length_operand =
-      (!g.CanBeImmediate(offset, opcode)) ? g.CanBeImmediate(length, opcode)
-      ? g.UseImmediate(length)
-      : g.UseRegister(length)
-      : g.UseRegister(length);
+  InstructionOperand length_operand = (!g.CanBeImmediate(offset, opcode))
+                                          ? g.CanBeImmediate(length, opcode)
+                                                ? g.UseImmediate(length)
+                                                : g.UseRegister(length)
+                                          : g.UseRegister(length);
 
   Emit(opcode | AddressingModeField::encode(kMode_MRI),
        g.DefineAsRegister(node), offset_operand, length_operand,
@@ -546,45 +893,46 @@
 
 
 void InstructionSelector::VisitCheckedStore(Node* node) {
-  MachineType rep = RepresentationOf(OpParameter<MachineType>(node));
+  MachineRepresentation rep = CheckedStoreRepresentationOf(node->op());
   MipsOperandGenerator g(this);
   Node* const buffer = node->InputAt(0);
   Node* const offset = node->InputAt(1);
   Node* const length = node->InputAt(2);
   Node* const value = node->InputAt(3);
-  ArchOpcode opcode;
+  ArchOpcode opcode = kArchNop;
   switch (rep) {
-    case kRepWord8:
+    case MachineRepresentation::kWord8:
       opcode = kCheckedStoreWord8;
       break;
-    case kRepWord16:
+    case MachineRepresentation::kWord16:
       opcode = kCheckedStoreWord16;
       break;
-    case kRepWord32:
+    case MachineRepresentation::kWord32:
       opcode = kCheckedStoreWord32;
       break;
-    case kRepFloat32:
+    case MachineRepresentation::kFloat32:
       opcode = kCheckedStoreFloat32;
       break;
-    case kRepFloat64:
+    case MachineRepresentation::kFloat64:
       opcode = kCheckedStoreFloat64;
       break;
     default:
       UNREACHABLE();
       return;
   }
-  InstructionOperand* offset_operand = g.CanBeImmediate(offset, opcode)
-                                           ? g.UseImmediate(offset)
-                                           : g.UseRegister(offset);
+  InstructionOperand offset_operand = g.CanBeImmediate(offset, opcode)
+                                          ? g.UseImmediate(offset)
+                                          : g.UseRegister(offset);
 
-  InstructionOperand* length_operand =
-      (!g.CanBeImmediate(offset, opcode)) ? g.CanBeImmediate(length, opcode)
-      ? g.UseImmediate(length)
-      : g.UseRegister(length)
-      : g.UseRegister(length);
+  InstructionOperand length_operand = (!g.CanBeImmediate(offset, opcode))
+                                          ? g.CanBeImmediate(length, opcode)
+                                                ? g.UseImmediate(length)
+                                                : g.UseRegister(length)
+                                          : g.UseRegister(length);
 
-  Emit(opcode | AddressingModeField::encode(kMode_MRI), nullptr, offset_operand,
-       length_operand, g.UseRegister(value), g.UseRegister(buffer));
+  Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
+       offset_operand, length_operand, g.UseRegister(value),
+       g.UseRegister(buffer));
 }
 
 
@@ -592,29 +940,47 @@
 
 // Shared routine for multiple compare operations.
 static void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
-                         InstructionOperand* left, InstructionOperand* right,
+                         InstructionOperand left, InstructionOperand right,
                          FlagsContinuation* cont) {
   MipsOperandGenerator g(selector);
   opcode = cont->Encode(opcode);
   if (cont->IsBranch()) {
-    selector->Emit(opcode, NULL, left, right, g.Label(cont->true_block()),
-                   g.Label(cont->false_block()))->MarkAsControl();
+    selector->Emit(opcode, g.NoOutput(), left, right,
+                   g.Label(cont->true_block()), g.Label(cont->false_block()));
   } else {
     DCHECK(cont->IsSet());
-    // TODO(plind): Revisit and test this path.
     selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right);
   }
 }
 
 
-// Shared routine for multiple float compare operations.
+// Shared routine for multiple float32 compare operations.
+void VisitFloat32Compare(InstructionSelector* selector, Node* node,
+                         FlagsContinuation* cont) {
+  MipsOperandGenerator g(selector);
+  Float32BinopMatcher m(node);
+  InstructionOperand lhs, rhs;
+
+  lhs = m.left().IsZero() ? g.UseImmediate(m.left().node())
+                          : g.UseRegister(m.left().node());
+  rhs = m.right().IsZero() ? g.UseImmediate(m.right().node())
+                           : g.UseRegister(m.right().node());
+  VisitCompare(selector, kMipsCmpS, lhs, rhs, cont);
+}
+
+
+// Shared routine for multiple float64 compare operations.
 void VisitFloat64Compare(InstructionSelector* selector, Node* node,
                          FlagsContinuation* cont) {
   MipsOperandGenerator g(selector);
-  Node* left = node->InputAt(0);
-  Node* right = node->InputAt(1);
-  VisitCompare(selector, kMipsCmpD, g.UseRegister(left), g.UseRegister(right),
-               cont);
+  Float64BinopMatcher m(node);
+  InstructionOperand lhs, rhs;
+
+  lhs = m.left().IsZero() ? g.UseImmediate(m.left().node())
+                          : g.UseRegister(m.left().node());
+  rhs = m.right().IsZero() ? g.UseImmediate(m.right().node())
+                           : g.UseRegister(m.right().node());
+  VisitCompare(selector, kMipsCmpD, lhs, rhs, cont);
 }
 
 
@@ -628,12 +994,52 @@
 
   // Match immediates on left or right side of comparison.
   if (g.CanBeImmediate(right, opcode)) {
-    VisitCompare(selector, opcode, g.UseRegister(left), g.UseImmediate(right),
-                 cont);
+    switch (cont->condition()) {
+      case kEqual:
+      case kNotEqual:
+        if (cont->IsSet()) {
+          VisitCompare(selector, opcode, g.UseRegister(left),
+                       g.UseImmediate(right), cont);
+        } else {
+          VisitCompare(selector, opcode, g.UseRegister(left),
+                       g.UseRegister(right), cont);
+        }
+        break;
+      case kSignedLessThan:
+      case kSignedGreaterThanOrEqual:
+      case kUnsignedLessThan:
+      case kUnsignedGreaterThanOrEqual:
+        VisitCompare(selector, opcode, g.UseRegister(left),
+                     g.UseImmediate(right), cont);
+        break;
+      default:
+        VisitCompare(selector, opcode, g.UseRegister(left),
+                     g.UseRegister(right), cont);
+    }
   } else if (g.CanBeImmediate(left, opcode)) {
     if (!commutative) cont->Commute();
-    VisitCompare(selector, opcode, g.UseRegister(right), g.UseImmediate(left),
-                 cont);
+    switch (cont->condition()) {
+      case kEqual:
+      case kNotEqual:
+        if (cont->IsSet()) {
+          VisitCompare(selector, opcode, g.UseRegister(right),
+                       g.UseImmediate(left), cont);
+        } else {
+          VisitCompare(selector, opcode, g.UseRegister(right),
+                       g.UseRegister(left), cont);
+        }
+        break;
+      case kSignedLessThan:
+      case kSignedGreaterThanOrEqual:
+      case kUnsignedLessThan:
+      case kUnsignedGreaterThanOrEqual:
+        VisitCompare(selector, opcode, g.UseRegister(right),
+                     g.UseImmediate(left), cont);
+        break;
+      default:
+        VisitCompare(selector, opcode, g.UseRegister(right),
+                     g.UseRegister(left), cont);
+    }
   } else {
     VisitCompare(selector, opcode, g.UseRegister(left), g.UseRegister(right),
                  cont);
@@ -679,26 +1085,35 @@
       case IrOpcode::kUint32LessThanOrEqual:
         cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
         return VisitWordCompare(selector, value, cont);
+      case IrOpcode::kFloat32Equal:
+        cont->OverwriteAndNegateIfEqual(kEqual);
+        return VisitFloat32Compare(selector, value, cont);
+      case IrOpcode::kFloat32LessThan:
+        cont->OverwriteAndNegateIfEqual(kUnsignedLessThan);
+        return VisitFloat32Compare(selector, value, cont);
+      case IrOpcode::kFloat32LessThanOrEqual:
+        cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
+        return VisitFloat32Compare(selector, value, cont);
       case IrOpcode::kFloat64Equal:
-        cont->OverwriteAndNegateIfEqual(kUnorderedEqual);
+        cont->OverwriteAndNegateIfEqual(kEqual);
         return VisitFloat64Compare(selector, value, cont);
       case IrOpcode::kFloat64LessThan:
-        cont->OverwriteAndNegateIfEqual(kUnorderedLessThan);
+        cont->OverwriteAndNegateIfEqual(kUnsignedLessThan);
         return VisitFloat64Compare(selector, value, cont);
       case IrOpcode::kFloat64LessThanOrEqual:
-        cont->OverwriteAndNegateIfEqual(kUnorderedLessThanOrEqual);
+        cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
         return VisitFloat64Compare(selector, value, cont);
       case IrOpcode::kProjection:
         // Check if this is the overflow output projection of an
         // <Operation>WithOverflow node.
-        if (OpParameter<size_t>(value) == 1u) {
+        if (ProjectionIndexOf(value->op()) == 1u) {
           // We cannot combine the <Operation>WithOverflow with this branch
           // unless the 0th projection (the use of the actual value of the
-          // <Operation> is either NULL, which means there's no use of the
+          // <Operation> is either nullptr, which means there's no use of the
           // actual value, or was already defined, which means it is scheduled
           // *AFTER* this branch).
           Node* const node = value->InputAt(0);
-          Node* const result = node->FindProjection(0);
+          Node* const result = NodeProperties::FindProjection(node, 0);
           if (!result || selector->IsDefined(result)) {
             switch (node->opcode()) {
               case IrOpcode::kInt32AddWithOverflow:
@@ -724,11 +1139,10 @@
   // Continuation could not be combined with a compare, emit compare against 0.
   MipsOperandGenerator g(selector);
   InstructionCode const opcode = cont->Encode(kMipsCmp);
-  InstructionOperand* const value_operand = g.UseRegister(value);
+  InstructionOperand const value_operand = g.UseRegister(value);
   if (cont->IsBranch()) {
-    selector->Emit(opcode, nullptr, value_operand, g.TempImmediate(0),
-                   g.Label(cont->true_block()),
-                   g.Label(cont->false_block()))->MarkAsControl();
+    selector->Emit(opcode, g.NoOutput(), value_operand, g.TempImmediate(0),
+                   g.Label(cont->true_block()), g.Label(cont->false_block()));
   } else {
     selector->Emit(opcode, g.DefineAsRegister(cont->result()), value_operand,
                    g.TempImmediate(0));
@@ -743,6 +1157,34 @@
 }
 
 
+void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) {
+  MipsOperandGenerator g(this);
+  InstructionOperand value_operand = g.UseRegister(node->InputAt(0));
+
+  // Emit either ArchTableSwitch or ArchLookupSwitch.
+  size_t table_space_cost = 9 + sw.value_range;
+  size_t table_time_cost = 3;
+  size_t lookup_space_cost = 2 + 2 * sw.case_count;
+  size_t lookup_time_cost = sw.case_count;
+  if (sw.case_count > 0 &&
+      table_space_cost + 3 * table_time_cost <=
+          lookup_space_cost + 3 * lookup_time_cost &&
+      sw.min_value > std::numeric_limits<int32_t>::min()) {
+    InstructionOperand index_operand = value_operand;
+    if (sw.min_value) {
+      index_operand = g.TempRegister();
+      Emit(kMipsSub, index_operand, value_operand,
+           g.TempImmediate(sw.min_value));
+    }
+    // Generate a table lookup.
+    return EmitTableSwitch(sw, index_operand);
+  }
+
+  // Generate a sequence of conditional jumps.
+  return EmitLookupSwitch(sw, value_operand);
+}
+
+
 void InstructionSelector::VisitWord32Equal(Node* const node) {
   FlagsContinuation cont(kEqual, node);
   Int32BinopMatcher m(node);
@@ -778,7 +1220,7 @@
 
 
 void InstructionSelector::VisitInt32AddWithOverflow(Node* node) {
-  if (Node* ovf = node->FindProjection(1)) {
+  if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
     FlagsContinuation cont(kOverflow, ovf);
     return VisitBinop(this, node, kMipsAddOvf, &cont);
   }
@@ -788,7 +1230,7 @@
 
 
 void InstructionSelector::VisitInt32SubWithOverflow(Node* node) {
-  if (Node* ovf = node->FindProjection(1)) {
+  if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
     FlagsContinuation cont(kOverflow, ovf);
     return VisitBinop(this, node, kMipsSubOvf, &cont);
   }
@@ -797,33 +1239,96 @@
 }
 
 
+void InstructionSelector::VisitFloat32Equal(Node* node) {
+  FlagsContinuation cont(kEqual, node);
+  VisitFloat32Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitFloat32LessThan(Node* node) {
+  FlagsContinuation cont(kUnsignedLessThan, node);
+  VisitFloat32Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitFloat32LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kUnsignedLessThanOrEqual, node);
+  VisitFloat32Compare(this, node, &cont);
+}
+
+
 void InstructionSelector::VisitFloat64Equal(Node* node) {
-  FlagsContinuation cont(kUnorderedEqual, node);
+  FlagsContinuation cont(kEqual, node);
   VisitFloat64Compare(this, node, &cont);
 }
 
 
 void InstructionSelector::VisitFloat64LessThan(Node* node) {
-  FlagsContinuation cont(kUnorderedLessThan, node);
+  FlagsContinuation cont(kUnsignedLessThan, node);
   VisitFloat64Compare(this, node, &cont);
 }
 
 
 void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
-  FlagsContinuation cont(kUnorderedLessThanOrEqual, node);
+  FlagsContinuation cont(kUnsignedLessThanOrEqual, node);
   VisitFloat64Compare(this, node, &cont);
 }
 
 
+void InstructionSelector::VisitFloat64ExtractLowWord32(Node* node) {
+  MipsOperandGenerator g(this);
+  Emit(kMipsFloat64ExtractLowWord32, g.DefineAsRegister(node),
+       g.UseRegister(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitFloat64ExtractHighWord32(Node* node) {
+  MipsOperandGenerator g(this);
+  Emit(kMipsFloat64ExtractHighWord32, g.DefineAsRegister(node),
+       g.UseRegister(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitFloat64InsertLowWord32(Node* node) {
+  MipsOperandGenerator g(this);
+  Node* left = node->InputAt(0);
+  Node* right = node->InputAt(1);
+  Emit(kMipsFloat64InsertLowWord32, g.DefineSameAsFirst(node),
+       g.UseRegister(left), g.UseRegister(right));
+}
+
+
+void InstructionSelector::VisitFloat64InsertHighWord32(Node* node) {
+  MipsOperandGenerator g(this);
+  Node* left = node->InputAt(0);
+  Node* right = node->InputAt(1);
+  Emit(kMipsFloat64InsertHighWord32, g.DefineSameAsFirst(node),
+       g.UseRegister(left), g.UseRegister(right));
+}
+
+
 // static
 MachineOperatorBuilder::Flags
 InstructionSelector::SupportedMachineOperatorFlags() {
-  if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
-    return MachineOperatorBuilder::kFloat64Floor |
-           MachineOperatorBuilder::kFloat64Ceil |
-           MachineOperatorBuilder::kFloat64RoundTruncate;
+  MachineOperatorBuilder::Flags flags = MachineOperatorBuilder::kNoFlags;
+  if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) &&
+      IsFp64Mode()) {
+    flags |= MachineOperatorBuilder::kFloat64RoundDown |
+             MachineOperatorBuilder::kFloat64RoundUp |
+             MachineOperatorBuilder::kFloat64RoundTruncate |
+             MachineOperatorBuilder::kFloat64RoundTiesEven;
   }
-  return MachineOperatorBuilder::kNoFlags;
+  return flags | MachineOperatorBuilder::kInt32DivIsSafe |
+         MachineOperatorBuilder::kUint32DivIsSafe |
+         MachineOperatorBuilder::kWord32ShiftIsSafe |
+         MachineOperatorBuilder::kFloat64Min |
+         MachineOperatorBuilder::kFloat64Max |
+         MachineOperatorBuilder::kFloat32Min |
+         MachineOperatorBuilder::kFloat32Max |
+         MachineOperatorBuilder::kFloat32RoundDown |
+         MachineOperatorBuilder::kFloat32RoundUp |
+         MachineOperatorBuilder::kFloat32RoundTruncate |
+         MachineOperatorBuilder::kFloat32RoundTiesEven;
 }
 
 }  // namespace compiler
diff --git a/src/compiler/mips/linkage-mips.cc b/src/compiler/mips/linkage-mips.cc
deleted file mode 100644
index 2b314a2..0000000
--- a/src/compiler/mips/linkage-mips.cc
+++ /dev/null
@@ -1,67 +0,0 @@
-// 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/v8.h"
-
-#include "src/assembler.h"
-#include "src/code-stubs.h"
-#include "src/compiler/linkage.h"
-#include "src/compiler/linkage-impl.h"
-#include "src/zone.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-struct MipsLinkageHelperTraits {
-  static Register ReturnValueReg() { return v0; }
-  static Register ReturnValue2Reg() { return v1; }
-  static Register JSCallFunctionReg() { return a1; }
-  static Register ContextReg() { return cp; }
-  static Register RuntimeCallFunctionReg() { return a1; }
-  static Register RuntimeCallArgCountReg() { return a0; }
-  static RegList CCalleeSaveRegisters() {
-    return s0.bit() | s1.bit() | s2.bit() | s3.bit() | s4.bit() | s5.bit() |
-           s6.bit() | s7.bit();
-  }
-  static Register CRegisterParameter(int i) {
-    static Register register_parameters[] = {a0, a1, a2, a3};
-    return register_parameters[i];
-  }
-  static int CRegisterParametersLength() { return 4; }
-};
-
-
-typedef LinkageHelper<MipsLinkageHelperTraits> LH;
-
-CallDescriptor* Linkage::GetJSCallDescriptor(int parameter_count, Zone* zone,
-                                             CallDescriptor::Flags flags) {
-  return LH::GetJSCallDescriptor(zone, parameter_count, flags);
-}
-
-
-CallDescriptor* Linkage::GetRuntimeCallDescriptor(
-    Runtime::FunctionId function, int parameter_count,
-    Operator::Properties properties, Zone* zone) {
-  return LH::GetRuntimeCallDescriptor(zone, function, parameter_count,
-                                      properties);
-}
-
-
-CallDescriptor* Linkage::GetStubCallDescriptor(
-    const CallInterfaceDescriptor& descriptor, int stack_parameter_count,
-    CallDescriptor::Flags flags, Operator::Properties properties, Zone* zone) {
-  return LH::GetStubCallDescriptor(zone, descriptor, stack_parameter_count,
-                                   flags, properties);
-}
-
-
-CallDescriptor* Linkage::GetSimplifiedCDescriptor(Zone* zone,
-                                                  MachineSignature* sig) {
-  return LH::GetSimplifiedCDescriptor(zone, sig);
-}
-
-}  // namespace compiler
-}  // namespace internal
-}  // namespace v8
diff --git a/src/compiler/mips64/OWNERS b/src/compiler/mips64/OWNERS
index 5508ba6..89455a4 100644
--- a/src/compiler/mips64/OWNERS
+++ b/src/compiler/mips64/OWNERS
@@ -3,3 +3,4 @@
 akos.palfi@imgtec.com
 balazs.kilvady@imgtec.com
 dusan.milosavljevic@imgtec.com
+ivica.bogosavljevic@imgtec.com
diff --git a/src/compiler/mips64/code-generator-mips64.cc b/src/compiler/mips64/code-generator-mips64.cc
index dee7705..1b81aa5 100644
--- a/src/compiler/mips64/code-generator-mips64.cc
+++ b/src/compiler/mips64/code-generator-mips64.cc
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "src/ast/scopes.h"
 #include "src/compiler/code-generator.h"
 #include "src/compiler/code-generator-impl.h"
 #include "src/compiler/gap-resolver.h"
 #include "src/compiler/node-matchers.h"
-#include "src/compiler/node-properties-inl.h"
+#include "src/compiler/osr.h"
 #include "src/mips/macro-assembler-mips.h"
-#include "src/scopes.h"
 
 namespace v8 {
 namespace internal {
@@ -34,16 +34,16 @@
 
 
 // Adds Mips-specific methods to convert InstructionOperands.
-class MipsOperandConverter FINAL : public InstructionOperandConverter {
+class MipsOperandConverter final : public InstructionOperandConverter {
  public:
   MipsOperandConverter(CodeGenerator* gen, Instruction* instr)
       : InstructionOperandConverter(gen, instr) {}
 
-  FloatRegister OutputSingleRegister(int index = 0) {
+  FloatRegister OutputSingleRegister(size_t index = 0) {
     return ToSingleRegister(instr_->OutputAt(index));
   }
 
-  FloatRegister InputSingleRegister(int index) {
+  FloatRegister InputSingleRegister(size_t index) {
     return ToSingleRegister(instr_->InputAt(index));
   }
 
@@ -53,7 +53,19 @@
     return ToDoubleRegister(op);
   }
 
-  Operand InputImmediate(int index) {
+  DoubleRegister InputOrZeroDoubleRegister(size_t index) {
+    if (instr_->InputAt(index)->IsImmediate()) return kDoubleRegZero;
+
+    return InputDoubleRegister(index);
+  }
+
+  DoubleRegister InputOrZeroSingleRegister(size_t index) {
+    if (instr_->InputAt(index)->IsImmediate()) return kDoubleRegZero;
+
+    return InputSingleRegister(index);
+  }
+
+  Operand InputImmediate(size_t index) {
     Constant constant = ToConstant(instr_->InputAt(index));
     switch (constant.type()) {
       case Constant::kInt32:
@@ -79,7 +91,7 @@
     return Operand(zero_reg);
   }
 
-  Operand InputOperand(int index) {
+  Operand InputOperand(size_t index) {
     InstructionOperand* op = instr_->InputAt(index);
     if (op->IsRegister()) {
       return Operand(ToRegister(op));
@@ -87,8 +99,8 @@
     return InputImmediate(index);
   }
 
-  MemOperand MemoryOperand(int* first_index) {
-    const int index = *first_index;
+  MemOperand MemoryOperand(size_t* first_index) {
+    const size_t index = *first_index;
     switch (AddressingModeField::decode(instr_->opcode())) {
       case kMode_None:
         break;
@@ -103,33 +115,31 @@
     return MemOperand(no_reg);
   }
 
-  MemOperand MemoryOperand(int index = 0) { return MemoryOperand(&index); }
+  MemOperand MemoryOperand(size_t index = 0) { return MemoryOperand(&index); }
 
   MemOperand ToMemOperand(InstructionOperand* op) const {
-    DCHECK(op != NULL);
-    DCHECK(!op->IsRegister());
-    DCHECK(!op->IsDoubleRegister());
+    DCHECK_NOT_NULL(op);
     DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot());
-    // The linkage computes where all spill slots are located.
-    FrameOffset offset = linkage()->GetFrameOffset(op->index(), frame(), 0);
+    FrameOffset offset = frame_access_state()->GetFrameOffset(
+        AllocatedOperand::cast(op)->index());
     return MemOperand(offset.from_stack_pointer() ? sp : fp, offset.offset());
   }
 };
 
 
-static inline bool HasRegisterInput(Instruction* instr, int index) {
+static inline bool HasRegisterInput(Instruction* instr, size_t index) {
   return instr->InputAt(index)->IsRegister();
 }
 
 
 namespace {
 
-class OutOfLineLoadSingle FINAL : public OutOfLineCode {
+class OutOfLineLoadSingle final : public OutOfLineCode {
  public:
   OutOfLineLoadSingle(CodeGenerator* gen, FloatRegister result)
       : OutOfLineCode(gen), result_(result) {}
 
-  void Generate() FINAL {
+  void Generate() final {
     __ Move(result_, std::numeric_limits<float>::quiet_NaN());
   }
 
@@ -138,12 +148,12 @@
 };
 
 
-class OutOfLineLoadDouble FINAL : public OutOfLineCode {
+class OutOfLineLoadDouble final : public OutOfLineCode {
  public:
   OutOfLineLoadDouble(CodeGenerator* gen, DoubleRegister result)
       : OutOfLineCode(gen), result_(result) {}
 
-  void Generate() FINAL {
+  void Generate() final {
     __ Move(result_, std::numeric_limits<double>::quiet_NaN());
   }
 
@@ -152,12 +162,12 @@
 };
 
 
-class OutOfLineLoadInteger FINAL : public OutOfLineCode {
+class OutOfLineLoadInteger final : public OutOfLineCode {
  public:
   OutOfLineLoadInteger(CodeGenerator* gen, Register result)
       : OutOfLineCode(gen), result_(result) {}
 
-  void Generate() FINAL { __ mov(result_, zero_reg); }
+  void Generate() final { __ mov(result_, zero_reg); }
 
  private:
   Register const result_;
@@ -169,7 +179,7 @@
   OutOfLineRound(CodeGenerator* gen, DoubleRegister result)
       : OutOfLineCode(gen), result_(result) {}
 
-  void Generate() FINAL {
+  void Generate() final {
     // Handle rounding to zero case where sign has to be preserved.
     // High bits of double input already in kScratchReg.
     __ dsrl(at, kScratchReg, 31);
@@ -182,27 +192,160 @@
 };
 
 
-class OutOfLineTruncate FINAL : public OutOfLineRound {
+class OutOfLineRound32 : public OutOfLineCode {
  public:
-  OutOfLineTruncate(CodeGenerator* gen, DoubleRegister result)
-      : OutOfLineRound(gen, result) {}
+  OutOfLineRound32(CodeGenerator* gen, DoubleRegister result)
+      : OutOfLineCode(gen), result_(result) {}
+
+  void Generate() final {
+    // Handle rounding to zero case where sign has to be preserved.
+    // High bits of float input already in kScratchReg.
+    __ srl(at, kScratchReg, 31);
+    __ sll(at, at, 31);
+    __ mtc1(at, result_);
+  }
+
+ private:
+  DoubleRegister const result_;
 };
 
 
-class OutOfLineFloor FINAL : public OutOfLineRound {
+class OutOfLineRecordWrite final : public OutOfLineCode {
  public:
-  OutOfLineFloor(CodeGenerator* gen, DoubleRegister result)
-      : OutOfLineRound(gen, result) {}
+  OutOfLineRecordWrite(CodeGenerator* gen, Register object, Register index,
+                       Register value, Register scratch0, Register scratch1,
+                       RecordWriteMode mode)
+      : OutOfLineCode(gen),
+        object_(object),
+        index_(index),
+        value_(value),
+        scratch0_(scratch0),
+        scratch1_(scratch1),
+        mode_(mode) {}
+
+  void Generate() final {
+    if (mode_ > RecordWriteMode::kValueIsPointer) {
+      __ JumpIfSmi(value_, exit());
+    }
+    if (mode_ > RecordWriteMode::kValueIsMap) {
+      __ CheckPageFlag(value_, scratch0_,
+                       MemoryChunk::kPointersToHereAreInterestingMask, eq,
+                       exit());
+    }
+    SaveFPRegsMode const save_fp_mode =
+        frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs;
+    // TODO(turbofan): Once we get frame elision working, we need to save
+    // and restore lr properly here if the frame was elided.
+    RecordWriteStub stub(isolate(), object_, scratch0_, scratch1_,
+                         EMIT_REMEMBERED_SET, save_fp_mode);
+    __ Daddu(scratch1_, object_, index_);
+    __ CallStub(&stub);
+  }
+
+ private:
+  Register const object_;
+  Register const index_;
+  Register const value_;
+  Register const scratch0_;
+  Register const scratch1_;
+  RecordWriteMode const mode_;
 };
 
 
-class OutOfLineCeil FINAL : public OutOfLineRound {
- public:
-  OutOfLineCeil(CodeGenerator* gen, DoubleRegister result)
-      : OutOfLineRound(gen, result) {}
-};
+Condition FlagsConditionToConditionCmp(FlagsCondition condition) {
+  switch (condition) {
+    case kEqual:
+      return eq;
+    case kNotEqual:
+      return ne;
+    case kSignedLessThan:
+      return lt;
+    case kSignedGreaterThanOrEqual:
+      return ge;
+    case kSignedLessThanOrEqual:
+      return le;
+    case kSignedGreaterThan:
+      return gt;
+    case kUnsignedLessThan:
+      return lo;
+    case kUnsignedGreaterThanOrEqual:
+      return hs;
+    case kUnsignedLessThanOrEqual:
+      return ls;
+    case kUnsignedGreaterThan:
+      return hi;
+    case kUnorderedEqual:
+    case kUnorderedNotEqual:
+      break;
+    default:
+      break;
+  }
+  UNREACHABLE();
+  return kNoCondition;
+}
 
 
+Condition FlagsConditionToConditionTst(FlagsCondition condition) {
+  switch (condition) {
+    case kNotEqual:
+      return ne;
+    case kEqual:
+      return eq;
+    default:
+      break;
+  }
+  UNREACHABLE();
+  return kNoCondition;
+}
+
+
+Condition FlagsConditionToConditionOvf(FlagsCondition condition) {
+  switch (condition) {
+    case kOverflow:
+      return ne;
+    case kNotOverflow:
+      return eq;
+    default:
+      break;
+  }
+  UNREACHABLE();
+  return kNoCondition;
+}
+
+
+FPUCondition FlagsConditionToConditionCmpFPU(bool& predicate,
+                                             FlagsCondition condition) {
+  switch (condition) {
+    case kEqual:
+      predicate = true;
+      return EQ;
+    case kNotEqual:
+      predicate = false;
+      return EQ;
+    case kUnsignedLessThan:
+      predicate = true;
+      return OLT;
+    case kUnsignedGreaterThanOrEqual:
+      predicate = false;
+      return ULT;
+    case kUnsignedLessThanOrEqual:
+      predicate = true;
+      return OLE;
+    case kUnsignedGreaterThan:
+      predicate = false;
+      return ULE;
+    case kUnorderedEqual:
+    case kUnorderedNotEqual:
+      predicate = true;
+      break;
+    default:
+      predicate = true;
+      break;
+  }
+  UNREACHABLE();
+  return kNoFPUCondition;
+}
+
 }  // namespace
 
 
@@ -213,10 +356,10 @@
     if (instr->InputAt(0)->IsRegister()) {                                    \
       auto offset = i.InputRegister(0);                                       \
       __ Branch(USE_DELAY_SLOT, ool->entry(), hs, offset, i.InputOperand(1)); \
-      __ Daddu(at, i.InputRegister(2), offset);                               \
-      __ asm_instr(result, MemOperand(at, 0));                                \
+      __ Daddu(kScratchReg, i.InputRegister(2), offset);                      \
+      __ asm_instr(result, MemOperand(kScratchReg, 0));                       \
     } else {                                                                  \
-      auto offset = i.InputOperand(0).immediate();                            \
+      int offset = static_cast<int>(i.InputOperand(0).immediate());           \
       __ Branch(ool->entry(), ls, i.InputRegister(1), Operand(offset));       \
       __ asm_instr(result, MemOperand(i.InputRegister(2), offset));           \
     }                                                                         \
@@ -231,10 +374,10 @@
     if (instr->InputAt(0)->IsRegister()) {                                    \
       auto offset = i.InputRegister(0);                                       \
       __ Branch(USE_DELAY_SLOT, ool->entry(), hs, offset, i.InputOperand(1)); \
-      __ Daddu(at, i.InputRegister(2), offset);                               \
-      __ asm_instr(result, MemOperand(at, 0));                                \
+      __ Daddu(kScratchReg, i.InputRegister(2), offset);                      \
+      __ asm_instr(result, MemOperand(kScratchReg, 0));                       \
     } else {                                                                  \
-      auto offset = i.InputOperand(0).immediate();                            \
+      int offset = static_cast<int>(i.InputOperand(0).immediate());           \
       __ Branch(ool->entry(), ls, i.InputRegister(1), Operand(offset));       \
       __ asm_instr(result, MemOperand(i.InputRegister(2), offset));           \
     }                                                                         \
@@ -249,10 +392,10 @@
       auto offset = i.InputRegister(0);                                \
       auto value = i.Input##width##Register(2);                        \
       __ Branch(USE_DELAY_SLOT, &done, hs, offset, i.InputOperand(1)); \
-      __ Daddu(at, i.InputRegister(3), offset);                        \
-      __ asm_instr(value, MemOperand(at, 0));                          \
+      __ Daddu(kScratchReg, i.InputRegister(3), offset);               \
+      __ asm_instr(value, MemOperand(kScratchReg, 0));                 \
     } else {                                                           \
-      auto offset = i.InputOperand(0).immediate();                     \
+      int offset = static_cast<int>(i.InputOperand(0).immediate());    \
       auto value = i.Input##width##Register(2);                        \
       __ Branch(&done, ls, i.InputRegister(1), Operand(offset));       \
       __ asm_instr(value, MemOperand(i.InputRegister(3), offset));     \
@@ -268,10 +411,10 @@
       auto offset = i.InputRegister(0);                                \
       auto value = i.InputRegister(2);                                 \
       __ Branch(USE_DELAY_SLOT, &done, hs, offset, i.InputOperand(1)); \
-      __ Daddu(at, i.InputRegister(3), offset);                        \
-      __ asm_instr(value, MemOperand(at, 0));                          \
+      __ Daddu(kScratchReg, i.InputRegister(3), offset);               \
+      __ asm_instr(value, MemOperand(kScratchReg, 0));                 \
     } else {                                                           \
-      auto offset = i.InputOperand(0).immediate();                     \
+      int offset = static_cast<int>(i.InputOperand(0).immediate());    \
       auto value = i.InputRegister(2);                                 \
       __ Branch(&done, ls, i.InputRegister(1), Operand(offset));       \
       __ asm_instr(value, MemOperand(i.InputRegister(3), offset));     \
@@ -280,10 +423,15 @@
   } while (0)
 
 
-#define ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(asm_instr, operation)                  \
-  do {                                                                         \
-    auto ool =                                                                 \
-        new (zone()) OutOfLine##operation(this, i.OutputDoubleRegister());     \
+#define ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(mode)                                  \
+  if (kArchVariant == kMips64r6) {                                             \
+    __ cfc1(kScratchReg, FCSR);                                                \
+    __ li(at, Operand(mode_##mode));                                           \
+    __ ctc1(at, FCSR);                                                         \
+    __ rint_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0));             \
+    __ ctc1(kScratchReg, FCSR);                                                \
+  } else {                                                                     \
+    auto ool = new (zone()) OutOfLineRound(this, i.OutputDoubleRegister());    \
     Label done;                                                                \
     __ mfhc1(kScratchReg, i.InputDoubleRegister(0));                           \
     __ Ext(at, kScratchReg, HeapNumber::kExponentShift,                        \
@@ -291,13 +439,61 @@
     __ Branch(USE_DELAY_SLOT, &done, hs, at,                                   \
               Operand(HeapNumber::kExponentBias + HeapNumber::kMantissaBits)); \
     __ mov_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0));              \
-    __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0));          \
+    __ mode##_l_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0));         \
     __ dmfc1(at, i.OutputDoubleRegister());                                    \
     __ Branch(USE_DELAY_SLOT, ool->entry(), eq, at, Operand(zero_reg));        \
     __ cvt_d_l(i.OutputDoubleRegister(), i.OutputDoubleRegister());            \
     __ bind(ool->exit());                                                      \
     __ bind(&done);                                                            \
-  } while (0)
+  }
+
+#define ASSEMBLE_ROUND_FLOAT_TO_FLOAT(mode)                                   \
+  if (kArchVariant == kMips64r6) {                                            \
+    __ cfc1(kScratchReg, FCSR);                                               \
+    __ li(at, Operand(mode_##mode));                                          \
+    __ ctc1(at, FCSR);                                                        \
+    __ rint_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0));            \
+    __ ctc1(kScratchReg, FCSR);                                               \
+  } else {                                                                    \
+    int32_t kFloat32ExponentBias = 127;                                       \
+    int32_t kFloat32MantissaBits = 23;                                        \
+    int32_t kFloat32ExponentBits = 8;                                         \
+    auto ool = new (zone()) OutOfLineRound32(this, i.OutputDoubleRegister()); \
+    Label done;                                                               \
+    __ mfc1(kScratchReg, i.InputDoubleRegister(0));                           \
+    __ Ext(at, kScratchReg, kFloat32MantissaBits, kFloat32ExponentBits);      \
+    __ Branch(USE_DELAY_SLOT, &done, hs, at,                                  \
+              Operand(kFloat32ExponentBias + kFloat32MantissaBits));          \
+    __ mov_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0));             \
+    __ mode##_w_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0));        \
+    __ mfc1(at, i.OutputDoubleRegister());                                    \
+    __ Branch(USE_DELAY_SLOT, ool->entry(), eq, at, Operand(zero_reg));       \
+    __ cvt_s_w(i.OutputDoubleRegister(), i.OutputDoubleRegister());           \
+    __ bind(ool->exit());                                                     \
+    __ bind(&done);                                                           \
+  }
+
+void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) {
+  int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta);
+  if (sp_slot_delta > 0) {
+    __ daddiu(sp, sp, sp_slot_delta * kPointerSize);
+  }
+  frame_access_state()->SetFrameAccessToDefault();
+}
+
+
+void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) {
+  int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta);
+  if (sp_slot_delta < 0) {
+    __ Dsubu(sp, sp, Operand(-sp_slot_delta * kPointerSize));
+    frame_access_state()->IncreaseSPDelta(-sp_slot_delta);
+  }
+  if (frame()->needs_frame()) {
+    __ ld(ra, MemOperand(fp, StandardFrameConstants::kCallerPCOffset));
+    __ ld(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
+  }
+  frame_access_state()->SetFrameAccessToSP();
+}
 
 
 // Assembles an instruction after register allocation, producing machine code.
@@ -315,7 +511,21 @@
         __ daddiu(at, i.InputRegister(0), Code::kHeaderSize - kHeapObjectTag);
         __ Call(at);
       }
-      AddSafepointAndDeopt(instr);
+      RecordCallPosition(instr);
+      frame_access_state()->ClearSPDelta();
+      break;
+    }
+    case kArchTailCallCodeObject: {
+      int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
+      AssembleDeconstructActivationRecord(stack_param_delta);
+      if (instr->InputAt(0)->IsImmediate()) {
+        __ Jump(Handle<Code>::cast(i.InputHeapObject(0)),
+                RelocInfo::CODE_TARGET);
+      } else {
+        __ daddiu(at, i.InputRegister(0), Code::kHeaderSize - kHeapObjectTag);
+        __ Jump(at);
+      }
+      frame_access_state()->ClearSPDelta();
       break;
     }
     case kArchCallJSFunction: {
@@ -326,39 +536,123 @@
         __ ld(kScratchReg, FieldMemOperand(func, JSFunction::kContextOffset));
         __ Assert(eq, kWrongFunctionContext, cp, Operand(kScratchReg));
       }
-
       __ ld(at, FieldMemOperand(func, JSFunction::kCodeEntryOffset));
       __ Call(at);
-      AddSafepointAndDeopt(instr);
+      RecordCallPosition(instr);
+      frame_access_state()->ClearSPDelta();
+      break;
+    }
+    case kArchTailCallJSFunction: {
+      Register func = i.InputRegister(0);
+      if (FLAG_debug_code) {
+        // Check the function's context matches the context argument.
+        __ ld(kScratchReg, FieldMemOperand(func, JSFunction::kContextOffset));
+        __ Assert(eq, kWrongFunctionContext, cp, Operand(kScratchReg));
+      }
+      int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
+      AssembleDeconstructActivationRecord(stack_param_delta);
+      __ ld(at, FieldMemOperand(func, JSFunction::kCodeEntryOffset));
+      __ Jump(at);
+      frame_access_state()->ClearSPDelta();
+      break;
+    }
+    case kArchLazyBailout: {
+      EnsureSpaceForLazyDeopt();
+      RecordCallPosition(instr);
+      break;
+    }
+    case kArchPrepareCallCFunction: {
+      int const num_parameters = MiscField::decode(instr->opcode());
+      __ PrepareCallCFunction(num_parameters, kScratchReg);
+      // Frame alignment requires using FP-relative frame addressing.
+      frame_access_state()->SetFrameAccessToFP();
+      break;
+    }
+    case kArchPrepareTailCall:
+      AssemblePrepareTailCall(i.InputInt32(instr->InputCount() - 1));
+      break;
+    case kArchCallCFunction: {
+      int const num_parameters = MiscField::decode(instr->opcode());
+      if (instr->InputAt(0)->IsImmediate()) {
+        ExternalReference ref = i.InputExternalReference(0);
+        __ CallCFunction(ref, num_parameters);
+      } else {
+        Register func = i.InputRegister(0);
+        __ CallCFunction(func, num_parameters);
+      }
+      frame_access_state()->SetFrameAccessToDefault();
+      frame_access_state()->ClearSPDelta();
       break;
     }
     case kArchJmp:
       AssembleArchJump(i.InputRpo(0));
       break;
+    case kArchLookupSwitch:
+      AssembleArchLookupSwitch(instr);
+      break;
+    case kArchTableSwitch:
+      AssembleArchTableSwitch(instr);
+      break;
     case kArchNop:
+    case kArchThrowTerminator:
       // don't emit code for nops.
       break;
+    case kArchDeoptimize: {
+      int deopt_state_id =
+          BuildTranslation(instr, -1, 0, OutputFrameStateCombine::Ignore());
+      Deoptimizer::BailoutType bailout_type =
+          Deoptimizer::BailoutType(MiscField::decode(instr->opcode()));
+      AssembleDeoptimizerCall(deopt_state_id, bailout_type);
+      break;
+    }
     case kArchRet:
       AssembleReturn();
       break;
     case kArchStackPointer:
       __ mov(i.OutputRegister(), sp);
       break;
+    case kArchFramePointer:
+      __ mov(i.OutputRegister(), fp);
+      break;
     case kArchTruncateDoubleToI:
       __ TruncateDoubleToI(i.OutputRegister(), i.InputDoubleRegister(0));
       break;
+    case kArchStoreWithWriteBarrier: {
+      RecordWriteMode mode =
+          static_cast<RecordWriteMode>(MiscField::decode(instr->opcode()));
+      Register object = i.InputRegister(0);
+      Register index = i.InputRegister(1);
+      Register value = i.InputRegister(2);
+      Register scratch0 = i.TempRegister(0);
+      Register scratch1 = i.TempRegister(1);
+      auto ool = new (zone()) OutOfLineRecordWrite(this, object, index, value,
+                                                   scratch0, scratch1, mode);
+      __ Daddu(at, object, index);
+      __ sd(value, MemOperand(at));
+      __ CheckPageFlag(object, scratch0,
+                       MemoryChunk::kPointersFromHereAreInterestingMask, ne,
+                       ool->entry());
+      __ bind(ool->exit());
+      break;
+    }
     case kMips64Add:
       __ Addu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
       break;
     case kMips64Dadd:
       __ Daddu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
       break;
+    case kMips64DaddOvf:
+      // Pseudo-instruction used for overflow/branch. No opcode emitted here.
+      break;
     case kMips64Sub:
       __ Subu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
       break;
     case kMips64Dsub:
       __ Dsubu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
       break;
+    case kMips64DsubOvf:
+      // Pseudo-instruction used for overflow/branch. No opcode emitted here.
+      break;
     case kMips64Mul:
       __ Mul(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
       break;
@@ -368,11 +662,24 @@
     case kMips64MulHighU:
       __ Mulhu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
       break;
+    case kMips64DMulHigh:
+      __ Dmulh(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      break;
     case kMips64Div:
       __ Div(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      if (kArchVariant == kMips64r6) {
+        __ selnez(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
+      } else {
+        __ Movz(i.OutputRegister(), i.InputRegister(1), i.InputRegister(1));
+      }
       break;
     case kMips64DivU:
       __ Divu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      if (kArchVariant == kMips64r6) {
+        __ selnez(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
+      } else {
+        __ Movz(i.OutputRegister(), i.InputRegister(1), i.InputRegister(1));
+      }
       break;
     case kMips64Mod:
       __ Mod(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
@@ -385,9 +692,19 @@
       break;
     case kMips64Ddiv:
       __ Ddiv(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      if (kArchVariant == kMips64r6) {
+        __ selnez(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
+      } else {
+        __ Movz(i.OutputRegister(), i.InputRegister(1), i.InputRegister(1));
+      }
       break;
     case kMips64DdivU:
       __ Ddivu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      if (kArchVariant == kMips64r6) {
+        __ selnez(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
+      } else {
+        __ Movz(i.OutputRegister(), i.InputRegister(1), i.InputRegister(1));
+      }
       break;
     case kMips64Dmod:
       __ Dmod(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
@@ -395,58 +712,103 @@
     case kMips64DmodU:
       __ Dmodu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
       break;
-      __ And(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
-      break;
     case kMips64And:
       __ And(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
       break;
     case kMips64Or:
       __ Or(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
       break;
+    case kMips64Nor:
+      if (instr->InputAt(1)->IsRegister()) {
+        __ Nor(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      } else {
+        DCHECK(i.InputOperand(1).immediate() == 0);
+        __ Nor(i.OutputRegister(), i.InputRegister(0), zero_reg);
+      }
+      break;
     case kMips64Xor:
       __ Xor(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
       break;
+    case kMips64Clz:
+      __ Clz(i.OutputRegister(), i.InputRegister(0));
+      break;
+    case kMips64Dclz:
+      __ dclz(i.OutputRegister(), i.InputRegister(0));
+      break;
     case kMips64Shl:
       if (instr->InputAt(1)->IsRegister()) {
         __ sllv(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
       } else {
-        int32_t imm = i.InputOperand(1).immediate();
-        __ sll(i.OutputRegister(), i.InputRegister(0), imm);
+        int64_t imm = i.InputOperand(1).immediate();
+        __ sll(i.OutputRegister(), i.InputRegister(0),
+               static_cast<uint16_t>(imm));
       }
       break;
     case kMips64Shr:
       if (instr->InputAt(1)->IsRegister()) {
         __ srlv(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
       } else {
-        int32_t imm = i.InputOperand(1).immediate();
-        __ srl(i.OutputRegister(), i.InputRegister(0), imm);
+        int64_t imm = i.InputOperand(1).immediate();
+        __ srl(i.OutputRegister(), i.InputRegister(0),
+               static_cast<uint16_t>(imm));
       }
       break;
     case kMips64Sar:
       if (instr->InputAt(1)->IsRegister()) {
         __ srav(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
       } else {
-        int32_t imm = i.InputOperand(1).immediate();
-        __ sra(i.OutputRegister(), i.InputRegister(0), imm);
+        int64_t imm = i.InputOperand(1).immediate();
+        __ sra(i.OutputRegister(), i.InputRegister(0),
+               static_cast<uint16_t>(imm));
       }
       break;
     case kMips64Ext:
       __ Ext(i.OutputRegister(), i.InputRegister(0), i.InputInt8(1),
              i.InputInt8(2));
       break;
-    case kMips64Dext:
-      __ Dext(i.OutputRegister(), i.InputRegister(0), i.InputInt8(1),
-              i.InputInt8(2));
+    case kMips64Ins:
+      if (instr->InputAt(1)->IsImmediate() && i.InputInt8(1) == 0) {
+        __ Ins(i.OutputRegister(), zero_reg, i.InputInt8(1), i.InputInt8(2));
+      } else {
+        __ Ins(i.OutputRegister(), i.InputRegister(0), i.InputInt8(1),
+               i.InputInt8(2));
+      }
+      break;
+    case kMips64Dext: {
+      int16_t pos = i.InputInt8(1);
+      int16_t size = i.InputInt8(2);
+      if (size > 0 && size <= 32 && pos >= 0 && pos < 32) {
+        __ Dext(i.OutputRegister(), i.InputRegister(0), i.InputInt8(1),
+                i.InputInt8(2));
+      } else if (size > 32 && size <= 64 && pos > 0 && pos < 32) {
+        __ Dextm(i.OutputRegister(), i.InputRegister(0), i.InputInt8(1),
+                 i.InputInt8(2));
+      } else {
+        DCHECK(size > 0 && size <= 32 && pos >= 32 && pos < 64);
+        __ Dextu(i.OutputRegister(), i.InputRegister(0), i.InputInt8(1),
+                 i.InputInt8(2));
+      }
+      break;
+    }
+    case kMips64Dins:
+      if (instr->InputAt(1)->IsImmediate() && i.InputInt8(1) == 0) {
+        __ Dins(i.OutputRegister(), zero_reg, i.InputInt8(1), i.InputInt8(2));
+      } else {
+        __ Dins(i.OutputRegister(), i.InputRegister(0), i.InputInt8(1),
+                i.InputInt8(2));
+      }
       break;
     case kMips64Dshl:
       if (instr->InputAt(1)->IsRegister()) {
         __ dsllv(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
       } else {
-        int32_t imm = i.InputOperand(1).immediate();
+        int64_t imm = i.InputOperand(1).immediate();
         if (imm < 32) {
-          __ dsll(i.OutputRegister(), i.InputRegister(0), imm);
+          __ dsll(i.OutputRegister(), i.InputRegister(0),
+                  static_cast<uint16_t>(imm));
         } else {
-          __ dsll32(i.OutputRegister(), i.InputRegister(0), imm - 32);
+          __ dsll32(i.OutputRegister(), i.InputRegister(0),
+                    static_cast<uint16_t>(imm - 32));
         }
       }
       break;
@@ -454,11 +816,13 @@
       if (instr->InputAt(1)->IsRegister()) {
         __ dsrlv(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
       } else {
-        int32_t imm = i.InputOperand(1).immediate();
+        int64_t imm = i.InputOperand(1).immediate();
         if (imm < 32) {
-          __ dsrl(i.OutputRegister(), i.InputRegister(0), imm);
+          __ dsrl(i.OutputRegister(), i.InputRegister(0),
+                  static_cast<uint16_t>(imm));
         } else {
-          __ dsrl32(i.OutputRegister(), i.InputRegister(0), imm - 32);
+          __ dsrl32(i.OutputRegister(), i.InputRegister(0),
+                    static_cast<uint16_t>(imm - 32));
         }
       }
       break;
@@ -466,7 +830,7 @@
       if (instr->InputAt(1)->IsRegister()) {
         __ dsrav(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
       } else {
-        int32_t imm = i.InputOperand(1).immediate();
+        int64_t imm = i.InputOperand(1).immediate();
         if (imm < 32) {
           __ dsra(i.OutputRegister(), i.InputRegister(0), imm);
         } else {
@@ -481,11 +845,9 @@
       __ Dror(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
       break;
     case kMips64Tst:
-    case kMips64Tst32:
       // Pseudo-instruction used for cmp/branch. No opcode emitted here.
       break;
     case kMips64Cmp:
-    case kMips64Cmp32:
       // Pseudo-instruction used for cmp/branch. No opcode emitted here.
       break;
     case kMips64Mov:
@@ -498,6 +860,56 @@
       }
       break;
 
+    case kMips64CmpS:
+      // Psuedo-instruction used for FP cmp/branch. No opcode emitted here.
+      break;
+    case kMips64AddS:
+      // TODO(plind): add special case: combine mult & add.
+      __ add_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+               i.InputDoubleRegister(1));
+      break;
+    case kMips64SubS:
+      __ sub_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+               i.InputDoubleRegister(1));
+      break;
+    case kMips64MulS:
+      // TODO(plind): add special case: right op is -1.0, see arm port.
+      __ mul_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+               i.InputDoubleRegister(1));
+      break;
+    case kMips64DivS:
+      __ div_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+               i.InputDoubleRegister(1));
+      break;
+    case kMips64ModS: {
+      // TODO(bmeurer): We should really get rid of this special instruction,
+      // and generate a CallAddress instruction instead.
+      FrameScope scope(masm(), StackFrame::MANUAL);
+      __ PrepareCallCFunction(0, 2, kScratchReg);
+      __ MovToFloatParameters(i.InputDoubleRegister(0),
+                              i.InputDoubleRegister(1));
+      // TODO(balazs.kilvady): implement mod_two_floats_operation(isolate())
+      __ CallCFunction(ExternalReference::mod_two_doubles_operation(isolate()),
+                       0, 2);
+      // Move the result in the double result register.
+      __ MovFromFloatResult(i.OutputSingleRegister());
+      break;
+    }
+    case kMips64AbsS:
+      __ abs_s(i.OutputSingleRegister(), i.InputSingleRegister(0));
+      break;
+    case kMips64SqrtS: {
+      __ sqrt_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
+      break;
+    }
+    case kMips64MaxS:
+      __ max_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+               i.InputDoubleRegister(1));
+      break;
+    case kMips64MinS:
+      __ min_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+               i.InputDoubleRegister(1));
+      break;
     case kMips64CmpD:
       // Psuedo-instruction used for FP cmp/branch. No opcode emitted here.
       break;
@@ -532,39 +944,167 @@
       __ MovFromFloatResult(i.OutputDoubleRegister());
       break;
     }
-    case kMips64Float64Floor: {
-      ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(floor_l_d, Floor);
+    case kMips64AbsD:
+      __ abs_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
       break;
-    }
-    case kMips64Float64Ceil: {
-      ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(ceil_l_d, Ceil);
-      break;
-    }
-    case kMips64Float64RoundTruncate: {
-      ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(trunc_l_d, Truncate);
-      break;
-    }
     case kMips64SqrtD: {
       __ sqrt_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
       break;
     }
-    case kMips64CvtSD: {
+    case kMips64MaxD:
+      __ max_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+               i.InputDoubleRegister(1));
+      break;
+    case kMips64MinD:
+      __ min_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+               i.InputDoubleRegister(1));
+      break;
+    case kMips64Float64RoundDown: {
+      ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(floor);
+      break;
+    }
+    case kMips64Float32RoundDown: {
+      ASSEMBLE_ROUND_FLOAT_TO_FLOAT(floor);
+      break;
+    }
+    case kMips64Float64RoundTruncate: {
+      ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(trunc);
+      break;
+    }
+    case kMips64Float32RoundTruncate: {
+      ASSEMBLE_ROUND_FLOAT_TO_FLOAT(trunc);
+      break;
+    }
+    case kMips64Float64RoundUp: {
+      ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(ceil);
+      break;
+    }
+    case kMips64Float32RoundUp: {
+      ASSEMBLE_ROUND_FLOAT_TO_FLOAT(ceil);
+      break;
+    }
+    case kMips64Float64RoundTiesEven: {
+      ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(round);
+      break;
+    }
+    case kMips64Float32RoundTiesEven: {
+      ASSEMBLE_ROUND_FLOAT_TO_FLOAT(round);
+      break;
+    }
+    case kMips64Float64Max: {
+      // (b < a) ? a : b
+      if (kArchVariant == kMips64r6) {
+        __ cmp_d(OLT, i.OutputDoubleRegister(), i.InputDoubleRegister(1),
+                 i.InputDoubleRegister(0));
+        __ sel_d(i.OutputDoubleRegister(), i.InputDoubleRegister(1),
+                 i.InputDoubleRegister(0));
+      } else {
+        __ c_d(OLT, i.InputDoubleRegister(0), i.InputDoubleRegister(1));
+        // Left operand is result, passthrough if false.
+        __ movt_d(i.OutputDoubleRegister(), i.InputDoubleRegister(1));
+      }
+      break;
+    }
+    case kMips64Float64Min: {
+      // (a < b) ? a : b
+      if (kArchVariant == kMips64r6) {
+        __ cmp_d(OLT, i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+                 i.InputDoubleRegister(1));
+        __ sel_d(i.OutputDoubleRegister(), i.InputDoubleRegister(1),
+                 i.InputDoubleRegister(0));
+      } else {
+        __ c_d(OLT, i.InputDoubleRegister(1), i.InputDoubleRegister(0));
+        // Right operand is result, passthrough if false.
+        __ movt_d(i.OutputDoubleRegister(), i.InputDoubleRegister(1));
+      }
+      break;
+    }
+    case kMips64Float32Max: {
+      // (b < a) ? a : b
+      if (kArchVariant == kMips64r6) {
+        __ cmp_s(OLT, i.OutputDoubleRegister(), i.InputDoubleRegister(1),
+                 i.InputDoubleRegister(0));
+        __ sel_s(i.OutputDoubleRegister(), i.InputDoubleRegister(1),
+                 i.InputDoubleRegister(0));
+      } else {
+        __ c_s(OLT, i.InputDoubleRegister(0), i.InputDoubleRegister(1));
+        // Left operand is result, passthrough if false.
+        __ movt_s(i.OutputDoubleRegister(), i.InputDoubleRegister(1));
+      }
+      break;
+    }
+    case kMips64Float32Min: {
+      // (a < b) ? a : b
+      if (kArchVariant == kMips64r6) {
+        __ cmp_s(OLT, i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+                 i.InputDoubleRegister(1));
+        __ sel_s(i.OutputDoubleRegister(), i.InputDoubleRegister(1),
+                 i.InputDoubleRegister(0));
+      } else {
+        __ c_s(OLT, i.InputDoubleRegister(1), i.InputDoubleRegister(0));
+        // Right operand is result, passthrough if false.
+        __ movt_s(i.OutputDoubleRegister(), i.InputDoubleRegister(1));
+      }
+      break;
+    }
+    case kMips64CvtSD:
       __ cvt_s_d(i.OutputSingleRegister(), i.InputDoubleRegister(0));
       break;
-    }
-    case kMips64CvtDS: {
+    case kMips64CvtDS:
       __ cvt_d_s(i.OutputDoubleRegister(), i.InputSingleRegister(0));
       break;
-    }
     case kMips64CvtDW: {
       FPURegister scratch = kScratchDoubleReg;
       __ mtc1(i.InputRegister(0), scratch);
       __ cvt_d_w(i.OutputDoubleRegister(), scratch);
       break;
     }
-    case kMips64CvtDUw: {
+    case kMips64CvtSW: {
       FPURegister scratch = kScratchDoubleReg;
-      __ Cvt_d_uw(i.OutputDoubleRegister(), i.InputRegister(0), scratch);
+      __ mtc1(i.InputRegister(0), scratch);
+      __ cvt_s_w(i.OutputDoubleRegister(), scratch);
+      break;
+    }
+    case kMips64CvtSL: {
+      FPURegister scratch = kScratchDoubleReg;
+      __ dmtc1(i.InputRegister(0), scratch);
+      __ cvt_s_l(i.OutputDoubleRegister(), scratch);
+      break;
+    }
+    case kMips64CvtDL: {
+      FPURegister scratch = kScratchDoubleReg;
+      __ dmtc1(i.InputRegister(0), scratch);
+      __ cvt_d_l(i.OutputDoubleRegister(), scratch);
+      break;
+    }
+    case kMips64CvtDUw: {
+      __ Cvt_d_uw(i.OutputDoubleRegister(), i.InputRegister(0));
+      break;
+    }
+    case kMips64CvtDUl: {
+      __ Cvt_d_ul(i.OutputDoubleRegister(), i.InputRegister(0));
+      break;
+    }
+    case kMips64CvtSUl: {
+      __ Cvt_s_ul(i.OutputDoubleRegister(), i.InputRegister(0));
+      break;
+    }
+    case kMips64FloorWD: {
+      FPURegister scratch = kScratchDoubleReg;
+      __ floor_w_d(scratch, i.InputDoubleRegister(0));
+      __ mfc1(i.OutputRegister(), scratch);
+      break;
+    }
+    case kMips64CeilWD: {
+      FPURegister scratch = kScratchDoubleReg;
+      __ ceil_w_d(scratch, i.InputDoubleRegister(0));
+      __ mfc1(i.OutputRegister(), scratch);
+      break;
+    }
+    case kMips64RoundWD: {
+      FPURegister scratch = kScratchDoubleReg;
+      __ round_w_d(scratch, i.InputDoubleRegister(0));
+      __ mfc1(i.OutputRegister(), scratch);
       break;
     }
     case kMips64TruncWD: {
@@ -574,12 +1114,126 @@
       __ mfc1(i.OutputRegister(), scratch);
       break;
     }
+    case kMips64FloorWS: {
+      FPURegister scratch = kScratchDoubleReg;
+      __ floor_w_s(scratch, i.InputDoubleRegister(0));
+      __ mfc1(i.OutputRegister(), scratch);
+      break;
+    }
+    case kMips64CeilWS: {
+      FPURegister scratch = kScratchDoubleReg;
+      __ ceil_w_s(scratch, i.InputDoubleRegister(0));
+      __ mfc1(i.OutputRegister(), scratch);
+      break;
+    }
+    case kMips64RoundWS: {
+      FPURegister scratch = kScratchDoubleReg;
+      __ round_w_s(scratch, i.InputDoubleRegister(0));
+      __ mfc1(i.OutputRegister(), scratch);
+      break;
+    }
+    case kMips64TruncWS: {
+      FPURegister scratch = kScratchDoubleReg;
+      __ trunc_w_s(scratch, i.InputDoubleRegister(0));
+      __ mfc1(i.OutputRegister(), scratch);
+      break;
+    }
+    case kMips64TruncLS: {
+      FPURegister scratch = kScratchDoubleReg;
+      Register tmp_fcsr = kScratchReg;
+      Register result = kScratchReg2;
+
+      bool load_status = instr->OutputCount() > 1;
+      if (load_status) {
+        // Save FCSR.
+        __ cfc1(tmp_fcsr, FCSR);
+        // Clear FPU flags.
+        __ ctc1(zero_reg, FCSR);
+      }
+      // Other arches use round to zero here, so we follow.
+      __ trunc_l_s(scratch, i.InputDoubleRegister(0));
+      __ dmfc1(i.OutputRegister(), scratch);
+      if (load_status) {
+        __ cfc1(result, FCSR);
+        // Check for overflow and NaNs.
+        __ andi(result, result,
+                (kFCSROverflowFlagMask | kFCSRInvalidOpFlagMask));
+        __ Slt(result, zero_reg, result);
+        __ xori(result, result, 1);
+        __ mov(i.OutputRegister(1), result);
+        // Restore FCSR
+        __ ctc1(tmp_fcsr, FCSR);
+      }
+      break;
+    }
+    case kMips64TruncLD: {
+      FPURegister scratch = kScratchDoubleReg;
+      Register tmp_fcsr = kScratchReg;
+      Register result = kScratchReg2;
+
+      bool load_status = instr->OutputCount() > 1;
+      if (load_status) {
+        // Save FCSR.
+        __ cfc1(tmp_fcsr, FCSR);
+        // Clear FPU flags.
+        __ ctc1(zero_reg, FCSR);
+      }
+      // Other arches use round to zero here, so we follow.
+      __ trunc_l_d(scratch, i.InputDoubleRegister(0));
+      __ dmfc1(i.OutputRegister(0), scratch);
+      if (load_status) {
+        __ cfc1(result, FCSR);
+        // Check for overflow and NaNs.
+        __ andi(result, result,
+                (kFCSROverflowFlagMask | kFCSRInvalidOpFlagMask));
+        __ Slt(result, zero_reg, result);
+        __ xori(result, result, 1);
+        __ mov(i.OutputRegister(1), result);
+        // Restore FCSR
+        __ ctc1(tmp_fcsr, FCSR);
+      }
+      break;
+    }
     case kMips64TruncUwD: {
       FPURegister scratch = kScratchDoubleReg;
       // TODO(plind): Fix wrong param order of Trunc_uw_d() macro-asm function.
       __ Trunc_uw_d(i.InputDoubleRegister(0), i.OutputRegister(), scratch);
       break;
     }
+    case kMips64TruncUlS: {
+      FPURegister scratch = kScratchDoubleReg;
+      Register result = instr->OutputCount() > 1 ? i.OutputRegister(1) : no_reg;
+      // TODO(plind): Fix wrong param order of Trunc_ul_s() macro-asm function.
+      __ Trunc_ul_s(i.InputDoubleRegister(0), i.OutputRegister(), scratch,
+                    result);
+      break;
+    }
+    case kMips64TruncUlD: {
+      FPURegister scratch = kScratchDoubleReg;
+      Register result = instr->OutputCount() > 1 ? i.OutputRegister(1) : no_reg;
+      // TODO(plind): Fix wrong param order of Trunc_ul_d() macro-asm function.
+      __ Trunc_ul_d(i.InputDoubleRegister(0), i.OutputRegister(0), scratch,
+                    result);
+      break;
+    }
+    case kMips64BitcastDL:
+      __ dmfc1(i.OutputRegister(), i.InputDoubleRegister(0));
+      break;
+    case kMips64BitcastLD:
+      __ dmtc1(i.InputRegister(0), i.OutputDoubleRegister());
+      break;
+    case kMips64Float64ExtractLowWord32:
+      __ FmoveLow(i.OutputRegister(), i.InputDoubleRegister(0));
+      break;
+    case kMips64Float64ExtractHighWord32:
+      __ FmoveHigh(i.OutputRegister(), i.InputDoubleRegister(0));
+      break;
+    case kMips64Float64InsertLowWord32:
+      __ FmoveLow(i.OutputDoubleRegister(), i.InputRegister(1));
+      break;
+    case kMips64Float64InsertHighWord32:
+      __ FmoveHigh(i.OutputDoubleRegister(), i.InputRegister(1));
+      break;
     // ... more basic instructions ...
 
     case kMips64Lbu:
@@ -617,7 +1271,7 @@
       break;
     }
     case kMips64Swc1: {
-      int index = 0;
+      size_t index = 0;
       MemOperand operand = i.MemoryOperand(&index);
       __ swc1(i.InputSingleRegister(index), operand);
       break;
@@ -629,28 +1283,26 @@
       __ sdc1(i.InputDoubleRegister(2), i.MemoryOperand());
       break;
     case kMips64Push:
-      __ Push(i.InputRegister(0));
+      if (instr->InputAt(0)->IsDoubleRegister()) {
+        __ sdc1(i.InputDoubleRegister(0), MemOperand(sp, -kDoubleSize));
+        __ Subu(sp, sp, Operand(kDoubleSize));
+        frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize);
+      } else {
+        __ Push(i.InputRegister(0));
+        frame_access_state()->IncreaseSPDelta(1);
+      }
       break;
     case kMips64StackClaim: {
-      int words = MiscField::decode(instr->opcode());
-      __ Dsubu(sp, sp, Operand(words << kPointerSizeLog2));
+      __ Dsubu(sp, sp, Operand(i.InputInt32(0)));
+      frame_access_state()->IncreaseSPDelta(i.InputInt32(0) / kPointerSize);
       break;
     }
     case kMips64StoreToStackSlot: {
-      int slot = MiscField::decode(instr->opcode());
-      __ sd(i.InputRegister(0), MemOperand(sp, slot << kPointerSizeLog2));
-      break;
-    }
-    case kMips64StoreWriteBarrier: {
-      Register object = i.InputRegister(0);
-      Register index = i.InputRegister(1);
-      Register value = i.InputRegister(2);
-      __ daddu(index, object, index);
-      __ sd(value, MemOperand(index));
-      SaveFPRegsMode mode =
-          frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs;
-      RAStatus ra_status = kRAHasNotBeenSaved;
-      __ RecordWrite(object, index, value, ra_status, mode);
+      if (instr->InputAt(0)->IsDoubleRegister()) {
+        __ sdc1(i.InputDoubleRegister(0), MemOperand(sp, i.InputInt32(1)));
+      } else {
+        __ sd(i.InputRegister(0), MemOperand(sp, i.InputInt32(1)));
+      }
       break;
     }
     case kCheckedLoadInt8:
@@ -668,6 +1320,9 @@
     case kCheckedLoadWord32:
       ASSEMBLE_CHECKED_LOAD_INTEGER(lw);
       break;
+    case kCheckedLoadWord64:
+      ASSEMBLE_CHECKED_LOAD_INTEGER(ld);
+      break;
     case kCheckedLoadFloat32:
       ASSEMBLE_CHECKED_LOAD_FLOAT(Single, lwc1);
       break;
@@ -683,6 +1338,9 @@
     case kCheckedStoreWord32:
       ASSEMBLE_CHECKED_STORE_INTEGER(sw);
       break;
+    case kCheckedStoreWord64:
+      ASSEMBLE_CHECKED_STORE_INTEGER(sd);
+      break;
     case kCheckedStoreFloat32:
       ASSEMBLE_CHECKED_STORE_FLOAT(Single, swc1);
       break;
@@ -690,7 +1348,7 @@
       ASSEMBLE_CHECKED_STORE_FLOAT(Double, sdc1);
       break;
   }
-}
+}  // NOLINT(readability/fn_size)
 
 
 #define UNSUPPORTED_COND(opcode, condition)                                  \
@@ -698,225 +1356,119 @@
   out << "Unsupported " << #opcode << " condition: \"" << condition << "\""; \
   UNIMPLEMENTED();
 
+static bool convertCondition(FlagsCondition condition, Condition& cc) {
+  switch (condition) {
+    case kEqual:
+      cc = eq;
+      return true;
+    case kNotEqual:
+      cc = ne;
+      return true;
+    case kUnsignedLessThan:
+      cc = lt;
+      return true;
+    case kUnsignedGreaterThanOrEqual:
+      cc = uge;
+      return true;
+    case kUnsignedLessThanOrEqual:
+      cc = le;
+      return true;
+    case kUnsignedGreaterThan:
+      cc = ugt;
+      return true;
+    default:
+      break;
+  }
+  return false;
+}
+
+
 // Assembles branches after an instruction.
 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) {
   MipsOperandConverter i(this, instr);
   Label* tlabel = branch->true_label;
   Label* flabel = branch->false_label;
   Condition cc = kNoCondition;
-
   // MIPS does not have condition code flags, so compare and branch are
   // implemented differently than on the other arch's. The compare operations
   // emit mips psuedo-instructions, which are handled here by branch
   // instructions that do the actual comparison. Essential that the input
-  // registers to compare psuedo-op are not modified before this branch op, as
+  // registers to compare pseudo-op are not modified before this branch op, as
   // they are tested here.
-  // TODO(plind): Add CHECK() to ensure that test/cmp and this branch were
-  //    not separated by other instructions.
 
   if (instr->arch_opcode() == kMips64Tst) {
-    switch (branch->condition) {
-      case kNotEqual:
-        cc = ne;
-        break;
-      case kEqual:
-        cc = eq;
-        break;
-      default:
-        UNSUPPORTED_COND(kMips64Tst, branch->condition);
-        break;
-    }
+    cc = FlagsConditionToConditionTst(branch->condition);
     __ And(at, i.InputRegister(0), i.InputOperand(1));
     __ Branch(tlabel, cc, at, Operand(zero_reg));
-  } else if (instr->arch_opcode() == kMips64Tst32) {
-    switch (branch->condition) {
-      case kNotEqual:
-        cc = ne;
-        break;
-      case kEqual:
-        cc = eq;
-        break;
-      default:
-        UNSUPPORTED_COND(kMips64Tst32, branch->condition);
-        break;
-    }
-    // Zero-extend registers on MIPS64 only 64-bit operand
-    // branch and compare op. is available.
-    // This is a disadvantage to perform 32-bit operation on MIPS64.
-    // Try to force globally in front-end Word64 representation to be preferred
-    // for MIPS64 even for Word32.
-    __ And(at, i.InputRegister(0), i.InputOperand(1));
-    __ Dext(at, at, 0, 32);
-    __ Branch(tlabel, cc, at, Operand(zero_reg));
   } else if (instr->arch_opcode() == kMips64Dadd ||
              instr->arch_opcode() == kMips64Dsub) {
-    switch (branch->condition) {
-      case kOverflow:
-        cc = ne;
-        break;
-      case kNotOverflow:
-        cc = eq;
-        break;
-      default:
-        UNSUPPORTED_COND(kMips64Dadd, branch->condition);
-        break;
-    }
-
+    cc = FlagsConditionToConditionOvf(branch->condition);
     __ dsra32(kScratchReg, i.OutputRegister(), 0);
     __ sra(at, i.OutputRegister(), 31);
     __ Branch(tlabel, cc, at, Operand(kScratchReg));
+  } else if (instr->arch_opcode() == kMips64DaddOvf) {
+    switch (branch->condition) {
+      case kOverflow:
+        __ DaddBranchOvf(i.OutputRegister(), i.InputRegister(0),
+                         i.InputOperand(1), tlabel, flabel);
+        break;
+      case kNotOverflow:
+        __ DaddBranchOvf(i.OutputRegister(), i.InputRegister(0),
+                         i.InputOperand(1), flabel, tlabel);
+        break;
+      default:
+        UNSUPPORTED_COND(kMips64DaddOvf, branch->condition);
+        break;
+    }
+  } else if (instr->arch_opcode() == kMips64DsubOvf) {
+    switch (branch->condition) {
+      case kOverflow:
+        __ DsubBranchOvf(i.OutputRegister(), i.InputRegister(0),
+                         i.InputOperand(1), tlabel, flabel);
+        break;
+      case kNotOverflow:
+        __ DsubBranchOvf(i.OutputRegister(), i.InputRegister(0),
+                         i.InputOperand(1), flabel, tlabel);
+        break;
+      default:
+        UNSUPPORTED_COND(kMips64DsubOvf, branch->condition);
+        break;
+    }
   } else if (instr->arch_opcode() == kMips64Cmp) {
-    switch (branch->condition) {
-      case kEqual:
-        cc = eq;
-        break;
-      case kNotEqual:
-        cc = ne;
-        break;
-      case kSignedLessThan:
-        cc = lt;
-        break;
-      case kSignedGreaterThanOrEqual:
-        cc = ge;
-        break;
-      case kSignedLessThanOrEqual:
-        cc = le;
-        break;
-      case kSignedGreaterThan:
-        cc = gt;
-        break;
-      case kUnsignedLessThan:
-        cc = lo;
-        break;
-      case kUnsignedGreaterThanOrEqual:
-        cc = hs;
-        break;
-      case kUnsignedLessThanOrEqual:
-        cc = ls;
-        break;
-      case kUnsignedGreaterThan:
-        cc = hi;
-        break;
-      default:
-        UNSUPPORTED_COND(kMips64Cmp, branch->condition);
-        break;
-    }
+    cc = FlagsConditionToConditionCmp(branch->condition);
     __ Branch(tlabel, cc, i.InputRegister(0), i.InputOperand(1));
-
-    if (!branch->fallthru) __ Branch(flabel);  // no fallthru to flabel.
-
-  } else if (instr->arch_opcode() == kMips64Cmp32) {
-    switch (branch->condition) {
-      case kEqual:
-        cc = eq;
-        break;
-      case kNotEqual:
-        cc = ne;
-        break;
-      case kSignedLessThan:
-        cc = lt;
-        break;
-      case kSignedGreaterThanOrEqual:
-        cc = ge;
-        break;
-      case kSignedLessThanOrEqual:
-        cc = le;
-        break;
-      case kSignedGreaterThan:
-        cc = gt;
-        break;
-      case kUnsignedLessThan:
-        cc = lo;
-        break;
-      case kUnsignedGreaterThanOrEqual:
-        cc = hs;
-        break;
-      case kUnsignedLessThanOrEqual:
-        cc = ls;
-        break;
-      case kUnsignedGreaterThan:
-        cc = hi;
-        break;
-      default:
-        UNSUPPORTED_COND(kMips64Cmp32, branch->condition);
-        break;
+  } else if (instr->arch_opcode() == kMips64CmpS) {
+    if (!convertCondition(branch->condition, cc)) {
+      UNSUPPORTED_COND(kMips64CmpS, branch->condition);
     }
-
-    switch (branch->condition) {
-      case kEqual:
-      case kNotEqual:
-      case kSignedLessThan:
-      case kSignedGreaterThanOrEqual:
-      case kSignedLessThanOrEqual:
-      case kSignedGreaterThan:
-        // Sign-extend registers on MIPS64 only 64-bit operand
-        // branch and compare op. is available.
-        __ sll(i.InputRegister(0), i.InputRegister(0), 0);
-        if (instr->InputAt(1)->IsRegister()) {
-          __ sll(i.InputRegister(1), i.InputRegister(1), 0);
-        }
-        break;
-      case kUnsignedLessThan:
-      case kUnsignedGreaterThanOrEqual:
-      case kUnsignedLessThanOrEqual:
-      case kUnsignedGreaterThan:
-        // Zero-extend registers on MIPS64 only 64-bit operand
-        // branch and compare op. is available.
-        __ Dext(i.InputRegister(0), i.InputRegister(0), 0, 32);
-        if (instr->InputAt(1)->IsRegister()) {
-          __ Dext(i.InputRegister(1), i.InputRegister(1), 0, 32);
-        }
-        break;
-      default:
-        UNSUPPORTED_COND(kMips64Cmp, branch->condition);
-        break;
+    FPURegister left = i.InputOrZeroSingleRegister(0);
+    FPURegister right = i.InputOrZeroSingleRegister(1);
+    if ((left.is(kDoubleRegZero) || right.is(kDoubleRegZero)) &&
+        !__ IsDoubleZeroRegSet()) {
+      __ Move(kDoubleRegZero, 0.0);
     }
-    __ Branch(tlabel, cc, i.InputRegister(0), i.InputOperand(1));
-
-    if (!branch->fallthru) __ Branch(flabel);  // no fallthru to flabel.
+    __ BranchF32(tlabel, nullptr, cc, left, right);
   } else if (instr->arch_opcode() == kMips64CmpD) {
-    // TODO(dusmil) optimize unordered checks to use less instructions
-    // even if we have to unfold BranchF macro.
-    Label* nan = flabel;
-    switch (branch->condition) {
-      case kUnorderedEqual:
-        cc = eq;
-        break;
-      case kUnorderedNotEqual:
-        cc = ne;
-        nan = tlabel;
-        break;
-      case kUnorderedLessThan:
-        cc = lt;
-        break;
-      case kUnorderedGreaterThanOrEqual:
-        cc = ge;
-        nan = tlabel;
-        break;
-      case kUnorderedLessThanOrEqual:
-        cc = le;
-        break;
-      case kUnorderedGreaterThan:
-        cc = gt;
-        nan = tlabel;
-        break;
-      default:
-        UNSUPPORTED_COND(kMips64CmpD, branch->condition);
-        break;
+    if (!convertCondition(branch->condition, cc)) {
+      UNSUPPORTED_COND(kMips64CmpD, branch->condition);
     }
-    __ BranchF(tlabel, nan, cc, i.InputDoubleRegister(0),
-               i.InputDoubleRegister(1));
-
-    if (!branch->fallthru) __ Branch(flabel);  // no fallthru to flabel.
+    FPURegister left = i.InputOrZeroDoubleRegister(0);
+    FPURegister right = i.InputOrZeroDoubleRegister(1);
+    if ((left.is(kDoubleRegZero) || right.is(kDoubleRegZero)) &&
+        !__ IsDoubleZeroRegSet()) {
+      __ Move(kDoubleRegZero, 0.0);
+    }
+    __ BranchF64(tlabel, nullptr, cc, left, right);
   } else {
     PrintF("AssembleArchBranch Unimplemented arch_opcode: %d\n",
            instr->arch_opcode());
     UNIMPLEMENTED();
   }
+  if (!branch->fallthru) __ Branch(flabel);  // no fallthru to flabel.
 }
 
 
-void CodeGenerator::AssembleArchJump(BasicBlock::RpoNumber target) {
+void CodeGenerator::AssembleArchJump(RpoNumber target) {
   if (!IsNextInAssemblyOrder(target)) __ Branch(GetLabel(target));
 }
 
@@ -930,325 +1482,302 @@
   // Materialize a full 32-bit 1 or 0 value. The result register is always the
   // last output of the instruction.
   Label false_value;
-  DCHECK_NE(0, instr->OutputCount());
+  DCHECK_NE(0u, instr->OutputCount());
   Register result = i.OutputRegister(instr->OutputCount() - 1);
   Condition cc = kNoCondition;
-
   // MIPS does not have condition code flags, so compare and branch are
   // implemented differently than on the other arch's. The compare operations
   // emit mips pseudo-instructions, which are checked and handled here.
 
-  // For materializations, we use delay slot to set the result true, and
-  // in the false case, where we fall through the branch, we reset the result
-  // false.
-
   if (instr->arch_opcode() == kMips64Tst) {
-    switch (condition) {
-      case kNotEqual:
-        cc = ne;
-        break;
-      case kEqual:
-        cc = eq;
-        break;
-      default:
-        UNSUPPORTED_COND(kMips64Tst, condition);
-        break;
+    cc = FlagsConditionToConditionTst(condition);
+    __ And(kScratchReg, i.InputRegister(0), i.InputOperand(1));
+    __ Sltu(result, zero_reg, kScratchReg);
+    if (cc == eq) {
+      // Sltu produces 0 for equality, invert the result.
+      __ xori(result, result, 1);
     }
-    __ And(at, i.InputRegister(0), i.InputOperand(1));
-    __ Branch(USE_DELAY_SLOT, &done, cc, at, Operand(zero_reg));
-    __ li(result, Operand(1));  // In delay slot.
-  } else if (instr->arch_opcode() == kMips64Tst32) {
-    switch (condition) {
-      case kNotEqual:
-        cc = ne;
-        break;
-      case kEqual:
-        cc = eq;
-        break;
-      default:
-        UNSUPPORTED_COND(kMips64Tst, condition);
-        break;
-    }
-    // Zero-extend register on MIPS64 only 64-bit operand
-    // branch and compare op. is available.
-    __ And(at, i.InputRegister(0), i.InputOperand(1));
-    __ Dext(at, at, 0, 32);
-    __ Branch(USE_DELAY_SLOT, &done, cc, at, Operand(zero_reg));
-    __ li(result, Operand(1));  // In delay slot.
+    return;
   } else if (instr->arch_opcode() == kMips64Dadd ||
              instr->arch_opcode() == kMips64Dsub) {
-    switch (condition) {
-      case kOverflow:
-        cc = ne;
+    cc = FlagsConditionToConditionOvf(condition);
+    // Check for overflow creates 1 or 0 for result.
+    __ dsrl32(kScratchReg, i.OutputRegister(), 31);
+    __ srl(at, i.OutputRegister(), 31);
+    __ xor_(result, kScratchReg, at);
+    if (cc == eq)  // Toggle result for not overflow.
+      __ xori(result, result, 1);
+    return;
+  } else if (instr->arch_opcode() == kMips64DaddOvf ||
+             instr->arch_opcode() == kMips64DsubOvf) {
+    Label flabel, tlabel;
+    switch (instr->arch_opcode()) {
+      case kMips64DaddOvf:
+        __ DaddBranchNoOvf(i.OutputRegister(), i.InputRegister(0),
+                           i.InputOperand(1), &flabel);
+
         break;
-      case kNotOverflow:
-        cc = eq;
+      case kMips64DsubOvf:
+        __ DsubBranchNoOvf(i.OutputRegister(), i.InputRegister(0),
+                           i.InputOperand(1), &flabel);
         break;
       default:
-        UNSUPPORTED_COND(kMips64DAdd, condition);
+        UNREACHABLE();
         break;
     }
-    __ dsra32(kScratchReg, i.OutputRegister(), 0);
-    __ sra(at, i.OutputRegister(), 31);
-    __ Branch(USE_DELAY_SLOT, &done, cc, at, Operand(kScratchReg));
-    __ li(result, Operand(1));  // In delay slot.
+    __ li(result, 1);
+    __ Branch(&tlabel);
+    __ bind(&flabel);
+    __ li(result, 0);
+    __ bind(&tlabel);
   } else if (instr->arch_opcode() == kMips64Cmp) {
-    Register left = i.InputRegister(0);
-    Operand right = i.InputOperand(1);
-    switch (condition) {
-      case kEqual:
-        cc = eq;
-        break;
-      case kNotEqual:
-        cc = ne;
-        break;
-      case kSignedLessThan:
-        cc = lt;
-        break;
-      case kSignedGreaterThanOrEqual:
-        cc = ge;
-        break;
-      case kSignedLessThanOrEqual:
-        cc = le;
-        break;
-      case kSignedGreaterThan:
-        cc = gt;
-        break;
-      case kUnsignedLessThan:
-        cc = lo;
-        break;
-      case kUnsignedGreaterThanOrEqual:
-        cc = hs;
-        break;
-      case kUnsignedLessThanOrEqual:
-        cc = ls;
-        break;
-      case kUnsignedGreaterThan:
-        cc = hi;
-        break;
-      default:
-        UNSUPPORTED_COND(kMips64Cmp, condition);
-        break;
-    }
-    __ Branch(USE_DELAY_SLOT, &done, cc, left, right);
-    __ li(result, Operand(1));  // In delay slot.
-  } else if (instr->arch_opcode() == kMips64Cmp32) {
-    Register left = i.InputRegister(0);
-    Operand right = i.InputOperand(1);
-    switch (condition) {
-      case kEqual:
-        cc = eq;
-        break;
-      case kNotEqual:
-        cc = ne;
-        break;
-      case kSignedLessThan:
-        cc = lt;
-        break;
-      case kSignedGreaterThanOrEqual:
-        cc = ge;
-        break;
-      case kSignedLessThanOrEqual:
-        cc = le;
-        break;
-      case kSignedGreaterThan:
-        cc = gt;
-        break;
-      case kUnsignedLessThan:
-        cc = lo;
-        break;
-      case kUnsignedGreaterThanOrEqual:
-        cc = hs;
-        break;
-      case kUnsignedLessThanOrEqual:
-        cc = ls;
-        break;
-      case kUnsignedGreaterThan:
-        cc = hi;
-        break;
-      default:
-        UNSUPPORTED_COND(kMips64Cmp, condition);
-        break;
-    }
-
-    switch (condition) {
-      case kEqual:
-      case kNotEqual:
-      case kSignedLessThan:
-      case kSignedGreaterThanOrEqual:
-      case kSignedLessThanOrEqual:
-      case kSignedGreaterThan:
-        // Sign-extend registers on MIPS64 only 64-bit operand
-        // branch and compare op. is available.
-        __ sll(left, left, 0);
-        if (instr->InputAt(1)->IsRegister()) {
-          __ sll(i.InputRegister(1), i.InputRegister(1), 0);
+    cc = FlagsConditionToConditionCmp(condition);
+    switch (cc) {
+      case eq:
+      case ne: {
+        Register left = i.InputRegister(0);
+        Operand right = i.InputOperand(1);
+        Register select;
+        if (instr->InputAt(1)->IsImmediate() && right.immediate() == 0) {
+          // Pass left operand if right is zero.
+          select = left;
+        } else {
+          __ Dsubu(kScratchReg, left, right);
+          select = kScratchReg;
         }
-        break;
-      case kUnsignedLessThan:
-      case kUnsignedGreaterThanOrEqual:
-      case kUnsignedLessThanOrEqual:
-      case kUnsignedGreaterThan:
-        // Zero-extend registers on MIPS64 only 64-bit operand
-        // branch and compare op. is available.
-        __ Dext(left, left, 0, 32);
-        if (instr->InputAt(1)->IsRegister()) {
-          __ Dext(i.InputRegister(1), i.InputRegister(1), 0, 32);
+        __ Sltu(result, zero_reg, select);
+        if (cc == eq) {
+          // Sltu produces 0 for equality, invert the result.
+          __ xori(result, result, 1);
         }
-        break;
+      } break;
+      case lt:
+      case ge: {
+        Register left = i.InputRegister(0);
+        Operand right = i.InputOperand(1);
+        __ Slt(result, left, right);
+        if (cc == ge) {
+          __ xori(result, result, 1);
+        }
+      } break;
+      case gt:
+      case le: {
+        Register left = i.InputRegister(1);
+        Operand right = i.InputOperand(0);
+        __ Slt(result, left, right);
+        if (cc == le) {
+          __ xori(result, result, 1);
+        }
+      } break;
+      case lo:
+      case hs: {
+        Register left = i.InputRegister(0);
+        Operand right = i.InputOperand(1);
+        __ Sltu(result, left, right);
+        if (cc == hs) {
+          __ xori(result, result, 1);
+        }
+      } break;
+      case hi:
+      case ls: {
+        Register left = i.InputRegister(1);
+        Operand right = i.InputOperand(0);
+        __ Sltu(result, left, right);
+        if (cc == ls) {
+          __ xori(result, result, 1);
+        }
+      } break;
       default:
-        UNSUPPORTED_COND(kMips64Cmp32, condition);
-        break;
+        UNREACHABLE();
     }
-    __ Branch(USE_DELAY_SLOT, &done, cc, left, right);
-    __ li(result, Operand(1));  // In delay slot.
-  } else if (instr->arch_opcode() == kMips64CmpD) {
-    FPURegister left = i.InputDoubleRegister(0);
-    FPURegister right = i.InputDoubleRegister(1);
-    // TODO(plind): Provide NaN-testing macro-asm function without need for
-    // BranchF.
-    FPURegister dummy1 = f0;
-    FPURegister dummy2 = f2;
-    switch (condition) {
-      case kUnorderedEqual:
-        // TODO(plind):  improve the NaN testing throughout this function.
-        __ BranchF(NULL, &false_value, kNoCondition, dummy1, dummy2);
-        cc = eq;
-        break;
-      case kUnorderedNotEqual:
-        __ BranchF(USE_DELAY_SLOT, NULL, &done, kNoCondition, dummy1, dummy2);
-        __ li(result, Operand(1));  // In delay slot - returns 1 on NaN.
-        cc = ne;
-        break;
-      case kUnorderedLessThan:
-        __ BranchF(NULL, &false_value, kNoCondition, dummy1, dummy2);
-        cc = lt;
-        break;
-      case kUnorderedGreaterThanOrEqual:
-        __ BranchF(USE_DELAY_SLOT, NULL, &done, kNoCondition, dummy1, dummy2);
-        __ li(result, Operand(1));  // In delay slot - returns 1 on NaN.
-        cc = ge;
-        break;
-      case kUnorderedLessThanOrEqual:
-        __ BranchF(NULL, &false_value, kNoCondition, dummy1, dummy2);
-        cc = le;
-        break;
-      case kUnorderedGreaterThan:
-        __ BranchF(USE_DELAY_SLOT, NULL, &done, kNoCondition, dummy1, dummy2);
-        __ li(result, Operand(1));  // In delay slot - returns 1 on NaN.
-        cc = gt;
-        break;
-      default:
-        UNSUPPORTED_COND(kMips64Cmp, condition);
-        break;
+    return;
+  } else if (instr->arch_opcode() == kMips64CmpD ||
+             instr->arch_opcode() == kMips64CmpS) {
+    FPURegister left = i.InputOrZeroDoubleRegister(0);
+    FPURegister right = i.InputOrZeroDoubleRegister(1);
+    if ((left.is(kDoubleRegZero) || right.is(kDoubleRegZero)) &&
+        !__ IsDoubleZeroRegSet()) {
+      __ Move(kDoubleRegZero, 0.0);
     }
-    __ BranchF(USE_DELAY_SLOT, &done, NULL, cc, left, right);
-    __ li(result, Operand(1));  // In delay slot - branch taken returns 1.
-                                // Fall-thru (branch not taken) returns 0.
+    bool predicate;
+    FPUCondition cc = FlagsConditionToConditionCmpFPU(predicate, condition);
+    if (kArchVariant != kMips64r6) {
+      __ li(result, Operand(1));
+      if (instr->arch_opcode() == kMips64CmpD) {
+        __ c(cc, D, left, right);
+      } else {
+        DCHECK(instr->arch_opcode() == kMips64CmpS);
+        __ c(cc, S, left, right);
+      }
+      if (predicate) {
+        __ Movf(result, zero_reg);
+      } else {
+        __ Movt(result, zero_reg);
+      }
+    } else {
+      if (instr->arch_opcode() == kMips64CmpD) {
+        __ cmp(cc, L, kDoubleCompareReg, left, right);
+      } else {
+        DCHECK(instr->arch_opcode() == kMips64CmpS);
+        __ cmp(cc, W, kDoubleCompareReg, left, right);
+      }
+      __ dmfc1(result, kDoubleCompareReg);
+      __ andi(result, result, 1);  // Cmp returns all 1's/0's, use only LSB.
 
+      if (!predicate)  // Toggle result for not equal.
+        __ xori(result, result, 1);
+    }
+    return;
   } else {
     PrintF("AssembleArchBranch Unimplemented arch_opcode is : %d\n",
            instr->arch_opcode());
     TRACE_UNIMPL();
     UNIMPLEMENTED();
   }
-  // Fallthru case is the false materialization.
-  __ bind(&false_value);
-  __ li(result, Operand(static_cast<int64_t>(0)));
-  __ bind(&done);
 }
 
 
-void CodeGenerator::AssembleDeoptimizerCall(int deoptimization_id) {
+void CodeGenerator::AssembleArchLookupSwitch(Instruction* instr) {
+  MipsOperandConverter i(this, instr);
+  Register input = i.InputRegister(0);
+  for (size_t index = 2; index < instr->InputCount(); index += 2) {
+    __ li(at, Operand(i.InputInt32(index + 0)));
+    __ beq(input, at, GetLabel(i.InputRpo(index + 1)));
+  }
+  __ nop();  // Branch delay slot of the last beq.
+  AssembleArchJump(i.InputRpo(1));
+}
+
+
+void CodeGenerator::AssembleArchTableSwitch(Instruction* instr) {
+  MipsOperandConverter i(this, instr);
+  Register input = i.InputRegister(0);
+  size_t const case_count = instr->InputCount() - 2;
+  Label here;
+
+  __ Branch(GetLabel(i.InputRpo(1)), hs, input, Operand(case_count));
+  __ BlockTrampolinePoolFor(static_cast<int>(case_count) * 2 + 7);
+  // Ensure that dd-ed labels use 8 byte aligned addresses.
+  __ Align(8);
+  __ bal(&here);
+  __ dsll(at, input, 3);  // Branch delay slot.
+  __ bind(&here);
+  __ daddu(at, at, ra);
+  __ ld(at, MemOperand(at, 4 * v8::internal::Assembler::kInstrSize));
+  __ jr(at);
+  __ nop();  // Branch delay slot nop.
+  for (size_t index = 0; index < case_count; ++index) {
+    __ dd(GetLabel(i.InputRpo(index + 2)));
+  }
+}
+
+
+void CodeGenerator::AssembleDeoptimizerCall(
+    int deoptimization_id, Deoptimizer::BailoutType bailout_type) {
   Address deopt_entry = Deoptimizer::GetDeoptimizationEntry(
-      isolate(), deoptimization_id, Deoptimizer::LAZY);
+      isolate(), deoptimization_id, bailout_type);
   __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY);
 }
 
 
 void CodeGenerator::AssemblePrologue() {
   CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
-  if (descriptor->kind() == CallDescriptor::kCallAddress) {
+  if (descriptor->IsCFunctionCall()) {
     __ Push(ra, fp);
     __ mov(fp, sp);
-    const RegList saves = descriptor->CalleeSavedRegisters();
-    if (saves != 0) {  // Save callee-saved registers.
-      // TODO(plind): make callee save size const, possibly DCHECK it.
-      int register_save_area_size = 0;
-      for (int i = Register::kNumRegisters - 1; i >= 0; i--) {
-        if (!((1 << i) & saves)) continue;
-        register_save_area_size += kPointerSize;
-      }
-      frame()->SetRegisterSaveAreaSize(register_save_area_size);
-      __ MultiPush(saves);
-    }
   } else if (descriptor->IsJSFunctionCall()) {
-    CompilationInfo* info = this->info();
-    __ Prologue(info->IsCodePreAgingActive());
-    frame()->SetRegisterSaveAreaSize(
-        StandardFrameConstants::kFixedFrameSizeFromFp);
-
-    // Sloppy mode functions and builtins need to replace the receiver with the
-    // global proxy when called as functions (without an explicit receiver
-    // object).
-    // TODO(mstarzinger/verwaest): Should this be moved back into the CallIC?
-    if (info->strict_mode() == SLOPPY && !info->is_native()) {
-      Label ok;
-      // +2 for return address and saved frame pointer.
-      int receiver_slot = info->scope()->num_parameters() + 2;
-      __ ld(a2, MemOperand(fp, receiver_slot * kPointerSize));
-      __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
-      __ Branch(&ok, ne, a2, Operand(at));
-
-      __ ld(a2, GlobalObjectOperand());
-      __ ld(a2, FieldMemOperand(a2, GlobalObject::kGlobalProxyOffset));
-      __ sd(a2, MemOperand(fp, receiver_slot * kPointerSize));
-      __ bind(&ok);
-    }
-  } else {
+    __ Prologue(this->info()->GeneratePreagedPrologue());
+  } else if (frame()->needs_frame()) {
     __ StubPrologue();
-    frame()->SetRegisterSaveAreaSize(
-        StandardFrameConstants::kFixedFrameSizeFromFp);
+  } else {
+    frame()->SetElidedFrameSizeInSlots(0);
   }
-  int stack_slots = frame()->GetSpillSlotCount();
-  if (stack_slots > 0) {
-    __ Dsubu(sp, sp, Operand(stack_slots * kPointerSize));
+  frame_access_state()->SetFrameAccessToDefault();
+
+  int stack_shrink_slots = frame()->GetSpillSlotCount();
+  if (info()->is_osr()) {
+    // TurboFan OSR-compiled functions cannot be entered directly.
+    __ Abort(kShouldNotDirectlyEnterOsrFunction);
+
+    // Unoptimized code jumps directly to this entrypoint while the unoptimized
+    // frame is still on the stack. Optimized code uses OSR values directly from
+    // the unoptimized frame. Thus, all that needs to be done is to allocate the
+    // remaining stack slots.
+    if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --");
+    osr_pc_offset_ = __ pc_offset();
+    // TODO(titzer): cannot address target function == local #-1
+    __ ld(a1, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
+    stack_shrink_slots -= OsrHelper(info()).UnoptimizedFrameSlots();
+  }
+
+  if (stack_shrink_slots > 0) {
+    __ Dsubu(sp, sp, Operand(stack_shrink_slots * kPointerSize));
+  }
+
+  const RegList saves_fpu = descriptor->CalleeSavedFPRegisters();
+  if (saves_fpu != 0) {
+    // Save callee-saved FPU registers.
+    __ MultiPushFPU(saves_fpu);
+    int count = base::bits::CountPopulation32(saves_fpu);
+    DCHECK(kNumCalleeSavedFPU == count);
+    frame()->AllocateSavedCalleeRegisterSlots(count *
+                                              (kDoubleSize / kPointerSize));
+  }
+
+  const RegList saves = descriptor->CalleeSavedRegisters();
+  if (saves != 0) {
+    // Save callee-saved registers.
+    __ MultiPush(saves);
+    // kNumCalleeSaved includes the fp register, but the fp register
+    // is saved separately in TF.
+    int count = base::bits::CountPopulation32(saves);
+    DCHECK(kNumCalleeSaved == count + 1);
+    frame()->AllocateSavedCalleeRegisterSlots(count);
   }
 }
 
 
 void CodeGenerator::AssembleReturn() {
   CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
-  if (descriptor->kind() == CallDescriptor::kCallAddress) {
-    if (frame()->GetRegisterSaveAreaSize() > 0) {
-      // Remove this frame's spill slots first.
-      int stack_slots = frame()->GetSpillSlotCount();
-      if (stack_slots > 0) {
-        __ Daddu(sp, sp, Operand(stack_slots * kPointerSize));
-      }
-      // Restore registers.
-      const RegList saves = descriptor->CalleeSavedRegisters();
-      if (saves != 0) {
-        __ MultiPop(saves);
-      }
+
+  // Restore GP registers.
+  const RegList saves = descriptor->CalleeSavedRegisters();
+  if (saves != 0) {
+    __ MultiPop(saves);
+  }
+
+  // Restore FPU registers.
+  const RegList saves_fpu = descriptor->CalleeSavedFPRegisters();
+  if (saves_fpu != 0) {
+    __ MultiPopFPU(saves_fpu);
+  }
+
+  if (descriptor->IsCFunctionCall()) {
+    __ mov(sp, fp);
+    __ Pop(ra, fp);
+  } else if (frame()->needs_frame()) {
+    // Canonicalize JSFunction return sites for now.
+    if (return_label_.is_bound()) {
+      __ Branch(&return_label_);
+      return;
+    } else {
+      __ bind(&return_label_);
+      __ mov(sp, fp);
+      __ Pop(ra, fp);
     }
-    __ mov(sp, fp);
-    __ Pop(ra, fp);
-    __ Ret();
-  } else {
-    __ mov(sp, fp);
-    __ Pop(ra, fp);
-    int pop_count = descriptor->IsJSFunctionCall()
-                        ? static_cast<int>(descriptor->JSParameterCount())
-                        : 0;
+  }
+  int pop_count = static_cast<int>(descriptor->StackParameterCount());
+  if (pop_count != 0) {
     __ DropAndRet(pop_count);
+  } else {
+    __ Ret();
   }
 }
 
 
 void CodeGenerator::AssembleMove(InstructionOperand* source,
                                  InstructionOperand* destination) {
-  MipsOperandConverter g(this, NULL);
+  MipsOperandConverter g(this, nullptr);
   // Dispatch on the source and destination operand kinds.  Not all
   // combinations are possible.
   if (source->IsRegister()) {
@@ -1290,9 +1819,19 @@
         case Constant::kExternalReference:
           __ li(dst, Operand(src.ToExternalReference()));
           break;
-        case Constant::kHeapObject:
-          __ li(dst, src.ToHeapObject());
+        case Constant::kHeapObject: {
+          Handle<HeapObject> src_object = src.ToHeapObject();
+          Heap::RootListIndex index;
+          int offset;
+          if (IsMaterializableFromFrame(src_object, &offset)) {
+            __ ld(dst, MemOperand(fp, offset));
+          } else if (IsMaterializableFromRoot(src_object, &index)) {
+            __ LoadRoot(dst, index);
+          } else {
+            __ li(dst, src_object);
+          }
           break;
+        }
         case Constant::kRpoNumber:
           UNREACHABLE();  // TODO(titzer): loading RPO numbers on mips64.
           break;
@@ -1344,7 +1883,7 @@
 
 void CodeGenerator::AssembleSwap(InstructionOperand* source,
                                  InstructionOperand* destination) {
-  MipsOperandConverter g(this, NULL);
+  MipsOperandConverter g(this, nullptr);
   // Dispatch on the source and destination operand kinds.  Not all
   // combinations are possible.
   if (source->IsRegister()) {
@@ -1393,9 +1932,9 @@
     Register temp_0 = kScratchReg;
     FPURegister temp_1 = kScratchDoubleReg;
     MemOperand src0 = g.ToMemOperand(source);
-    MemOperand src1(src0.rm(), src0.offset() + kPointerSize);
+    MemOperand src1(src0.rm(), src0.offset() + kIntSize);
     MemOperand dst0 = g.ToMemOperand(destination);
-    MemOperand dst1(dst0.rm(), dst0.offset() + kPointerSize);
+    MemOperand dst1(dst0.rm(), dst0.offset() + kIntSize);
     __ ldc1(temp_1, dst0);  // Save destination in temp_1.
     __ lw(temp_0, src0);    // Then use temp_0 to copy source to destination.
     __ sw(temp_0, dst0);
@@ -1409,6 +1948,12 @@
 }
 
 
+void CodeGenerator::AssembleJumpTable(Label** targets, size_t target_count) {
+  // On 64-bit MIPS we emit the jump tables inline.
+  UNREACHABLE();
+}
+
+
 void CodeGenerator::AddNopForSmiCodeInlining() {
   // Unused on 32-bit ARM. Still exists on 64-bit arm.
   // TODO(plind): Unclear when this is called now. Understand, fix if needed.
@@ -1417,24 +1962,25 @@
 
 
 void CodeGenerator::EnsureSpaceForLazyDeopt() {
+  if (!info()->ShouldEnsureSpaceForLazyDeopt()) {
+    return;
+  }
+
   int space_needed = Deoptimizer::patch_size();
-  if (!info()->IsStub()) {
-    // Ensure that we have enough space after the previous lazy-bailout
-    // instruction for patching the code here.
-    int current_pc = masm()->pc_offset();
-    if (current_pc < last_lazy_deopt_pc_ + space_needed) {
-      // Block tramoline pool emission for duration of padding.
-      v8::internal::Assembler::BlockTrampolinePoolScope block_trampoline_pool(
-          masm());
-      int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc;
-      DCHECK_EQ(0, padding_size % v8::internal::Assembler::kInstrSize);
-      while (padding_size > 0) {
-        __ nop();
-        padding_size -= v8::internal::Assembler::kInstrSize;
-      }
+  // Ensure that we have enough space after the previous lazy-bailout
+  // instruction for patching the code here.
+  int current_pc = masm()->pc_offset();
+  if (current_pc < last_lazy_deopt_pc_ + space_needed) {
+    // Block tramoline pool emission for duration of padding.
+    v8::internal::Assembler::BlockTrampolinePoolScope block_trampoline_pool(
+        masm());
+    int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc;
+    DCHECK_EQ(0, padding_size % v8::internal::Assembler::kInstrSize);
+    while (padding_size > 0) {
+      __ nop();
+      padding_size -= v8::internal::Assembler::kInstrSize;
     }
   }
-  MarkLazyDeoptSite();
 }
 
 #undef __
diff --git a/src/compiler/mips64/instruction-codes-mips64.h b/src/compiler/mips64/instruction-codes-mips64.h
index dd019f9..778c6ad 100644
--- a/src/compiler/mips64/instruction-codes-mips64.h
+++ b/src/compiler/mips64/instruction-codes-mips64.h
@@ -11,75 +11,124 @@
 
 // MIPS64-specific opcodes that specify which assembly sequence to emit.
 // Most opcodes specify a single instruction.
-#define TARGET_ARCH_OPCODE_LIST(V) \
-  V(Mips64Add)                     \
-  V(Mips64Dadd)                    \
-  V(Mips64Sub)                     \
-  V(Mips64Dsub)                    \
-  V(Mips64Mul)                     \
-  V(Mips64MulHigh)                 \
-  V(Mips64MulHighU)                \
-  V(Mips64Dmul)                    \
-  V(Mips64Div)                     \
-  V(Mips64Ddiv)                    \
-  V(Mips64DivU)                    \
-  V(Mips64DdivU)                   \
-  V(Mips64Mod)                     \
-  V(Mips64Dmod)                    \
-  V(Mips64ModU)                    \
-  V(Mips64DmodU)                   \
-  V(Mips64And)                     \
-  V(Mips64Or)                      \
-  V(Mips64Xor)                     \
-  V(Mips64Shl)                     \
-  V(Mips64Shr)                     \
-  V(Mips64Sar)                     \
-  V(Mips64Ext)                     \
-  V(Mips64Dext)                    \
-  V(Mips64Dshl)                    \
-  V(Mips64Dshr)                    \
-  V(Mips64Dsar)                    \
-  V(Mips64Ror)                     \
-  V(Mips64Dror)                    \
-  V(Mips64Mov)                     \
-  V(Mips64Tst)                     \
-  V(Mips64Tst32)                   \
-  V(Mips64Cmp)                     \
-  V(Mips64Cmp32)                   \
-  V(Mips64CmpD)                    \
-  V(Mips64AddD)                    \
-  V(Mips64SubD)                    \
-  V(Mips64MulD)                    \
-  V(Mips64DivD)                    \
-  V(Mips64ModD)                    \
-  V(Mips64SqrtD)                   \
-  V(Mips64Float64Floor)            \
-  V(Mips64Float64Ceil)             \
-  V(Mips64Float64RoundTruncate)    \
-  V(Mips64CvtSD)                   \
-  V(Mips64CvtDS)                   \
-  V(Mips64TruncWD)                 \
-  V(Mips64TruncUwD)                \
-  V(Mips64CvtDW)                   \
-  V(Mips64CvtDUw)                  \
-  V(Mips64Lb)                      \
-  V(Mips64Lbu)                     \
-  V(Mips64Sb)                      \
-  V(Mips64Lh)                      \
-  V(Mips64Lhu)                     \
-  V(Mips64Sh)                      \
-  V(Mips64Ld)                      \
-  V(Mips64Lw)                      \
-  V(Mips64Sw)                      \
-  V(Mips64Sd)                      \
-  V(Mips64Lwc1)                    \
-  V(Mips64Swc1)                    \
-  V(Mips64Ldc1)                    \
-  V(Mips64Sdc1)                    \
-  V(Mips64Push)                    \
-  V(Mips64StoreToStackSlot)        \
-  V(Mips64StackClaim)              \
-  V(Mips64StoreWriteBarrier)
+#define TARGET_ARCH_OPCODE_LIST(V)  \
+  V(Mips64Add)                      \
+  V(Mips64Dadd)                     \
+  V(Mips64DaddOvf)                  \
+  V(Mips64Sub)                      \
+  V(Mips64Dsub)                     \
+  V(Mips64DsubOvf)                  \
+  V(Mips64Mul)                      \
+  V(Mips64MulHigh)                  \
+  V(Mips64DMulHigh)                 \
+  V(Mips64MulHighU)                 \
+  V(Mips64Dmul)                     \
+  V(Mips64Div)                      \
+  V(Mips64Ddiv)                     \
+  V(Mips64DivU)                     \
+  V(Mips64DdivU)                    \
+  V(Mips64Mod)                      \
+  V(Mips64Dmod)                     \
+  V(Mips64ModU)                     \
+  V(Mips64DmodU)                    \
+  V(Mips64And)                      \
+  V(Mips64Or)                       \
+  V(Mips64Nor)                      \
+  V(Mips64Xor)                      \
+  V(Mips64Clz)                      \
+  V(Mips64Shl)                      \
+  V(Mips64Shr)                      \
+  V(Mips64Sar)                      \
+  V(Mips64Ext)                      \
+  V(Mips64Ins)                      \
+  V(Mips64Dext)                     \
+  V(Mips64Dins)                     \
+  V(Mips64Dclz)                     \
+  V(Mips64Dshl)                     \
+  V(Mips64Dshr)                     \
+  V(Mips64Dsar)                     \
+  V(Mips64Ror)                      \
+  V(Mips64Dror)                     \
+  V(Mips64Mov)                      \
+  V(Mips64Tst)                      \
+  V(Mips64Cmp)                      \
+  V(Mips64CmpS)                     \
+  V(Mips64AddS)                     \
+  V(Mips64SubS)                     \
+  V(Mips64MulS)                     \
+  V(Mips64DivS)                     \
+  V(Mips64ModS)                     \
+  V(Mips64AbsS)                     \
+  V(Mips64SqrtS)                    \
+  V(Mips64MaxS)                     \
+  V(Mips64MinS)                     \
+  V(Mips64CmpD)                     \
+  V(Mips64AddD)                     \
+  V(Mips64SubD)                     \
+  V(Mips64MulD)                     \
+  V(Mips64DivD)                     \
+  V(Mips64ModD)                     \
+  V(Mips64AbsD)                     \
+  V(Mips64SqrtD)                    \
+  V(Mips64MaxD)                     \
+  V(Mips64MinD)                     \
+  V(Mips64Float64RoundDown)         \
+  V(Mips64Float64RoundTruncate)     \
+  V(Mips64Float64RoundUp)           \
+  V(Mips64Float64RoundTiesEven)     \
+  V(Mips64Float32RoundDown)         \
+  V(Mips64Float32RoundTruncate)     \
+  V(Mips64Float32RoundUp)           \
+  V(Mips64Float32RoundTiesEven)     \
+  V(Mips64CvtSD)                    \
+  V(Mips64CvtDS)                    \
+  V(Mips64TruncWD)                  \
+  V(Mips64RoundWD)                  \
+  V(Mips64FloorWD)                  \
+  V(Mips64CeilWD)                   \
+  V(Mips64TruncWS)                  \
+  V(Mips64RoundWS)                  \
+  V(Mips64FloorWS)                  \
+  V(Mips64CeilWS)                   \
+  V(Mips64TruncLS)                  \
+  V(Mips64TruncLD)                  \
+  V(Mips64TruncUwD)                 \
+  V(Mips64TruncUlS)                 \
+  V(Mips64TruncUlD)                 \
+  V(Mips64CvtDW)                    \
+  V(Mips64CvtSL)                    \
+  V(Mips64CvtSW)                    \
+  V(Mips64CvtSUl)                   \
+  V(Mips64CvtDL)                    \
+  V(Mips64CvtDUw)                   \
+  V(Mips64CvtDUl)                   \
+  V(Mips64Lb)                       \
+  V(Mips64Lbu)                      \
+  V(Mips64Sb)                       \
+  V(Mips64Lh)                       \
+  V(Mips64Lhu)                      \
+  V(Mips64Sh)                       \
+  V(Mips64Ld)                       \
+  V(Mips64Lw)                       \
+  V(Mips64Sw)                       \
+  V(Mips64Sd)                       \
+  V(Mips64Lwc1)                     \
+  V(Mips64Swc1)                     \
+  V(Mips64Ldc1)                     \
+  V(Mips64Sdc1)                     \
+  V(Mips64BitcastDL)                \
+  V(Mips64BitcastLD)                \
+  V(Mips64Float64ExtractLowWord32)  \
+  V(Mips64Float64ExtractHighWord32) \
+  V(Mips64Float64InsertLowWord32)   \
+  V(Mips64Float64InsertHighWord32)  \
+  V(Mips64Float64Max)               \
+  V(Mips64Float64Min)               \
+  V(Mips64Float32Max)               \
+  V(Mips64Float32Min)               \
+  V(Mips64Push)                     \
+  V(Mips64StoreToStackSlot)         \
+  V(Mips64StackClaim)
 
 
 // Addressing modes represent the "shape" of inputs to an instruction.
diff --git a/src/compiler/mips64/instruction-scheduler-mips64.cc b/src/compiler/mips64/instruction-scheduler-mips64.cc
new file mode 100644
index 0000000..af86a87
--- /dev/null
+++ b/src/compiler/mips64/instruction-scheduler-mips64.cc
@@ -0,0 +1,26 @@
+// Copyright 2015 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/instruction-scheduler.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+bool InstructionScheduler::SchedulerSupported() { return false; }
+
+
+int InstructionScheduler::GetTargetInstructionFlags(
+    const Instruction* instr) const {
+  UNIMPLEMENTED();
+}
+
+
+int InstructionScheduler::GetInstructionLatency(const Instruction* instr) {
+  UNIMPLEMENTED();
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/mips64/instruction-selector-mips64.cc b/src/compiler/mips64/instruction-selector-mips64.cc
index 35ad16b..1b12bd9 100644
--- a/src/compiler/mips64/instruction-selector-mips64.cc
+++ b/src/compiler/mips64/instruction-selector-mips64.cc
@@ -2,9 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "src/base/adapters.h"
 #include "src/base/bits.h"
 #include "src/compiler/instruction-selector-impl.h"
 #include "src/compiler/node-matchers.h"
+#include "src/compiler/node-properties.h"
 
 namespace v8 {
 namespace internal {
@@ -17,12 +19,12 @@
 
 
 // Adds Mips-specific methods for generating InstructionOperands.
-class Mips64OperandGenerator FINAL : public OperandGenerator {
+class Mips64OperandGenerator final : public OperandGenerator {
  public:
   explicit Mips64OperandGenerator(InstructionSelector* selector)
       : OperandGenerator(selector) {}
 
-  InstructionOperand* UseOperand(Node* node, InstructionCode opcode) {
+  InstructionOperand UseOperand(Node* node, InstructionCode opcode) {
     if (CanBeImmediate(node, opcode)) {
       return UseImmediate(node);
     }
@@ -56,35 +58,6 @@
     }
   }
 
-
-  bool CanBeImmediate(Node* node, InstructionCode opcode,
-                      FlagsContinuation* cont) {
-    int64_t value;
-    if (node->opcode() == IrOpcode::kInt32Constant)
-      value = OpParameter<int32_t>(node);
-    else if (node->opcode() == IrOpcode::kInt64Constant)
-      value = OpParameter<int64_t>(node);
-    else
-      return false;
-    switch (ArchOpcodeField::decode(opcode)) {
-      case kMips64Cmp32:
-        switch (cont->condition()) {
-          case kUnsignedLessThan:
-          case kUnsignedGreaterThanOrEqual:
-          case kUnsignedLessThanOrEqual:
-          case kUnsignedGreaterThan:
-            // Immediate operands for unsigned 32-bit compare operations
-            // should not be sign-extended.
-            return is_uint15(value);
-          default:
-            return false;
-        }
-      default:
-        return is_int16(value);
-    }
-  }
-
-
  private:
   bool ImmediateFitsAddrMode1Instruction(int32_t imm) const {
     TRACE_UNIMPL();
@@ -123,9 +96,9 @@
                        InstructionCode opcode, FlagsContinuation* cont) {
   Mips64OperandGenerator g(selector);
   Int32BinopMatcher m(node);
-  InstructionOperand* inputs[4];
+  InstructionOperand inputs[4];
   size_t input_count = 0;
-  InstructionOperand* outputs[2];
+  InstructionOperand outputs[2];
   size_t output_count = 0;
 
   inputs[input_count++] = g.UseRegister(m.left().node());
@@ -141,14 +114,13 @@
     outputs[output_count++] = g.DefineAsRegister(cont->result());
   }
 
-  DCHECK_NE(0, input_count);
-  DCHECK_NE(0, output_count);
+  DCHECK_NE(0u, input_count);
+  DCHECK_NE(0u, output_count);
   DCHECK_GE(arraysize(inputs), input_count);
   DCHECK_GE(arraysize(outputs), output_count);
 
-  Instruction* instr = selector->Emit(cont->Encode(opcode), output_count,
-                                      outputs, input_count, inputs);
-  if (cont->IsBranch()) instr->MarkAsControl();
+  selector->Emit(cont->Encode(opcode), output_count, outputs, input_count,
+                 inputs);
 }
 
 
@@ -160,35 +132,34 @@
 
 
 void InstructionSelector::VisitLoad(Node* node) {
-  MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node));
-  MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node));
+  LoadRepresentation load_rep = LoadRepresentationOf(node->op());
   Mips64OperandGenerator g(this);
   Node* base = node->InputAt(0);
   Node* index = node->InputAt(1);
 
-  ArchOpcode opcode;
-  switch (rep) {
-    case kRepFloat32:
+  ArchOpcode opcode = kArchNop;
+  switch (load_rep.representation()) {
+    case MachineRepresentation::kFloat32:
       opcode = kMips64Lwc1;
       break;
-    case kRepFloat64:
+    case MachineRepresentation::kFloat64:
       opcode = kMips64Ldc1;
       break;
-    case kRepBit:  // Fall through.
-    case kRepWord8:
-      opcode = typ == kTypeUint32 ? kMips64Lbu : kMips64Lb;
+    case MachineRepresentation::kBit:  // Fall through.
+    case MachineRepresentation::kWord8:
+      opcode = load_rep.IsUnsigned() ? kMips64Lbu : kMips64Lb;
       break;
-    case kRepWord16:
-      opcode = typ == kTypeUint32 ? kMips64Lhu : kMips64Lh;
+    case MachineRepresentation::kWord16:
+      opcode = load_rep.IsUnsigned() ? kMips64Lhu : kMips64Lh;
       break;
-    case kRepWord32:
+    case MachineRepresentation::kWord32:
       opcode = kMips64Lw;
       break;
-    case kRepTagged:  // Fall through.
-    case kRepWord64:
+    case MachineRepresentation::kTagged:  // Fall through.
+    case MachineRepresentation::kWord64:
       opcode = kMips64Ld;
       break;
-    default:
+    case MachineRepresentation::kNone:
       UNREACHABLE();
       return;
   }
@@ -197,7 +168,7 @@
     Emit(opcode | AddressingModeField::encode(kMode_MRI),
          g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index));
   } else {
-    InstructionOperand* addr_reg = g.TempRegister();
+    InstructionOperand addr_reg = g.TempRegister();
     Emit(kMips64Dadd | AddressingModeField::encode(kMode_None), addr_reg,
          g.UseRegister(index), g.UseRegister(base));
     // Emit desired load opcode, using temp addr_reg.
@@ -213,67 +184,180 @@
   Node* index = node->InputAt(1);
   Node* value = node->InputAt(2);
 
-  StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node);
-  MachineType rep = RepresentationOf(store_rep.machine_type());
-  if (store_rep.write_barrier_kind() == kFullWriteBarrier) {
-    DCHECK(rep == kRepTagged);
-    // TODO(dcarney): refactor RecordWrite function to take temp registers
-    //                and pass them here instead of using fixed regs
-    // TODO(dcarney): handle immediate indices.
-    InstructionOperand* temps[] = {g.TempRegister(t1), g.TempRegister(t2)};
-    Emit(kMips64StoreWriteBarrier, NULL, g.UseFixed(base, t0),
-         g.UseFixed(index, t1), g.UseFixed(value, t2), arraysize(temps), temps);
-    return;
-  }
-  DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind());
+  StoreRepresentation store_rep = StoreRepresentationOf(node->op());
+  WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind();
+  MachineRepresentation rep = store_rep.representation();
 
-  ArchOpcode opcode;
-  switch (rep) {
-    case kRepFloat32:
-      opcode = kMips64Swc1;
-      break;
-    case kRepFloat64:
-      opcode = kMips64Sdc1;
-      break;
-    case kRepBit:  // Fall through.
-    case kRepWord8:
-      opcode = kMips64Sb;
-      break;
-    case kRepWord16:
-      opcode = kMips64Sh;
-      break;
-    case kRepWord32:
-      opcode = kMips64Sw;
-      break;
-    case kRepTagged:  // Fall through.
-    case kRepWord64:
-      opcode = kMips64Sd;
-      break;
-    default:
-      UNREACHABLE();
-      return;
-  }
-
-  if (g.CanBeImmediate(index, opcode)) {
-    Emit(opcode | AddressingModeField::encode(kMode_MRI), NULL,
-         g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value));
+  // TODO(mips): I guess this could be done in a better way.
+  if (write_barrier_kind != kNoWriteBarrier) {
+    DCHECK_EQ(MachineRepresentation::kTagged, rep);
+    InstructionOperand inputs[3];
+    size_t input_count = 0;
+    inputs[input_count++] = g.UseUniqueRegister(base);
+    inputs[input_count++] = g.UseUniqueRegister(index);
+    inputs[input_count++] = (write_barrier_kind == kMapWriteBarrier)
+                                ? g.UseRegister(value)
+                                : g.UseUniqueRegister(value);
+    RecordWriteMode record_write_mode = RecordWriteMode::kValueIsAny;
+    switch (write_barrier_kind) {
+      case kNoWriteBarrier:
+        UNREACHABLE();
+        break;
+      case kMapWriteBarrier:
+        record_write_mode = RecordWriteMode::kValueIsMap;
+        break;
+      case kPointerWriteBarrier:
+        record_write_mode = RecordWriteMode::kValueIsPointer;
+        break;
+      case kFullWriteBarrier:
+        record_write_mode = RecordWriteMode::kValueIsAny;
+        break;
+    }
+    InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()};
+    size_t const temp_count = arraysize(temps);
+    InstructionCode code = kArchStoreWithWriteBarrier;
+    code |= MiscField::encode(static_cast<int>(record_write_mode));
+    Emit(code, 0, nullptr, input_count, inputs, temp_count, temps);
   } else {
-    InstructionOperand* addr_reg = g.TempRegister();
-    Emit(kMips64Dadd | AddressingModeField::encode(kMode_None), addr_reg,
-         g.UseRegister(index), g.UseRegister(base));
-    // Emit desired store opcode, using temp addr_reg.
-    Emit(opcode | AddressingModeField::encode(kMode_MRI), NULL, addr_reg,
-         g.TempImmediate(0), g.UseRegister(value));
+    ArchOpcode opcode = kArchNop;
+    switch (rep) {
+      case MachineRepresentation::kFloat32:
+        opcode = kMips64Swc1;
+        break;
+      case MachineRepresentation::kFloat64:
+        opcode = kMips64Sdc1;
+        break;
+      case MachineRepresentation::kBit:  // Fall through.
+      case MachineRepresentation::kWord8:
+        opcode = kMips64Sb;
+        break;
+      case MachineRepresentation::kWord16:
+        opcode = kMips64Sh;
+        break;
+      case MachineRepresentation::kWord32:
+        opcode = kMips64Sw;
+        break;
+      case MachineRepresentation::kTagged:  // Fall through.
+      case MachineRepresentation::kWord64:
+        opcode = kMips64Sd;
+        break;
+      case MachineRepresentation::kNone:
+        UNREACHABLE();
+        return;
+    }
+
+    if (g.CanBeImmediate(index, opcode)) {
+      Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
+           g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value));
+    } else {
+      InstructionOperand addr_reg = g.TempRegister();
+      Emit(kMips64Dadd | AddressingModeField::encode(kMode_None), addr_reg,
+           g.UseRegister(index), g.UseRegister(base));
+      // Emit desired store opcode, using temp addr_reg.
+      Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
+           addr_reg, g.TempImmediate(0), g.UseRegister(value));
+    }
   }
 }
 
 
 void InstructionSelector::VisitWord32And(Node* node) {
+  Mips64OperandGenerator g(this);
+  Int32BinopMatcher m(node);
+  if (m.left().IsWord32Shr() && CanCover(node, m.left().node()) &&
+      m.right().HasValue()) {
+    uint32_t mask = m.right().Value();
+    uint32_t mask_width = base::bits::CountPopulation32(mask);
+    uint32_t mask_msb = base::bits::CountLeadingZeros32(mask);
+    if ((mask_width != 0) && (mask_msb + mask_width == 32)) {
+      // The mask must be contiguous, and occupy the least-significant bits.
+      DCHECK_EQ(0u, base::bits::CountTrailingZeros32(mask));
+
+      // Select Ext for And(Shr(x, imm), mask) where the mask is in the least
+      // significant bits.
+      Int32BinopMatcher mleft(m.left().node());
+      if (mleft.right().HasValue()) {
+        // Any shift value can match; int32 shifts use `value % 32`.
+        uint32_t lsb = mleft.right().Value() & 0x1f;
+
+        // Ext cannot extract bits past the register size, however since
+        // shifting the original value would have introduced some zeros we can
+        // still use Ext with a smaller mask and the remaining bits will be
+        // zeros.
+        if (lsb + mask_width > 32) mask_width = 32 - lsb;
+
+        Emit(kMips64Ext, g.DefineAsRegister(node),
+             g.UseRegister(mleft.left().node()), g.TempImmediate(lsb),
+             g.TempImmediate(mask_width));
+        return;
+      }
+      // Other cases fall through to the normal And operation.
+    }
+  }
+  if (m.right().HasValue()) {
+    uint32_t mask = m.right().Value();
+    uint32_t shift = base::bits::CountPopulation32(~mask);
+    uint32_t msb = base::bits::CountLeadingZeros32(~mask);
+    if (shift != 0 && shift != 32 && msb + shift == 32) {
+      // Insert zeros for (x >> K) << K => x & ~(2^K - 1) expression reduction
+      // and remove constant loading of inverted mask.
+      Emit(kMips64Ins, g.DefineSameAsFirst(node),
+           g.UseRegister(m.left().node()), g.TempImmediate(0),
+           g.TempImmediate(shift));
+      return;
+    }
+  }
   VisitBinop(this, node, kMips64And);
 }
 
 
 void InstructionSelector::VisitWord64And(Node* node) {
+  Mips64OperandGenerator g(this);
+  Int64BinopMatcher m(node);
+  if (m.left().IsWord64Shr() && CanCover(node, m.left().node()) &&
+      m.right().HasValue()) {
+    uint64_t mask = m.right().Value();
+    uint32_t mask_width = base::bits::CountPopulation64(mask);
+    uint32_t mask_msb = base::bits::CountLeadingZeros64(mask);
+    if ((mask_width != 0) && (mask_msb + mask_width == 64)) {
+      // The mask must be contiguous, and occupy the least-significant bits.
+      DCHECK_EQ(0u, base::bits::CountTrailingZeros64(mask));
+
+      // Select Dext for And(Shr(x, imm), mask) where the mask is in the least
+      // significant bits.
+      Int64BinopMatcher mleft(m.left().node());
+      if (mleft.right().HasValue()) {
+        // Any shift value can match; int64 shifts use `value % 64`.
+        uint32_t lsb = static_cast<uint32_t>(mleft.right().Value() & 0x3f);
+
+        // Dext cannot extract bits past the register size, however since
+        // shifting the original value would have introduced some zeros we can
+        // still use Dext with a smaller mask and the remaining bits will be
+        // zeros.
+        if (lsb + mask_width > 64) mask_width = 64 - lsb;
+
+        Emit(kMips64Dext, g.DefineAsRegister(node),
+             g.UseRegister(mleft.left().node()), g.TempImmediate(lsb),
+             g.TempImmediate(static_cast<int32_t>(mask_width)));
+        return;
+      }
+      // Other cases fall through to the normal And operation.
+    }
+  }
+  if (m.right().HasValue()) {
+    uint64_t mask = m.right().Value();
+    uint32_t shift = base::bits::CountPopulation64(~mask);
+    uint32_t msb = base::bits::CountLeadingZeros64(~mask);
+    if (shift != 0 && shift < 32 && msb + shift == 64) {
+      // Insert zeros for (x >> K) << K => x & ~(2^K - 1) expression reduction
+      // and remove constant loading of inverted mask. Dins cannot insert bits
+      // past word size, so shifts smaller than 32 are covered.
+      Emit(kMips64Dins, g.DefineSameAsFirst(node),
+           g.UseRegister(m.left().node()), g.TempImmediate(0),
+           g.TempImmediate(shift));
+      return;
+    }
+  }
   VisitBinop(this, node, kMips64And);
 }
 
@@ -289,21 +373,105 @@
 
 
 void InstructionSelector::VisitWord32Xor(Node* node) {
+  Int32BinopMatcher m(node);
+  if (m.left().IsWord32Or() && CanCover(node, m.left().node()) &&
+      m.right().Is(-1)) {
+    Int32BinopMatcher mleft(m.left().node());
+    if (!mleft.right().HasValue()) {
+      Mips64OperandGenerator g(this);
+      Emit(kMips64Nor, g.DefineAsRegister(node),
+           g.UseRegister(mleft.left().node()),
+           g.UseRegister(mleft.right().node()));
+      return;
+    }
+  }
+  if (m.right().Is(-1)) {
+    // Use Nor for bit negation and eliminate constant loading for xori.
+    Mips64OperandGenerator g(this);
+    Emit(kMips64Nor, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
+         g.TempImmediate(0));
+    return;
+  }
   VisitBinop(this, node, kMips64Xor);
 }
 
 
 void InstructionSelector::VisitWord64Xor(Node* node) {
+  Int64BinopMatcher m(node);
+  if (m.left().IsWord64Or() && CanCover(node, m.left().node()) &&
+      m.right().Is(-1)) {
+    Int64BinopMatcher mleft(m.left().node());
+    if (!mleft.right().HasValue()) {
+      Mips64OperandGenerator g(this);
+      Emit(kMips64Nor, g.DefineAsRegister(node),
+           g.UseRegister(mleft.left().node()),
+           g.UseRegister(mleft.right().node()));
+      return;
+    }
+  }
+  if (m.right().Is(-1)) {
+    // Use Nor for bit negation and eliminate constant loading for xori.
+    Mips64OperandGenerator g(this);
+    Emit(kMips64Nor, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
+         g.TempImmediate(0));
+    return;
+  }
   VisitBinop(this, node, kMips64Xor);
 }
 
 
 void InstructionSelector::VisitWord32Shl(Node* node) {
+  Int32BinopMatcher m(node);
+  if (m.left().IsWord32And() && CanCover(node, m.left().node()) &&
+      m.right().IsInRange(1, 31)) {
+    Mips64OperandGenerator g(this);
+    Int32BinopMatcher mleft(m.left().node());
+    // Match Word32Shl(Word32And(x, mask), imm) to Shl where the mask is
+    // contiguous, and the shift immediate non-zero.
+    if (mleft.right().HasValue()) {
+      uint32_t mask = mleft.right().Value();
+      uint32_t mask_width = base::bits::CountPopulation32(mask);
+      uint32_t mask_msb = base::bits::CountLeadingZeros32(mask);
+      if ((mask_width != 0) && (mask_msb + mask_width == 32)) {
+        uint32_t shift = m.right().Value();
+        DCHECK_EQ(0u, base::bits::CountTrailingZeros32(mask));
+        DCHECK_NE(0u, shift);
+        if ((shift + mask_width) >= 32) {
+          // If the mask is contiguous and reaches or extends beyond the top
+          // bit, only the shift is needed.
+          Emit(kMips64Shl, g.DefineAsRegister(node),
+               g.UseRegister(mleft.left().node()),
+               g.UseImmediate(m.right().node()));
+          return;
+        }
+      }
+    }
+  }
   VisitRRO(this, kMips64Shl, node);
 }
 
 
 void InstructionSelector::VisitWord32Shr(Node* node) {
+  Int32BinopMatcher m(node);
+  if (m.left().IsWord32And() && m.right().HasValue()) {
+    uint32_t lsb = m.right().Value() & 0x1f;
+    Int32BinopMatcher mleft(m.left().node());
+    if (mleft.right().HasValue()) {
+      // Select Ext for Shr(And(x, mask), imm) where the result of the mask is
+      // shifted into the least-significant bits.
+      uint32_t mask = (mleft.right().Value() >> lsb) << lsb;
+      unsigned mask_width = base::bits::CountPopulation32(mask);
+      unsigned mask_msb = base::bits::CountLeadingZeros32(mask);
+      if ((mask_msb + mask_width + lsb) == 32) {
+        Mips64OperandGenerator g(this);
+        DCHECK_EQ(lsb, base::bits::CountTrailingZeros32(mask));
+        Emit(kMips64Ext, g.DefineAsRegister(node),
+             g.UseRegister(mleft.left().node()), g.TempImmediate(lsb),
+             g.TempImmediate(mask_width));
+        return;
+      }
+    }
+  }
   VisitRRO(this, kMips64Shr, node);
 }
 
@@ -314,11 +482,67 @@
 
 
 void InstructionSelector::VisitWord64Shl(Node* node) {
+  Mips64OperandGenerator g(this);
+  Int64BinopMatcher m(node);
+  if ((m.left().IsChangeInt32ToInt64() || m.left().IsChangeUint32ToUint64()) &&
+      m.right().IsInRange(32, 63)) {
+    // There's no need to sign/zero-extend to 64-bit if we shift out the upper
+    // 32 bits anyway.
+    Emit(kMips64Dshl, g.DefineSameAsFirst(node),
+         g.UseRegister(m.left().node()->InputAt(0)),
+         g.UseImmediate(m.right().node()));
+    return;
+  }
+  if (m.left().IsWord64And() && CanCover(node, m.left().node()) &&
+      m.right().IsInRange(1, 63)) {
+    // Match Word64Shl(Word64And(x, mask), imm) to Dshl where the mask is
+    // contiguous, and the shift immediate non-zero.
+    Int64BinopMatcher mleft(m.left().node());
+    if (mleft.right().HasValue()) {
+      uint64_t mask = mleft.right().Value();
+      uint32_t mask_width = base::bits::CountPopulation64(mask);
+      uint32_t mask_msb = base::bits::CountLeadingZeros64(mask);
+      if ((mask_width != 0) && (mask_msb + mask_width == 64)) {
+        uint64_t shift = m.right().Value();
+        DCHECK_EQ(0u, base::bits::CountTrailingZeros64(mask));
+        DCHECK_NE(0u, shift);
+
+        if ((shift + mask_width) >= 64) {
+          // If the mask is contiguous and reaches or extends beyond the top
+          // bit, only the shift is needed.
+          Emit(kMips64Dshl, g.DefineAsRegister(node),
+               g.UseRegister(mleft.left().node()),
+               g.UseImmediate(m.right().node()));
+          return;
+        }
+      }
+    }
+  }
   VisitRRO(this, kMips64Dshl, node);
 }
 
 
 void InstructionSelector::VisitWord64Shr(Node* node) {
+  Int64BinopMatcher m(node);
+  if (m.left().IsWord64And() && m.right().HasValue()) {
+    uint32_t lsb = m.right().Value() & 0x3f;
+    Int64BinopMatcher mleft(m.left().node());
+    if (mleft.right().HasValue()) {
+      // Select Dext for Shr(And(x, mask), imm) where the result of the mask is
+      // shifted into the least-significant bits.
+      uint64_t mask = (mleft.right().Value() >> lsb) << lsb;
+      unsigned mask_width = base::bits::CountPopulation64(mask);
+      unsigned mask_msb = base::bits::CountLeadingZeros64(mask);
+      if ((mask_msb + mask_width + lsb) == 64) {
+        Mips64OperandGenerator g(this);
+        DCHECK_EQ(lsb, base::bits::CountTrailingZeros64(mask));
+        Emit(kMips64Dext, g.DefineAsRegister(node),
+             g.UseRegister(mleft.left().node()), g.TempImmediate(lsb),
+             g.TempImmediate(mask_width));
+        return;
+      }
+    }
+  }
   VisitRRO(this, kMips64Dshr, node);
 }
 
@@ -333,11 +557,33 @@
 }
 
 
+void InstructionSelector::VisitWord32Clz(Node* node) {
+  VisitRR(this, kMips64Clz, node);
+}
+
+
+void InstructionSelector::VisitWord32Ctz(Node* node) { UNREACHABLE(); }
+
+
+void InstructionSelector::VisitWord64Ctz(Node* node) { UNREACHABLE(); }
+
+
+void InstructionSelector::VisitWord32Popcnt(Node* node) { UNREACHABLE(); }
+
+
+void InstructionSelector::VisitWord64Popcnt(Node* node) { UNREACHABLE(); }
+
+
 void InstructionSelector::VisitWord64Ror(Node* node) {
   VisitRRO(this, kMips64Dror, node);
 }
 
 
+void InstructionSelector::VisitWord64Clz(Node* node) {
+  VisitRR(this, kMips64Dclz, node);
+}
+
+
 void InstructionSelector::VisitInt32Add(Node* node) {
   Mips64OperandGenerator g(this);
   // TODO(plind): Consider multiply & add optimization from arm port.
@@ -374,7 +620,7 @@
       return;
     }
     if (base::bits::IsPowerOfTwo32(value - 1)) {
-      InstructionOperand* temp = g.TempRegister();
+      InstructionOperand temp = g.TempRegister();
       Emit(kMips64Shl | AddressingModeField::encode(kMode_None), temp,
            g.UseRegister(m.left().node()),
            g.TempImmediate(WhichPowerOf2(value - 1)));
@@ -383,7 +629,7 @@
       return;
     }
     if (base::bits::IsPowerOfTwo32(value + 1)) {
-      InstructionOperand* temp = g.TempRegister();
+      InstructionOperand temp = g.TempRegister();
       Emit(kMips64Shl | AddressingModeField::encode(kMode_None), temp,
            g.UseRegister(m.left().node()),
            g.TempImmediate(WhichPowerOf2(value + 1)));
@@ -392,25 +638,32 @@
       return;
     }
   }
-  Emit(kMips64Mul, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
-       g.UseRegister(m.right().node()));
+  Node* left = node->InputAt(0);
+  Node* right = node->InputAt(1);
+  if (CanCover(node, left) && CanCover(node, right)) {
+    if (left->opcode() == IrOpcode::kWord64Sar &&
+        right->opcode() == IrOpcode::kWord64Sar) {
+      Int64BinopMatcher leftInput(left), rightInput(right);
+      if (leftInput.right().Is(32) && rightInput.right().Is(32)) {
+        // Combine untagging shifts with Dmul high.
+        Emit(kMips64DMulHigh, g.DefineSameAsFirst(node),
+             g.UseRegister(leftInput.left().node()),
+             g.UseRegister(rightInput.left().node()));
+        return;
+      }
+    }
+  }
+  VisitRRR(this, kMips64Mul, node);
 }
 
 
 void InstructionSelector::VisitInt32MulHigh(Node* node) {
-  Mips64OperandGenerator g(this);
-  Emit(kMips64MulHigh, g.DefineAsRegister(node),
-       g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)));
+  VisitRRR(this, kMips64MulHigh, node);
 }
 
 
 void InstructionSelector::VisitUint32MulHigh(Node* node) {
-  Mips64OperandGenerator g(this);
-  InstructionOperand* const dmul_operand = g.TempRegister();
-  Emit(kMips64MulHighU, dmul_operand, g.UseRegister(node->InputAt(0)),
-       g.UseRegister(node->InputAt(1)));
-  Emit(kMips64Ext, g.DefineAsRegister(node), dmul_operand, g.TempImmediate(0),
-       g.TempImmediate(32));
+  VisitRRR(this, kMips64MulHighU, node);
 }
 
 
@@ -419,7 +672,7 @@
   Int64BinopMatcher m(node);
   // TODO(dusmil): Add optimization for shifts larger than 32.
   if (m.right().HasValue() && m.right().Value() > 0) {
-    int64_t value = m.right().Value();
+    int32_t value = static_cast<int32_t>(m.right().Value());
     if (base::bits::IsPowerOfTwo32(value)) {
       Emit(kMips64Dshl | AddressingModeField::encode(kMode_None),
            g.DefineAsRegister(node), g.UseRegister(m.left().node()),
@@ -427,7 +680,7 @@
       return;
     }
     if (base::bits::IsPowerOfTwo32(value - 1)) {
-      InstructionOperand* temp = g.TempRegister();
+      InstructionOperand temp = g.TempRegister();
       Emit(kMips64Dshl | AddressingModeField::encode(kMode_None), temp,
            g.UseRegister(m.left().node()),
            g.TempImmediate(WhichPowerOf2(value - 1)));
@@ -436,7 +689,7 @@
       return;
     }
     if (base::bits::IsPowerOfTwo32(value + 1)) {
-      InstructionOperand* temp = g.TempRegister();
+      InstructionOperand temp = g.TempRegister();
       Emit(kMips64Dshl | AddressingModeField::encode(kMode_None), temp,
            g.UseRegister(m.left().node()),
            g.TempImmediate(WhichPowerOf2(value + 1)));
@@ -453,7 +706,22 @@
 void InstructionSelector::VisitInt32Div(Node* node) {
   Mips64OperandGenerator g(this);
   Int32BinopMatcher m(node);
-  Emit(kMips64Div, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
+  Node* left = node->InputAt(0);
+  Node* right = node->InputAt(1);
+  if (CanCover(node, left) && CanCover(node, right)) {
+    if (left->opcode() == IrOpcode::kWord64Sar &&
+        right->opcode() == IrOpcode::kWord64Sar) {
+      Int64BinopMatcher rightInput(right), leftInput(left);
+      if (rightInput.right().Is(32) && leftInput.right().Is(32)) {
+        // Combine both shifted operands with Ddiv.
+        Emit(kMips64Ddiv, g.DefineSameAsFirst(node),
+             g.UseRegister(leftInput.left().node()),
+             g.UseRegister(rightInput.left().node()));
+        return;
+      }
+    }
+  }
+  Emit(kMips64Div, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()),
        g.UseRegister(m.right().node()));
 }
 
@@ -461,7 +729,7 @@
 void InstructionSelector::VisitUint32Div(Node* node) {
   Mips64OperandGenerator g(this);
   Int32BinopMatcher m(node);
-  Emit(kMips64DivU, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
+  Emit(kMips64DivU, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()),
        g.UseRegister(m.right().node()));
 }
 
@@ -469,6 +737,21 @@
 void InstructionSelector::VisitInt32Mod(Node* node) {
   Mips64OperandGenerator g(this);
   Int32BinopMatcher m(node);
+  Node* left = node->InputAt(0);
+  Node* right = node->InputAt(1);
+  if (CanCover(node, left) && CanCover(node, right)) {
+    if (left->opcode() == IrOpcode::kWord64Sar &&
+        right->opcode() == IrOpcode::kWord64Sar) {
+      Int64BinopMatcher rightInput(right), leftInput(left);
+      if (rightInput.right().Is(32) && leftInput.right().Is(32)) {
+        // Combine both shifted operands with Dmod.
+        Emit(kMips64Dmod, g.DefineSameAsFirst(node),
+             g.UseRegister(leftInput.left().node()),
+             g.UseRegister(rightInput.left().node()));
+        return;
+      }
+    }
+  }
   Emit(kMips64Mod, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
        g.UseRegister(m.right().node()));
 }
@@ -485,7 +768,7 @@
 void InstructionSelector::VisitInt64Div(Node* node) {
   Mips64OperandGenerator g(this);
   Int64BinopMatcher m(node);
-  Emit(kMips64Ddiv, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
+  Emit(kMips64Ddiv, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()),
        g.UseRegister(m.right().node()));
 }
 
@@ -493,7 +776,7 @@
 void InstructionSelector::VisitUint64Div(Node* node) {
   Mips64OperandGenerator g(this);
   Int64BinopMatcher m(node);
-  Emit(kMips64DdivU, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
+  Emit(kMips64DdivU, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()),
        g.UseRegister(m.right().node()));
 }
 
@@ -515,35 +798,151 @@
 
 
 void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) {
-  Mips64OperandGenerator g(this);
-  Emit(kMips64CvtDS, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)));
+  VisitRR(this, kMips64CvtDS, node);
 }
 
 
 void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) {
-  Mips64OperandGenerator g(this);
-  Emit(kMips64CvtDW, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)));
+  VisitRR(this, kMips64CvtDW, node);
 }
 
 
 void InstructionSelector::VisitChangeUint32ToFloat64(Node* node) {
-  Mips64OperandGenerator g(this);
-  Emit(kMips64CvtDUw, g.DefineAsRegister(node),
-       g.UseRegister(node->InputAt(0)));
+  VisitRR(this, kMips64CvtDUw, node);
 }
 
 
 void InstructionSelector::VisitChangeFloat64ToInt32(Node* node) {
   Mips64OperandGenerator g(this);
-  Emit(kMips64TruncWD, g.DefineAsRegister(node),
-       g.UseRegister(node->InputAt(0)));
+  Node* value = node->InputAt(0);
+  // Match ChangeFloat64ToInt32(Float64Round##OP) to corresponding instruction
+  // which does rounding and conversion to integer format.
+  if (CanCover(node, value)) {
+    switch (value->opcode()) {
+      case IrOpcode::kFloat64RoundDown:
+        Emit(kMips64FloorWD, g.DefineAsRegister(node),
+             g.UseRegister(value->InputAt(0)));
+        return;
+      case IrOpcode::kFloat64RoundUp:
+        Emit(kMips64CeilWD, g.DefineAsRegister(node),
+             g.UseRegister(value->InputAt(0)));
+        return;
+      case IrOpcode::kFloat64RoundTiesEven:
+        Emit(kMips64RoundWD, g.DefineAsRegister(node),
+             g.UseRegister(value->InputAt(0)));
+        return;
+      case IrOpcode::kFloat64RoundTruncate:
+        Emit(kMips64TruncWD, g.DefineAsRegister(node),
+             g.UseRegister(value->InputAt(0)));
+        return;
+      default:
+        break;
+    }
+    if (value->opcode() == IrOpcode::kChangeFloat32ToFloat64) {
+      Node* next = value->InputAt(0);
+      if (CanCover(value, next)) {
+        // Match ChangeFloat64ToInt32(ChangeFloat32ToFloat64(Float64Round##OP))
+        switch (next->opcode()) {
+          case IrOpcode::kFloat32RoundDown:
+            Emit(kMips64FloorWS, g.DefineAsRegister(node),
+                 g.UseRegister(next->InputAt(0)));
+            return;
+          case IrOpcode::kFloat32RoundUp:
+            Emit(kMips64CeilWS, g.DefineAsRegister(node),
+                 g.UseRegister(next->InputAt(0)));
+            return;
+          case IrOpcode::kFloat32RoundTiesEven:
+            Emit(kMips64RoundWS, g.DefineAsRegister(node),
+                 g.UseRegister(next->InputAt(0)));
+            return;
+          case IrOpcode::kFloat32RoundTruncate:
+            Emit(kMips64TruncWS, g.DefineAsRegister(node),
+                 g.UseRegister(next->InputAt(0)));
+            return;
+          default:
+            Emit(kMips64TruncWS, g.DefineAsRegister(node),
+                 g.UseRegister(value->InputAt(0)));
+            return;
+        }
+      } else {
+        // Match float32 -> float64 -> int32 representation change path.
+        Emit(kMips64TruncWS, g.DefineAsRegister(node),
+             g.UseRegister(value->InputAt(0)));
+        return;
+      }
+    }
+  }
+  VisitRR(this, kMips64TruncWD, node);
 }
 
 
 void InstructionSelector::VisitChangeFloat64ToUint32(Node* node) {
+  VisitRR(this, kMips64TruncUwD, node);
+}
+
+
+void InstructionSelector::VisitTryTruncateFloat32ToInt64(Node* node) {
   Mips64OperandGenerator g(this);
-  Emit(kMips64TruncUwD, g.DefineAsRegister(node),
-       g.UseRegister(node->InputAt(0)));
+  InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0))};
+  InstructionOperand outputs[2];
+  size_t output_count = 0;
+  outputs[output_count++] = g.DefineAsRegister(node);
+
+  Node* success_output = NodeProperties::FindProjection(node, 1);
+  if (success_output) {
+    outputs[output_count++] = g.DefineAsRegister(success_output);
+  }
+
+  this->Emit(kMips64TruncLS, output_count, outputs, 1, inputs);
+}
+
+
+void InstructionSelector::VisitTryTruncateFloat64ToInt64(Node* node) {
+  Mips64OperandGenerator g(this);
+  InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0))};
+  InstructionOperand outputs[2];
+  size_t output_count = 0;
+  outputs[output_count++] = g.DefineAsRegister(node);
+
+  Node* success_output = NodeProperties::FindProjection(node, 1);
+  if (success_output) {
+    outputs[output_count++] = g.DefineAsRegister(success_output);
+  }
+
+  Emit(kMips64TruncLD, output_count, outputs, 1, inputs);
+}
+
+
+void InstructionSelector::VisitTryTruncateFloat32ToUint64(Node* node) {
+  Mips64OperandGenerator g(this);
+  InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0))};
+  InstructionOperand outputs[2];
+  size_t output_count = 0;
+  outputs[output_count++] = g.DefineAsRegister(node);
+
+  Node* success_output = NodeProperties::FindProjection(node, 1);
+  if (success_output) {
+    outputs[output_count++] = g.DefineAsRegister(success_output);
+  }
+
+  Emit(kMips64TruncUlS, output_count, outputs, 1, inputs);
+}
+
+
+void InstructionSelector::VisitTryTruncateFloat64ToUint64(Node* node) {
+  Mips64OperandGenerator g(this);
+
+  InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0))};
+  InstructionOperand outputs[2];
+  size_t output_count = 0;
+  outputs[output_count++] = g.DefineAsRegister(node);
+
+  Node* success_output = NodeProperties::FindProjection(node, 1);
+  if (success_output) {
+    outputs[output_count++] = g.DefineAsRegister(success_output);
+  }
+
+  Emit(kMips64TruncUlD, output_count, outputs, 1, inputs);
 }
 
 
@@ -563,6 +962,24 @@
 
 void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) {
   Mips64OperandGenerator g(this);
+  Node* value = node->InputAt(0);
+  if (CanCover(node, value)) {
+    switch (value->opcode()) {
+      case IrOpcode::kWord64Sar: {
+        Int64BinopMatcher m(value);
+        if (m.right().IsInRange(32, 63)) {
+          // After smi untagging no need for truncate. Combine sequence.
+          Emit(kMips64Dsar, g.DefineSameAsFirst(node),
+               g.UseRegister(m.left().node()),
+               g.UseImmediate(m.right().node()));
+          return;
+        }
+        break;
+      }
+      default:
+        break;
+    }
+  }
   Emit(kMips64Ext, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)),
        g.TempImmediate(0), g.TempImmediate(32));
 }
@@ -570,7 +987,75 @@
 
 void InstructionSelector::VisitTruncateFloat64ToFloat32(Node* node) {
   Mips64OperandGenerator g(this);
-  Emit(kMips64CvtSD, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)));
+  Node* value = node->InputAt(0);
+  // Match TruncateFloat64ToFloat32(ChangeInt32ToFloat64) to corresponding
+  // instruction.
+  if (CanCover(node, value) &&
+      value->opcode() == IrOpcode::kChangeInt32ToFloat64) {
+    Emit(kMips64CvtSW, g.DefineAsRegister(node),
+         g.UseRegister(value->InputAt(0)));
+    return;
+  }
+  VisitRR(this, kMips64CvtSD, node);
+}
+
+
+void InstructionSelector::VisitTruncateFloat64ToInt32(Node* node) {
+  switch (TruncationModeOf(node->op())) {
+    case TruncationMode::kJavaScript:
+      return VisitRR(this, kArchTruncateDoubleToI, node);
+    case TruncationMode::kRoundToZero:
+      return VisitRR(this, kMips64TruncWD, node);
+  }
+  UNREACHABLE();
+}
+
+
+void InstructionSelector::VisitRoundInt64ToFloat32(Node* node) {
+  VisitRR(this, kMips64CvtSL, node);
+}
+
+
+void InstructionSelector::VisitRoundInt64ToFloat64(Node* node) {
+  VisitRR(this, kMips64CvtDL, node);
+}
+
+
+void InstructionSelector::VisitRoundUint64ToFloat32(Node* node) {
+  VisitRR(this, kMips64CvtSUl, node);
+}
+
+
+void InstructionSelector::VisitRoundUint64ToFloat64(Node* node) {
+  VisitRR(this, kMips64CvtDUl, node);
+}
+
+
+void InstructionSelector::VisitBitcastFloat32ToInt32(Node* node) {
+  VisitRR(this, kMips64Float64ExtractLowWord32, node);
+}
+
+
+void InstructionSelector::VisitBitcastFloat64ToInt64(Node* node) {
+  VisitRR(this, kMips64BitcastDL, node);
+}
+
+
+void InstructionSelector::VisitBitcastInt32ToFloat32(Node* node) {
+  Mips64OperandGenerator g(this);
+  Emit(kMips64Float64InsertLowWord32, g.DefineAsRegister(node),
+       ImmediateOperand(ImmediateOperand::INLINE, 0),
+       g.UseRegister(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitBitcastInt64ToFloat64(Node* node) {
+  VisitRR(this, kMips64BitcastLD, node);
+}
+
+
+void InstructionSelector::VisitFloat32Add(Node* node) {
+  VisitRRR(this, kMips64AddS, node);
 }
 
 
@@ -579,16 +1064,45 @@
 }
 
 
+void InstructionSelector::VisitFloat32Sub(Node* node) {
+  VisitRRR(this, kMips64SubS, node);
+}
+
+
 void InstructionSelector::VisitFloat64Sub(Node* node) {
+  Mips64OperandGenerator g(this);
+  Float64BinopMatcher m(node);
+  if (m.left().IsMinusZero() && m.right().IsFloat64RoundDown() &&
+      CanCover(m.node(), m.right().node())) {
+    if (m.right().InputAt(0)->opcode() == IrOpcode::kFloat64Sub &&
+        CanCover(m.right().node(), m.right().InputAt(0))) {
+      Float64BinopMatcher mright0(m.right().InputAt(0));
+      if (mright0.left().IsMinusZero()) {
+        Emit(kMips64Float64RoundUp, g.DefineAsRegister(node),
+             g.UseRegister(mright0.right().node()));
+        return;
+      }
+    }
+  }
   VisitRRR(this, kMips64SubD, node);
 }
 
 
+void InstructionSelector::VisitFloat32Mul(Node* node) {
+  VisitRRR(this, kMips64MulS, node);
+}
+
+
 void InstructionSelector::VisitFloat64Mul(Node* node) {
   VisitRRR(this, kMips64MulD, node);
 }
 
 
+void InstructionSelector::VisitFloat32Div(Node* node) {
+  VisitRRR(this, kMips64DivS, node);
+}
+
+
 void InstructionSelector::VisitFloat64Div(Node* node) {
   VisitRRR(this, kMips64DivD, node);
 }
@@ -602,19 +1116,108 @@
 }
 
 
-void InstructionSelector::VisitFloat64Sqrt(Node* node) {
+void InstructionSelector::VisitFloat32Max(Node* node) {
   Mips64OperandGenerator g(this);
-  Emit(kMips64SqrtD, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)));
+  if (kArchVariant == kMips64r6) {
+    Emit(kMips64Float32Max, g.DefineAsRegister(node),
+         g.UseUniqueRegister(node->InputAt(0)),
+         g.UseUniqueRegister(node->InputAt(1)));
+
+  } else {
+    // Reverse operands, and use same reg. for result and right operand.
+    Emit(kMips64Float32Max, g.DefineSameAsFirst(node),
+         g.UseRegister(node->InputAt(1)), g.UseRegister(node->InputAt(0)));
+  }
 }
 
 
-void InstructionSelector::VisitFloat64Floor(Node* node) {
-  VisitRR(this, kMips64Float64Floor, node);
+void InstructionSelector::VisitFloat64Max(Node* node) {
+  Mips64OperandGenerator g(this);
+  if (kArchVariant == kMips64r6) {
+    Emit(kMips64Float64Max, g.DefineAsRegister(node),
+         g.UseUniqueRegister(node->InputAt(0)),
+         g.UseUniqueRegister(node->InputAt(1)));
+
+  } else {
+    // Reverse operands, and use same reg. for result and right operand.
+    Emit(kMips64Float64Max, g.DefineSameAsFirst(node),
+         g.UseRegister(node->InputAt(1)), g.UseRegister(node->InputAt(0)));
+  }
 }
 
 
-void InstructionSelector::VisitFloat64Ceil(Node* node) {
-  VisitRR(this, kMips64Float64Ceil, node);
+void InstructionSelector::VisitFloat32Min(Node* node) {
+  Mips64OperandGenerator g(this);
+  if (kArchVariant == kMips64r6) {
+    Emit(kMips64Float32Min, g.DefineAsRegister(node),
+         g.UseUniqueRegister(node->InputAt(0)),
+         g.UseUniqueRegister(node->InputAt(1)));
+
+  } else {
+    // Reverse operands, and use same reg. for result and right operand.
+    Emit(kMips64Float32Min, g.DefineSameAsFirst(node),
+         g.UseRegister(node->InputAt(1)), g.UseRegister(node->InputAt(0)));
+  }
+}
+
+
+void InstructionSelector::VisitFloat64Min(Node* node) {
+  Mips64OperandGenerator g(this);
+  if (kArchVariant == kMips64r6) {
+    Emit(kMips64Float64Min, g.DefineAsRegister(node),
+         g.UseUniqueRegister(node->InputAt(0)),
+         g.UseUniqueRegister(node->InputAt(1)));
+
+  } else {
+    // Reverse operands, and use same reg. for result and right operand.
+    Emit(kMips64Float64Min, g.DefineSameAsFirst(node),
+         g.UseRegister(node->InputAt(1)), g.UseRegister(node->InputAt(0)));
+  }
+}
+
+
+void InstructionSelector::VisitFloat32Abs(Node* node) {
+  VisitRR(this, kMips64AbsS, node);
+}
+
+
+void InstructionSelector::VisitFloat64Abs(Node* node) {
+  VisitRR(this, kMips64AbsD, node);
+}
+
+
+void InstructionSelector::VisitFloat32Sqrt(Node* node) {
+  VisitRR(this, kMips64SqrtS, node);
+}
+
+
+void InstructionSelector::VisitFloat64Sqrt(Node* node) {
+  VisitRR(this, kMips64SqrtD, node);
+}
+
+
+void InstructionSelector::VisitFloat32RoundDown(Node* node) {
+  VisitRR(this, kMips64Float32RoundDown, node);
+}
+
+
+void InstructionSelector::VisitFloat64RoundDown(Node* node) {
+  VisitRR(this, kMips64Float64RoundDown, node);
+}
+
+
+void InstructionSelector::VisitFloat32RoundUp(Node* node) {
+  VisitRR(this, kMips64Float32RoundUp, node);
+}
+
+
+void InstructionSelector::VisitFloat64RoundUp(Node* node) {
+  VisitRR(this, kMips64Float64RoundUp, node);
+}
+
+
+void InstructionSelector::VisitFloat32RoundTruncate(Node* node) {
+  VisitRR(this, kMips64Float32RoundTruncate, node);
 }
 
 
@@ -628,95 +1231,95 @@
 }
 
 
-void InstructionSelector::VisitCall(Node* node) {
-  Mips64OperandGenerator g(this);
-  const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(node);
-
-  FrameStateDescriptor* frame_state_descriptor = NULL;
-  if (descriptor->NeedsFrameState()) {
-    frame_state_descriptor =
-        GetFrameStateDescriptor(node->InputAt(descriptor->InputCount()));
-  }
-
-  CallBuffer buffer(zone(), descriptor, frame_state_descriptor);
-
-  // Compute InstructionOperands for inputs and outputs.
-  InitializeCallBuffer(node, &buffer, true, false);
-
-  int push_count = buffer.pushed_nodes.size();
-  if (push_count > 0) {
-    Emit(kMips64StackClaim | MiscField::encode(push_count), NULL);
-  }
-  int slot = buffer.pushed_nodes.size() - 1;
-  for (NodeVectorRIter input = buffer.pushed_nodes.rbegin();
-       input != buffer.pushed_nodes.rend(); input++) {
-    Emit(kMips64StoreToStackSlot | MiscField::encode(slot), NULL,
-         g.UseRegister(*input));
-    slot--;
-  }
-
-  // Select the appropriate opcode based on the call type.
-  InstructionCode opcode;
-  switch (descriptor->kind()) {
-    case CallDescriptor::kCallCodeObject: {
-      opcode = kArchCallCodeObject;
-      break;
-    }
-    case CallDescriptor::kCallJSFunction:
-      opcode = kArchCallJSFunction;
-      break;
-    default:
-      UNREACHABLE();
-      return;
-  }
-  opcode |= MiscField::encode(descriptor->flags());
-
-  // Emit the call instruction.
-  Instruction* call_instr =
-      Emit(opcode, buffer.outputs.size(), &buffer.outputs.front(),
-           buffer.instruction_args.size(), &buffer.instruction_args.front());
-
-  call_instr->MarkAsCall();
+void InstructionSelector::VisitFloat32RoundTiesEven(Node* node) {
+  VisitRR(this, kMips64Float32RoundTiesEven, node);
 }
 
 
+void InstructionSelector::VisitFloat64RoundTiesEven(Node* node) {
+  VisitRR(this, kMips64Float64RoundTiesEven, node);
+}
+
+
+void InstructionSelector::EmitPrepareArguments(
+    ZoneVector<PushParameter>* arguments, const CallDescriptor* descriptor,
+    Node* node) {
+  Mips64OperandGenerator g(this);
+
+  // Prepare for C function call.
+  if (descriptor->IsCFunctionCall()) {
+    Emit(kArchPrepareCallCFunction |
+             MiscField::encode(static_cast<int>(descriptor->CParameterCount())),
+         0, nullptr, 0, nullptr);
+
+    // Poke any stack arguments.
+    int slot = kCArgSlotCount;
+    for (PushParameter input : (*arguments)) {
+      Emit(kMips64StoreToStackSlot, g.NoOutput(), g.UseRegister(input.node()),
+           g.TempImmediate(slot << kPointerSizeLog2));
+      ++slot;
+    }
+  } else {
+    int push_count = static_cast<int>(descriptor->StackParameterCount());
+    if (push_count > 0) {
+      Emit(kMips64StackClaim, g.NoOutput(),
+           g.TempImmediate(push_count << kPointerSizeLog2));
+    }
+    for (size_t n = 0; n < arguments->size(); ++n) {
+      PushParameter input = (*arguments)[n];
+      if (input.node()) {
+        Emit(kMips64StoreToStackSlot, g.NoOutput(), g.UseRegister(input.node()),
+             g.TempImmediate(static_cast<int>(n << kPointerSizeLog2)));
+      }
+    }
+  }
+}
+
+
+bool InstructionSelector::IsTailCallAddressImmediate() { return false; }
+
+
 void InstructionSelector::VisitCheckedLoad(Node* node) {
-  MachineType rep = RepresentationOf(OpParameter<MachineType>(node));
-  MachineType typ = TypeOf(OpParameter<MachineType>(node));
+  CheckedLoadRepresentation load_rep = CheckedLoadRepresentationOf(node->op());
   Mips64OperandGenerator g(this);
   Node* const buffer = node->InputAt(0);
   Node* const offset = node->InputAt(1);
   Node* const length = node->InputAt(2);
-  ArchOpcode opcode;
-  switch (rep) {
-    case kRepWord8:
-      opcode = typ == kTypeInt32 ? kCheckedLoadInt8 : kCheckedLoadUint8;
+  ArchOpcode opcode = kArchNop;
+  switch (load_rep.representation()) {
+    case MachineRepresentation::kWord8:
+      opcode = load_rep.IsSigned() ? kCheckedLoadInt8 : kCheckedLoadUint8;
       break;
-    case kRepWord16:
-      opcode = typ == kTypeInt32 ? kCheckedLoadInt16 : kCheckedLoadUint16;
+    case MachineRepresentation::kWord16:
+      opcode = load_rep.IsSigned() ? kCheckedLoadInt16 : kCheckedLoadUint16;
       break;
-    case kRepWord32:
+    case MachineRepresentation::kWord32:
       opcode = kCheckedLoadWord32;
       break;
-    case kRepFloat32:
+    case MachineRepresentation::kWord64:
+      opcode = kCheckedLoadWord64;
+      break;
+    case MachineRepresentation::kFloat32:
       opcode = kCheckedLoadFloat32;
       break;
-    case kRepFloat64:
+    case MachineRepresentation::kFloat64:
       opcode = kCheckedLoadFloat64;
       break;
-    default:
+    case MachineRepresentation::kBit:
+    case MachineRepresentation::kTagged:
+    case MachineRepresentation::kNone:
       UNREACHABLE();
       return;
   }
-  InstructionOperand* offset_operand = g.CanBeImmediate(offset, opcode)
-                                           ? g.UseImmediate(offset)
-                                           : g.UseRegister(offset);
+  InstructionOperand offset_operand = g.CanBeImmediate(offset, opcode)
+                                          ? g.UseImmediate(offset)
+                                          : g.UseRegister(offset);
 
-  InstructionOperand* length_operand =
-      (!g.CanBeImmediate(offset, opcode)) ? g.CanBeImmediate(length, opcode)
-      ? g.UseImmediate(length)
-      : g.UseRegister(length)
-      : g.UseRegister(length);
+  InstructionOperand length_operand = (!g.CanBeImmediate(offset, opcode))
+                                          ? g.CanBeImmediate(length, opcode)
+                                                ? g.UseImmediate(length)
+                                                : g.UseRegister(length)
+                                          : g.UseRegister(length);
 
   Emit(opcode | AddressingModeField::encode(kMode_MRI),
        g.DefineAsRegister(node), offset_operand, length_operand,
@@ -725,45 +1328,51 @@
 
 
 void InstructionSelector::VisitCheckedStore(Node* node) {
-  MachineType rep = RepresentationOf(OpParameter<MachineType>(node));
+  MachineRepresentation rep = CheckedStoreRepresentationOf(node->op());
   Mips64OperandGenerator g(this);
   Node* const buffer = node->InputAt(0);
   Node* const offset = node->InputAt(1);
   Node* const length = node->InputAt(2);
   Node* const value = node->InputAt(3);
-  ArchOpcode opcode;
+  ArchOpcode opcode = kArchNop;
   switch (rep) {
-    case kRepWord8:
+    case MachineRepresentation::kWord8:
       opcode = kCheckedStoreWord8;
       break;
-    case kRepWord16:
+    case MachineRepresentation::kWord16:
       opcode = kCheckedStoreWord16;
       break;
-    case kRepWord32:
+    case MachineRepresentation::kWord32:
       opcode = kCheckedStoreWord32;
       break;
-    case kRepFloat32:
+    case MachineRepresentation::kWord64:
+      opcode = kCheckedStoreWord64;
+      break;
+    case MachineRepresentation::kFloat32:
       opcode = kCheckedStoreFloat32;
       break;
-    case kRepFloat64:
+    case MachineRepresentation::kFloat64:
       opcode = kCheckedStoreFloat64;
       break;
-    default:
+    case MachineRepresentation::kBit:
+    case MachineRepresentation::kTagged:
+    case MachineRepresentation::kNone:
       UNREACHABLE();
       return;
   }
-  InstructionOperand* offset_operand = g.CanBeImmediate(offset, opcode)
-                                           ? g.UseImmediate(offset)
-                                           : g.UseRegister(offset);
+  InstructionOperand offset_operand = g.CanBeImmediate(offset, opcode)
+                                          ? g.UseImmediate(offset)
+                                          : g.UseRegister(offset);
 
-  InstructionOperand* length_operand =
-      (!g.CanBeImmediate(offset, opcode)) ? g.CanBeImmediate(length, opcode)
-      ? g.UseImmediate(length)
-      : g.UseRegister(length)
-      : g.UseRegister(length);
+  InstructionOperand length_operand = (!g.CanBeImmediate(offset, opcode))
+                                          ? g.CanBeImmediate(length, opcode)
+                                                ? g.UseImmediate(length)
+                                                : g.UseRegister(length)
+                                          : g.UseRegister(length);
 
-  Emit(opcode | AddressingModeField::encode(kMode_MRI), nullptr, offset_operand,
-       length_operand, g.UseRegister(value), g.UseRegister(buffer));
+  Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
+       offset_operand, length_operand, g.UseRegister(value),
+       g.UseRegister(buffer));
 }
 
 
@@ -771,13 +1380,13 @@
 
 // Shared routine for multiple compare operations.
 static void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
-                         InstructionOperand* left, InstructionOperand* right,
+                         InstructionOperand left, InstructionOperand right,
                          FlagsContinuation* cont) {
   Mips64OperandGenerator g(selector);
   opcode = cont->Encode(opcode);
   if (cont->IsBranch()) {
-    selector->Emit(opcode, NULL, left, right, g.Label(cont->true_block()),
-                   g.Label(cont->false_block()))->MarkAsControl();
+    selector->Emit(opcode, g.NoOutput(), left, right,
+                   g.Label(cont->true_block()), g.Label(cont->false_block()));
   } else {
     DCHECK(cont->IsSet());
     selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right);
@@ -785,14 +1394,33 @@
 }
 
 
-// Shared routine for multiple float compare operations.
+// Shared routine for multiple float32 compare operations.
+void VisitFloat32Compare(InstructionSelector* selector, Node* node,
+                         FlagsContinuation* cont) {
+  Mips64OperandGenerator g(selector);
+  Float32BinopMatcher m(node);
+  InstructionOperand lhs, rhs;
+
+  lhs = m.left().IsZero() ? g.UseImmediate(m.left().node())
+                          : g.UseRegister(m.left().node());
+  rhs = m.right().IsZero() ? g.UseImmediate(m.right().node())
+                           : g.UseRegister(m.right().node());
+  VisitCompare(selector, kMips64CmpS, lhs, rhs, cont);
+}
+
+
+// Shared routine for multiple float64 compare operations.
 void VisitFloat64Compare(InstructionSelector* selector, Node* node,
                          FlagsContinuation* cont) {
   Mips64OperandGenerator g(selector);
-  Node* left = node->InputAt(0);
-  Node* right = node->InputAt(1);
-  VisitCompare(selector, kMips64CmpD, g.UseRegister(left), g.UseRegister(right),
-               cont);
+  Float64BinopMatcher m(node);
+  InstructionOperand lhs, rhs;
+
+  lhs = m.left().IsZero() ? g.UseImmediate(m.left().node())
+                          : g.UseRegister(m.left().node());
+  rhs = m.right().IsZero() ? g.UseImmediate(m.right().node())
+                           : g.UseRegister(m.right().node());
+  VisitCompare(selector, kMips64CmpD, lhs, rhs, cont);
 }
 
 
@@ -805,13 +1433,53 @@
   Node* right = node->InputAt(1);
 
   // Match immediates on left or right side of comparison.
-  if (g.CanBeImmediate(right, opcode, cont)) {
-    VisitCompare(selector, opcode, g.UseRegister(left), g.UseImmediate(right),
-                 cont);
-  } else if (g.CanBeImmediate(left, opcode, cont)) {
+  if (g.CanBeImmediate(right, opcode)) {
+    switch (cont->condition()) {
+      case kEqual:
+      case kNotEqual:
+        if (cont->IsSet()) {
+          VisitCompare(selector, opcode, g.UseRegister(left),
+                       g.UseImmediate(right), cont);
+        } else {
+          VisitCompare(selector, opcode, g.UseRegister(left),
+                       g.UseRegister(right), cont);
+        }
+        break;
+      case kSignedLessThan:
+      case kSignedGreaterThanOrEqual:
+      case kUnsignedLessThan:
+      case kUnsignedGreaterThanOrEqual:
+        VisitCompare(selector, opcode, g.UseRegister(left),
+                     g.UseImmediate(right), cont);
+        break;
+      default:
+        VisitCompare(selector, opcode, g.UseRegister(left),
+                     g.UseRegister(right), cont);
+    }
+  } else if (g.CanBeImmediate(left, opcode)) {
     if (!commutative) cont->Commute();
-    VisitCompare(selector, opcode, g.UseRegister(right), g.UseImmediate(left),
-                 cont);
+    switch (cont->condition()) {
+      case kEqual:
+      case kNotEqual:
+        if (cont->IsSet()) {
+          VisitCompare(selector, opcode, g.UseRegister(right),
+                       g.UseImmediate(left), cont);
+        } else {
+          VisitCompare(selector, opcode, g.UseRegister(right),
+                       g.UseRegister(left), cont);
+        }
+        break;
+      case kSignedLessThan:
+      case kSignedGreaterThanOrEqual:
+      case kUnsignedLessThan:
+      case kUnsignedGreaterThanOrEqual:
+        VisitCompare(selector, opcode, g.UseRegister(right),
+                     g.UseImmediate(left), cont);
+        break;
+      default:
+        VisitCompare(selector, opcode, g.UseRegister(right),
+                     g.UseRegister(left), cont);
+    }
   } else {
     VisitCompare(selector, opcode, g.UseRegister(left), g.UseRegister(right),
                  cont);
@@ -821,7 +1489,7 @@
 
 void VisitWord32Compare(InstructionSelector* selector, Node* node,
                         FlagsContinuation* cont) {
-  VisitWordCompare(selector, node, kMips64Cmp32, cont, false);
+  VisitWordCompare(selector, node, kMips64Cmp, cont, false);
 }
 
 
@@ -833,15 +1501,14 @@
 }  // namespace
 
 
-void EmitWordCompareZero(InstructionSelector* selector, InstructionCode opcode,
-                         Node* value, FlagsContinuation* cont) {
+void EmitWordCompareZero(InstructionSelector* selector, Node* value,
+                         FlagsContinuation* cont) {
   Mips64OperandGenerator g(selector);
-  opcode = cont->Encode(opcode);
-  InstructionOperand* const value_operand = g.UseRegister(value);
+  InstructionCode opcode = cont->Encode(kMips64Cmp);
+  InstructionOperand const value_operand = g.UseRegister(value);
   if (cont->IsBranch()) {
-    selector->Emit(opcode, nullptr, value_operand, g.TempImmediate(0),
-                   g.Label(cont->true_block()),
-                   g.Label(cont->false_block()))->MarkAsControl();
+    selector->Emit(opcode, g.NoOutput(), value_operand, g.TempImmediate(0),
+                   g.Label(cont->true_block()), g.Label(cont->false_block()));
   } else {
     selector->Emit(opcode, g.DefineAsRegister(cont->result()), value_operand,
                    g.TempImmediate(0));
@@ -852,13 +1519,7 @@
 // Shared routine for word comparisons against zero.
 void VisitWordCompareZero(InstructionSelector* selector, Node* user,
                           Node* value, FlagsContinuation* cont) {
-  // Initially set comparison against 0 to be 64-bit variant for branches that
-  // cannot combine.
-  InstructionCode opcode = kMips64Cmp;
   while (selector->CanCover(user, value)) {
-    if (user->opcode() == IrOpcode::kWord32Equal) {
-      opcode = kMips64Cmp32;
-    }
     switch (value->opcode()) {
       case IrOpcode::kWord32Equal: {
         // Combine with comparisons against 0 by simply inverting the
@@ -868,7 +1529,6 @@
           user = value;
           value = m.left().node();
           cont->Negate();
-          opcode = kMips64Cmp32;
           continue;
         }
         cont->OverwriteAndNegateIfEqual(kEqual);
@@ -908,27 +1568,39 @@
       case IrOpcode::kUint64LessThan:
         cont->OverwriteAndNegateIfEqual(kUnsignedLessThan);
         return VisitWord64Compare(selector, value, cont);
+      case IrOpcode::kUint64LessThanOrEqual:
+        cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
+        return VisitWord64Compare(selector, value, cont);
+      case IrOpcode::kFloat32Equal:
+        cont->OverwriteAndNegateIfEqual(kEqual);
+        return VisitFloat32Compare(selector, value, cont);
+      case IrOpcode::kFloat32LessThan:
+        cont->OverwriteAndNegateIfEqual(kUnsignedLessThan);
+        return VisitFloat32Compare(selector, value, cont);
+      case IrOpcode::kFloat32LessThanOrEqual:
+        cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
+        return VisitFloat32Compare(selector, value, cont);
       case IrOpcode::kFloat64Equal:
-        cont->OverwriteAndNegateIfEqual(kUnorderedEqual);
+        cont->OverwriteAndNegateIfEqual(kEqual);
         return VisitFloat64Compare(selector, value, cont);
       case IrOpcode::kFloat64LessThan:
-        cont->OverwriteAndNegateIfEqual(kUnorderedLessThan);
+        cont->OverwriteAndNegateIfEqual(kUnsignedLessThan);
         return VisitFloat64Compare(selector, value, cont);
       case IrOpcode::kFloat64LessThanOrEqual:
-        cont->OverwriteAndNegateIfEqual(kUnorderedLessThanOrEqual);
+        cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
         return VisitFloat64Compare(selector, value, cont);
       case IrOpcode::kProjection:
         // Check if this is the overflow output projection of an
         // <Operation>WithOverflow node.
-        if (OpParameter<size_t>(value) == 1u) {
+        if (ProjectionIndexOf(value->op()) == 1u) {
           // We cannot combine the <Operation>WithOverflow with this branch
           // unless the 0th projection (the use of the actual value of the
-          // <Operation> is either NULL, which means there's no use of the
+          // <Operation> is either nullptr, which means there's no use of the
           // actual value, or was already defined, which means it is scheduled
           // *AFTER* this branch).
-          Node* node = value->InputAt(0);
-          Node* result = node->FindProjection(0);
-          if (result == NULL || selector->IsDefined(result)) {
+          Node* const node = value->InputAt(0);
+          Node* const result = NodeProperties::FindProjection(node, 0);
+          if (result == nullptr || selector->IsDefined(result)) {
             switch (node->opcode()) {
               case IrOpcode::kInt32AddWithOverflow:
                 cont->OverwriteAndNegateIfEqual(kOverflow);
@@ -936,6 +1608,12 @@
               case IrOpcode::kInt32SubWithOverflow:
                 cont->OverwriteAndNegateIfEqual(kOverflow);
                 return VisitBinop(selector, node, kMips64Dsub, cont);
+              case IrOpcode::kInt64AddWithOverflow:
+                cont->OverwriteAndNegateIfEqual(kOverflow);
+                return VisitBinop(selector, node, kMips64DaddOvf, cont);
+              case IrOpcode::kInt64SubWithOverflow:
+                cont->OverwriteAndNegateIfEqual(kOverflow);
+                return VisitBinop(selector, node, kMips64DsubOvf, cont);
               default:
                 break;
             }
@@ -943,7 +1621,6 @@
         }
         break;
       case IrOpcode::kWord32And:
-        return VisitWordCompare(selector, value, kMips64Tst32, cont, true);
       case IrOpcode::kWord64And:
         return VisitWordCompare(selector, value, kMips64Tst, cont, true);
       default:
@@ -953,7 +1630,7 @@
   }
 
   // Continuation could not be combined with a compare, emit compare against 0.
-  EmitWordCompareZero(selector, opcode, value, cont);
+  EmitWordCompareZero(selector, value, cont);
 }
 
 
@@ -964,6 +1641,34 @@
 }
 
 
+void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) {
+  Mips64OperandGenerator g(this);
+  InstructionOperand value_operand = g.UseRegister(node->InputAt(0));
+
+  // Emit either ArchTableSwitch or ArchLookupSwitch.
+  size_t table_space_cost = 10 + 2 * sw.value_range;
+  size_t table_time_cost = 3;
+  size_t lookup_space_cost = 2 + 2 * sw.case_count;
+  size_t lookup_time_cost = sw.case_count;
+  if (sw.case_count > 0 &&
+      table_space_cost + 3 * table_time_cost <=
+          lookup_space_cost + 3 * lookup_time_cost &&
+      sw.min_value > std::numeric_limits<int32_t>::min()) {
+    InstructionOperand index_operand = value_operand;
+    if (sw.min_value) {
+      index_operand = g.TempRegister();
+      Emit(kMips64Sub, index_operand, value_operand,
+           g.TempImmediate(sw.min_value));
+    }
+    // Generate a table lookup.
+    return EmitTableSwitch(sw, index_operand);
+  }
+
+  // Generate a sequence of conditional jumps.
+  return EmitLookupSwitch(sw, value_operand);
+}
+
+
 void InstructionSelector::VisitWord32Equal(Node* const node) {
   FlagsContinuation cont(kEqual, node);
   Int32BinopMatcher m(node);
@@ -1000,7 +1705,7 @@
 
 
 void InstructionSelector::VisitInt32AddWithOverflow(Node* node) {
-  if (Node* ovf = node->FindProjection(1)) {
+  if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
     FlagsContinuation cont(kOverflow, ovf);
     return VisitBinop(this, node, kMips64Dadd, &cont);
   }
@@ -1010,7 +1715,7 @@
 
 
 void InstructionSelector::VisitInt32SubWithOverflow(Node* node) {
-  if (Node* ovf = node->FindProjection(1)) {
+  if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
     FlagsContinuation cont(kOverflow, ovf);
     return VisitBinop(this, node, kMips64Dsub, &cont);
   }
@@ -1019,6 +1724,26 @@
 }
 
 
+void InstructionSelector::VisitInt64AddWithOverflow(Node* node) {
+  if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
+    FlagsContinuation cont(kOverflow, ovf);
+    return VisitBinop(this, node, kMips64DaddOvf, &cont);
+  }
+  FlagsContinuation cont;
+  VisitBinop(this, node, kMips64DaddOvf, &cont);
+}
+
+
+void InstructionSelector::VisitInt64SubWithOverflow(Node* node) {
+  if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
+    FlagsContinuation cont(kOverflow, ovf);
+    return VisitBinop(this, node, kMips64DsubOvf, &cont);
+  }
+  FlagsContinuation cont;
+  VisitBinop(this, node, kMips64DsubOvf, &cont);
+}
+
+
 void InstructionSelector::VisitWord64Equal(Node* const node) {
   FlagsContinuation cont(kEqual, node);
   Int64BinopMatcher m(node);
@@ -1048,30 +1773,94 @@
 }
 
 
+void InstructionSelector::VisitUint64LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kUnsignedLessThanOrEqual, node);
+  VisitWord64Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitFloat32Equal(Node* node) {
+  FlagsContinuation cont(kEqual, node);
+  VisitFloat32Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitFloat32LessThan(Node* node) {
+  FlagsContinuation cont(kUnsignedLessThan, node);
+  VisitFloat32Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitFloat32LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kUnsignedLessThanOrEqual, node);
+  VisitFloat32Compare(this, node, &cont);
+}
+
+
 void InstructionSelector::VisitFloat64Equal(Node* node) {
-  FlagsContinuation cont(kUnorderedEqual, node);
+  FlagsContinuation cont(kEqual, node);
   VisitFloat64Compare(this, node, &cont);
 }
 
 
 void InstructionSelector::VisitFloat64LessThan(Node* node) {
-  FlagsContinuation cont(kUnorderedLessThan, node);
+  FlagsContinuation cont(kUnsignedLessThan, node);
   VisitFloat64Compare(this, node, &cont);
 }
 
 
 void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
-  FlagsContinuation cont(kUnorderedLessThanOrEqual, node);
+  FlagsContinuation cont(kUnsignedLessThanOrEqual, node);
   VisitFloat64Compare(this, node, &cont);
 }
 
 
+void InstructionSelector::VisitFloat64ExtractLowWord32(Node* node) {
+  VisitRR(this, kMips64Float64ExtractLowWord32, node);
+}
+
+
+void InstructionSelector::VisitFloat64ExtractHighWord32(Node* node) {
+  VisitRR(this, kMips64Float64ExtractHighWord32, node);
+}
+
+
+void InstructionSelector::VisitFloat64InsertLowWord32(Node* node) {
+  Mips64OperandGenerator g(this);
+  Node* left = node->InputAt(0);
+  Node* right = node->InputAt(1);
+  Emit(kMips64Float64InsertLowWord32, g.DefineSameAsFirst(node),
+       g.UseRegister(left), g.UseRegister(right));
+}
+
+
+void InstructionSelector::VisitFloat64InsertHighWord32(Node* node) {
+  Mips64OperandGenerator g(this);
+  Node* left = node->InputAt(0);
+  Node* right = node->InputAt(1);
+  Emit(kMips64Float64InsertHighWord32, g.DefineSameAsFirst(node),
+       g.UseRegister(left), g.UseRegister(right));
+}
+
+
 // static
 MachineOperatorBuilder::Flags
 InstructionSelector::SupportedMachineOperatorFlags() {
-  return MachineOperatorBuilder::kFloat64Floor |
-         MachineOperatorBuilder::kFloat64Ceil |
-         MachineOperatorBuilder::kFloat64RoundTruncate;
+  return MachineOperatorBuilder::kWord32ShiftIsSafe |
+         MachineOperatorBuilder::kInt32DivIsSafe |
+         MachineOperatorBuilder::kUint32DivIsSafe |
+         MachineOperatorBuilder::kFloat64Min |
+         MachineOperatorBuilder::kFloat64Max |
+         MachineOperatorBuilder::kFloat32Min |
+         MachineOperatorBuilder::kFloat32Max |
+         MachineOperatorBuilder::kFloat64RoundDown |
+         MachineOperatorBuilder::kFloat32RoundDown |
+         MachineOperatorBuilder::kFloat64RoundUp |
+         MachineOperatorBuilder::kFloat32RoundUp |
+         MachineOperatorBuilder::kFloat64RoundTruncate |
+         MachineOperatorBuilder::kFloat32RoundTruncate |
+         MachineOperatorBuilder::kFloat64RoundTiesEven |
+         MachineOperatorBuilder::kFloat32RoundTiesEven;
 }
 
 }  // namespace compiler
diff --git a/src/compiler/mips64/linkage-mips64.cc b/src/compiler/mips64/linkage-mips64.cc
deleted file mode 100644
index 0e1a590..0000000
--- a/src/compiler/mips64/linkage-mips64.cc
+++ /dev/null
@@ -1,67 +0,0 @@
-// 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/v8.h"
-
-#include "src/assembler.h"
-#include "src/code-stubs.h"
-#include "src/compiler/linkage.h"
-#include "src/compiler/linkage-impl.h"
-#include "src/zone.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-struct MipsLinkageHelperTraits {
-  static Register ReturnValueReg() { return v0; }
-  static Register ReturnValue2Reg() { return v1; }
-  static Register JSCallFunctionReg() { return a1; }
-  static Register ContextReg() { return cp; }
-  static Register RuntimeCallFunctionReg() { return a1; }
-  static Register RuntimeCallArgCountReg() { return a0; }
-  static RegList CCalleeSaveRegisters() {
-    return s0.bit() | s1.bit() | s2.bit() | s3.bit() | s4.bit() | s5.bit() |
-           s6.bit() | s7.bit();
-  }
-  static Register CRegisterParameter(int i) {
-    static Register register_parameters[] = {a0, a1, a2, a3, a4, a5, a6, a7};
-    return register_parameters[i];
-  }
-  static int CRegisterParametersLength() { return 8; }
-};
-
-
-typedef LinkageHelper<MipsLinkageHelperTraits> LH;
-
-CallDescriptor* Linkage::GetJSCallDescriptor(int parameter_count, Zone* zone,
-                                             CallDescriptor::Flags flags) {
-  return LH::GetJSCallDescriptor(zone, parameter_count, flags);
-}
-
-
-CallDescriptor* Linkage::GetRuntimeCallDescriptor(
-    Runtime::FunctionId function, int parameter_count,
-    Operator::Properties properties, Zone* zone) {
-  return LH::GetRuntimeCallDescriptor(zone, function, parameter_count,
-                                      properties);
-}
-
-
-CallDescriptor* Linkage::GetStubCallDescriptor(
-    const CallInterfaceDescriptor& descriptor, int stack_parameter_count,
-    CallDescriptor::Flags flags, Operator::Properties properties, Zone* zone) {
-  return LH::GetStubCallDescriptor(zone, descriptor, stack_parameter_count,
-                                   flags, properties);
-}
-
-
-CallDescriptor* Linkage::GetSimplifiedCDescriptor(Zone* zone,
-                                                  MachineSignature* sig) {
-  return LH::GetSimplifiedCDescriptor(zone, sig);
-}
-
-}  // namespace compiler
-}  // namespace internal
-}  // namespace v8
diff --git a/src/compiler/move-optimizer.cc b/src/compiler/move-optimizer.cc
index 330f32f..bde3f7f 100644
--- a/src/compiler/move-optimizer.cc
+++ b/src/compiler/move-optimizer.cc
@@ -8,196 +8,342 @@
 namespace internal {
 namespace compiler {
 
+namespace {
+
+typedef std::pair<InstructionOperand, InstructionOperand> MoveKey;
+
+struct MoveKeyCompare {
+  bool operator()(const MoveKey& a, const MoveKey& b) const {
+    if (a.first.EqualsCanonicalized(b.first)) {
+      return a.second.CompareCanonicalized(b.second);
+    }
+    return a.first.CompareCanonicalized(b.first);
+  }
+};
+
+struct OperandCompare {
+  bool operator()(const InstructionOperand& a,
+                  const InstructionOperand& b) const {
+    return a.CompareCanonicalized(b);
+  }
+};
+
+typedef ZoneMap<MoveKey, unsigned, MoveKeyCompare> MoveMap;
+typedef ZoneSet<InstructionOperand, CompareOperandModuloType> OperandSet;
+
+
+bool GapsCanMoveOver(Instruction* instr, Zone* zone) {
+  if (instr->IsNop()) return true;
+  if (instr->ClobbersTemps() || instr->ClobbersRegisters() ||
+      instr->ClobbersDoubleRegisters()) {
+    return false;
+  }
+  if (instr->arch_opcode() != ArchOpcode::kArchNop) return false;
+
+  ZoneSet<InstructionOperand, OperandCompare> operands(zone);
+  for (size_t i = 0; i < instr->InputCount(); ++i) {
+    operands.insert(*instr->InputAt(i));
+  }
+  for (size_t i = 0; i < instr->OutputCount(); ++i) {
+    operands.insert(*instr->OutputAt(i));
+  }
+  for (size_t i = 0; i < instr->TempCount(); ++i) {
+    operands.insert(*instr->TempAt(i));
+  }
+  for (int i = Instruction::GapPosition::FIRST_GAP_POSITION;
+       i <= Instruction::GapPosition::LAST_GAP_POSITION; ++i) {
+    ParallelMove* moves = instr->parallel_moves()[i];
+    if (moves == nullptr) continue;
+    for (MoveOperands* move : *moves) {
+      if (operands.count(move->source()) > 0 ||
+          operands.count(move->destination()) > 0) {
+        return false;
+      }
+    }
+  }
+  return true;
+}
+
+
+int FindFirstNonEmptySlot(const Instruction* instr) {
+  int i = Instruction::FIRST_GAP_POSITION;
+  for (; i <= Instruction::LAST_GAP_POSITION; i++) {
+    ParallelMove* moves = instr->parallel_moves()[i];
+    if (moves == nullptr) continue;
+    for (MoveOperands* move : *moves) {
+      if (!move->IsRedundant()) return i;
+      move->Eliminate();
+    }
+    moves->clear();  // Clear this redundant move.
+  }
+  return i;
+}
+
+}  // namespace
+
+
 MoveOptimizer::MoveOptimizer(Zone* local_zone, InstructionSequence* code)
     : local_zone_(local_zone),
       code_(code),
-      temp_vector_0_(local_zone),
-      temp_vector_1_(local_zone) {}
+      to_finalize_(local_zone),
+      local_vector_(local_zone) {}
 
 
 void MoveOptimizer::Run() {
-  // First smash all consecutive moves into the left most move slot.
-  for (auto* block : code()->instruction_blocks()) {
-    GapInstruction* prev_gap = nullptr;
-    for (int index = block->code_start(); index < block->code_end(); ++index) {
-      auto instr = code()->instructions()[index];
-      if (!instr->IsGapMoves()) {
-        if (instr->IsSourcePosition() || instr->IsNop()) continue;
-        FinalizeMoves(&temp_vector_0_, &temp_vector_1_, prev_gap);
-        prev_gap = nullptr;
-        continue;
-      }
-      auto gap = GapInstruction::cast(instr);
-      // Find first non-empty slot.
-      int i = GapInstruction::FIRST_INNER_POSITION;
-      for (; i <= GapInstruction::LAST_INNER_POSITION; i++) {
-        auto move = gap->parallel_moves()[i];
-        if (move == nullptr) continue;
-        auto move_ops = move->move_operands();
-        auto op = move_ops->begin();
-        for (; op != move_ops->end(); ++op) {
-          if (!op->IsRedundant()) break;
-        }
-        if (op == move_ops->end()) {
-          move_ops->Rewind(0);  // Clear this redundant move.
-        } else {
-          break;  // Found index of first non-redundant move.
+  for (InstructionBlock* block : code()->instruction_blocks()) {
+    CompressBlock(block);
+  }
+  for (InstructionBlock* block : code()->instruction_blocks()) {
+    if (block->PredecessorCount() <= 1) continue;
+    if (!block->IsDeferred()) {
+      bool has_only_deferred = true;
+      for (RpoNumber& pred_id : block->predecessors()) {
+        if (!code()->InstructionBlockAt(pred_id)->IsDeferred()) {
+          has_only_deferred = false;
+          break;
         }
       }
-      // Nothing to do here.
-      if (i == GapInstruction::LAST_INNER_POSITION + 1) {
-        if (prev_gap != nullptr) {
-          // Slide prev_gap down so we always know where to look for it.
-          std::swap(prev_gap->parallel_moves()[0], gap->parallel_moves()[0]);
-          prev_gap = gap;
-        }
-        continue;
-      }
-      // Move the first non-empty gap to position 0.
-      std::swap(gap->parallel_moves()[0], gap->parallel_moves()[i]);
-      auto left = gap->parallel_moves()[0];
-      // Compress everything into position 0.
-      for (++i; i <= GapInstruction::LAST_INNER_POSITION; ++i) {
-        auto move = gap->parallel_moves()[i];
-        if (move == nullptr) continue;
-        CompressMoves(&temp_vector_0_, left, move);
-      }
-      if (prev_gap != nullptr) {
-        // Smash left into prev_gap, killing left.
-        auto pred_moves = prev_gap->parallel_moves()[0];
-        CompressMoves(&temp_vector_0_, pred_moves, left);
-        std::swap(prev_gap->parallel_moves()[0], gap->parallel_moves()[0]);
-      }
-      prev_gap = gap;
+      // This would pull down common moves. If the moves occur in deferred
+      // blocks, and the closest common successor is not deferred, we lose the
+      // optimization of just spilling/filling in deferred blocks, when the
+      // current block is not deferred.
+      if (has_only_deferred) continue;
     }
-    FinalizeMoves(&temp_vector_0_, &temp_vector_1_, prev_gap);
+    OptimizeMerge(block);
+  }
+  for (Instruction* gap : to_finalize_) {
+    FinalizeMoves(gap);
   }
 }
 
 
-static MoveOperands* PrepareInsertAfter(ParallelMove* left, MoveOperands* move,
-                                        Zone* zone) {
-  auto move_ops = left->move_operands();
-  MoveOperands* replacement = nullptr;
-  MoveOperands* to_eliminate = nullptr;
-  for (auto curr = move_ops->begin(); curr != move_ops->end(); ++curr) {
-    if (curr->IsEliminated()) continue;
-    if (curr->destination()->Equals(move->source())) {
-      DCHECK_EQ(nullptr, replacement);
-      replacement = curr;
-      if (to_eliminate != nullptr) break;
-    } else if (curr->destination()->Equals(move->destination())) {
-      DCHECK_EQ(nullptr, to_eliminate);
-      to_eliminate = curr;
-      if (replacement != nullptr) break;
-    }
-  }
-  DCHECK(!(replacement == to_eliminate && replacement != nullptr));
-  if (replacement != nullptr) {
-    auto new_source = new (zone) InstructionOperand(
-        replacement->source()->kind(), replacement->source()->index());
-    move->set_source(new_source);
-  }
-  return to_eliminate;
-}
+void MoveOptimizer::CompressMoves(ParallelMove* left, ParallelMove* right) {
+  if (right == nullptr) return;
 
+  MoveOpVector& eliminated = local_vector();
+  DCHECK(eliminated.empty());
 
-void MoveOptimizer::CompressMoves(MoveOpVector* eliminated, ParallelMove* left,
-                                  ParallelMove* right) {
-  DCHECK(eliminated->empty());
-  auto move_ops = right->move_operands();
-  // Modify the right moves in place and collect moves that will be killed by
-  // merging the two gaps.
-  for (auto op = move_ops->begin(); op != move_ops->end(); ++op) {
-    if (op->IsRedundant()) continue;
-    MoveOperands* to_eliminate = PrepareInsertAfter(left, op, code_zone());
-    if (to_eliminate != nullptr) {
-      eliminated->push_back(to_eliminate);
+  if (!left->empty()) {
+    // Modify the right moves in place and collect moves that will be killed by
+    // merging the two gaps.
+    for (MoveOperands* move : *right) {
+      if (move->IsRedundant()) continue;
+      MoveOperands* to_eliminate = left->PrepareInsertAfter(move);
+      if (to_eliminate != nullptr) eliminated.push_back(to_eliminate);
     }
+    // Eliminate dead moves.
+    for (MoveOperands* to_eliminate : eliminated) {
+      to_eliminate->Eliminate();
+    }
+    eliminated.clear();
   }
-  // Eliminate dead moves.  Must happen before insertion of new moves as the
-  // contents of eliminated are pointers into a list.
-  for (auto to_eliminate : *eliminated) {
-    to_eliminate->Eliminate();
-  }
-  eliminated->clear();
   // Add all possibly modified moves from right side.
-  for (auto op = move_ops->begin(); op != move_ops->end(); ++op) {
-    if (op->IsRedundant()) continue;
-    left->move_operands()->Add(*op, code_zone());
+  for (MoveOperands* move : *right) {
+    if (move->IsRedundant()) continue;
+    left->push_back(move);
   }
   // Nuke right.
-  move_ops->Rewind(0);
+  right->clear();
+  DCHECK(eliminated.empty());
 }
 
 
-void MoveOptimizer::FinalizeMoves(MoveOpVector* loads, MoveOpVector* new_moves,
-                                  GapInstruction* gap) {
-  DCHECK(loads->empty());
-  DCHECK(new_moves->empty());
-  if (gap == nullptr) return;
-  // Split multiple loads of the same constant or stack slot off into the second
-  // slot and keep remaining moves in the first slot.
-  auto move_ops = gap->parallel_moves()[0]->move_operands();
-  for (auto move = move_ops->begin(); move != move_ops->end(); ++move) {
-    if (move->IsRedundant()) {
-      move->Eliminate();
-      continue;
+// Smash all consecutive moves into the left most move slot and accumulate them
+// as much as possible across instructions.
+void MoveOptimizer::CompressBlock(InstructionBlock* block) {
+  Instruction* prev_instr = nullptr;
+  for (int index = block->code_start(); index < block->code_end(); ++index) {
+    Instruction* instr = code()->instructions()[index];
+    int i = FindFirstNonEmptySlot(instr);
+    bool has_moves = i <= Instruction::LAST_GAP_POSITION;
+
+    if (i == Instruction::LAST_GAP_POSITION) {
+      std::swap(instr->parallel_moves()[Instruction::FIRST_GAP_POSITION],
+                instr->parallel_moves()[Instruction::LAST_GAP_POSITION]);
+    } else if (i == Instruction::FIRST_GAP_POSITION) {
+      CompressMoves(instr->parallel_moves()[Instruction::FIRST_GAP_POSITION],
+                    instr->parallel_moves()[Instruction::LAST_GAP_POSITION]);
     }
-    if (!(move->source()->IsConstant() || move->source()->IsStackSlot() ||
-          move->source()->IsDoubleStackSlot()))
-      continue;
-    // Search for existing move to this slot.
-    MoveOperands* found = nullptr;
-    for (auto load : *loads) {
-      if (load->source()->Equals(move->source())) {
-        found = load;
-        break;
+    // We either have no moves, or, after swapping or compressing, we have
+    // all the moves in the first gap position, and none in the second/end gap
+    // position.
+    ParallelMove* first =
+        instr->parallel_moves()[Instruction::FIRST_GAP_POSITION];
+    ParallelMove* last =
+        instr->parallel_moves()[Instruction::LAST_GAP_POSITION];
+    USE(last);
+
+    DCHECK(!has_moves ||
+           (first != nullptr && (last == nullptr || last->empty())));
+
+    if (prev_instr != nullptr) {
+      if (has_moves) {
+        // Smash first into prev_instr, killing left.
+        ParallelMove* pred_moves = prev_instr->parallel_moves()[0];
+        CompressMoves(pred_moves, first);
+      }
+      // Slide prev_instr down so we always know where to look for it.
+      std::swap(prev_instr->parallel_moves()[0], instr->parallel_moves()[0]);
+    }
+
+    prev_instr = instr->parallel_moves()[0] == nullptr ? nullptr : instr;
+    if (GapsCanMoveOver(instr, local_zone())) continue;
+    if (prev_instr != nullptr) {
+      to_finalize_.push_back(prev_instr);
+      prev_instr = nullptr;
+    }
+  }
+  if (prev_instr != nullptr) {
+    to_finalize_.push_back(prev_instr);
+  }
+}
+
+
+const Instruction* MoveOptimizer::LastInstruction(
+    const InstructionBlock* block) const {
+  return code()->instructions()[block->last_instruction_index()];
+}
+
+
+void MoveOptimizer::OptimizeMerge(InstructionBlock* block) {
+  DCHECK(block->PredecessorCount() > 1);
+  // Ensure that the last instruction in all incoming blocks don't contain
+  // things that would prevent moving gap moves across them.
+  for (RpoNumber& pred_index : block->predecessors()) {
+    const InstructionBlock* pred = code()->InstructionBlockAt(pred_index);
+    const Instruction* last_instr =
+        code()->instructions()[pred->last_instruction_index()];
+    if (last_instr->IsCall()) return;
+    if (last_instr->TempCount() != 0) return;
+    if (last_instr->OutputCount() != 0) return;
+    for (size_t i = 0; i < last_instr->InputCount(); ++i) {
+      const InstructionOperand* op = last_instr->InputAt(i);
+      if (!op->IsConstant() && !op->IsImmediate()) return;
+    }
+  }
+  // TODO(dcarney): pass a ZonePool down for this?
+  MoveMap move_map(local_zone());
+  size_t correct_counts = 0;
+  // Accumulate set of shared moves.
+  for (RpoNumber& pred_index : block->predecessors()) {
+    const InstructionBlock* pred = code()->InstructionBlockAt(pred_index);
+    const Instruction* instr = LastInstruction(pred);
+    if (instr->parallel_moves()[0] == nullptr ||
+        instr->parallel_moves()[0]->empty()) {
+      return;
+    }
+    for (const MoveOperands* move : *instr->parallel_moves()[0]) {
+      if (move->IsRedundant()) continue;
+      InstructionOperand src = move->source();
+      InstructionOperand dst = move->destination();
+      MoveKey key = {src, dst};
+      auto res = move_map.insert(std::make_pair(key, 1));
+      if (!res.second) {
+        res.first->second++;
+        if (res.first->second == block->PredecessorCount()) {
+          correct_counts++;
+        }
       }
     }
-    // Not found so insert.
-    if (found == nullptr) {
-      loads->push_back(move);
-      // Replace source with copy for later use.
-      auto dest = move->destination();
-      move->set_destination(new (code_zone())
-                            InstructionOperand(dest->kind(), dest->index()));
+  }
+  if (move_map.empty() || correct_counts != move_map.size()) return;
+  // Find insertion point.
+  Instruction* instr = nullptr;
+  for (int i = block->first_instruction_index();
+       i <= block->last_instruction_index(); ++i) {
+    instr = code()->instructions()[i];
+    if (!GapsCanMoveOver(instr, local_zone()) || !instr->AreMovesRedundant())
+      break;
+  }
+  DCHECK_NOT_NULL(instr);
+  bool gap_initialized = true;
+  if (instr->parallel_moves()[0] == nullptr ||
+      instr->parallel_moves()[0]->empty()) {
+    to_finalize_.push_back(instr);
+  } else {
+    // Will compress after insertion.
+    gap_initialized = false;
+    std::swap(instr->parallel_moves()[0], instr->parallel_moves()[1]);
+  }
+  ParallelMove* moves = instr->GetOrCreateParallelMove(
+      static_cast<Instruction::GapPosition>(0), code_zone());
+  // Delete relevant entries in predecessors and move everything to block.
+  bool first_iteration = true;
+  for (RpoNumber& pred_index : block->predecessors()) {
+    const InstructionBlock* pred = code()->InstructionBlockAt(pred_index);
+    for (MoveOperands* move : *LastInstruction(pred)->parallel_moves()[0]) {
+      if (move->IsRedundant()) continue;
+      MoveKey key = {move->source(), move->destination()};
+      auto it = move_map.find(key);
+      USE(it);
+      DCHECK(it != move_map.end());
+      if (first_iteration) {
+        moves->AddMove(move->source(), move->destination());
+      }
+      move->Eliminate();
+    }
+    first_iteration = false;
+  }
+  // Compress.
+  if (!gap_initialized) {
+    CompressMoves(instr->parallel_moves()[0], instr->parallel_moves()[1]);
+  }
+}
+
+
+namespace {
+
+bool IsSlot(const InstructionOperand& op) {
+  return op.IsStackSlot() || op.IsDoubleStackSlot();
+}
+
+
+bool LoadCompare(const MoveOperands* a, const MoveOperands* b) {
+  if (!a->source().EqualsCanonicalized(b->source())) {
+    return a->source().CompareCanonicalized(b->source());
+  }
+  if (IsSlot(a->destination()) && !IsSlot(b->destination())) return false;
+  if (!IsSlot(a->destination()) && IsSlot(b->destination())) return true;
+  return a->destination().CompareCanonicalized(b->destination());
+}
+
+}  // namespace
+
+
+// Split multiple loads of the same constant or stack slot off into the second
+// slot and keep remaining moves in the first slot.
+void MoveOptimizer::FinalizeMoves(Instruction* instr) {
+  MoveOpVector& loads = local_vector();
+  DCHECK(loads.empty());
+
+  // Find all the loads.
+  for (MoveOperands* move : *instr->parallel_moves()[0]) {
+    if (move->IsRedundant()) continue;
+    if (move->source().IsConstant() || IsSlot(move->source())) {
+      loads.push_back(move);
+    }
+  }
+  if (loads.empty()) return;
+  // Group the loads by source, moving the preferred destination to the
+  // beginning of the group.
+  std::sort(loads.begin(), loads.end(), LoadCompare);
+  MoveOperands* group_begin = nullptr;
+  for (MoveOperands* load : loads) {
+    // New group.
+    if (group_begin == nullptr ||
+        !load->source().EqualsCanonicalized(group_begin->source())) {
+      group_begin = load;
       continue;
     }
-    if ((found->destination()->IsStackSlot() ||
-         found->destination()->IsDoubleStackSlot()) &&
-        !(move->destination()->IsStackSlot() ||
-          move->destination()->IsDoubleStackSlot())) {
-      // Found a better source for this load.  Smash it in place to affect other
-      // loads that have already been split.
-      InstructionOperand::Kind found_kind = found->destination()->kind();
-      int found_index = found->destination()->index();
-      auto next_dest =
-          new (code_zone()) InstructionOperand(found_kind, found_index);
-      auto dest = move->destination();
-      found->destination()->ConvertTo(dest->kind(), dest->index());
-      move->set_destination(next_dest);
-    }
-    // move from load destination.
-    move->set_source(found->destination());
-    new_moves->push_back(move);
+    // Nothing to be gained from splitting here.
+    if (IsSlot(group_begin->destination())) continue;
+    // Insert new move into slot 1.
+    ParallelMove* slot_1 = instr->GetOrCreateParallelMove(
+        static_cast<Instruction::GapPosition>(1), code_zone());
+    slot_1->AddMove(group_begin->destination(), load->destination());
+    load->Eliminate();
   }
-  loads->clear();
-  if (new_moves->empty()) return;
-  // Insert all new moves into slot 1.
-  auto slot_1 = gap->GetOrCreateParallelMove(
-      static_cast<GapInstruction::InnerPosition>(1), code_zone());
-  DCHECK(slot_1->move_operands()->is_empty());
-  slot_1->move_operands()->AddBlock(MoveOperands(nullptr, nullptr),
-                                    static_cast<int>(new_moves->size()),
-                                    code_zone());
-  auto it = slot_1->move_operands()->begin();
-  for (auto new_move : *new_moves) {
-    std::swap(*new_move, *it);
-    ++it;
-  }
-  DCHECK_EQ(it, slot_1->move_operands()->end());
-  new_moves->clear();
+  loads.clear();
 }
 
 }  // namespace compiler
diff --git a/src/compiler/move-optimizer.h b/src/compiler/move-optimizer.h
index bbce686..c9a3289 100644
--- a/src/compiler/move-optimizer.h
+++ b/src/compiler/move-optimizer.h
@@ -12,27 +12,30 @@
 namespace internal {
 namespace compiler {
 
-class MoveOptimizer FINAL {
+class MoveOptimizer final {
  public:
   MoveOptimizer(Zone* local_zone, InstructionSequence* code);
   void Run();
 
  private:
   typedef ZoneVector<MoveOperands*> MoveOpVector;
+  typedef ZoneVector<Instruction*> Instructions;
 
   InstructionSequence* code() const { return code_; }
   Zone* local_zone() const { return local_zone_; }
   Zone* code_zone() const { return code()->zone(); }
+  MoveOpVector& local_vector() { return local_vector_; }
 
-  void CompressMoves(MoveOpVector* eliminated, ParallelMove* left,
-                     ParallelMove* right);
-  void FinalizeMoves(MoveOpVector* loads, MoveOpVector* new_moves,
-                     GapInstruction* gap);
+  void CompressBlock(InstructionBlock* blocke);
+  void CompressMoves(ParallelMove* left, ParallelMove* right);
+  const Instruction* LastInstruction(const InstructionBlock* block) const;
+  void OptimizeMerge(InstructionBlock* block);
+  void FinalizeMoves(Instruction* instr);
 
   Zone* const local_zone_;
   InstructionSequence* const code_;
-  MoveOpVector temp_vector_0_;
-  MoveOpVector temp_vector_1_;
+  Instructions to_finalize_;
+  MoveOpVector local_vector_;
 
   DISALLOW_COPY_AND_ASSIGN(MoveOptimizer);
 };
diff --git a/src/compiler/node-aux-data-inl.h b/src/compiler/node-aux-data-inl.h
deleted file mode 100644
index d8db4b9..0000000
--- a/src/compiler/node-aux-data-inl.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// 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.
-
-#ifndef V8_COMPILER_NODE_AUX_DATA_INL_H_
-#define V8_COMPILER_NODE_AUX_DATA_INL_H_
-
-#include "src/compiler/graph.h"
-#include "src/compiler/node.h"
-#include "src/compiler/node-aux-data.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-template <class T>
-NodeAuxData<T>::NodeAuxData(Zone* zone)
-    : aux_data_(zone) {}
-
-
-template <class T>
-void NodeAuxData<T>::Set(Node* node, const T& data) {
-  int id = node->id();
-  if (id >= static_cast<int>(aux_data_.size())) {
-    aux_data_.resize(id + 1);
-  }
-  aux_data_[id] = data;
-}
-
-
-template <class T>
-T NodeAuxData<T>::Get(Node* node) const {
-  int id = node->id();
-  if (id >= static_cast<int>(aux_data_.size())) {
-    return T();
-  }
-  return aux_data_[id];
-}
-}
-}
-}  // namespace v8::internal::compiler
-
-#endif
diff --git a/src/compiler/node-aux-data.h b/src/compiler/node-aux-data.h
index a08dc58..7a88292 100644
--- a/src/compiler/node-aux-data.h
+++ b/src/compiler/node-aux-data.h
@@ -5,6 +5,7 @@
 #ifndef V8_COMPILER_NODE_AUX_DATA_H_
 #define V8_COMPILER_NODE_AUX_DATA_H_
 
+#include "src/compiler/node.h"
 #include "src/zone-containers.h"
 
 namespace v8 {
@@ -12,22 +13,81 @@
 namespace compiler {
 
 // Forward declarations.
-class Graph;
 class Node;
 
 template <class T>
 class NodeAuxData {
  public:
-  inline explicit NodeAuxData(Zone* zone);
+  explicit NodeAuxData(Zone* zone) : aux_data_(zone) {}
 
-  inline void Set(Node* node, const T& data);
-  inline T Get(Node* node) const;
+  void Set(Node* node, T const& data) {
+    size_t const id = node->id();
+    if (id >= aux_data_.size()) aux_data_.resize(id + 1);
+    aux_data_[id] = data;
+  }
+
+  T Get(Node* node) const {
+    size_t const id = node->id();
+    return (id < aux_data_.size()) ? aux_data_[id] : T();
+  }
+
+  class const_iterator;
+  friend class const_iterator;
+
+  const_iterator begin() const;
+  const_iterator end() const;
 
  private:
   ZoneVector<T> aux_data_;
 };
-}
-}
-}  // namespace v8::internal::compiler
 
-#endif
+
+template <class T>
+class NodeAuxData<T>::const_iterator {
+ public:
+  typedef std::forward_iterator_tag iterator_category;
+  typedef int difference_type;
+  typedef std::pair<size_t, T> value_type;
+  typedef value_type* pointer;
+  typedef value_type& reference;
+
+  const_iterator(const ZoneVector<T>* data, size_t current)
+      : data_(data), current_(current) {}
+  const_iterator(const const_iterator& other)
+      : data_(other.data_), current_(other.current_) {}
+
+  value_type operator*() const {
+    return std::make_pair(current_, (*data_)[current_]);
+  }
+  bool operator==(const const_iterator& other) const {
+    return current_ == other.current_ && data_ == other.data_;
+  }
+  bool operator!=(const const_iterator& other) const {
+    return !(*this == other);
+  }
+  const_iterator& operator++() {
+    ++current_;
+    return *this;
+  }
+  const_iterator operator++(int);
+
+ private:
+  const ZoneVector<T>* data_;
+  size_t current_;
+};
+
+template <class T>
+typename NodeAuxData<T>::const_iterator NodeAuxData<T>::begin() const {
+  return typename NodeAuxData<T>::const_iterator(&aux_data_, 0);
+}
+
+template <class T>
+typename NodeAuxData<T>::const_iterator NodeAuxData<T>::end() const {
+  return typename NodeAuxData<T>::const_iterator(&aux_data_, aux_data_.size());
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_NODE_AUX_DATA_H_
diff --git a/src/compiler/node-cache.cc b/src/compiler/node-cache.cc
index 92a3fa0..79c342b 100644
--- a/src/compiler/node-cache.cc
+++ b/src/compiler/node-cache.cc
@@ -36,7 +36,7 @@
   size_t old_size = size_ + kLinearProbe;
   size_ *= 4;
   size_t num_entries = size_ + kLinearProbe;
-  entries_ = zone->NewArray<Entry>(static_cast<int>(num_entries));
+  entries_ = zone->NewArray<Entry>(num_entries);
   memset(entries_, 0, sizeof(Entry) * num_entries);
 
   // Insert the old entries into the new block.
@@ -66,7 +66,7 @@
   if (!entries_) {
     // Allocate the initial entries and insert the first entry.
     size_t num_entries = kInitialSize + kLinearProbe;
-    entries_ = zone->NewArray<Entry>(static_cast<int>(num_entries));
+    entries_ = zone->NewArray<Entry>(num_entries);
     size_ = kInitialSize;
     memset(entries_, 0, sizeof(Entry) * num_entries);
     Entry* entry = &entries_[hash & (kInitialSize - 1)];
diff --git a/src/compiler/node-cache.h b/src/compiler/node-cache.h
index b123922..a8f9071 100644
--- a/src/compiler/node-cache.h
+++ b/src/compiler/node-cache.h
@@ -27,7 +27,7 @@
 // nodes such as constants, parameters, etc.
 template <typename Key, typename Hash = base::hash<Key>,
           typename Pred = std::equal_to<Key> >
-class NodeCache FINAL {
+class NodeCache final {
  public:
   explicit NodeCache(unsigned max = 256)
       : entries_(nullptr), size_(0), max_(max) {}
@@ -35,7 +35,8 @@
 
   // Search for node associated with {key} and return a pointer to a memory
   // location in this cache that stores an entry for the key. If the location
-  // returned by this method contains a non-NULL node, the caller can use that
+  // returned by this method contains a non-nullptr node, the caller can use
+  // that
   // node. Otherwise it is the responsibility of the caller to fill the entry
   // with a new node.
   // Note that a previous cache entry may be overwritten if the cache becomes
diff --git a/src/compiler/node-marker.cc b/src/compiler/node-marker.cc
new file mode 100644
index 0000000..fdfb22b
--- /dev/null
+++ b/src/compiler/node-marker.cc
@@ -0,0 +1,21 @@
+// Copyright 2015 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/node-marker.h"
+
+#include "src/compiler/graph.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+NodeMarkerBase::NodeMarkerBase(Graph* graph, uint32_t num_states)
+    : mark_min_(graph->mark_max_), mark_max_(graph->mark_max_ += num_states) {
+  DCHECK_NE(0u, num_states);        // user error!
+  DCHECK_LT(mark_min_, mark_max_);  // check for wraparound.
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/node-marker.h b/src/compiler/node-marker.h
new file mode 100644
index 0000000..5ef2063
--- /dev/null
+++ b/src/compiler/node-marker.h
@@ -0,0 +1,67 @@
+// Copyright 2015 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.
+
+#ifndef V8_COMPILER_NODE_MARKER_H_
+#define V8_COMPILER_NODE_MARKER_H_
+
+#include "src/compiler/node.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+// Forward declarations.
+class Graph;
+
+
+// Base class for templatized NodeMarkers.
+class NodeMarkerBase {
+ public:
+  NodeMarkerBase(Graph* graph, uint32_t num_states);
+
+  V8_INLINE Mark Get(Node* node) {
+    Mark mark = node->mark();
+    if (mark < mark_min_) {
+      mark = mark_min_;
+      node->set_mark(mark_min_);
+    }
+    DCHECK_LT(mark, mark_max_);
+    return mark - mark_min_;
+  }
+  V8_INLINE void Set(Node* node, Mark mark) {
+    DCHECK_LT(mark, mark_max_ - mark_min_);
+    DCHECK_LT(node->mark(), mark_max_);
+    node->set_mark(mark + mark_min_);
+  }
+
+ private:
+  Mark const mark_min_;
+  Mark const mark_max_;
+
+  DISALLOW_COPY_AND_ASSIGN(NodeMarkerBase);
+};
+
+
+// A NodeMarker uses monotonically increasing marks to assign local "states"
+// to nodes. Only one NodeMarker per graph is valid at a given time.
+template <typename State>
+class NodeMarker : public NodeMarkerBase {
+ public:
+  V8_INLINE NodeMarker(Graph* graph, uint32_t num_states)
+      : NodeMarkerBase(graph, num_states) {}
+
+  V8_INLINE State Get(Node* node) {
+    return static_cast<State>(NodeMarkerBase::Get(node));
+  }
+
+  V8_INLINE void Set(Node* node, State state) {
+    NodeMarkerBase::Set(node, static_cast<Mark>(state));
+  }
+};
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_NODE_MARKER_H_
diff --git a/src/compiler/node-matchers.cc b/src/compiler/node-matchers.cc
new file mode 100644
index 0000000..1627b88
--- /dev/null
+++ b/src/compiler/node-matchers.cc
@@ -0,0 +1,60 @@
+// Copyright 2015 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/node-matchers.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+bool NodeMatcher::IsComparison() const {
+  return IrOpcode::IsComparisonOpcode(opcode());
+}
+
+
+BranchMatcher::BranchMatcher(Node* branch)
+    : NodeMatcher(branch), if_true_(nullptr), if_false_(nullptr) {
+  if (branch->opcode() != IrOpcode::kBranch) return;
+  for (Node* use : branch->uses()) {
+    if (use->opcode() == IrOpcode::kIfTrue) {
+      DCHECK_NULL(if_true_);
+      if_true_ = use;
+    } else if (use->opcode() == IrOpcode::kIfFalse) {
+      DCHECK_NULL(if_false_);
+      if_false_ = use;
+    }
+  }
+}
+
+
+DiamondMatcher::DiamondMatcher(Node* merge)
+    : NodeMatcher(merge),
+      branch_(nullptr),
+      if_true_(nullptr),
+      if_false_(nullptr) {
+  if (merge->InputCount() != 2) return;
+  if (merge->opcode() != IrOpcode::kMerge) return;
+  Node* input0 = merge->InputAt(0);
+  if (input0->InputCount() != 1) return;
+  Node* input1 = merge->InputAt(1);
+  if (input1->InputCount() != 1) return;
+  Node* branch = input0->InputAt(0);
+  if (branch != input1->InputAt(0)) return;
+  if (branch->opcode() != IrOpcode::kBranch) return;
+  if (input0->opcode() == IrOpcode::kIfTrue &&
+      input1->opcode() == IrOpcode::kIfFalse) {
+    branch_ = branch;
+    if_true_ = input0;
+    if_false_ = input1;
+  } else if (input0->opcode() == IrOpcode::kIfFalse &&
+             input1->opcode() == IrOpcode::kIfTrue) {
+    branch_ = branch;
+    if_true_ = input1;
+    if_false_ = input0;
+  }
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/node-matchers.h b/src/compiler/node-matchers.h
index fc11a0a..37d0e1a 100644
--- a/src/compiler/node-matchers.h
+++ b/src/compiler/node-matchers.h
@@ -7,9 +7,10 @@
 
 #include <cmath>
 
+// TODO(turbofan): Move ExternalReference out of assembler.h
+#include "src/assembler.h"
 #include "src/compiler/node.h"
 #include "src/compiler/operator.h"
-#include "src/unique.h"
 
 namespace v8 {
 namespace internal {
@@ -28,6 +29,10 @@
   }
   Node* InputAt(int index) const { return node()->InputAt(index); }
 
+  bool Equals(const Node* node) const { return node_ == node; }
+
+  bool IsComparison() const;
+
 #define DEFINE_IS_OPCODE(Opcode) \
   bool Is##Opcode() const { return opcode() == IrOpcode::k##Opcode; }
   ALL_OP_LIST(DEFINE_IS_OPCODE)
@@ -56,14 +61,6 @@
     return value_;
   }
 
-  bool Is(const T& value) const {
-    return this->HasValue() && this->Value() == value;
-  }
-
-  bool IsInRange(const T& low, const T& high) const {
-    return this->HasValue() && low <= this->Value() && this->Value() <= high;
-  }
-
  private:
   T value_;
   bool has_value_;
@@ -71,6 +68,18 @@
 
 
 template <>
+inline ValueMatcher<uint32_t, IrOpcode::kInt32Constant>::ValueMatcher(
+    Node* node)
+    : NodeMatcher(node),
+      value_(),
+      has_value_(opcode() == IrOpcode::kInt32Constant) {
+  if (has_value_) {
+    value_ = static_cast<uint32_t>(OpParameter<int32_t>(node));
+  }
+}
+
+
+template <>
 inline ValueMatcher<int64_t, IrOpcode::kInt64Constant>::ValueMatcher(Node* node)
     : NodeMatcher(node), value_(), has_value_(false) {
   if (opcode() == IrOpcode::kInt32Constant) {
@@ -88,10 +97,10 @@
     Node* node)
     : NodeMatcher(node), value_(), has_value_(false) {
   if (opcode() == IrOpcode::kInt32Constant) {
-    value_ = OpParameter<uint32_t>(node);
+    value_ = static_cast<uint32_t>(OpParameter<int32_t>(node));
     has_value_ = true;
   } else if (opcode() == IrOpcode::kInt64Constant) {
-    value_ = OpParameter<uint64_t>(node);
+    value_ = static_cast<uint64_t>(OpParameter<int64_t>(node));
     has_value_ = true;
   }
 }
@@ -99,9 +108,15 @@
 
 // A pattern matcher for integer constants.
 template <typename T, IrOpcode::Value kOpcode>
-struct IntMatcher FINAL : public ValueMatcher<T, kOpcode> {
+struct IntMatcher final : public ValueMatcher<T, kOpcode> {
   explicit IntMatcher(Node* node) : ValueMatcher<T, kOpcode>(node) {}
 
+  bool Is(const T& value) const {
+    return this->HasValue() && this->Value() == value;
+  }
+  bool IsInRange(const T& low, const T& high) const {
+    return this->HasValue() && low <= this->Value() && this->Value() <= high;
+  }
   bool IsMultipleOf(T n) const {
     return this->HasValue() && (this->Value() % n) == 0;
   }
@@ -130,13 +145,20 @@
 
 // A pattern matcher for floating point constants.
 template <typename T, IrOpcode::Value kOpcode>
-struct FloatMatcher FINAL : public ValueMatcher<T, kOpcode> {
+struct FloatMatcher final : public ValueMatcher<T, kOpcode> {
   explicit FloatMatcher(Node* node) : ValueMatcher<T, kOpcode>(node) {}
 
+  bool Is(const T& value) const {
+    return this->HasValue() && this->Value() == value;
+  }
+  bool IsInRange(const T& low, const T& high) const {
+    return this->HasValue() && low <= this->Value() && this->Value() <= high;
+  }
   bool IsMinusZero() const {
     return this->Is(0.0) && std::signbit(this->Value());
   }
   bool IsNaN() const { return this->HasValue() && std::isnan(this->Value()); }
+  bool IsZero() const { return this->Is(0.0) && !std::signbit(this->Value()); }
 };
 
 typedef FloatMatcher<float, IrOpcode::kFloat32Constant> Float32Matcher;
@@ -145,11 +167,39 @@
 
 
 // A pattern matcher for heap object constants.
-template <typename T>
-struct HeapObjectMatcher FINAL
-    : public ValueMatcher<Unique<T>, IrOpcode::kHeapConstant> {
+struct HeapObjectMatcher final
+    : public ValueMatcher<Handle<HeapObject>, IrOpcode::kHeapConstant> {
   explicit HeapObjectMatcher(Node* node)
-      : ValueMatcher<Unique<T>, IrOpcode::kHeapConstant>(node) {}
+      : ValueMatcher<Handle<HeapObject>, IrOpcode::kHeapConstant>(node) {}
+};
+
+
+// A pattern matcher for external reference constants.
+struct ExternalReferenceMatcher final
+    : public ValueMatcher<ExternalReference, IrOpcode::kExternalConstant> {
+  explicit ExternalReferenceMatcher(Node* node)
+      : ValueMatcher<ExternalReference, IrOpcode::kExternalConstant>(node) {}
+  bool Is(const ExternalReference& value) const {
+    return this->HasValue() && this->Value() == value;
+  }
+};
+
+
+// For shorter pattern matching code, this struct matches the inputs to
+// machine-level load operations.
+template <typename Object>
+struct LoadMatcher : public NodeMatcher {
+  explicit LoadMatcher(Node* node)
+      : NodeMatcher(node), object_(InputAt(0)), index_(InputAt(1)) {}
+
+  typedef Object ObjectMatcher;
+
+  Object const& object() const { return object_; }
+  IntPtrMatcher const& index() const { return index_; }
+
+ private:
+  Object const object_;
+  IntPtrMatcher const index_;
 };
 
 
@@ -200,6 +250,7 @@
 typedef BinopMatcher<Uint64Matcher, Uint64Matcher> Uint64BinopMatcher;
 typedef BinopMatcher<IntPtrMatcher, IntPtrMatcher> IntPtrBinopMatcher;
 typedef BinopMatcher<UintPtrMatcher, UintPtrMatcher> UintPtrBinopMatcher;
+typedef BinopMatcher<Float32Matcher, Float32Matcher> Float32BinopMatcher;
 typedef BinopMatcher<Float64Matcher, Float64Matcher> Float64BinopMatcher;
 typedef BinopMatcher<NumberMatcher, NumberMatcher> NumberBinopMatcher;
 
@@ -333,19 +384,19 @@
 struct BaseWithIndexAndDisplacementMatcher {
   BaseWithIndexAndDisplacementMatcher(Node* node, bool allow_input_swap)
       : matches_(false),
-        index_(NULL),
+        index_(nullptr),
         scale_(0),
-        base_(NULL),
-        displacement_(NULL) {
+        base_(nullptr),
+        displacement_(nullptr) {
     Initialize(node, allow_input_swap);
   }
 
   explicit BaseWithIndexAndDisplacementMatcher(Node* node)
       : matches_(false),
-        index_(NULL),
+        index_(nullptr),
         scale_(0),
-        base_(NULL),
-        displacement_(NULL) {
+        base_(nullptr),
+        displacement_(nullptr) {
     Initialize(node, node->op()->HasProperty(Operator::kCommutative));
   }
 
@@ -383,10 +434,10 @@
     AddMatcher m(node, allow_input_swap);
     Node* left = m.left().node();
     Node* right = m.right().node();
-    Node* displacement = NULL;
-    Node* base = NULL;
-    Node* index = NULL;
-    Node* scale_expression = NULL;
+    Node* displacement = nullptr;
+    Node* base = nullptr;
+    Node* index = nullptr;
+    Node* scale_expression = nullptr;
     bool power_of_two_plus_one = false;
     int scale = 0;
     if (m.HasIndexInput() && left->OwnedBy(node)) {
@@ -468,7 +519,7 @@
       }
     }
     int64_t value = 0;
-    if (displacement != NULL) {
+    if (displacement != nullptr) {
       switch (displacement->opcode()) {
         case IrOpcode::kInt32Constant: {
           value = OpParameter<int32_t>(displacement);
@@ -483,11 +534,11 @@
           break;
       }
       if (value == 0) {
-        displacement = NULL;
+        displacement = nullptr;
       }
     }
     if (power_of_two_plus_one) {
-      if (base != NULL) {
+      if (base != nullptr) {
         // If the scale requires explicitly using the index as the base, but a
         // base is already part of the match, then the (1 << N + 1) scale factor
         // can't be folded into the match and the entire index * scale
@@ -511,6 +562,54 @@
 typedef BaseWithIndexAndDisplacementMatcher<Int64AddMatcher>
     BaseWithIndexAndDisplacement64Matcher;
 
+struct BranchMatcher : public NodeMatcher {
+  explicit BranchMatcher(Node* branch);
+
+  bool Matched() const { return if_true_ && if_false_; }
+
+  Node* Branch() const { return node(); }
+  Node* IfTrue() const { return if_true_; }
+  Node* IfFalse() const { return if_false_; }
+
+ private:
+  Node* if_true_;
+  Node* if_false_;
+};
+
+
+struct DiamondMatcher : public NodeMatcher {
+  explicit DiamondMatcher(Node* merge);
+
+  bool Matched() const { return branch_; }
+  bool IfProjectionsAreOwned() const {
+    return if_true_->OwnedBy(node()) && if_false_->OwnedBy(node());
+  }
+
+  Node* Branch() const { return branch_; }
+  Node* IfTrue() const { return if_true_; }
+  Node* IfFalse() const { return if_false_; }
+  Node* Merge() const { return node(); }
+
+  Node* TrueInputOf(Node* phi) const {
+    DCHECK(IrOpcode::IsPhiOpcode(phi->opcode()));
+    DCHECK_EQ(3, phi->InputCount());
+    DCHECK_EQ(Merge(), phi->InputAt(2));
+    return phi->InputAt(if_true_ == Merge()->InputAt(0) ? 0 : 1);
+  }
+
+  Node* FalseInputOf(Node* phi) const {
+    DCHECK(IrOpcode::IsPhiOpcode(phi->opcode()));
+    DCHECK_EQ(3, phi->InputCount());
+    DCHECK_EQ(Merge(), phi->InputAt(2));
+    return phi->InputAt(if_true_ == Merge()->InputAt(0) ? 1 : 0);
+  }
+
+ private:
+  Node* branch_;
+  Node* if_true_;
+  Node* if_false_;
+};
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/src/compiler/node-properties-inl.h b/src/compiler/node-properties-inl.h
deleted file mode 100644
index 0d29614..0000000
--- a/src/compiler/node-properties-inl.h
+++ /dev/null
@@ -1,226 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef V8_COMPILER_NODE_PROPERTIES_INL_H_
-#define V8_COMPILER_NODE_PROPERTIES_INL_H_
-
-#include "src/v8.h"
-
-#include "src/compiler/common-operator.h"
-#include "src/compiler/node-properties.h"
-#include "src/compiler/opcodes.h"
-#include "src/compiler/operator.h"
-#include "src/compiler/operator-properties.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-// -----------------------------------------------------------------------------
-// Input layout.
-// Inputs are always arranged in order as follows:
-//     0 [ values, context, effects, control ] node->InputCount()
-
-inline int NodeProperties::FirstValueIndex(Node* node) { return 0; }
-
-inline int NodeProperties::FirstContextIndex(Node* node) {
-  return PastValueIndex(node);
-}
-
-inline int NodeProperties::FirstFrameStateIndex(Node* node) {
-  return PastContextIndex(node);
-}
-
-inline int NodeProperties::FirstEffectIndex(Node* node) {
-  return PastFrameStateIndex(node);
-}
-
-inline int NodeProperties::FirstControlIndex(Node* node) {
-  return PastEffectIndex(node);
-}
-
-
-inline int NodeProperties::PastValueIndex(Node* node) {
-  return FirstValueIndex(node) + node->op()->ValueInputCount();
-}
-
-inline int NodeProperties::PastContextIndex(Node* node) {
-  return FirstContextIndex(node) +
-         OperatorProperties::GetContextInputCount(node->op());
-}
-
-inline int NodeProperties::PastFrameStateIndex(Node* node) {
-  return FirstFrameStateIndex(node) +
-         OperatorProperties::GetFrameStateInputCount(node->op());
-}
-
-inline int NodeProperties::PastEffectIndex(Node* node) {
-  return FirstEffectIndex(node) + node->op()->EffectInputCount();
-}
-
-inline int NodeProperties::PastControlIndex(Node* node) {
-  return FirstControlIndex(node) + node->op()->ControlInputCount();
-}
-
-
-// -----------------------------------------------------------------------------
-// Input accessors.
-
-inline Node* NodeProperties::GetValueInput(Node* node, int index) {
-  DCHECK(0 <= index && index < node->op()->ValueInputCount());
-  return node->InputAt(FirstValueIndex(node) + index);
-}
-
-inline Node* NodeProperties::GetContextInput(Node* node) {
-  DCHECK(OperatorProperties::HasContextInput(node->op()));
-  return node->InputAt(FirstContextIndex(node));
-}
-
-inline Node* NodeProperties::GetFrameStateInput(Node* node) {
-  DCHECK(OperatorProperties::HasFrameStateInput(node->op()));
-  return node->InputAt(FirstFrameStateIndex(node));
-}
-
-inline Node* NodeProperties::GetEffectInput(Node* node, int index) {
-  DCHECK(0 <= index && index < node->op()->EffectInputCount());
-  return node->InputAt(FirstEffectIndex(node) + index);
-}
-
-inline Node* NodeProperties::GetControlInput(Node* node, int index) {
-  DCHECK(0 <= index && index < node->op()->ControlInputCount());
-  return node->InputAt(FirstControlIndex(node) + index);
-}
-
-inline int NodeProperties::GetFrameStateIndex(Node* node) {
-  DCHECK(OperatorProperties::HasFrameStateInput(node->op()));
-  return FirstFrameStateIndex(node);
-}
-
-// -----------------------------------------------------------------------------
-// Edge kinds.
-
-inline bool NodeProperties::IsInputRange(Edge edge, int first, int num) {
-  // TODO(titzer): edge.index() is linear time;
-  // edges maybe need to be marked as value/effect/control.
-  if (num == 0) return false;
-  int index = edge.index();
-  return first <= index && index < first + num;
-}
-
-inline bool NodeProperties::IsValueEdge(Edge edge) {
-  Node* node = edge.from();
-  return IsInputRange(edge, FirstValueIndex(node),
-                      node->op()->ValueInputCount());
-}
-
-inline bool NodeProperties::IsContextEdge(Edge edge) {
-  Node* node = edge.from();
-  return IsInputRange(edge, FirstContextIndex(node),
-                      OperatorProperties::GetContextInputCount(node->op()));
-}
-
-inline bool NodeProperties::IsEffectEdge(Edge edge) {
-  Node* node = edge.from();
-  return IsInputRange(edge, FirstEffectIndex(node),
-                      node->op()->EffectInputCount());
-}
-
-inline bool NodeProperties::IsControlEdge(Edge edge) {
-  Node* node = edge.from();
-  return IsInputRange(edge, FirstControlIndex(node),
-                      node->op()->ControlInputCount());
-}
-
-
-// -----------------------------------------------------------------------------
-// Miscellaneous predicates.
-
-inline bool NodeProperties::IsControl(Node* node) {
-  return IrOpcode::IsControlOpcode(node->opcode());
-}
-
-
-// -----------------------------------------------------------------------------
-// Miscellaneous mutators.
-
-inline void NodeProperties::ReplaceControlInput(Node* node, Node* control) {
-  node->ReplaceInput(FirstControlIndex(node), control);
-}
-
-inline void NodeProperties::ReplaceEffectInput(Node* node, Node* effect,
-                                               int index) {
-  DCHECK(index < node->op()->EffectInputCount());
-  return node->ReplaceInput(FirstEffectIndex(node) + index, effect);
-}
-
-inline void NodeProperties::ReplaceFrameStateInput(Node* node,
-                                                   Node* frame_state) {
-  DCHECK(OperatorProperties::HasFrameStateInput(node->op()));
-  node->ReplaceInput(FirstFrameStateIndex(node), frame_state);
-}
-
-inline void NodeProperties::RemoveNonValueInputs(Node* node) {
-  node->TrimInputCount(node->op()->ValueInputCount());
-}
-
-
-// Replace value uses of {node} with {value} and effect uses of {node} with
-// {effect}. If {effect == NULL}, then use the effect input to {node}.
-inline void NodeProperties::ReplaceWithValue(Node* node, Node* value,
-                                             Node* effect) {
-  DCHECK(node->op()->ControlOutputCount() == 0);
-  if (effect == NULL && node->op()->EffectInputCount() > 0) {
-    effect = NodeProperties::GetEffectInput(node);
-  }
-
-  // Requires distinguishing between value and effect edges.
-  for (Edge edge : node->use_edges()) {
-    if (NodeProperties::IsEffectEdge(edge)) {
-      DCHECK_NE(NULL, effect);
-      edge.UpdateTo(effect);
-    } else {
-      edge.UpdateTo(value);
-    }
-  }
-}
-
-
-// -----------------------------------------------------------------------------
-// Type Bounds.
-
-inline bool NodeProperties::IsTyped(Node* node) {
-  Bounds bounds = node->bounds();
-  DCHECK((bounds.lower == NULL) == (bounds.upper == NULL));
-  return bounds.upper != NULL;
-}
-
-inline Bounds NodeProperties::GetBounds(Node* node) {
-  DCHECK(IsTyped(node));
-  return node->bounds();
-}
-
-inline void NodeProperties::RemoveBounds(Node* node) {
-  Bounds empty;
-  node->set_bounds(empty);
-}
-
-inline void NodeProperties::SetBounds(Node* node, Bounds b) {
-  DCHECK(b.lower != NULL && b.upper != NULL);
-  node->set_bounds(b);
-}
-
-inline bool NodeProperties::AllValueInputsAreTyped(Node* node) {
-  int input_count = node->op()->ValueInputCount();
-  for (int i = 0; i < input_count; ++i) {
-    if (!IsTyped(GetValueInput(node, i))) return false;
-  }
-  return true;
-}
-
-
-}
-}
-}  // namespace v8::internal::compiler
-
-#endif  // V8_COMPILER_NODE_PROPERTIES_INL_H_
diff --git a/src/compiler/node-properties.cc b/src/compiler/node-properties.cc
new file mode 100644
index 0000000..cb6c3c4
--- /dev/null
+++ b/src/compiler/node-properties.cc
@@ -0,0 +1,416 @@
+// Copyright 2015 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/common-operator.h"
+#include "src/compiler/graph.h"
+#include "src/compiler/linkage.h"
+#include "src/compiler/node-properties.h"
+#include "src/compiler/operator-properties.h"
+#include "src/compiler/verifier.h"
+#include "src/types-inl.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+// static
+int NodeProperties::PastValueIndex(Node* node) {
+  return FirstValueIndex(node) + node->op()->ValueInputCount();
+}
+
+
+// static
+int NodeProperties::PastContextIndex(Node* node) {
+  return FirstContextIndex(node) +
+         OperatorProperties::GetContextInputCount(node->op());
+}
+
+
+// static
+int NodeProperties::PastFrameStateIndex(Node* node) {
+  return FirstFrameStateIndex(node) +
+         OperatorProperties::GetFrameStateInputCount(node->op());
+}
+
+
+// static
+int NodeProperties::PastEffectIndex(Node* node) {
+  return FirstEffectIndex(node) + node->op()->EffectInputCount();
+}
+
+
+// static
+int NodeProperties::PastControlIndex(Node* node) {
+  return FirstControlIndex(node) + node->op()->ControlInputCount();
+}
+
+
+// static
+Node* NodeProperties::GetValueInput(Node* node, int index) {
+  DCHECK(0 <= index && index < node->op()->ValueInputCount());
+  return node->InputAt(FirstValueIndex(node) + index);
+}
+
+
+// static
+Node* NodeProperties::GetContextInput(Node* node) {
+  DCHECK(OperatorProperties::HasContextInput(node->op()));
+  return node->InputAt(FirstContextIndex(node));
+}
+
+
+// static
+Node* NodeProperties::GetFrameStateInput(Node* node, int index) {
+  DCHECK_LT(index, OperatorProperties::GetFrameStateInputCount(node->op()));
+  return node->InputAt(FirstFrameStateIndex(node) + index);
+}
+
+
+// static
+Node* NodeProperties::GetEffectInput(Node* node, int index) {
+  DCHECK(0 <= index && index < node->op()->EffectInputCount());
+  return node->InputAt(FirstEffectIndex(node) + index);
+}
+
+
+// static
+Node* NodeProperties::GetControlInput(Node* node, int index) {
+  DCHECK(0 <= index && index < node->op()->ControlInputCount());
+  return node->InputAt(FirstControlIndex(node) + index);
+}
+
+
+// static
+bool NodeProperties::IsValueEdge(Edge edge) {
+  Node* const node = edge.from();
+  return IsInputRange(edge, FirstValueIndex(node),
+                      node->op()->ValueInputCount());
+}
+
+
+// static
+bool NodeProperties::IsContextEdge(Edge edge) {
+  Node* const node = edge.from();
+  return IsInputRange(edge, FirstContextIndex(node),
+                      OperatorProperties::GetContextInputCount(node->op()));
+}
+
+
+// static
+bool NodeProperties::IsFrameStateEdge(Edge edge) {
+  Node* const node = edge.from();
+  return IsInputRange(edge, FirstFrameStateIndex(node),
+                      OperatorProperties::GetFrameStateInputCount(node->op()));
+}
+
+
+// static
+bool NodeProperties::IsEffectEdge(Edge edge) {
+  Node* const node = edge.from();
+  return IsInputRange(edge, FirstEffectIndex(node),
+                      node->op()->EffectInputCount());
+}
+
+
+// static
+bool NodeProperties::IsControlEdge(Edge edge) {
+  Node* const node = edge.from();
+  return IsInputRange(edge, FirstControlIndex(node),
+                      node->op()->ControlInputCount());
+}
+
+
+// static
+bool NodeProperties::IsExceptionalCall(Node* node) {
+  for (Edge const edge : node->use_edges()) {
+    if (!NodeProperties::IsControlEdge(edge)) continue;
+    if (edge.from()->opcode() == IrOpcode::kIfException) return true;
+  }
+  return false;
+}
+
+
+// static
+void NodeProperties::ReplaceValueInput(Node* node, Node* value, int index) {
+  DCHECK(index < node->op()->ValueInputCount());
+  node->ReplaceInput(FirstValueIndex(node) + index, value);
+}
+
+
+// static
+void NodeProperties::ReplaceValueInputs(Node* node, Node* value) {
+  int value_input_count = node->op()->ValueInputCount();
+  DCHECK_LE(1, value_input_count);
+  node->ReplaceInput(0, value);
+  while (--value_input_count > 0) {
+    node->RemoveInput(value_input_count);
+  }
+}
+
+
+// static
+void NodeProperties::ReplaceContextInput(Node* node, Node* context) {
+  node->ReplaceInput(FirstContextIndex(node), context);
+}
+
+
+// static
+void NodeProperties::ReplaceControlInput(Node* node, Node* control) {
+  node->ReplaceInput(FirstControlIndex(node), control);
+}
+
+
+// static
+void NodeProperties::ReplaceEffectInput(Node* node, Node* effect, int index) {
+  DCHECK(index < node->op()->EffectInputCount());
+  return node->ReplaceInput(FirstEffectIndex(node) + index, effect);
+}
+
+
+// static
+void NodeProperties::ReplaceFrameStateInput(Node* node, int index,
+                                            Node* frame_state) {
+  DCHECK_LT(index, OperatorProperties::GetFrameStateInputCount(node->op()));
+  node->ReplaceInput(FirstFrameStateIndex(node) + index, frame_state);
+}
+
+
+// static
+void NodeProperties::RemoveFrameStateInput(Node* node, int index) {
+  DCHECK_LT(index, OperatorProperties::GetFrameStateInputCount(node->op()));
+  node->RemoveInput(FirstFrameStateIndex(node) + index);
+}
+
+
+// static
+void NodeProperties::RemoveNonValueInputs(Node* node) {
+  node->TrimInputCount(node->op()->ValueInputCount());
+}
+
+
+// static
+void NodeProperties::RemoveValueInputs(Node* node) {
+  int value_input_count = node->op()->ValueInputCount();
+  while (--value_input_count >= 0) {
+    node->RemoveInput(value_input_count);
+  }
+}
+
+
+void NodeProperties::MergeControlToEnd(Graph* graph,
+                                       CommonOperatorBuilder* common,
+                                       Node* node) {
+  graph->end()->AppendInput(graph->zone(), node);
+  graph->end()->set_op(common->End(graph->end()->InputCount()));
+}
+
+
+// static
+void NodeProperties::ReplaceUses(Node* node, Node* value, Node* effect,
+                                 Node* success, Node* exception) {
+  // Requires distinguishing between value, effect and control edges.
+  for (Edge edge : node->use_edges()) {
+    if (IsControlEdge(edge)) {
+      if (edge.from()->opcode() == IrOpcode::kIfSuccess) {
+        DCHECK_NOT_NULL(success);
+        edge.UpdateTo(success);
+      } else if (edge.from()->opcode() == IrOpcode::kIfException) {
+        DCHECK_NOT_NULL(exception);
+        edge.UpdateTo(exception);
+      } else {
+        UNREACHABLE();
+      }
+    } else if (IsEffectEdge(edge)) {
+      DCHECK_NOT_NULL(effect);
+      edge.UpdateTo(effect);
+    } else {
+      DCHECK_NOT_NULL(value);
+      edge.UpdateTo(value);
+    }
+  }
+}
+
+
+// static
+void NodeProperties::ChangeOp(Node* node, const Operator* new_op) {
+  node->set_op(new_op);
+  Verifier::VerifyNode(node);
+}
+
+
+// static
+Node* NodeProperties::FindProjection(Node* node, size_t projection_index) {
+  for (auto use : node->uses()) {
+    if (use->opcode() == IrOpcode::kProjection &&
+        ProjectionIndexOf(use->op()) == projection_index) {
+      return use;
+    }
+  }
+  return nullptr;
+}
+
+
+// static
+void NodeProperties::CollectControlProjections(Node* node, Node** projections,
+                                               size_t projection_count) {
+#ifdef DEBUG
+  DCHECK_LE(static_cast<int>(projection_count), node->UseCount());
+  std::memset(projections, 0, sizeof(*projections) * projection_count);
+#endif
+  size_t if_value_index = 0;
+  for (Edge const edge : node->use_edges()) {
+    if (!IsControlEdge(edge)) continue;
+    Node* use = edge.from();
+    size_t index;
+    switch (use->opcode()) {
+      case IrOpcode::kIfTrue:
+        DCHECK_EQ(IrOpcode::kBranch, node->opcode());
+        index = 0;
+        break;
+      case IrOpcode::kIfFalse:
+        DCHECK_EQ(IrOpcode::kBranch, node->opcode());
+        index = 1;
+        break;
+      case IrOpcode::kIfSuccess:
+        DCHECK(!node->op()->HasProperty(Operator::kNoThrow));
+        index = 0;
+        break;
+      case IrOpcode::kIfException:
+        DCHECK(!node->op()->HasProperty(Operator::kNoThrow));
+        index = 1;
+        break;
+      case IrOpcode::kIfValue:
+        DCHECK_EQ(IrOpcode::kSwitch, node->opcode());
+        index = if_value_index++;
+        break;
+      case IrOpcode::kIfDefault:
+        DCHECK_EQ(IrOpcode::kSwitch, node->opcode());
+        index = projection_count - 1;
+        break;
+      default:
+        continue;
+    }
+    DCHECK_LT(if_value_index, projection_count);
+    DCHECK_LT(index, projection_count);
+    DCHECK_NULL(projections[index]);
+    projections[index] = use;
+  }
+#ifdef DEBUG
+  for (size_t index = 0; index < projection_count; ++index) {
+    DCHECK_NOT_NULL(projections[index]);
+  }
+#endif
+}
+
+
+// static
+MaybeHandle<Context> NodeProperties::GetSpecializationContext(
+    Node* node, MaybeHandle<Context> context) {
+  switch (node->opcode()) {
+    case IrOpcode::kHeapConstant:
+      return Handle<Context>::cast(OpParameter<Handle<HeapObject>>(node));
+    case IrOpcode::kParameter: {
+      Node* const start = NodeProperties::GetValueInput(node, 0);
+      DCHECK_EQ(IrOpcode::kStart, start->opcode());
+      int const index = ParameterIndexOf(node->op());
+      // The context is always the last parameter to a JavaScript function, and
+      // {Parameter} indices start at -1, so value outputs of {Start} look like
+      // this: closure, receiver, param0, ..., paramN, context.
+      if (index == start->op()->ValueOutputCount() - 2) {
+        return context;
+      }
+      break;
+    }
+    default:
+      break;
+  }
+  return MaybeHandle<Context>();
+}
+
+
+// static
+MaybeHandle<Context> NodeProperties::GetSpecializationNativeContext(
+    Node* node, MaybeHandle<Context> native_context) {
+  while (true) {
+    switch (node->opcode()) {
+      case IrOpcode::kJSCreateBlockContext:
+      case IrOpcode::kJSCreateCatchContext:
+      case IrOpcode::kJSCreateFunctionContext:
+      case IrOpcode::kJSCreateModuleContext:
+      case IrOpcode::kJSCreateScriptContext:
+      case IrOpcode::kJSCreateWithContext: {
+        // Skip over the intermediate contexts, we're only interested in the
+        // very last context in the context chain anyway.
+        node = NodeProperties::GetContextInput(node);
+        break;
+      }
+      case IrOpcode::kHeapConstant: {
+        // Extract the native context from the actual {context}.
+        Handle<Context> context =
+            Handle<Context>::cast(OpParameter<Handle<HeapObject>>(node));
+        return handle(context->native_context());
+      }
+      case IrOpcode::kOsrValue: {
+        int const index = OpParameter<int>(node);
+        if (index == Linkage::kOsrContextSpillSlotIndex) {
+          return native_context;
+        }
+        return MaybeHandle<Context>();
+      }
+      case IrOpcode::kParameter: {
+        Node* const start = NodeProperties::GetValueInput(node, 0);
+        DCHECK_EQ(IrOpcode::kStart, start->opcode());
+        int const index = ParameterIndexOf(node->op());
+        // The context is always the last parameter to a JavaScript function,
+        // and {Parameter} indices start at -1, so value outputs of {Start}
+        // look like this: closure, receiver, param0, ..., paramN, context.
+        if (index == start->op()->ValueOutputCount() - 2) {
+          return native_context;
+        }
+        return MaybeHandle<Context>();
+      }
+      default:
+        return MaybeHandle<Context>();
+    }
+  }
+}
+
+
+// static
+MaybeHandle<JSGlobalObject> NodeProperties::GetSpecializationGlobalObject(
+    Node* node, MaybeHandle<Context> native_context) {
+  Handle<Context> context;
+  if (GetSpecializationNativeContext(node, native_context).ToHandle(&context)) {
+    return handle(context->global_object());
+  }
+  return MaybeHandle<JSGlobalObject>();
+}
+
+
+// static
+Type* NodeProperties::GetTypeOrAny(Node* node) {
+  return IsTyped(node) ? node->type() : Type::Any();
+}
+
+
+// static
+bool NodeProperties::AllValueInputsAreTyped(Node* node) {
+  int input_count = node->op()->ValueInputCount();
+  for (int index = 0; index < input_count; ++index) {
+    if (!IsTyped(GetValueInput(node, index))) return false;
+  }
+  return true;
+}
+
+
+// static
+bool NodeProperties::IsInputRange(Edge edge, int first, int num) {
+  if (num == 0) return false;
+  int const index = edge.index();
+  return first <= index && index < first + num;
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/node-properties.h b/src/compiler/node-properties.h
index 025be78..58005a7 100644
--- a/src/compiler/node-properties.h
+++ b/src/compiler/node-properties.h
@@ -12,51 +12,150 @@
 namespace internal {
 namespace compiler {
 
+class Graph;
 class Operator;
+class CommonOperatorBuilder;
 
 // A facade that simplifies access to the different kinds of inputs to a node.
-class NodeProperties {
+class NodeProperties final {
  public:
-  static inline Node* GetValueInput(Node* node, int index);
-  static inline Node* GetContextInput(Node* node);
-  static inline Node* GetFrameStateInput(Node* node);
-  static inline Node* GetEffectInput(Node* node, int index = 0);
-  static inline Node* GetControlInput(Node* node, int index = 0);
+  // ---------------------------------------------------------------------------
+  // Input layout.
+  // Inputs are always arranged in order as follows:
+  //     0 [ values, context, frame state, effects, control ] node->InputCount()
 
-  static inline int GetFrameStateIndex(Node* node);
+  static int FirstValueIndex(Node* node) { return 0; }
+  static int FirstContextIndex(Node* node) { return PastValueIndex(node); }
+  static int FirstFrameStateIndex(Node* node) { return PastContextIndex(node); }
+  static int FirstEffectIndex(Node* node) { return PastFrameStateIndex(node); }
+  static int FirstControlIndex(Node* node) { return PastEffectIndex(node); }
+  static int PastValueIndex(Node* node);
+  static int PastContextIndex(Node* node);
+  static int PastFrameStateIndex(Node* node);
+  static int PastEffectIndex(Node* node);
+  static int PastControlIndex(Node* node);
 
-  static inline bool IsValueEdge(Edge edge);
-  static inline bool IsContextEdge(Edge edge);
-  static inline bool IsEffectEdge(Edge edge);
-  static inline bool IsControlEdge(Edge edge);
 
-  static inline bool IsControl(Node* node);
+  // ---------------------------------------------------------------------------
+  // Input accessors.
 
-  static inline void ReplaceControlInput(Node* node, Node* control);
-  static inline void ReplaceEffectInput(Node* node, Node* effect,
-                                        int index = 0);
-  static inline void ReplaceFrameStateInput(Node* node, Node* frame_state);
-  static inline void RemoveNonValueInputs(Node* node);
-  static inline void ReplaceWithValue(Node* node, Node* value,
-                                      Node* effect = NULL);
+  static Node* GetValueInput(Node* node, int index);
+  static Node* GetContextInput(Node* node);
+  static Node* GetFrameStateInput(Node* node, int index);
+  static Node* GetEffectInput(Node* node, int index = 0);
+  static Node* GetControlInput(Node* node, int index = 0);
 
-  static inline bool IsTyped(Node* node);
-  static inline Bounds GetBounds(Node* node);
-  static inline void SetBounds(Node* node, Bounds bounds);
-  static inline void RemoveBounds(Node* node);
-  static inline bool AllValueInputsAreTyped(Node* node);
 
-  static inline int FirstValueIndex(Node* node);
-  static inline int FirstContextIndex(Node* node);
-  static inline int FirstFrameStateIndex(Node* node);
-  static inline int FirstEffectIndex(Node* node);
-  static inline int FirstControlIndex(Node* node);
-  static inline int PastValueIndex(Node* node);
-  static inline int PastContextIndex(Node* node);
-  static inline int PastFrameStateIndex(Node* node);
-  static inline int PastEffectIndex(Node* node);
-  static inline int PastControlIndex(Node* node);
+  // ---------------------------------------------------------------------------
+  // Edge kinds.
 
+  static bool IsValueEdge(Edge edge);
+  static bool IsContextEdge(Edge edge);
+  static bool IsFrameStateEdge(Edge edge);
+  static bool IsEffectEdge(Edge edge);
+  static bool IsControlEdge(Edge edge);
+
+
+  // ---------------------------------------------------------------------------
+  // Miscellaneous predicates.
+
+  static bool IsCommon(Node* node) {
+    return IrOpcode::IsCommonOpcode(node->opcode());
+  }
+  static bool IsControl(Node* node) {
+    return IrOpcode::IsControlOpcode(node->opcode());
+  }
+  static bool IsConstant(Node* node) {
+    return IrOpcode::IsConstantOpcode(node->opcode());
+  }
+  static bool IsPhi(Node* node) {
+    return IrOpcode::IsPhiOpcode(node->opcode());
+  }
+
+  // Determines whether exceptions thrown by the given node are handled locally
+  // within the graph (i.e. an IfException projection is present).
+  static bool IsExceptionalCall(Node* node);
+
+  // ---------------------------------------------------------------------------
+  // Miscellaneous mutators.
+
+  static void ReplaceValueInput(Node* node, Node* value, int index);
+  static void ReplaceContextInput(Node* node, Node* context);
+  static void ReplaceControlInput(Node* node, Node* control);
+  static void ReplaceEffectInput(Node* node, Node* effect, int index = 0);
+  static void ReplaceFrameStateInput(Node* node, int index, Node* frame_state);
+  static void RemoveFrameStateInput(Node* node, int index);
+  static void RemoveNonValueInputs(Node* node);
+  static void RemoveValueInputs(Node* node);
+
+  // Replaces all value inputs of {node} with the single input {value}.
+  static void ReplaceValueInputs(Node* node, Node* value);
+
+  // Merge the control node {node} into the end of the graph, introducing a
+  // merge node or expanding an existing merge node if necessary.
+  static void MergeControlToEnd(Graph* graph, CommonOperatorBuilder* common,
+                                Node* node);
+
+  // Replace all uses of {node} with the given replacement nodes. All occurring
+  // use kinds need to be replaced, {nullptr} is only valid if a use kind is
+  // guaranteed not to exist.
+  static void ReplaceUses(Node* node, Node* value, Node* effect = nullptr,
+                          Node* success = nullptr, Node* exception = nullptr);
+
+  // Safe wrapper to mutate the operator of a node. Checks that the node is
+  // currently in a state that satisfies constraints of the new operator.
+  static void ChangeOp(Node* node, const Operator* new_op);
+
+  // ---------------------------------------------------------------------------
+  // Miscellaneous utilities.
+
+  static Node* FindProjection(Node* node, size_t projection_index);
+
+  // Collect the branch-related projections from a node, such as IfTrue,
+  // IfFalse, IfSuccess, IfException, IfValue and IfDefault.
+  //  - Branch: [ IfTrue, IfFalse ]
+  //  - Call  : [ IfSuccess, IfException ]
+  //  - Switch: [ IfValue, ..., IfDefault ]
+  static void CollectControlProjections(Node* node, Node** proj, size_t count);
+
+  // ---------------------------------------------------------------------------
+  // Context.
+
+  // Try to retrieve the specialization context from the given {node},
+  // optionally utilizing the knowledge about the (outermost) function
+  // {context}.
+  static MaybeHandle<Context> GetSpecializationContext(
+      Node* node, MaybeHandle<Context> context = MaybeHandle<Context>());
+
+  // Try to retrieve the specialization native context from the given
+  // {node}, optionally utilizing the knowledge about the (outermost)
+  // {native_context}.
+  static MaybeHandle<Context> GetSpecializationNativeContext(
+      Node* node, MaybeHandle<Context> native_context = MaybeHandle<Context>());
+
+  // Try to retrieve the specialization global object from the given
+  // {node}, optionally utilizing the knowledge about the (outermost)
+  // {native_context}.
+  static MaybeHandle<JSGlobalObject> GetSpecializationGlobalObject(
+      Node* node, MaybeHandle<Context> native_context = MaybeHandle<Context>());
+
+  // ---------------------------------------------------------------------------
+  // Type.
+
+  static bool IsTyped(Node* node) { return node->type() != nullptr; }
+  static Type* GetType(Node* node) {
+    DCHECK(IsTyped(node));
+    return node->type();
+  }
+  static Type* GetTypeOrAny(Node* node);
+  static void SetType(Node* node, Type* type) {
+    DCHECK_NOT_NULL(type);
+    node->set_type(type);
+  }
+  static void RemoveType(Node* node) { node->set_type(nullptr); }
+  static bool AllValueInputsAreTyped(Node* node);
+
+ private:
   static inline bool IsInputRange(Edge edge, int first, int count);
 };
 
diff --git a/src/compiler/node.cc b/src/compiler/node.cc
index 8f44c24..198c353 100644
--- a/src/compiler/node.cc
+++ b/src/compiler/node.cc
@@ -4,83 +4,235 @@
 
 #include "src/compiler/node.h"
 
-#include "src/compiler/graph.h"
-#include "src/zone.h"
-
 namespace v8 {
 namespace internal {
 namespace compiler {
 
-Node::Node(NodeId id, int input_count, int reserved_input_count)
-    : id_(id),
-      bit_field_(InputCountField::encode(input_count) |
-                 ReservedInputCountField::encode(reserved_input_count) |
-                 HasAppendableInputsField::encode(false)),
-      first_use_(nullptr),
-      last_use_(nullptr) {
-  inputs_.static_ = reinterpret_cast<Input*>(this + 1);
+Node::OutOfLineInputs* Node::OutOfLineInputs::New(Zone* zone, int capacity) {
+  size_t size =
+      sizeof(OutOfLineInputs) + capacity * (sizeof(Node*) + sizeof(Use));
+  intptr_t raw_buffer = reinterpret_cast<intptr_t>(zone->New(size));
+  Node::OutOfLineInputs* outline =
+      reinterpret_cast<OutOfLineInputs*>(raw_buffer + capacity * sizeof(Use));
+  outline->capacity_ = capacity;
+  outline->count_ = 0;
+  return outline;
 }
 
 
-Node* Node::New(Graph* graph, int input_count, Node** inputs,
-                bool has_extensible_inputs) {
-  size_t node_size = sizeof(Node);
-  int reserve_input_count = has_extensible_inputs ? kDefaultReservedInputs : 0;
-  size_t inputs_size = (input_count + reserve_input_count) * sizeof(Input);
-  size_t uses_size = input_count * sizeof(Use);
-  int size = static_cast<int>(node_size + inputs_size + uses_size);
-  Zone* zone = graph->zone();
-  void* buffer = zone->New(size);
-  Node* result =
-      new (buffer) Node(graph->NextNodeID(), input_count, reserve_input_count);
-  Input* input =
-      reinterpret_cast<Input*>(reinterpret_cast<char*>(buffer) + node_size);
-  Use* use =
-      reinterpret_cast<Use*>(reinterpret_cast<char*>(input) + inputs_size);
+void Node::OutOfLineInputs::ExtractFrom(Use* old_use_ptr, Node** old_input_ptr,
+                                        int count) {
+  // Extract the inputs from the old use and input pointers and copy them
+  // to this out-of-line-storage.
+  Use* new_use_ptr = reinterpret_cast<Use*>(this) - 1;
+  Node** new_input_ptr = inputs_;
+  for (int current = 0; current < count; current++) {
+    new_use_ptr->bit_field_ =
+        Use::InputIndexField::encode(current) | Use::InlineField::encode(false);
+    DCHECK_EQ(old_input_ptr, old_use_ptr->input_ptr());
+    DCHECK_EQ(new_input_ptr, new_use_ptr->input_ptr());
+    Node* old_to = *old_input_ptr;
+    if (old_to) {
+      *old_input_ptr = nullptr;
+      old_to->RemoveUse(old_use_ptr);
+      *new_input_ptr = old_to;
+      old_to->AppendUse(new_use_ptr);
+    } else {
+      *new_input_ptr = nullptr;
+    }
+    old_input_ptr++;
+    new_input_ptr++;
+    old_use_ptr--;
+    new_use_ptr--;
+  }
+  this->count_ = count;
+}
 
+
+Node* Node::New(Zone* zone, NodeId id, const Operator* op, int input_count,
+                Node* const* inputs, bool has_extensible_inputs) {
+  Node** input_ptr;
+  Use* use_ptr;
+  Node* node;
+  bool is_inline;
+
+#if DEBUG
+  // Verify that none of the inputs are {nullptr}.
+  for (int i = 0; i < input_count; i++) {
+    if (inputs[i] == nullptr) {
+      V8_Fatal(__FILE__, __LINE__, "Node::New() Error: #%d:%s[%d] is nullptr",
+               static_cast<int>(id), op->mnemonic(), i);
+    }
+  }
+#endif
+
+  if (input_count > kMaxInlineCapacity) {
+    // Allocate out-of-line inputs.
+    int capacity =
+        has_extensible_inputs ? input_count + kMaxInlineCapacity : input_count;
+    OutOfLineInputs* outline = OutOfLineInputs::New(zone, capacity);
+
+    // Allocate node.
+    void* node_buffer = zone->New(sizeof(Node));
+    node = new (node_buffer) Node(id, op, kOutlineMarker, 0);
+    node->inputs_.outline_ = outline;
+
+    outline->node_ = node;
+    outline->count_ = input_count;
+
+    input_ptr = outline->inputs_;
+    use_ptr = reinterpret_cast<Use*>(outline);
+    is_inline = false;
+  } else {
+    // Allocate node with inline inputs.
+    int capacity = input_count;
+    if (has_extensible_inputs) {
+      const int max = kMaxInlineCapacity;
+      capacity = std::min(input_count + 3, max);
+    }
+
+    size_t size = sizeof(Node) + capacity * (sizeof(Node*) + sizeof(Use));
+    intptr_t raw_buffer = reinterpret_cast<intptr_t>(zone->New(size));
+    void* node_buffer =
+        reinterpret_cast<void*>(raw_buffer + capacity * sizeof(Use));
+
+    node = new (node_buffer) Node(id, op, input_count, capacity);
+    input_ptr = node->inputs_.inline_;
+    use_ptr = reinterpret_cast<Use*>(node);
+    is_inline = true;
+  }
+
+  // Initialize the input pointers and the uses.
   for (int current = 0; current < input_count; ++current) {
     Node* to = *inputs++;
-    input->to = to;
-    input->use = use;
-    use->input_index = current;
-    use->from = result;
+    input_ptr[current] = to;
+    Use* use = use_ptr - 1 - current;
+    use->bit_field_ = Use::InputIndexField::encode(current) |
+                      Use::InlineField::encode(is_inline);
     to->AppendUse(use);
-    ++use;
-    ++input;
   }
-  return result;
+  node->Verify();
+  return node;
+}
+
+
+Node* Node::Clone(Zone* zone, NodeId id, const Node* node) {
+  int const input_count = node->InputCount();
+  Node* const* const inputs = node->has_inline_inputs()
+                                  ? node->inputs_.inline_
+                                  : node->inputs_.outline_->inputs_;
+  Node* const clone = New(zone, id, node->op(), input_count, inputs, false);
+  clone->set_type(node->type());
+  return clone;
 }
 
 
 void Node::Kill() {
   DCHECK_NOT_NULL(op());
-  RemoveAllInputs();
+  NullAllInputs();
   DCHECK(uses().empty());
 }
 
 
-void Node::CollectProjections(NodeVector* projections) {
-  for (size_t i = 0; i < projections->size(); i++) {
-    (*projections)[i] = NULL;
+void Node::AppendInput(Zone* zone, Node* new_to) {
+  DCHECK_NOT_NULL(zone);
+  DCHECK_NOT_NULL(new_to);
+
+  int inline_count = InlineCountField::decode(bit_field_);
+  int inline_capacity = InlineCapacityField::decode(bit_field_);
+  if (inline_count < inline_capacity) {
+    // Append inline input.
+    bit_field_ = InlineCountField::update(bit_field_, inline_count + 1);
+    *GetInputPtr(inline_count) = new_to;
+    Use* use = GetUsePtr(inline_count);
+    use->bit_field_ = Use::InputIndexField::encode(inline_count) |
+                      Use::InlineField::encode(true);
+    new_to->AppendUse(use);
+  } else {
+    // Append out-of-line input.
+    int input_count = InputCount();
+    OutOfLineInputs* outline = nullptr;
+    if (inline_count != kOutlineMarker) {
+      // switch to out of line inputs.
+      outline = OutOfLineInputs::New(zone, input_count * 2 + 3);
+      outline->node_ = this;
+      outline->ExtractFrom(GetUsePtr(0), GetInputPtr(0), input_count);
+      bit_field_ = InlineCountField::update(bit_field_, kOutlineMarker);
+      inputs_.outline_ = outline;
+    } else {
+      // use current out of line inputs.
+      outline = inputs_.outline_;
+      if (input_count >= outline->capacity_) {
+        // out of space in out-of-line inputs.
+        outline = OutOfLineInputs::New(zone, input_count * 2 + 3);
+        outline->node_ = this;
+        outline->ExtractFrom(GetUsePtr(0), GetInputPtr(0), input_count);
+        inputs_.outline_ = outline;
+      }
+    }
+    outline->count_++;
+    *GetInputPtr(input_count) = new_to;
+    Use* use = GetUsePtr(input_count);
+    use->bit_field_ = Use::InputIndexField::encode(input_count) |
+                      Use::InlineField::encode(false);
+    new_to->AppendUse(use);
   }
-  for (UseIter i = uses().begin(); i != uses().end(); ++i) {
-    if ((*i)->opcode() != IrOpcode::kProjection) continue;
-    size_t index = OpParameter<size_t>(*i);
-    DCHECK_LT(index, projections->size());
-    DCHECK_EQ(NULL, (*projections)[index]);
-    (*projections)[index] = *i;
-  }
+  Verify();
 }
 
 
-Node* Node::FindProjection(size_t projection_index) {
-  for (UseIter i = uses().begin(); i != uses().end(); ++i) {
-    if ((*i)->opcode() == IrOpcode::kProjection &&
-        OpParameter<size_t>(*i) == projection_index) {
-      return *i;
-    }
+void Node::InsertInput(Zone* zone, int index, Node* new_to) {
+  DCHECK_NOT_NULL(zone);
+  DCHECK_LE(0, index);
+  DCHECK_LT(index, InputCount());
+  AppendInput(zone, InputAt(InputCount() - 1));
+  for (int i = InputCount() - 1; i > index; --i) {
+    ReplaceInput(i, InputAt(i - 1));
   }
-  return NULL;
+  ReplaceInput(index, new_to);
+  Verify();
+}
+
+
+void Node::RemoveInput(int index) {
+  DCHECK_LE(0, index);
+  DCHECK_LT(index, InputCount());
+  for (; index < InputCount() - 1; ++index) {
+    ReplaceInput(index, InputAt(index + 1));
+  }
+  TrimInputCount(InputCount() - 1);
+  Verify();
+}
+
+
+void Node::ClearInputs(int start, int count) {
+  Node** input_ptr = GetInputPtr(start);
+  Use* use_ptr = GetUsePtr(start);
+  while (count-- > 0) {
+    DCHECK_EQ(input_ptr, use_ptr->input_ptr());
+    Node* input = *input_ptr;
+    *input_ptr = nullptr;
+    if (input) input->RemoveUse(use_ptr);
+    input_ptr++;
+    use_ptr--;
+  }
+  Verify();
+}
+
+
+void Node::NullAllInputs() { ClearInputs(0, InputCount()); }
+
+
+void Node::TrimInputCount(int new_input_count) {
+  int current_count = InputCount();
+  DCHECK_LE(new_input_count, current_count);
+  if (new_input_count == current_count) return;  // Nothing to do.
+  ClearInputs(new_input_count, current_count - new_input_count);
+  if (has_inline_inputs()) {
+    bit_field_ = InlineCountField::update(bit_field_, new_input_count);
+  } else {
+    inputs_.outline_->count_ = new_input_count;
+  }
 }
 
 
@@ -93,17 +245,124 @@
 }
 
 
-Node* Node::UseAt(int index) const {
-  DCHECK_LE(0, index);
-  DCHECK_LT(index, UseCount());
-  Use* current = first_use_;
-  while (index-- != 0) {
-    current = current->next;
+void Node::ReplaceUses(Node* that) {
+  DCHECK(this->first_use_ == nullptr || this->first_use_->prev == nullptr);
+  DCHECK(that->first_use_ == nullptr || that->first_use_->prev == nullptr);
+
+  // Update the pointers to {this} to point to {that}.
+  Use* last_use = nullptr;
+  for (Use* use = this->first_use_; use; use = use->next) {
+    *use->input_ptr() = that;
+    last_use = use;
   }
-  return current->from;
+  if (last_use) {
+    // Concat the use list of {this} and {that}.
+    last_use->next = that->first_use_;
+    if (that->first_use_) that->first_use_->prev = last_use;
+    that->first_use_ = this->first_use_;
+  }
+  first_use_ = nullptr;
 }
 
 
+bool Node::OwnedBy(Node const* owner1, Node const* owner2) const {
+  unsigned mask = 0;
+  for (Use* use = first_use_; use; use = use->next) {
+    Node* from = use->from();
+    if (from == owner1) {
+      mask |= 1;
+    } else if (from == owner2) {
+      mask |= 2;
+    } else {
+      return false;
+    }
+  }
+  return mask == 3;
+}
+
+
+void Node::Print() const {
+  OFStream os(stdout);
+  os << *this << std::endl;
+}
+
+
+Node::Node(NodeId id, const Operator* op, int inline_count, int inline_capacity)
+    : op_(op),
+      type_(nullptr),
+      mark_(0),
+      bit_field_(IdField::encode(id) | InlineCountField::encode(inline_count) |
+                 InlineCapacityField::encode(inline_capacity)),
+      first_use_(nullptr) {
+  // Inputs must either be out of line or within the inline capacity.
+  DCHECK(inline_capacity <= kMaxInlineCapacity);
+  DCHECK(inline_count == kOutlineMarker || inline_count <= inline_capacity);
+}
+
+
+void Node::AppendUse(Use* use) {
+  DCHECK(first_use_ == nullptr || first_use_->prev == nullptr);
+  DCHECK_EQ(this, *use->input_ptr());
+  use->next = first_use_;
+  use->prev = nullptr;
+  if (first_use_) first_use_->prev = use;
+  first_use_ = use;
+}
+
+
+void Node::RemoveUse(Use* use) {
+  DCHECK(first_use_ == nullptr || first_use_->prev == nullptr);
+  if (use->prev) {
+    DCHECK_NE(first_use_, use);
+    use->prev->next = use->next;
+  } else {
+    DCHECK_EQ(first_use_, use);
+    first_use_ = use->next;
+  }
+  if (use->next) {
+    use->next->prev = use->prev;
+  }
+}
+
+
+#if DEBUG
+void Node::Verify() {
+  // Check basic sanity of input data structures.
+  fflush(stdout);
+  int count = this->InputCount();
+  // Avoid quadratic explosion for mega nodes; only verify if the input
+  // count is less than 200 or is a round number of 100s.
+  if (count > 200 && count % 100) return;
+
+  for (int i = 0; i < count; i++) {
+    CHECK_EQ(i, this->GetUsePtr(i)->input_index());
+    CHECK_EQ(this->GetInputPtr(i), this->GetUsePtr(i)->input_ptr());
+    CHECK_EQ(count, this->InputCount());
+  }
+  {  // Direct input iteration.
+    int index = 0;
+    for (Node* input : this->inputs()) {
+      CHECK_EQ(this->InputAt(index), input);
+      index++;
+    }
+    CHECK_EQ(count, index);
+    CHECK_EQ(this->InputCount(), index);
+  }
+  {  // Input edge iteration.
+    int index = 0;
+    for (Edge edge : this->input_edges()) {
+      CHECK_EQ(edge.from(), this);
+      CHECK_EQ(index, edge.index());
+      CHECK_EQ(this->InputAt(index), edge.to());
+      index++;
+    }
+    CHECK_EQ(count, index);
+    CHECK_EQ(this->InputCount(), index);
+  }
+}
+#endif
+
+
 std::ostream& operator<<(std::ostream& os, const Node& n) {
   os << n.id() << ": " << *n.op();
   if (n.InputCount() > 0) {
@@ -117,6 +376,46 @@
   return os;
 }
 
+
+Node::InputEdges::iterator Node::InputEdges::iterator::operator++(int n) {
+  iterator result(*this);
+  ++(*this);
+  return result;
+}
+
+
+bool Node::InputEdges::empty() const { return begin() == end(); }
+
+
+Node::Inputs::const_iterator Node::Inputs::const_iterator::operator++(int n) {
+  const_iterator result(*this);
+  ++(*this);
+  return result;
+}
+
+
+bool Node::Inputs::empty() const { return begin() == end(); }
+
+
+Node::UseEdges::iterator Node::UseEdges::iterator::operator++(int n) {
+  iterator result(*this);
+  ++(*this);
+  return result;
+}
+
+
+bool Node::UseEdges::empty() const { return begin() == end(); }
+
+
+Node::Uses::const_iterator Node::Uses::const_iterator::operator++(int n) {
+  const_iterator result(*this);
+  ++(*this);
+  return result;
+}
+
+
+bool Node::Uses::empty() const { return begin() == end(); }
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/src/compiler/node.h b/src/compiler/node.h
index 2295b7b..c73482f 100644
--- a/src/compiler/node.h
+++ b/src/compiler/node.h
@@ -5,17 +5,9 @@
 #ifndef V8_COMPILER_NODE_H_
 #define V8_COMPILER_NODE_H_
 
-#include <deque>
-#include <set>
-#include <vector>
-
-#include "src/v8.h"
-
 #include "src/compiler/opcodes.h"
 #include "src/compiler/operator.h"
 #include "src/types.h"
-#include "src/zone.h"
-#include "src/zone-allocator.h"
 #include "src/zone-containers.h"
 
 namespace v8 {
@@ -32,9 +24,11 @@
 // {NodeMarker} has a range of values that indicate states of a node.
 typedef uint32_t Mark;
 
+
 // NodeIds are identifying numbers for nodes that can be used to index auxiliary
 // out-of-line data associated with each node.
-typedef int NodeId;
+typedef uint32_t NodeId;
+
 
 // A Node is the basic primitive of graphs. Nodes are chained together by
 // input/use chains but by default otherwise contain only an identifying number
@@ -45,50 +39,82 @@
 // compilation, e.g. during lowering passes. Other information that needs to be
 // associated with Nodes during compilation must be stored out-of-line indexed
 // by the Node's id.
-class Node FINAL {
+class Node final {
  public:
-  void Initialize(const Operator* op) {
-    set_op(op);
-    set_mark(0);
-  }
+  static Node* New(Zone* zone, NodeId id, const Operator* op, int input_count,
+                   Node* const* inputs, bool has_extensible_inputs);
+  static Node* Clone(Zone* zone, NodeId id, const Node* node);
 
-  bool IsDead() const { return InputCount() > 0 && InputAt(0) == NULL; }
+  bool IsDead() const { return InputCount() > 0 && !InputAt(0); }
   void Kill();
 
-  void CollectProjections(ZoneVector<Node*>* projections);
-  Node* FindProjection(size_t projection_index);
-
   const Operator* op() const { return op_; }
-  void set_op(const Operator* op) { op_ = op; }
 
   IrOpcode::Value opcode() const {
     DCHECK(op_->opcode() <= IrOpcode::kLast);
     return static_cast<IrOpcode::Value>(op_->opcode());
   }
 
-  NodeId id() const { return id_; }
+  NodeId id() const { return IdField::decode(bit_field_); }
 
-  int InputCount() const { return input_count(); }
-  Node* InputAt(int index) const { return GetInputRecordPtr(index)->to; }
-  inline void ReplaceInput(int index, Node* new_input);
-  inline void AppendInput(Zone* zone, Node* new_input);
-  inline void InsertInput(Zone* zone, int index, Node* new_input);
-  inline void RemoveInput(int index);
+  int InputCount() const {
+    return has_inline_inputs() ? InlineCountField::decode(bit_field_)
+                               : inputs_.outline_->count_;
+  }
+
+#if DEBUG
+  void Verify();
+#define BOUNDS_CHECK(index)                                                  \
+  do {                                                                       \
+    if (index < 0 || index >= InputCount()) {                                \
+      V8_Fatal(__FILE__, __LINE__, "Node #%d:%s->InputAt(%d) out of bounds", \
+               id(), op()->mnemonic(), index);                               \
+    }                                                                        \
+  } while (false)
+#else
+  // No bounds checks or verification in release mode.
+  inline void Verify() {}
+#define BOUNDS_CHECK(index) \
+  do {                      \
+  } while (false)
+#endif
+
+  Node* InputAt(int index) const {
+    BOUNDS_CHECK(index);
+    return *GetInputPtrConst(index);
+  }
+
+  void ReplaceInput(int index, Node* new_to) {
+    BOUNDS_CHECK(index);
+    Node** input_ptr = GetInputPtr(index);
+    Node* old_to = *input_ptr;
+    if (old_to != new_to) {
+      Use* use = GetUsePtr(index);
+      if (old_to) old_to->RemoveUse(use);
+      *input_ptr = new_to;
+      if (new_to) new_to->AppendUse(use);
+    }
+  }
+
+#undef BOUNDS_CHECK
+
+  void AppendInput(Zone* zone, Node* new_to);
+  void InsertInput(Zone* zone, int index, Node* new_to);
+  void RemoveInput(int index);
+  void NullAllInputs();
+  void TrimInputCount(int new_input_count);
 
   int UseCount() const;
-  Node* UseAt(int index) const;
-  inline void ReplaceUses(Node* replace_to);
-  template <class UnaryPredicate>
-  inline void ReplaceUsesIf(UnaryPredicate pred, Node* replace_to);
-  inline void RemoveAllInputs();
+  void ReplaceUses(Node* replace_to);
 
-  inline void TrimInputCount(int input_count);
-
-  class InputEdges {
+  class InputEdges final {
    public:
+    typedef Edge value_type;
+
     class iterator;
-    iterator begin() const;
-    iterator end() const;
+    inline iterator begin() const;
+    inline iterator end() const;
+
     bool empty() const;
 
     explicit InputEdges(Node* node) : node_(node) {}
@@ -97,11 +123,16 @@
     Node* node_;
   };
 
-  class Inputs {
+  InputEdges input_edges() { return InputEdges(this); }
+
+  class Inputs final {
    public:
-    class iterator;
-    iterator begin() const;
-    iterator end() const;
+    typedef Node* value_type;
+
+    class const_iterator;
+    inline const_iterator begin() const;
+    inline const_iterator end() const;
+
     bool empty() const;
 
     explicit Inputs(Node* node) : node_(node) {}
@@ -111,13 +142,15 @@
   };
 
   Inputs inputs() { return Inputs(this); }
-  InputEdges input_edges() { return InputEdges(this); }
 
-  class UseEdges {
+  class UseEdges final {
    public:
+    typedef Edge value_type;
+
     class iterator;
-    iterator begin() const;
-    iterator end() const;
+    inline iterator begin() const;
+    inline iterator end() const;
+
     bool empty() const;
 
     explicit UseEdges(Node* node) : node_(node) {}
@@ -126,11 +159,16 @@
     Node* node_;
   };
 
-  class Uses {
+  UseEdges use_edges() { return UseEdges(this); }
+
+  class Uses final {
    public:
-    class iterator;
-    iterator begin() const;
-    iterator end() const;
+    typedef Node* value_type;
+
+    class const_iterator;
+    inline const_iterator begin() const;
+    inline const_iterator end() const;
+
     bool empty() const;
 
     explicit Uses(Node* node) : node_(node) {}
@@ -140,324 +178,164 @@
   };
 
   Uses uses() { return Uses(this); }
-  UseEdges use_edges() { return UseEdges(this); }
 
-  bool OwnedBy(Node* owner) const;
-
-  static Node* New(Graph* graph, int input_count, Node** inputs,
-                   bool has_extensible_inputs);
-
- protected:
-  friend class Graph;
-  friend class Edge;
-
-  class Use : public ZoneObject {
-   public:
-    Node* from;
-    Use* next;
-    Use* prev;
-    int input_index;
-  };
-
-  class Input {
-   public:
-    Node* to;
-    Use* use;
-
-    void Update(Node* new_to);
-  };
-
-  void EnsureAppendableInputs(Zone* zone);
-
-  Input* GetInputRecordPtr(int index) const {
-    if (has_appendable_inputs()) {
-      return &((*inputs_.appendable_)[index]);
-    } else {
-      return &inputs_.static_[index];
-    }
+  // Returns true if {owner} is the user of {this} node.
+  bool OwnedBy(Node* owner) const {
+    return first_use_ && first_use_->from() == owner && !first_use_->next;
   }
 
-  inline void AppendUse(Use* use);
-  inline void RemoveUse(Use* use);
+  // Returns true if {owner1} and {owner2} are the only users of {this} node.
+  bool OwnedBy(Node const* owner1, Node const* owner2) const;
+  void Print() const;
+
+ private:
+  struct Use;
+  // Out of line storage for inputs when the number of inputs overflowed the
+  // capacity of the inline-allocated space.
+  struct OutOfLineInputs {
+    Node* node_;
+    int count_;
+    int capacity_;
+    Node* inputs_[1];
+
+    static OutOfLineInputs* New(Zone* zone, int capacity);
+    void ExtractFrom(Use* use_ptr, Node** input_ptr, int count);
+  };
+
+  // A link in the use chain for a node. Every input {i} to a node {n} has an
+  // associated {Use} which is linked into the use chain of the {i} node.
+  struct Use {
+    Use* next;
+    Use* prev;
+    uint32_t bit_field_;
+
+    int input_index() const { return InputIndexField::decode(bit_field_); }
+    bool is_inline_use() const { return InlineField::decode(bit_field_); }
+    Node** input_ptr() {
+      int index = input_index();
+      Use* start = this + 1 + index;
+      Node** inputs = is_inline_use()
+                          ? reinterpret_cast<Node*>(start)->inputs_.inline_
+                          : reinterpret_cast<OutOfLineInputs*>(start)->inputs_;
+      return &inputs[index];
+    }
+
+    Node* from() {
+      Use* start = this + 1 + input_index();
+      return is_inline_use() ? reinterpret_cast<Node*>(start)
+                             : reinterpret_cast<OutOfLineInputs*>(start)->node_;
+    }
+
+    typedef BitField<bool, 0, 1> InlineField;
+    typedef BitField<unsigned, 1, 17> InputIndexField;
+    // Leaving some space in the bitset in case we ever decide to record
+    // the output index.
+  };
+
+  //============================================================================
+  //== Memory layout ===========================================================
+  //============================================================================
+  // Saving space for big graphs is important. We use a memory layout trick to
+  // be able to map {Node} objects to {Use} objects and vice-versa in a
+  // space-efficient manner.
+  //
+  // {Use} links are laid out in memory directly before a {Node}, followed by
+  // direct pointers to input {Nodes}.
+  //
+  // inline case:
+  // |Use #N  |Use #N-1|...|Use #1  |Use #0  |Node xxxx |I#0|I#1|...|I#N-1|I#N|
+  //          ^                              ^                  ^
+  //          + Use                          + Node             + Input
+  //
+  // Since every {Use} instance records its {input_index}, pointer arithmetic
+  // can compute the {Node}.
+  //
+  // out-of-line case:
+  //     |Node xxxx |
+  //     ^       + outline ------------------+
+  //     +----------------------------------------+
+  //                                         |    |
+  //                                         v    | node
+  // |Use #N  |Use #N-1|...|Use #1  |Use #0  |OOL xxxxx |I#0|I#1|...|I#N-1|I#N|
+  //          ^                                                 ^
+  //          + Use                                             + Input
+  //
+  // Out-of-line storage of input lists is needed if appending an input to
+  // a node exceeds the maximum inline capacity.
+
+  Node(NodeId id, const Operator* op, int inline_count, int inline_capacity);
+
+  Node* const* GetInputPtrConst(int input_index) const {
+    return has_inline_inputs() ? &(inputs_.inline_[input_index])
+                               : &inputs_.outline_->inputs_[input_index];
+  }
+  Node** GetInputPtr(int input_index) {
+    return has_inline_inputs() ? &(inputs_.inline_[input_index])
+                               : &inputs_.outline_->inputs_[input_index];
+  }
+  Use* GetUsePtr(int input_index) {
+    Use* ptr = has_inline_inputs() ? reinterpret_cast<Use*>(this)
+                                   : reinterpret_cast<Use*>(inputs_.outline_);
+    return &ptr[-1 - input_index];
+  }
+
+  void AppendUse(Use* use);
+  void RemoveUse(Use* use);
 
   void* operator new(size_t, void* location) { return location; }
 
- private:
-  inline Node(NodeId id, int input_count, int reserve_input_count);
+  // Only NodeProperties should manipulate the op.
+  void set_op(const Operator* op) { op_ = op; }
 
-  typedef ZoneDeque<Input> InputDeque;
-
-  friend class NodeProperties;
-  template <typename State>
-  friend class NodeMarker;
-
-  // Only NodeProperties should manipulate the bounds.
-  Bounds bounds() { return bounds_; }
-  void set_bounds(Bounds b) { bounds_ = b; }
+  // Only NodeProperties should manipulate the type.
+  Type* type() const { return type_; }
+  void set_type(Type* type) { type_ = type; }
 
   // Only NodeMarkers should manipulate the marks on nodes.
   Mark mark() { return mark_; }
   void set_mark(Mark mark) { mark_ = mark; }
 
-  int input_count() const { return InputCountField::decode(bit_field_); }
-  void set_input_count(int input_count) {
-    DCHECK_LE(0, input_count);
-    bit_field_ = InputCountField::update(bit_field_, input_count);
+  inline bool has_inline_inputs() const {
+    return InlineCountField::decode(bit_field_) != kOutlineMarker;
   }
 
-  int reserved_input_count() const {
-    return ReservedInputCountField::decode(bit_field_);
-  }
-  void set_reserved_input_count(int reserved_input_count) {
-    DCHECK_LE(0, reserved_input_count);
-    bit_field_ =
-        ReservedInputCountField::update(bit_field_, reserved_input_count);
-  }
+  void ClearInputs(int start, int count);
 
-  bool has_appendable_inputs() const {
-    return HasAppendableInputsField::decode(bit_field_);
-  }
-  void set_has_appendable_inputs(bool has_appendable_inputs) {
-    bit_field_ =
-        HasAppendableInputsField::update(bit_field_, has_appendable_inputs);
-  }
-
-  typedef BitField<unsigned, 0, 29> InputCountField;
-  typedef BitField<unsigned, 29, 2> ReservedInputCountField;
-  typedef BitField<unsigned, 31, 1> HasAppendableInputsField;
-  static const int kDefaultReservedInputs = ReservedInputCountField::kMax;
+  typedef BitField<NodeId, 0, 24> IdField;
+  typedef BitField<unsigned, 24, 4> InlineCountField;
+  typedef BitField<unsigned, 28, 4> InlineCapacityField;
+  static const int kOutlineMarker = InlineCountField::kMax;
+  static const int kMaxInlineCount = InlineCountField::kMax - 1;
+  static const int kMaxInlineCapacity = InlineCapacityField::kMax - 1;
 
   const Operator* op_;
-  Bounds bounds_;
+  Type* type_;
   Mark mark_;
-  NodeId id_;
-  unsigned bit_field_;
-  union {
-    // When a node is initially allocated, it uses a static buffer to hold its
-    // inputs under the assumption that the number of outputs will not increase.
-    // When the first input is appended, the static buffer is converted into a
-    // deque to allow for space-efficient growing.
-    Input* static_;
-    InputDeque* appendable_;
-  } inputs_;
+  uint32_t bit_field_;
   Use* first_use_;
-  Use* last_use_;
+  union {
+    // Inline storage for inputs or out-of-line storage.
+    Node* inline_[1];
+    OutOfLineInputs* outline_;
+  } inputs_;
+
+  friend class Edge;
+  friend class NodeMarkerBase;
+  friend class NodeProperties;
 
   DISALLOW_COPY_AND_ASSIGN(Node);
 };
 
 
-// An encapsulation for information associated with a single use of node as a
-// input from another node, allowing access to both the defining node and
-// the node having the input.
-class Edge {
- public:
-  Node* from() const { return input_->use->from; }
-  Node* to() const { return input_->to; }
-  int index() const {
-    int index = input_->use->input_index;
-    DCHECK(index < input_->use->from->input_count());
-    return index;
-  }
-
-  bool operator==(const Edge& other) { return input_ == other.input_; }
-  bool operator!=(const Edge& other) { return !(*this == other); }
-
-  void UpdateTo(Node* new_to) { input_->Update(new_to); }
-
- private:
-  friend class Node::Uses::iterator;
-  friend class Node::Inputs::iterator;
-  friend class Node::UseEdges::iterator;
-  friend class Node::InputEdges::iterator;
-
-  explicit Edge(Node::Input* input) : input_(input) {}
-
-  Node::Input* input_;
-};
-
-
-// A forward iterator to visit the edges for the input dependencies of a node..
-class Node::InputEdges::iterator {
- public:
-  typedef std::forward_iterator_tag iterator_category;
-  typedef int difference_type;
-  typedef Edge value_type;
-  typedef Edge* pointer;
-  typedef Edge& reference;
-  iterator(const Node::InputEdges::iterator& other)  // NOLINT
-      : input_(other.input_) {}
-  iterator() : input_(NULL) {}
-
-  Edge operator*() const { return Edge(input_); }
-  bool operator==(const iterator& other) const { return Equals(other); }
-  bool operator!=(const iterator& other) const { return !Equals(other); }
-  iterator& operator++() {
-    DCHECK(input_ != NULL);
-    Edge edge(input_);
-    Node* from = edge.from();
-    SetInput(from, input_->use->input_index + 1);
-    return *this;
-  }
-  iterator operator++(int) {
-    iterator result(*this);
-    ++(*this);
-    return result;
-  }
-
- private:
-  friend class Node;
-
-  explicit iterator(Node* from, int index = 0) : input_(NULL) {
-    SetInput(from, index);
-  }
-
-  bool Equals(const iterator& other) const { return other.input_ == input_; }
-  void SetInput(Node* from, int index) {
-    DCHECK(index >= 0 && index <= from->InputCount());
-    if (index < from->InputCount()) {
-      input_ = from->GetInputRecordPtr(index);
-    } else {
-      input_ = NULL;
-    }
-  }
-
-  Input* input_;
-};
-
-
-// A forward iterator to visit the inputs of a node.
-class Node::Inputs::iterator {
- public:
-  typedef std::forward_iterator_tag iterator_category;
-  typedef int difference_type;
-  typedef Node* value_type;
-  typedef Node** pointer;
-  typedef Node*& reference;
-
-  iterator(const Node::Inputs::iterator& other)  // NOLINT
-      : iter_(other.iter_) {}
-
-  Node* operator*() const { return (*iter_).to(); }
-  bool operator==(const iterator& other) const { return Equals(other); }
-  bool operator!=(const iterator& other) const { return !Equals(other); }
-  iterator& operator++() {
-    ++iter_;
-    return *this;
-  }
-  iterator operator++(int) {
-    iterator result(*this);
-    ++(*this);
-    return result;
-  }
-
-
- private:
-  friend class Node::Inputs;
-
-  explicit iterator(Node* node, int index) : iter_(node, index) {}
-
-  bool Equals(const iterator& other) const { return other.iter_ == iter_; }
-
-  Node::InputEdges::iterator iter_;
-};
-
-// A forward iterator to visit the uses edges of a node. The edges are returned
-// in
-// the order in which they were added as inputs.
-class Node::UseEdges::iterator {
- public:
-  iterator(const Node::UseEdges::iterator& other)  // NOLINT
-      : current_(other.current_),
-        next_(other.next_) {}
-
-  Edge operator*() const { return Edge(CurrentInput()); }
-
-  bool operator==(const iterator& other) { return Equals(other); }
-  bool operator!=(const iterator& other) { return !Equals(other); }
-  iterator& operator++() {
-    DCHECK(current_ != NULL);
-    current_ = next_;
-    next_ = (current_ == NULL) ? NULL : current_->next;
-    return *this;
-  }
-  iterator operator++(int) {
-    iterator result(*this);
-    ++(*this);
-    return result;
-  }
-
- private:
-  friend class Node::UseEdges;
-
-  iterator() : current_(NULL), next_(NULL) {}
-  explicit iterator(Node* node)
-      : current_(node->first_use_),
-        next_(current_ == NULL ? NULL : current_->next) {}
-
-  bool Equals(const iterator& other) const {
-    return other.current_ == current_;
-  }
-
-  Input* CurrentInput() const {
-    return current_->from->GetInputRecordPtr(current_->input_index);
-  }
-
-  Node::Use* current_;
-  Node::Use* next_;
-};
-
-
-// A forward iterator to visit the uses of a node. The uses are returned in
-// the order in which they were added as inputs.
-class Node::Uses::iterator {
- public:
-  iterator(const Node::Uses::iterator& other)  // NOLINT
-      : current_(other.current_) {}
-
-  Node* operator*() { return current_->from; }
-
-  bool operator==(const iterator& other) { return other.current_ == current_; }
-  bool operator!=(const iterator& other) { return other.current_ != current_; }
-  iterator& operator++() {
-    DCHECK(current_ != NULL);
-    current_ = current_->next;
-    return *this;
-  }
-
- private:
-  friend class Node::Uses;
-
-  iterator() : current_(NULL) {}
-  explicit iterator(Node* node) : current_(node->first_use_) {}
-
-  Input* CurrentInput() const {
-    return current_->from->GetInputRecordPtr(current_->input_index);
-  }
-
-  Node::Use* current_;
-};
-
-
 std::ostream& operator<<(std::ostream& os, const Node& n);
 
-typedef std::set<Node*, std::less<Node*>, zone_allocator<Node*> > NodeSet;
-typedef NodeSet::iterator NodeSetIter;
-typedef NodeSet::reverse_iterator NodeSetRIter;
 
+// Typedefs to shorten commonly used Node containers.
 typedef ZoneDeque<Node*> NodeDeque;
-
+typedef ZoneSet<Node*> NodeSet;
 typedef ZoneVector<Node*> NodeVector;
-typedef NodeVector::iterator NodeVectorIter;
-typedef NodeVector::const_iterator NodeVectorConstIter;
-typedef NodeVector::reverse_iterator NodeVectorRIter;
-
 typedef ZoneVector<NodeVector> NodeVectorVector;
-typedef NodeVectorVector::iterator NodeVectorVectorIter;
-typedef NodeVectorVector::reverse_iterator NodeVectorVectorRIter;
 
-typedef Node::Uses::iterator UseIter;
-typedef Node::Inputs::iterator InputIter;
 
 // Helper to extract parameters from Operator1<*> nodes.
 template <typename T>
@@ -465,194 +343,219 @@
   return OpParameter<T>(node->op());
 }
 
-inline Node::InputEdges::iterator Node::InputEdges::begin() const {
+
+// An encapsulation for information associated with a single use of node as a
+// input from another node, allowing access to both the defining node and
+// the node having the input.
+class Edge final {
+ public:
+  Node* from() const { return use_->from(); }
+  Node* to() const { return *input_ptr_; }
+  int index() const {
+    int const index = use_->input_index();
+    DCHECK_LT(index, use_->from()->InputCount());
+    return index;
+  }
+
+  bool operator==(const Edge& other) { return input_ptr_ == other.input_ptr_; }
+  bool operator!=(const Edge& other) { return !(*this == other); }
+
+  void UpdateTo(Node* new_to) {
+    Node* old_to = *input_ptr_;
+    if (old_to != new_to) {
+      if (old_to) old_to->RemoveUse(use_);
+      *input_ptr_ = new_to;
+      if (new_to) new_to->AppendUse(use_);
+    }
+  }
+
+ private:
+  friend class Node::UseEdges::iterator;
+  friend class Node::InputEdges::iterator;
+
+  Edge(Node::Use* use, Node** input_ptr) : use_(use), input_ptr_(input_ptr) {
+    DCHECK_NOT_NULL(use);
+    DCHECK_NOT_NULL(input_ptr);
+    DCHECK_EQ(input_ptr, use->input_ptr());
+  }
+
+  Node::Use* use_;
+  Node** input_ptr_;
+};
+
+
+// A forward iterator to visit the edges for the input dependencies of a node.
+class Node::InputEdges::iterator final {
+ public:
+  typedef std::forward_iterator_tag iterator_category;
+  typedef int difference_type;
+  typedef Edge value_type;
+  typedef Edge* pointer;
+  typedef Edge& reference;
+
+  iterator() : use_(nullptr), input_ptr_(nullptr) {}
+  iterator(const iterator& other)
+      : use_(other.use_), input_ptr_(other.input_ptr_) {}
+
+  Edge operator*() const { return Edge(use_, input_ptr_); }
+  bool operator==(const iterator& other) const {
+    return input_ptr_ == other.input_ptr_;
+  }
+  bool operator!=(const iterator& other) const { return !(*this == other); }
+  iterator& operator++() {
+    input_ptr_++;
+    use_--;
+    return *this;
+  }
+  iterator operator++(int);
+
+ private:
+  friend class Node;
+
+  explicit iterator(Node* from, int index = 0)
+      : use_(from->GetUsePtr(index)), input_ptr_(from->GetInputPtr(index)) {}
+
+  Use* use_;
+  Node** input_ptr_;
+};
+
+
+Node::InputEdges::iterator Node::InputEdges::begin() const {
   return Node::InputEdges::iterator(this->node_, 0);
 }
 
-inline Node::InputEdges::iterator Node::InputEdges::end() const {
+
+Node::InputEdges::iterator Node::InputEdges::end() const {
   return Node::InputEdges::iterator(this->node_, this->node_->InputCount());
 }
 
-inline Node::Inputs::iterator Node::Inputs::begin() const {
-  return Node::Inputs::iterator(this->node_, 0);
+
+// A forward iterator to visit the inputs of a node.
+class Node::Inputs::const_iterator final {
+ public:
+  typedef std::forward_iterator_tag iterator_category;
+  typedef int difference_type;
+  typedef Node* value_type;
+  typedef Node** pointer;
+  typedef Node*& reference;
+
+  const_iterator(const const_iterator& other) : iter_(other.iter_) {}
+
+  Node* operator*() const { return (*iter_).to(); }
+  bool operator==(const const_iterator& other) const {
+    return iter_ == other.iter_;
+  }
+  bool operator!=(const const_iterator& other) const {
+    return !(*this == other);
+  }
+  const_iterator& operator++() {
+    ++iter_;
+    return *this;
+  }
+  const_iterator operator++(int);
+
+ private:
+  friend class Node::Inputs;
+
+  const_iterator(Node* node, int index) : iter_(node, index) {}
+
+  Node::InputEdges::iterator iter_;
+};
+
+
+Node::Inputs::const_iterator Node::Inputs::begin() const {
+  return const_iterator(this->node_, 0);
 }
 
-inline Node::Inputs::iterator Node::Inputs::end() const {
-  return Node::Inputs::iterator(this->node_, this->node_->InputCount());
+
+Node::Inputs::const_iterator Node::Inputs::end() const {
+  return const_iterator(this->node_, this->node_->InputCount());
 }
 
-inline Node::UseEdges::iterator Node::UseEdges::begin() const {
+
+// A forward iterator to visit the uses edges of a node.
+class Node::UseEdges::iterator final {
+ public:
+  iterator(const iterator& other)
+      : current_(other.current_), next_(other.next_) {}
+
+  Edge operator*() const { return Edge(current_, current_->input_ptr()); }
+  bool operator==(const iterator& other) const {
+    return current_ == other.current_;
+  }
+  bool operator!=(const iterator& other) const { return !(*this == other); }
+  iterator& operator++() {
+    DCHECK_NOT_NULL(current_);
+    current_ = next_;
+    next_ = current_ ? current_->next : nullptr;
+    return *this;
+  }
+  iterator operator++(int);
+
+ private:
+  friend class Node::UseEdges;
+
+  iterator() : current_(nullptr), next_(nullptr) {}
+  explicit iterator(Node* node)
+      : current_(node->first_use_),
+        next_(current_ ? current_->next : nullptr) {}
+
+  Node::Use* current_;
+  Node::Use* next_;
+};
+
+
+Node::UseEdges::iterator Node::UseEdges::begin() const {
   return Node::UseEdges::iterator(this->node_);
 }
 
-inline Node::UseEdges::iterator Node::UseEdges::end() const {
+
+Node::UseEdges::iterator Node::UseEdges::end() const {
   return Node::UseEdges::iterator();
 }
 
-inline Node::Uses::iterator Node::Uses::begin() const {
-  return Node::Uses::iterator(this->node_);
+
+// A forward iterator to visit the uses of a node.
+class Node::Uses::const_iterator final {
+ public:
+  typedef std::forward_iterator_tag iterator_category;
+  typedef int difference_type;
+  typedef Node* value_type;
+  typedef Node** pointer;
+  typedef Node*& reference;
+
+  const_iterator(const const_iterator& other) : current_(other.current_) {}
+
+  Node* operator*() const { return current_->from(); }
+  bool operator==(const const_iterator& other) const {
+    return other.current_ == current_;
+  }
+  bool operator!=(const const_iterator& other) const {
+    return other.current_ != current_;
+  }
+  const_iterator& operator++() {
+    DCHECK_NOT_NULL(current_);
+    current_ = current_->next;
+    return *this;
+  }
+  const_iterator operator++(int);
+
+ private:
+  friend class Node::Uses;
+
+  const_iterator() : current_(nullptr) {}
+  explicit const_iterator(Node* node) : current_(node->first_use_) {}
+
+  Node::Use* current_;
+};
+
+
+Node::Uses::const_iterator Node::Uses::begin() const {
+  return const_iterator(this->node_);
 }
 
-inline Node::Uses::iterator Node::Uses::end() const {
-  return Node::Uses::iterator();
-}
 
-inline bool Node::InputEdges::empty() const { return begin() == end(); }
-inline bool Node::Uses::empty() const { return begin() == end(); }
-inline bool Node::UseEdges::empty() const { return begin() == end(); }
-inline bool Node::Inputs::empty() const { return begin() == end(); }
-
-inline void Node::ReplaceUses(Node* replace_to) {
-  for (Use* use = first_use_; use != NULL; use = use->next) {
-    use->from->GetInputRecordPtr(use->input_index)->to = replace_to;
-  }
-  if (replace_to->last_use_ == NULL) {
-    DCHECK_EQ(NULL, replace_to->first_use_);
-    replace_to->first_use_ = first_use_;
-    replace_to->last_use_ = last_use_;
-  } else if (first_use_ != NULL) {
-    DCHECK_NE(NULL, replace_to->first_use_);
-    replace_to->last_use_->next = first_use_;
-    first_use_->prev = replace_to->last_use_;
-    replace_to->last_use_ = last_use_;
-  }
-  first_use_ = NULL;
-  last_use_ = NULL;
-}
-
-template <class UnaryPredicate>
-inline void Node::ReplaceUsesIf(UnaryPredicate pred, Node* replace_to) {
-  for (Use* use = first_use_; use != NULL;) {
-    Use* next = use->next;
-    if (pred(use->from)) {
-      RemoveUse(use);
-      replace_to->AppendUse(use);
-      use->from->GetInputRecordPtr(use->input_index)->to = replace_to;
-    }
-    use = next;
-  }
-}
-
-inline void Node::RemoveAllInputs() {
-  for (Edge edge : input_edges()) {
-    edge.UpdateTo(NULL);
-  }
-}
-
-inline void Node::TrimInputCount(int new_input_count) {
-  if (new_input_count == input_count()) return;  // Nothing to do.
-
-  DCHECK(new_input_count < input_count());
-
-  // Update inline inputs.
-  for (int i = new_input_count; i < input_count(); i++) {
-    Node::Input* input = GetInputRecordPtr(i);
-    input->Update(NULL);
-  }
-  set_input_count(new_input_count);
-}
-
-inline void Node::ReplaceInput(int index, Node* new_to) {
-  Input* input = GetInputRecordPtr(index);
-  input->Update(new_to);
-}
-
-inline void Node::Input::Update(Node* new_to) {
-  Node* old_to = this->to;
-  if (new_to == old_to) return;  // Nothing to do.
-  // Snip out the use from where it used to be
-  if (old_to != NULL) {
-    old_to->RemoveUse(use);
-  }
-  to = new_to;
-  // And put it into the new node's use list.
-  if (new_to != NULL) {
-    new_to->AppendUse(use);
-  } else {
-    use->next = NULL;
-    use->prev = NULL;
-  }
-}
-
-inline void Node::EnsureAppendableInputs(Zone* zone) {
-  if (!has_appendable_inputs()) {
-    void* deque_buffer = zone->New(sizeof(InputDeque));
-    InputDeque* deque = new (deque_buffer) InputDeque(zone);
-    for (int i = 0; i < input_count(); ++i) {
-      deque->push_back(inputs_.static_[i]);
-    }
-    inputs_.appendable_ = deque;
-    set_has_appendable_inputs(true);
-  }
-}
-
-inline void Node::AppendInput(Zone* zone, Node* to_append) {
-  Use* new_use = new (zone) Use;
-  Input new_input;
-  new_input.to = to_append;
-  new_input.use = new_use;
-  if (reserved_input_count() > 0) {
-    DCHECK(!has_appendable_inputs());
-    set_reserved_input_count(reserved_input_count() - 1);
-    inputs_.static_[input_count()] = new_input;
-  } else {
-    EnsureAppendableInputs(zone);
-    inputs_.appendable_->push_back(new_input);
-  }
-  new_use->input_index = input_count();
-  new_use->from = this;
-  to_append->AppendUse(new_use);
-  set_input_count(input_count() + 1);
-}
-
-inline void Node::InsertInput(Zone* zone, int index, Node* to_insert) {
-  DCHECK(index >= 0 && index < InputCount());
-  // TODO(turbofan): Optimize this implementation!
-  AppendInput(zone, InputAt(InputCount() - 1));
-  for (int i = InputCount() - 1; i > index; --i) {
-    ReplaceInput(i, InputAt(i - 1));
-  }
-  ReplaceInput(index, to_insert);
-}
-
-inline void Node::RemoveInput(int index) {
-  DCHECK(index >= 0 && index < InputCount());
-  // TODO(turbofan): Optimize this implementation!
-  for (; index < InputCount() - 1; ++index) {
-    ReplaceInput(index, InputAt(index + 1));
-  }
-  TrimInputCount(InputCount() - 1);
-}
-
-inline void Node::AppendUse(Use* use) {
-  use->next = NULL;
-  use->prev = last_use_;
-  if (last_use_ == NULL) {
-    first_use_ = use;
-  } else {
-    last_use_->next = use;
-  }
-  last_use_ = use;
-}
-
-inline void Node::RemoveUse(Use* use) {
-  if (last_use_ == use) {
-    last_use_ = use->prev;
-  }
-  if (use->prev != NULL) {
-    use->prev->next = use->next;
-  } else {
-    first_use_ = use->next;
-  }
-  if (use->next != NULL) {
-    use->next->prev = use->prev;
-  }
-}
-
-inline bool Node::OwnedBy(Node* owner) const {
-  return first_use_ != NULL && first_use_->from == owner &&
-         first_use_->next == NULL;
-}
+Node::Uses::const_iterator Node::Uses::end() const { return const_iterator(); }
 
 }  // namespace compiler
 }  // namespace internal
diff --git a/src/compiler/opcodes.cc b/src/compiler/opcodes.cc
index 044395c..2a8e01a 100644
--- a/src/compiler/opcodes.cc
+++ b/src/compiler/opcodes.cc
@@ -5,6 +5,7 @@
 #include "src/compiler/opcodes.h"
 
 #include <algorithm>
+#include <ostream>
 
 #include "src/base/macros.h"
 
@@ -25,10 +26,15 @@
 
 // static
 char const* IrOpcode::Mnemonic(Value value) {
-  size_t const n = std::max<size_t>(value, arraysize(kMnemonics) - 1);
+  size_t const n = std::min<size_t>(value, arraysize(kMnemonics) - 1);
   return kMnemonics[n];
 }
 
+
+std::ostream& operator<<(std::ostream& os, IrOpcode::Value opcode) {
+  return os << IrOpcode::Mnemonic(opcode);
+}
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/src/compiler/opcodes.h b/src/compiler/opcodes.h
index d229b6d..a97fdfa 100644
--- a/src/compiler/opcodes.h
+++ b/src/compiler/opcodes.h
@@ -5,48 +5,61 @@
 #ifndef V8_COMPILER_OPCODES_H_
 #define V8_COMPILER_OPCODES_H_
 
-// Opcodes for control operators.
-#define INNER_CONTROL_OP_LIST(V) \
-  V(Dead)                        \
-  V(Loop)                        \
-  V(Branch)                      \
-  V(IfTrue)                      \
-  V(IfFalse)                     \
-  V(Merge)                       \
-  V(Return)                      \
-  V(Terminate)                   \
-  V(Throw)
+#include <iosfwd>
 
+// Opcodes for control operators.
 #define CONTROL_OP_LIST(V) \
-  INNER_CONTROL_OP_LIST(V) \
   V(Start)                 \
+  V(Loop)                  \
+  V(Branch)                \
+  V(Switch)                \
+  V(IfTrue)                \
+  V(IfFalse)               \
+  V(IfSuccess)             \
+  V(IfException)           \
+  V(IfValue)               \
+  V(IfDefault)             \
+  V(Merge)                 \
+  V(Deoptimize)            \
+  V(Return)                \
+  V(TailCall)              \
+  V(Terminate)             \
+  V(OsrNormalEntry)        \
+  V(OsrLoopEntry)          \
+  V(Throw)                 \
   V(End)
 
-// Opcodes for common operators.
-#define LEAF_OP_LIST(V) \
-  V(Int32Constant)      \
-  V(Int64Constant)      \
-  V(Float32Constant)    \
-  V(Float64Constant)    \
-  V(ExternalConstant)   \
-  V(NumberConstant)     \
+// Opcodes for constant operators.
+#define CONSTANT_OP_LIST(V) \
+  V(Int32Constant)          \
+  V(Int64Constant)          \
+  V(Float32Constant)        \
+  V(Float64Constant)        \
+  V(ExternalConstant)       \
+  V(NumberConstant)         \
   V(HeapConstant)
 
 #define INNER_OP_LIST(V) \
   V(Select)              \
   V(Phi)                 \
+  V(EffectSet)           \
   V(EffectPhi)           \
-  V(ValueEffect)         \
-  V(Finish)              \
+  V(Guard)               \
+  V(BeginRegion)         \
+  V(FinishRegion)        \
   V(FrameState)          \
   V(StateValues)         \
+  V(TypedStateValues)    \
+  V(ObjectState)         \
   V(Call)                \
   V(Parameter)           \
+  V(OsrValue)            \
   V(Projection)
 
 #define COMMON_OP_LIST(V) \
-  LEAF_OP_LIST(V)         \
-  INNER_OP_LIST(V)
+  CONSTANT_OP_LIST(V)     \
+  INNER_OP_LIST(V)        \
+  V(Dead)
 
 // Opcodes for JavaScript operators.
 #define JS_COMPARE_BINOP_LIST(V) \
@@ -79,8 +92,6 @@
   JS_BITWISE_BINOP_LIST(V)      \
   JS_ARITH_BINOP_LIST(V)
 
-#define JS_LOGIC_UNOP_LIST(V) V(JSUnaryNot)
-
 #define JS_CONVERSION_UNOP_LIST(V) \
   V(JSToBoolean)                   \
   V(JSToNumber)                    \
@@ -92,23 +103,32 @@
   V(JSTypeOf)
 
 #define JS_SIMPLE_UNOP_LIST(V) \
-  JS_LOGIC_UNOP_LIST(V)        \
   JS_CONVERSION_UNOP_LIST(V)   \
   JS_OTHER_UNOP_LIST(V)
 
-#define JS_OBJECT_OP_LIST(V) \
-  V(JSCreate)                \
-  V(JSLoadProperty)          \
-  V(JSLoadNamed)             \
-  V(JSStoreProperty)         \
-  V(JSStoreNamed)            \
-  V(JSDeleteProperty)        \
-  V(JSHasProperty)           \
+#define JS_OBJECT_OP_LIST(V)  \
+  V(JSCreate)                 \
+  V(JSCreateArguments)        \
+  V(JSCreateArray)            \
+  V(JSCreateClosure)          \
+  V(JSCreateIterResultObject) \
+  V(JSCreateLiteralArray)     \
+  V(JSCreateLiteralObject)    \
+  V(JSCreateLiteralRegExp)    \
+  V(JSLoadProperty)           \
+  V(JSLoadNamed)              \
+  V(JSLoadGlobal)             \
+  V(JSStoreProperty)          \
+  V(JSStoreNamed)             \
+  V(JSStoreGlobal)            \
+  V(JSDeleteProperty)         \
+  V(JSHasProperty)            \
   V(JSInstanceOf)
 
 #define JS_CONTEXT_OP_LIST(V) \
   V(JSLoadContext)            \
   V(JSStoreContext)           \
+  V(JSLoadDynamic)            \
   V(JSCreateFunctionContext)  \
   V(JSCreateCatchContext)     \
   V(JSCreateWithContext)      \
@@ -120,8 +140,15 @@
   V(JSCallConstruct)        \
   V(JSCallFunction)         \
   V(JSCallRuntime)          \
+  V(JSConvertReceiver)      \
+  V(JSForInDone)            \
+  V(JSForInNext)            \
+  V(JSForInPrepare)         \
+  V(JSForInStep)            \
+  V(JSLoadMessage)          \
+  V(JSStoreMessage)         \
   V(JSYield)                \
-  V(JSDebugger)
+  V(JSStackCheck)
 
 #define JS_OP_LIST(V)     \
   JS_SIMPLE_BINOP_LIST(V) \
@@ -131,112 +158,170 @@
   JS_OTHER_OP_LIST(V)
 
 // Opcodes for VirtuaMachine-level operators.
-#define SIMPLIFIED_OP_LIST(V) \
-  V(AnyToBoolean)             \
-  V(BooleanNot)               \
-  V(BooleanToNumber)          \
-  V(NumberEqual)              \
-  V(NumberLessThan)           \
-  V(NumberLessThanOrEqual)    \
-  V(NumberAdd)                \
-  V(NumberSubtract)           \
-  V(NumberMultiply)           \
-  V(NumberDivide)             \
-  V(NumberModulus)            \
-  V(NumberToInt32)            \
-  V(NumberToUint32)           \
-  V(ReferenceEqual)           \
-  V(StringEqual)              \
-  V(StringLessThan)           \
-  V(StringLessThanOrEqual)    \
-  V(StringAdd)                \
-  V(ChangeTaggedToInt32)      \
-  V(ChangeTaggedToUint32)     \
-  V(ChangeTaggedToFloat64)    \
-  V(ChangeInt32ToTagged)      \
-  V(ChangeUint32ToTagged)     \
-  V(ChangeFloat64ToTagged)    \
-  V(ChangeBoolToBit)          \
-  V(ChangeBitToBool)          \
-  V(LoadField)                \
-  V(LoadBuffer)               \
-  V(LoadElement)              \
-  V(StoreField)               \
-  V(StoreBuffer)              \
-  V(StoreElement)             \
-  V(ObjectIsSmi)              \
-  V(ObjectIsNonNegativeSmi)
+#define SIMPLIFIED_COMPARE_BINOP_LIST(V) \
+  V(NumberEqual)                         \
+  V(NumberLessThan)                      \
+  V(NumberLessThanOrEqual)               \
+  V(ReferenceEqual)                      \
+  V(StringEqual)                         \
+  V(StringLessThan)                      \
+  V(StringLessThanOrEqual)
+
+#define SIMPLIFIED_OP_LIST(V)      \
+  SIMPLIFIED_COMPARE_BINOP_LIST(V) \
+  V(BooleanNot)                    \
+  V(BooleanToNumber)               \
+  V(NumberAdd)                     \
+  V(NumberSubtract)                \
+  V(NumberMultiply)                \
+  V(NumberDivide)                  \
+  V(NumberModulus)                 \
+  V(NumberBitwiseOr)               \
+  V(NumberBitwiseXor)              \
+  V(NumberBitwiseAnd)              \
+  V(NumberShiftLeft)               \
+  V(NumberShiftRight)              \
+  V(NumberShiftRightLogical)       \
+  V(NumberToInt32)                 \
+  V(NumberToUint32)                \
+  V(NumberIsHoleNaN)               \
+  V(PlainPrimitiveToNumber)        \
+  V(ChangeTaggedToInt32)           \
+  V(ChangeTaggedToUint32)          \
+  V(ChangeTaggedToFloat64)         \
+  V(ChangeInt32ToTagged)           \
+  V(ChangeUint32ToTagged)          \
+  V(ChangeFloat64ToTagged)         \
+  V(ChangeBoolToBit)               \
+  V(ChangeBitToBool)               \
+  V(Allocate)                      \
+  V(LoadField)                     \
+  V(LoadBuffer)                    \
+  V(LoadElement)                   \
+  V(StoreField)                    \
+  V(StoreBuffer)                   \
+  V(StoreElement)                  \
+  V(ObjectIsNumber)                \
+  V(ObjectIsSmi)
 
 // Opcodes for Machine-level operators.
-#define MACHINE_OP_LIST(V)    \
-  V(Load)                     \
-  V(Store)                    \
-  V(Word32And)                \
-  V(Word32Or)                 \
-  V(Word32Xor)                \
-  V(Word32Shl)                \
-  V(Word32Shr)                \
-  V(Word32Sar)                \
-  V(Word32Ror)                \
-  V(Word32Equal)              \
-  V(Word64And)                \
-  V(Word64Or)                 \
-  V(Word64Xor)                \
-  V(Word64Shl)                \
-  V(Word64Shr)                \
-  V(Word64Sar)                \
-  V(Word64Ror)                \
-  V(Word64Equal)              \
-  V(Int32Add)                 \
-  V(Int32AddWithOverflow)     \
-  V(Int32Sub)                 \
-  V(Int32SubWithOverflow)     \
-  V(Int32Mul)                 \
-  V(Int32MulHigh)             \
-  V(Int32Div)                 \
-  V(Int32Mod)                 \
-  V(Int32LessThan)            \
-  V(Int32LessThanOrEqual)     \
-  V(Uint32Div)                \
-  V(Uint32LessThan)           \
-  V(Uint32LessThanOrEqual)    \
-  V(Uint32Mod)                \
-  V(Uint32MulHigh)            \
-  V(Int64Add)                 \
-  V(Int64Sub)                 \
-  V(Int64Mul)                 \
-  V(Int64Div)                 \
-  V(Int64Mod)                 \
-  V(Int64LessThan)            \
-  V(Int64LessThanOrEqual)     \
-  V(Uint64Div)                \
-  V(Uint64LessThan)           \
-  V(Uint64Mod)                \
-  V(ChangeFloat32ToFloat64)   \
-  V(ChangeFloat64ToInt32)     \
-  V(ChangeFloat64ToUint32)    \
-  V(ChangeInt32ToFloat64)     \
-  V(ChangeInt32ToInt64)       \
-  V(ChangeUint32ToFloat64)    \
-  V(ChangeUint32ToUint64)     \
-  V(TruncateFloat64ToFloat32) \
-  V(TruncateFloat64ToInt32)   \
-  V(TruncateInt64ToInt32)     \
-  V(Float64Add)               \
-  V(Float64Sub)               \
-  V(Float64Mul)               \
-  V(Float64Div)               \
-  V(Float64Mod)               \
-  V(Float64Sqrt)              \
-  V(Float64Equal)             \
-  V(Float64LessThan)          \
-  V(Float64LessThanOrEqual)   \
-  V(Float64Floor)             \
-  V(Float64Ceil)              \
-  V(Float64RoundTruncate)     \
-  V(Float64RoundTiesAway)     \
-  V(LoadStackPointer)         \
-  V(CheckedLoad)              \
+#define MACHINE_COMPARE_BINOP_LIST(V) \
+  V(Word32Equal)                      \
+  V(Word64Equal)                      \
+  V(Int32LessThan)                    \
+  V(Int32LessThanOrEqual)             \
+  V(Uint32LessThan)                   \
+  V(Uint32LessThanOrEqual)            \
+  V(Int64LessThan)                    \
+  V(Int64LessThanOrEqual)             \
+  V(Uint64LessThan)                   \
+  V(Uint64LessThanOrEqual)            \
+  V(Float32Equal)                     \
+  V(Float32LessThan)                  \
+  V(Float32LessThanOrEqual)           \
+  V(Float64Equal)                     \
+  V(Float64LessThan)                  \
+  V(Float64LessThanOrEqual)
+
+#define MACHINE_OP_LIST(V)      \
+  MACHINE_COMPARE_BINOP_LIST(V) \
+  V(Load)                       \
+  V(Store)                      \
+  V(Word32And)                  \
+  V(Word32Or)                   \
+  V(Word32Xor)                  \
+  V(Word32Shl)                  \
+  V(Word32Shr)                  \
+  V(Word32Sar)                  \
+  V(Word32Ror)                  \
+  V(Word32Clz)                  \
+  V(Word32Ctz)                  \
+  V(Word32Popcnt)               \
+  V(Word64Popcnt)               \
+  V(Word64And)                  \
+  V(Word64Or)                   \
+  V(Word64Xor)                  \
+  V(Word64Shl)                  \
+  V(Word64Shr)                  \
+  V(Word64Sar)                  \
+  V(Word64Ror)                  \
+  V(Word64Clz)                  \
+  V(Word64Ctz)                  \
+  V(Int32Add)                   \
+  V(Int32AddWithOverflow)       \
+  V(Int32Sub)                   \
+  V(Int32SubWithOverflow)       \
+  V(Int32Mul)                   \
+  V(Int32MulHigh)               \
+  V(Int32Div)                   \
+  V(Int32Mod)                   \
+  V(Uint32Div)                  \
+  V(Uint32Mod)                  \
+  V(Uint32MulHigh)              \
+  V(Int64Add)                   \
+  V(Int64AddWithOverflow)       \
+  V(Int64Sub)                   \
+  V(Int64SubWithOverflow)       \
+  V(Int64Mul)                   \
+  V(Int64Div)                   \
+  V(Int64Mod)                   \
+  V(Uint64Div)                  \
+  V(Uint64Mod)                  \
+  V(ChangeFloat32ToFloat64)     \
+  V(ChangeFloat64ToInt32)       \
+  V(ChangeFloat64ToUint32)      \
+  V(TryTruncateFloat32ToInt64)  \
+  V(TryTruncateFloat64ToInt64)  \
+  V(TryTruncateFloat32ToUint64) \
+  V(TryTruncateFloat64ToUint64) \
+  V(ChangeInt32ToFloat64)       \
+  V(ChangeInt32ToInt64)         \
+  V(ChangeUint32ToFloat64)      \
+  V(ChangeUint32ToUint64)       \
+  V(TruncateFloat64ToFloat32)   \
+  V(TruncateFloat64ToInt32)     \
+  V(TruncateInt64ToInt32)       \
+  V(RoundInt64ToFloat32)        \
+  V(RoundInt64ToFloat64)        \
+  V(RoundUint64ToFloat32)       \
+  V(RoundUint64ToFloat64)       \
+  V(BitcastFloat32ToInt32)      \
+  V(BitcastFloat64ToInt64)      \
+  V(BitcastInt32ToFloat32)      \
+  V(BitcastInt64ToFloat64)      \
+  V(Float32Add)                 \
+  V(Float32Sub)                 \
+  V(Float32Mul)                 \
+  V(Float32Div)                 \
+  V(Float32Max)                 \
+  V(Float32Min)                 \
+  V(Float32Abs)                 \
+  V(Float32Sqrt)                \
+  V(Float32RoundDown)           \
+  V(Float64Add)                 \
+  V(Float64Sub)                 \
+  V(Float64Mul)                 \
+  V(Float64Div)                 \
+  V(Float64Mod)                 \
+  V(Float64Max)                 \
+  V(Float64Min)                 \
+  V(Float64Abs)                 \
+  V(Float64Sqrt)                \
+  V(Float64RoundDown)           \
+  V(Float32RoundUp)             \
+  V(Float64RoundUp)             \
+  V(Float32RoundTruncate)       \
+  V(Float64RoundTruncate)       \
+  V(Float64RoundTiesAway)       \
+  V(Float32RoundTiesEven)       \
+  V(Float64RoundTiesEven)       \
+  V(Float64ExtractLowWord32)    \
+  V(Float64ExtractHighWord32)   \
+  V(Float64InsertLowWord32)     \
+  V(Float64InsertHighWord32)    \
+  V(LoadStackPointer)           \
+  V(LoadFramePointer)           \
+  V(CheckedLoad)                \
   V(CheckedStore)
 
 #define VALUE_OP_LIST(V) \
@@ -271,60 +356,53 @@
   // Returns the mnemonic name of an opcode.
   static char const* Mnemonic(Value value);
 
-  static bool IsJsOpcode(Value val) {
-    switch (val) {
-// TODO(turbofan): make this a range check.
-#define RETURN_NAME(x) \
-  case k##x:           \
-    return true;
-      JS_OP_LIST(RETURN_NAME)
-#undef RETURN_NAME
-      default:
-        return false;
-    }
+  // Returns true if opcode for common operator.
+  static bool IsCommonOpcode(Value value) {
+    return kStart <= value && value <= kDead;
   }
 
-  static bool IsControlOpcode(Value val) {
-    switch (val) {
-// TODO(turbofan): make this a range check.
-#define RETURN_NAME(x) \
-  case k##x:           \
-    return true;
-      CONTROL_OP_LIST(RETURN_NAME)
-#undef RETURN_NAME
-      default:
-        return false;
-    }
+  // Returns true if opcode for control operator.
+  static bool IsControlOpcode(Value value) {
+    return kStart <= value && value <= kEnd;
   }
 
-  static bool IsLeafOpcode(Value val) {
-    switch (val) {
-// TODO(turbofan): make this a table lookup.
-#define RETURN_NAME(x) \
-  case k##x:           \
-    return true;
-      LEAF_OP_LIST(RETURN_NAME)
-#undef RETURN_NAME
-      default:
-        return false;
-    }
+  // Returns true if opcode for JavaScript operator.
+  static bool IsJsOpcode(Value value) {
+    return kJSEqual <= value && value <= kJSStackCheck;
   }
 
-  static bool IsCommonOpcode(Value val) {
-    switch (val) {
-// TODO(turbofan): make this a table lookup or a range check.
-#define RETURN_NAME(x) \
-  case k##x:           \
-    return true;
-      CONTROL_OP_LIST(RETURN_NAME)
-      COMMON_OP_LIST(RETURN_NAME)
-#undef RETURN_NAME
-      default:
-        return false;
-    }
+  // Returns true if opcode for constant operator.
+  static bool IsConstantOpcode(Value value) {
+    return kInt32Constant <= value && value <= kHeapConstant;
+  }
+
+  static bool IsPhiOpcode(Value value) {
+    return value == kPhi || value == kEffectPhi;
+  }
+
+  static bool IsMergeOpcode(Value value) {
+    return value == kMerge || value == kLoop;
+  }
+
+  static bool IsIfProjectionOpcode(Value value) {
+    return kIfTrue <= value && value <= kIfDefault;
+  }
+
+  // Returns true if opcode can be inlined.
+  static bool IsInlineeOpcode(Value value) {
+    return value == kJSCallConstruct || value == kJSCallFunction;
+  }
+
+  // Returns true if opcode for comparison operator.
+  static bool IsComparisonOpcode(Value value) {
+    return (kJSEqual <= value && value <= kJSGreaterThanOrEqual) ||
+           (kNumberEqual <= value && value <= kStringLessThanOrEqual) ||
+           (kWord32Equal <= value && value <= kFloat64LessThanOrEqual);
   }
 };
 
+std::ostream& operator<<(std::ostream&, IrOpcode::Value);
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/src/compiler/operator-properties.cc b/src/compiler/operator-properties.cc
index abfc5fd..bd704a3 100644
--- a/src/compiler/operator-properties.cc
+++ b/src/compiler/operator-properties.cc
@@ -20,63 +20,95 @@
 
 
 // static
-bool OperatorProperties::HasFrameStateInput(const Operator* op) {
-  if (!FLAG_turbo_deoptimization) {
-    return false;
-  }
+int OperatorProperties::GetFrameStateInputCount(const Operator* op) {
   switch (op->opcode()) {
     case IrOpcode::kFrameState:
-      return true;
+      return 1;
     case IrOpcode::kJSCallRuntime: {
       const CallRuntimeParameters& p = CallRuntimeParametersOf(op);
-      return Linkage::NeedsFrameState(p.id());
+      return Linkage::FrameStateInputCount(p.id());
     }
 
     // Strict equality cannot lazily deoptimize.
     case IrOpcode::kJSStrictEqual:
     case IrOpcode::kJSStrictNotEqual:
-      return false;
+      return 0;
 
-    // Calls
-    case IrOpcode::kJSCallFunction:
+    // We record the frame state immediately before and immediately after every
+    // construct/function call.
     case IrOpcode::kJSCallConstruct:
+    case IrOpcode::kJSCallFunction:
+      return 2;
 
     // Compare operations
     case IrOpcode::kJSEqual:
-    case IrOpcode::kJSGreaterThan:
-    case IrOpcode::kJSGreaterThanOrEqual:
+    case IrOpcode::kJSNotEqual:
     case IrOpcode::kJSHasProperty:
     case IrOpcode::kJSInstanceOf:
-    case IrOpcode::kJSLessThan:
-    case IrOpcode::kJSLessThanOrEqual:
-    case IrOpcode::kJSNotEqual:
 
-    // Binary operations
+    // Object operations
+    case IrOpcode::kJSCreate:
+    case IrOpcode::kJSCreateArguments:
+    case IrOpcode::kJSCreateArray:
+    case IrOpcode::kJSCreateLiteralArray:
+    case IrOpcode::kJSCreateLiteralObject:
+    case IrOpcode::kJSCreateLiteralRegExp:
+
+    // Context operations
+    case IrOpcode::kJSLoadDynamic:
+    case IrOpcode::kJSCreateScriptContext:
+
+    // Conversions
+    case IrOpcode::kJSToName:
+    case IrOpcode::kJSToNumber:
+    case IrOpcode::kJSToObject:
+    case IrOpcode::kJSToString:
+
+    // Misc operations
+    case IrOpcode::kJSConvertReceiver:
+    case IrOpcode::kJSForInNext:
+    case IrOpcode::kJSForInPrepare:
+    case IrOpcode::kJSStackCheck:
+    case IrOpcode::kJSDeleteProperty:
+      return 1;
+
+    // We record the frame state immediately before and immediately after
+    // every property or global variable access.
+    case IrOpcode::kJSLoadNamed:
+    case IrOpcode::kJSStoreNamed:
+    case IrOpcode::kJSLoadProperty:
+    case IrOpcode::kJSStoreProperty:
+    case IrOpcode::kJSLoadGlobal:
+    case IrOpcode::kJSStoreGlobal:
+      return 2;
+
+    // Binary operators that can deopt in the middle the operation (e.g.,
+    // as a result of lazy deopt in ToNumber conversion) need a second frame
+    // state so that we can resume before the operation.
+    case IrOpcode::kJSMultiply:
     case IrOpcode::kJSAdd:
     case IrOpcode::kJSBitwiseAnd:
     case IrOpcode::kJSBitwiseOr:
     case IrOpcode::kJSBitwiseXor:
     case IrOpcode::kJSDivide:
-    case IrOpcode::kJSLoadNamed:
-    case IrOpcode::kJSLoadProperty:
     case IrOpcode::kJSModulus:
-    case IrOpcode::kJSMultiply:
     case IrOpcode::kJSShiftLeft:
     case IrOpcode::kJSShiftRight:
     case IrOpcode::kJSShiftRightLogical:
-    case IrOpcode::kJSStoreNamed:
-    case IrOpcode::kJSStoreProperty:
     case IrOpcode::kJSSubtract:
+      return 2;
 
-    // Conversions
-    case IrOpcode::kJSToObject:
-
-    // Other
-    case IrOpcode::kJSDeleteProperty:
-      return true;
+    // Compare operators that can deopt in the middle the operation (e.g.,
+    // as a result of lazy deopt in ToNumber conversion) need a second frame
+    // state so that we can resume before the operation.
+    case IrOpcode::kJSGreaterThan:
+    case IrOpcode::kJSGreaterThanOrEqual:
+    case IrOpcode::kJSLessThan:
+    case IrOpcode::kJSLessThanOrEqual:
+      return 2;
 
     default:
-      return false;
+      return 0;
   }
 }
 
@@ -95,7 +127,9 @@
   return opcode == IrOpcode::kStart || opcode == IrOpcode::kEnd ||
          opcode == IrOpcode::kDead || opcode == IrOpcode::kLoop ||
          opcode == IrOpcode::kMerge || opcode == IrOpcode::kIfTrue ||
-         opcode == IrOpcode::kIfFalse;
+         opcode == IrOpcode::kIfFalse || opcode == IrOpcode::kIfSuccess ||
+         opcode == IrOpcode::kIfException || opcode == IrOpcode::kIfValue ||
+         opcode == IrOpcode::kIfDefault;
 }
 
 }  // namespace compiler
diff --git a/src/compiler/operator-properties.h b/src/compiler/operator-properties.h
index 37c9755..e7ecd93 100644
--- a/src/compiler/operator-properties.h
+++ b/src/compiler/operator-properties.h
@@ -15,17 +15,14 @@
 class Operator;
 
 
-class OperatorProperties FINAL {
+class OperatorProperties final {
  public:
   static bool HasContextInput(const Operator* op);
-  static bool HasFrameStateInput(const Operator* op);
-
   static int GetContextInputCount(const Operator* op) {
     return HasContextInput(op) ? 1 : 0;
   }
-  static int GetFrameStateInputCount(const Operator* op) {
-    return HasFrameStateInput(op) ? 1 : 0;
-  }
+  static int GetFrameStateInputCount(const Operator* op);
+
   static int GetTotalInputCount(const Operator* op);
 
   static bool IsBasicBlockBegin(const Operator* op);
diff --git a/src/compiler/operator.cc b/src/compiler/operator.cc
index c8687f4..ae10348 100644
--- a/src/compiler/operator.cc
+++ b/src/compiler/operator.cc
@@ -10,13 +10,20 @@
 namespace internal {
 namespace compiler {
 
+namespace {
 
 template <typename N>
-static inline N CheckRange(size_t val) {
-  CHECK(val <= std::numeric_limits<N>::max());
+V8_INLINE N CheckRange(size_t val) {
+  CHECK_LE(val, std::numeric_limits<N>::max());
   return static_cast<N>(val);
 }
 
+}  // namespace
+
+
+// static
+STATIC_CONST_MEMBER_DEFINITION const size_t Operator::kMaxControlOutputCount;
+
 
 Operator::Operator(Opcode opcode, Properties properties, const char* mnemonic,
                    size_t value_in, size_t effect_in, size_t control_in,
@@ -29,7 +36,7 @@
       control_in_(CheckRange<uint16_t>(control_in)),
       value_out_(CheckRange<uint16_t>(value_out)),
       effect_out_(CheckRange<uint8_t>(effect_out)),
-      control_out_(CheckRange<uint8_t>(control_out)) {}
+      control_out_(CheckRange<uint16_t>(control_out)) {}
 
 
 std::ostream& operator<<(std::ostream& os, const Operator& op) {
diff --git a/src/compiler/operator.h b/src/compiler/operator.h
index fb144ce..fa85d59 100644
--- a/src/compiler/operator.h
+++ b/src/compiler/operator.h
@@ -9,6 +9,7 @@
 
 #include "src/base/flags.h"
 #include "src/base/functional.h"
+#include "src/handles.h"
 #include "src/zone.h"
 
 namespace v8 {
@@ -29,7 +30,7 @@
 // meaningful to the operator itself.
 class Operator : public ZoneObject {
  public:
-  typedef uint8_t Opcode;
+  typedef uint16_t Opcode;
 
   // Properties inform the operator-independent optimizer about legal
   // transformations for nodes that have this operator.
@@ -44,6 +45,7 @@
                             // create new scheduling dependencies.
     kNoThrow = 1 << 6,      // Can never generate an exception.
     kFoldable = kNoRead | kNoWrite,
+    kKontrol = kFoldable | kNoThrow,
     kEliminatable = kNoWrite | kNoThrow,
     kPure = kNoRead | kNoWrite | kNoThrow | kIdempotent
   };
@@ -84,6 +86,9 @@
 
   Properties properties() const { return properties_; }
 
+  // TODO(bmeurer): Use bit fields below?
+  static const size_t kMaxControlOutputCount = (1u << 16) - 1;
+
   // TODO(titzer): convert return values here to size_t.
   int ValueInputCount() const { return value_in_; }
   int EffectInputCount() const { return effect_in_; }
@@ -93,7 +98,15 @@
   int EffectOutputCount() const { return effect_out_; }
   int ControlOutputCount() const { return control_out_; }
 
-  static inline size_t ZeroIfPure(Properties properties) {
+  static size_t ZeroIfEliminatable(Properties properties) {
+    return (properties & kEliminatable) == kEliminatable ? 0 : 1;
+  }
+
+  static size_t ZeroIfNoThrow(Properties properties) {
+    return (properties & kNoThrow) == kNoThrow ? 0 : 2;
+  }
+
+  static size_t ZeroIfPure(Properties properties) {
     return (properties & kPure) == kPure ? 0 : 1;
   }
 
@@ -113,7 +126,7 @@
   uint16_t control_in_;
   uint16_t value_out_;
   uint8_t effect_out_;
-  uint8_t control_out_;
+  uint16_t control_out_;
 
   DISALLOW_COPY_AND_ASSIGN(Operator);
 };
@@ -123,10 +136,19 @@
 std::ostream& operator<<(std::ostream& os, const Operator& op);
 
 
+// Default equality function for below Operator1<*> class.
+template <typename T>
+struct OpEqualTo : public std::equal_to<T> {};
+
+
+// Default hashing function for below Operator1<*> class.
+template <typename T>
+struct OpHash : public base::hash<T> {};
+
+
 // A templatized implementation of Operator that has one static parameter of
-// type {T}.
-template <typename T, typename Pred = std::equal_to<T>,
-          typename Hash = base::hash<T>>
+// type {T} with the proper default equality and hashing functions.
+template <typename T, typename Pred = OpEqualTo<T>, typename Hash = OpHash<T>>
 class Operator1 : public Operator {
  public:
   Operator1(Opcode opcode, Properties properties, const char* mnemonic,
@@ -141,12 +163,13 @@
 
   T const& parameter() const { return parameter_; }
 
-  bool Equals(const Operator* other) const FINAL {
+  bool Equals(const Operator* other) const final {
     if (opcode() != other->opcode()) return false;
-    const Operator1<T>* that = static_cast<const Operator1<T>*>(other);
+    const Operator1<T, Pred, Hash>* that =
+        reinterpret_cast<const Operator1<T, Pred, Hash>*>(other);
     return this->pred_(this->parameter(), that->parameter());
   }
-  size_t HashCode() const FINAL {
+  size_t HashCode() const final {
     return base::hash_combine(this->opcode(), this->hash_(this->parameter()));
   }
   virtual void PrintParameter(std::ostream& os) const {
@@ -154,7 +177,7 @@
   }
 
  protected:
-  void PrintTo(std::ostream& os) const FINAL {
+  void PrintTo(std::ostream& os) const final {
     os << mnemonic();
     PrintParameter(os);
   }
@@ -169,22 +192,38 @@
 // Helper to extract parameters from Operator1<*> operator.
 template <typename T>
 inline T const& OpParameter(const Operator* op) {
-  return static_cast<const Operator1<T>*>(op)->parameter();
+  return reinterpret_cast<const Operator1<T, OpEqualTo<T>, OpHash<T>>*>(op)
+      ->parameter();
 }
 
+
 // NOTE: We have to be careful to use the right equal/hash functions below, for
-// float/double we always use the ones operating on the bit level.
+// float/double we always use the ones operating on the bit level, for Handle<>
+// we always use the ones operating on the location level.
 template <>
-inline float const& OpParameter(const Operator* op) {
-  return static_cast<const Operator1<float, base::bit_equal_to<float>,
-                                     base::bit_hash<float>>*>(op)->parameter();
-}
+struct OpEqualTo<float> : public base::bit_equal_to<float> {};
+template <>
+struct OpHash<float> : public base::bit_hash<float> {};
 
 template <>
-inline double const& OpParameter(const Operator* op) {
-  return static_cast<const Operator1<double, base::bit_equal_to<double>,
-                                     base::bit_hash<double>>*>(op)->parameter();
-}
+struct OpEqualTo<double> : public base::bit_equal_to<double> {};
+template <>
+struct OpHash<double> : public base::bit_hash<double> {};
+
+template <>
+struct OpEqualTo<Handle<HeapObject>> : public Handle<HeapObject>::equal_to {};
+template <>
+struct OpHash<Handle<HeapObject>> : public Handle<HeapObject>::hash {};
+
+template <>
+struct OpEqualTo<Handle<String>> : public Handle<String>::equal_to {};
+template <>
+struct OpHash<Handle<String>> : public Handle<String>::hash {};
+
+template <>
+struct OpEqualTo<Handle<ScopeInfo>> : public Handle<ScopeInfo>::equal_to {};
+template <>
+struct OpHash<Handle<ScopeInfo>> : public Handle<ScopeInfo>::hash {};
 
 }  // namespace compiler
 }  // namespace internal
diff --git a/src/compiler/osr.cc b/src/compiler/osr.cc
new file mode 100644
index 0000000..55431c2
--- /dev/null
+++ b/src/compiler/osr.cc
@@ -0,0 +1,337 @@
+// 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/ast/scopes.h"
+#include "src/compiler.h"
+#include "src/compiler/all-nodes.h"
+#include "src/compiler/common-operator.h"
+#include "src/compiler/common-operator-reducer.h"
+#include "src/compiler/dead-code-elimination.h"
+#include "src/compiler/frame.h"
+#include "src/compiler/graph.h"
+#include "src/compiler/graph-reducer.h"
+#include "src/compiler/graph-trimmer.h"
+#include "src/compiler/graph-visualizer.h"
+#include "src/compiler/js-graph.h"
+#include "src/compiler/loop-analysis.h"
+#include "src/compiler/node.h"
+#include "src/compiler/node-marker.h"
+#include "src/compiler/osr.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+OsrHelper::OsrHelper(CompilationInfo* info)
+    : parameter_count_(info->scope()->num_parameters()),
+      stack_slot_count_(info->scope()->num_stack_slots() +
+                        info->osr_expr_stack_height()) {}
+
+
+#ifdef DEBUG
+#define TRACE_COND (FLAG_trace_turbo_graph && FLAG_trace_osr)
+#else
+#define TRACE_COND false
+#endif
+
+#define TRACE(...)                       \
+  do {                                   \
+    if (TRACE_COND) PrintF(__VA_ARGS__); \
+  } while (false)
+
+
+// Peel outer loops and rewire the graph so that control reduction can
+// produce a properly formed graph.
+static void PeelOuterLoopsForOsr(Graph* graph, CommonOperatorBuilder* common,
+                                 Zone* tmp_zone, Node* dead,
+                                 LoopTree* loop_tree, LoopTree::Loop* osr_loop,
+                                 Node* osr_normal_entry, Node* osr_loop_entry) {
+  const size_t original_count = graph->NodeCount();
+  AllNodes all(tmp_zone, graph);
+  NodeVector tmp_inputs(tmp_zone);
+  Node* sentinel = graph->NewNode(dead->op());
+
+  // Make a copy of the graph for each outer loop.
+  ZoneVector<NodeVector*> copies(tmp_zone);
+  for (LoopTree::Loop* loop = osr_loop->parent(); loop; loop = loop->parent()) {
+    void* stuff = tmp_zone->New(sizeof(NodeVector));
+    NodeVector* mapping =
+        new (stuff) NodeVector(original_count, sentinel, tmp_zone);
+    copies.push_back(mapping);
+    TRACE("OsrDuplication #%zu, depth %zu, header #%d:%s\n", copies.size(),
+          loop->depth(), loop_tree->HeaderNode(loop)->id(),
+          loop_tree->HeaderNode(loop)->op()->mnemonic());
+
+    // Prepare the mapping for OSR values and the OSR loop entry.
+    mapping->at(osr_normal_entry->id()) = dead;
+    mapping->at(osr_loop_entry->id()) = dead;
+
+    // The outer loops are dead in this copy.
+    for (LoopTree::Loop* outer = loop->parent(); outer;
+         outer = outer->parent()) {
+      for (Node* node : loop_tree->HeaderNodes(outer)) {
+        mapping->at(node->id()) = dead;
+        TRACE(" ---- #%d:%s -> dead (header)\n", node->id(),
+              node->op()->mnemonic());
+      }
+    }
+
+    // Copy all nodes.
+    for (size_t i = 0; i < all.live.size(); i++) {
+      Node* orig = all.live[i];
+      Node* copy = mapping->at(orig->id());
+      if (copy != sentinel) {
+        // Mapping already exists.
+        continue;
+      }
+      if (orig->InputCount() == 0 || orig->opcode() == IrOpcode::kParameter ||
+          orig->opcode() == IrOpcode::kOsrValue) {
+        // No need to copy leaf nodes or parameters.
+        mapping->at(orig->id()) = orig;
+        continue;
+      }
+
+      // Copy the node.
+      tmp_inputs.clear();
+      for (Node* input : orig->inputs()) {
+        tmp_inputs.push_back(mapping->at(input->id()));
+      }
+      copy = graph->NewNode(orig->op(), orig->InputCount(), &tmp_inputs[0]);
+      if (NodeProperties::IsTyped(orig)) {
+        NodeProperties::SetType(copy, NodeProperties::GetType(orig));
+      }
+      mapping->at(orig->id()) = copy;
+      TRACE(" copy #%d:%s -> #%d\n", orig->id(), orig->op()->mnemonic(),
+            copy->id());
+    }
+
+    // Fix missing inputs.
+    for (Node* orig : all.live) {
+      Node* copy = mapping->at(orig->id());
+      for (int j = 0; j < copy->InputCount(); j++) {
+        if (copy->InputAt(j) == sentinel) {
+          copy->ReplaceInput(j, mapping->at(orig->InputAt(j)->id()));
+        }
+      }
+    }
+
+    // Construct the entry into this loop from previous copies.
+
+    // Gather the live loop header nodes, {loop_header} first.
+    Node* loop_header = loop_tree->HeaderNode(loop);
+    NodeVector header_nodes(tmp_zone);
+    header_nodes.reserve(loop->HeaderSize());
+    header_nodes.push_back(loop_header);  // put the loop header first.
+    for (Node* node : loop_tree->HeaderNodes(loop)) {
+      if (node != loop_header && all.IsLive(node)) {
+        header_nodes.push_back(node);
+      }
+    }
+
+    // Gather backedges from the previous copies of the inner loops of {loop}.
+    NodeVectorVector backedges(tmp_zone);
+    TRACE("Gathering backedges...\n");
+    for (int i = 1; i < loop_header->InputCount(); i++) {
+      if (TRACE_COND) {
+        Node* control = loop_header->InputAt(i);
+        size_t incoming_depth = 0;
+        for (int j = 0; j < control->op()->ControlInputCount(); j++) {
+          Node* k = NodeProperties::GetControlInput(control, j);
+          incoming_depth =
+              std::max(incoming_depth, loop_tree->ContainingLoop(k)->depth());
+        }
+
+        TRACE(" edge @%d #%d:%s, incoming depth %zu\n", i, control->id(),
+              control->op()->mnemonic(), incoming_depth);
+      }
+
+      for (int pos = static_cast<int>(copies.size()) - 1; pos >= 0; pos--) {
+        backedges.push_back(NodeVector(tmp_zone));
+        backedges.back().reserve(header_nodes.size());
+
+        NodeVector* previous_map = pos > 0 ? copies[pos - 1] : nullptr;
+
+        for (Node* node : header_nodes) {
+          Node* input = node->InputAt(i);
+          if (previous_map) input = previous_map->at(input->id());
+          backedges.back().push_back(input);
+          TRACE("   node #%d:%s(@%d) = #%d:%s\n", node->id(),
+                node->op()->mnemonic(), i, input->id(),
+                input->op()->mnemonic());
+        }
+      }
+    }
+
+    int backedge_count = static_cast<int>(backedges.size());
+    if (backedge_count == 1) {
+      // Simple case of single backedge, therefore a single entry.
+      int index = 0;
+      for (Node* node : header_nodes) {
+        Node* copy = mapping->at(node->id());
+        Node* input = backedges[0][index];
+        copy->ReplaceInput(0, input);
+        TRACE(" header #%d:%s(0) => #%d:%s\n", copy->id(),
+              copy->op()->mnemonic(), input->id(), input->op()->mnemonic());
+        index++;
+      }
+    } else {
+      // Complex case of multiple backedges from previous copies requires
+      // merging the backedges to create the entry into the loop header.
+      Node* merge = nullptr;
+      int index = 0;
+      for (Node* node : header_nodes) {
+        // Gather edge inputs into {tmp_inputs}.
+        tmp_inputs.clear();
+        for (int edge = 0; edge < backedge_count; edge++) {
+          tmp_inputs.push_back(backedges[edge][index]);
+        }
+        Node* copy = mapping->at(node->id());
+        Node* input;
+        if (node == loop_header) {
+          // Create the merge for the entry into the loop header.
+          input = merge = graph->NewNode(common->Merge(backedge_count),
+                                         backedge_count, &tmp_inputs[0]);
+          copy->ReplaceInput(0, merge);
+        } else {
+          // Create a phi that merges values at entry into the loop header.
+          DCHECK_NOT_NULL(merge);
+          DCHECK(IrOpcode::IsPhiOpcode(node->opcode()));
+          tmp_inputs.push_back(merge);
+          Node* phi = input = graph->NewNode(
+              common->ResizeMergeOrPhi(node->op(), backedge_count),
+              backedge_count + 1, &tmp_inputs[0]);
+          copy->ReplaceInput(0, phi);
+        }
+
+        // Print the merge.
+        if (TRACE_COND) {
+          TRACE(" header #%d:%s(0) => #%d:%s(", copy->id(),
+                copy->op()->mnemonic(), input->id(), input->op()->mnemonic());
+          for (size_t i = 0; i < tmp_inputs.size(); i++) {
+            if (i > 0) TRACE(", ");
+            Node* input = tmp_inputs[i];
+            TRACE("#%d:%s", input->id(), input->op()->mnemonic());
+          }
+          TRACE(")\n");
+        }
+
+        index++;
+      }
+    }
+  }
+
+  // Kill the outer loops in the original graph.
+  TRACE("Killing outer loop headers...\n");
+  for (LoopTree::Loop* outer = osr_loop->parent(); outer;
+       outer = outer->parent()) {
+    Node* loop_header = loop_tree->HeaderNode(outer);
+    loop_header->ReplaceUses(dead);
+    TRACE(" ---- #%d:%s\n", loop_header->id(), loop_header->op()->mnemonic());
+  }
+
+  // Merge the ends of the graph copies.
+  Node* const end = graph->end();
+  int const input_count = end->InputCount();
+  for (int i = 0; i < input_count; ++i) {
+    NodeId const id = end->InputAt(i)->id();
+    for (NodeVector* const copy : copies) {
+      end->AppendInput(graph->zone(), copy->at(id));
+      NodeProperties::ChangeOp(end, common->End(end->InputCount()));
+    }
+  }
+
+  if (FLAG_trace_turbo_graph) {  // Simple textual RPO.
+    OFStream os(stdout);
+    os << "-- Graph after OSR duplication -- " << std::endl;
+    os << AsRPO(*graph);
+  }
+}
+
+
+void OsrHelper::Deconstruct(JSGraph* jsgraph, CommonOperatorBuilder* common,
+                            Zone* tmp_zone) {
+  Graph* graph = jsgraph->graph();
+  Node* osr_normal_entry = nullptr;
+  Node* osr_loop_entry = nullptr;
+  Node* osr_loop = nullptr;
+
+  for (Node* node : graph->start()->uses()) {
+    if (node->opcode() == IrOpcode::kOsrLoopEntry) {
+      osr_loop_entry = node;  // found the OSR loop entry
+    } else if (node->opcode() == IrOpcode::kOsrNormalEntry) {
+      osr_normal_entry = node;
+    }
+  }
+
+  if (osr_loop_entry == nullptr) {
+    // No OSR entry found, do nothing.
+    CHECK(osr_normal_entry);
+    return;
+  }
+
+  for (Node* use : osr_loop_entry->uses()) {
+    if (use->opcode() == IrOpcode::kLoop) {
+      CHECK(!osr_loop);             // should be only one OSR loop.
+      osr_loop = use;               // found the OSR loop.
+    }
+  }
+
+  CHECK(osr_loop);  // Should have found the OSR loop.
+
+  // Analyze the graph to determine how deeply nested the OSR loop is.
+  LoopTree* loop_tree = LoopFinder::BuildLoopTree(graph, tmp_zone);
+
+  Node* dead = jsgraph->Dead();
+  LoopTree::Loop* loop = loop_tree->ContainingLoop(osr_loop);
+  if (loop->depth() > 0) {
+    PeelOuterLoopsForOsr(graph, common, tmp_zone, dead, loop_tree, loop,
+                         osr_normal_entry, osr_loop_entry);
+  }
+
+  // Replace the normal entry with {Dead} and the loop entry with {Start}
+  // and run the control reducer to clean up the graph.
+  osr_normal_entry->ReplaceUses(dead);
+  osr_normal_entry->Kill();
+  osr_loop_entry->ReplaceUses(graph->start());
+  osr_loop_entry->Kill();
+
+  // Remove the first input to the {osr_loop}.
+  int const live_input_count = osr_loop->InputCount() - 1;
+  CHECK_NE(0, live_input_count);
+  for (Node* const use : osr_loop->uses()) {
+    if (NodeProperties::IsPhi(use)) {
+      use->RemoveInput(0);
+      NodeProperties::ChangeOp(
+          use, common->ResizeMergeOrPhi(use->op(), live_input_count));
+    }
+  }
+  osr_loop->RemoveInput(0);
+  NodeProperties::ChangeOp(
+      osr_loop, common->ResizeMergeOrPhi(osr_loop->op(), live_input_count));
+
+  // Run control reduction and graph trimming.
+  // TODO(bmeurer): The OSR deconstruction could be a regular reducer and play
+  // nice together with the rest, instead of having this custom stuff here.
+  GraphReducer graph_reducer(tmp_zone, graph);
+  DeadCodeElimination dce(&graph_reducer, graph, common);
+  CommonOperatorReducer cor(&graph_reducer, graph, common, jsgraph->machine());
+  graph_reducer.AddReducer(&dce);
+  graph_reducer.AddReducer(&cor);
+  graph_reducer.ReduceGraph();
+  GraphTrimmer trimmer(tmp_zone, graph);
+  NodeVector roots(tmp_zone);
+  jsgraph->GetCachedNodes(&roots);
+  trimmer.TrimGraph(roots.begin(), roots.end());
+}
+
+
+void OsrHelper::SetupFrame(Frame* frame) {
+  // The optimized frame will subsume the unoptimized frame. Do so by reserving
+  // the first spill slots.
+  frame->ReserveSpillSlots(UnoptimizedFrameSlots());
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/osr.h b/src/compiler/osr.h
new file mode 100644
index 0000000..89773f0
--- /dev/null
+++ b/src/compiler/osr.h
@@ -0,0 +1,126 @@
+// 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.
+
+#ifndef V8_COMPILER_OSR_H_
+#define V8_COMPILER_OSR_H_
+
+#include "src/zone.h"
+
+// TurboFan structures OSR graphs in a way that separates almost all phases of
+// compilation from OSR implementation details. This is accomplished with
+// special control nodes that are added at graph building time. In particular,
+// the graph is built in such a way that typing still computes the best types
+// and optimizations and lowering work unchanged. All that remains is to
+// deconstruct the OSR artifacts before scheduling and code generation.
+
+// Graphs built for OSR from the AstGraphBuilder are structured as follows:
+//                             Start
+//          +-------------------^^-----+
+//          |                          |
+//   OsrNormalEntry               OsrLoopEntry <-------------+
+//          |                          |                     |
+//   control flow before loop          |           A     OsrValue
+//          |                          |           |         |
+//          | +------------------------+           | +-------+
+//          | | +-------------+                    | | +--------+
+//          | | |             |                    | | |        |
+//        ( Loop )<-----------|------------------ ( phi )       |
+//          |                 |                                 |
+//      loop body             | backedge(s)                     |
+//          |  |              |                                 |
+//          |  +--------------+                        B  <-----+
+//          |
+//         end
+
+// The control structure expresses the relationship that the loop has a separate
+// entrypoint which corresponds to entering the loop directly from the middle
+// of unoptimized code.
+// Similarly, the values that come in from unoptimized code are represented with
+// {OsrValue} nodes that merge into any phis associated with the OSR loop.
+// In the above diagram, nodes {A} and {B} represent values in the "normal"
+// graph that correspond to the values of those phis before the loop and on any
+// backedges, respectively.
+
+// To deconstruct OSR, we simply replace the uses of the {OsrNormalEntry}
+// control node with {Dead} and {OsrLoopEntry} with start and run the
+// {ControlReducer}. Control reduction propagates the dead control forward,
+// essentially "killing" all the code before the OSR loop. The entrypoint to the
+// loop corresponding to the "normal" entry path will also be removed, as well
+// as the inputs to the loop phis, resulting in the reduced graph:
+
+//                             Start
+//         Dead                  |^-------------------------+
+//          |                    |                          |
+//          |                    |                          |
+//          |                    |                          |
+//    disconnected, dead         |           A=dead      OsrValue
+//                               |                          |
+//            +------------------+                   +------+
+//            | +-------------+                      | +--------+
+//            | |             |                      | |        |
+//        ( Loop )<-----------|------------------ ( phi )       |
+//          |                 |                                 |
+//      loop body             | backedge(s)                     |
+//          |  |              |                                 |
+//          |  +--------------+                        B  <-----+
+//          |
+//         end
+
+// Other than the presences of the OsrValue nodes, this is a normal, schedulable
+// graph. OsrValue nodes are handled specially in the instruction selector to
+// simply load from the unoptimized frame.
+
+// For nested OSR loops, loop peeling must first be applied as many times as
+// necessary in order to bring the OSR loop up to the top level (i.e. to be
+// an outer loop).
+
+namespace v8 {
+namespace internal {
+
+class CompilationInfo;
+
+namespace compiler {
+
+class JSGraph;
+class CommonOperatorBuilder;
+class Frame;
+class Linkage;
+
+// Encapsulates logic relating to OSR compilations as well has handles some
+// details of the frame layout.
+class OsrHelper {
+ public:
+  explicit OsrHelper(CompilationInfo* info);
+  // Only for testing.
+  OsrHelper(size_t parameter_count, size_t stack_slot_count)
+      : parameter_count_(parameter_count),
+        stack_slot_count_(stack_slot_count) {}
+
+  // Deconstructs the artificial {OsrNormalEntry} and rewrites the graph so
+  // that only the path corresponding to {OsrLoopEntry} remains.
+  void Deconstruct(JSGraph* jsgraph, CommonOperatorBuilder* common,
+                   Zone* tmp_zone);
+
+  // Prepares the frame w.r.t. OSR.
+  void SetupFrame(Frame* frame);
+
+  // Returns the number of unoptimized frame slots for this OSR.
+  size_t UnoptimizedFrameSlots() { return stack_slot_count_; }
+
+  // Returns the environment index of the first stack slot.
+  static int FirstStackSlotIndex(int parameter_count) {
+    // n.b. unlike Crankshaft, TurboFan environments do not contain the context.
+    return 1 + parameter_count;  // receiver + params
+  }
+
+ private:
+  size_t parameter_count_;
+  size_t stack_slot_count_;
+};
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_OSR_H_
diff --git a/src/compiler/pipeline-statistics.cc b/src/compiler/pipeline-statistics.cc
index e58c396..b98f837 100644
--- a/src/compiler/pipeline-statistics.cc
+++ b/src/compiler/pipeline-statistics.cc
@@ -36,23 +36,23 @@
       diff->max_allocated_bytes_ + allocated_bytes_at_start_;
   diff->total_allocated_bytes_ =
       outer_zone_diff + scope_->GetTotalAllocatedBytes();
-  scope_.Reset(NULL);
+  scope_.Reset(nullptr);
   timer_.Stop();
 }
 
 
 PipelineStatistics::PipelineStatistics(CompilationInfo* info,
                                        ZonePool* zone_pool)
-    : isolate_(info->zone()->isolate()),
+    : isolate_(info->isolate()),
       outer_zone_(info->zone()),
       zone_pool_(zone_pool),
       compilation_stats_(isolate_->GetTurboStatistics()),
       source_size_(0),
-      phase_kind_name_(NULL),
-      phase_name_(NULL) {
-  if (!info->shared_info().is_null()) {
+      phase_kind_name_(nullptr),
+      phase_name_(nullptr) {
+  if (info->has_shared_info()) {
     source_size_ = static_cast<size_t>(info->shared_info()->SourceSize());
-    SmartArrayPointer<char> name =
+    base::SmartArrayPointer<char> name =
         info->shared_info()->DebugName()->ToCString();
     function_name_ = name.get();
   }
diff --git a/src/compiler/pipeline-statistics.h b/src/compiler/pipeline-statistics.h
index 01cc9de..2b6563d 100644
--- a/src/compiler/pipeline-statistics.h
+++ b/src/compiler/pipeline-statistics.h
@@ -36,7 +36,7 @@
     void End(PipelineStatistics* pipeline_stats,
              CompilationStatistics::BasicStats* diff);
 
-    SmartPointer<ZonePool::StatsScope> scope_;
+    base::SmartPointer<ZonePool::StatsScope> scope_;
     base::ElapsedTimer timer_;
     size_t outer_zone_initial_size_;
     size_t allocated_bytes_at_start_;
@@ -76,10 +76,10 @@
  public:
   PhaseScope(PipelineStatistics* pipeline_stats, const char* name)
       : pipeline_stats_(pipeline_stats) {
-    if (pipeline_stats_ != NULL) pipeline_stats_->BeginPhase(name);
+    if (pipeline_stats_ != nullptr) pipeline_stats_->BeginPhase(name);
   }
   ~PhaseScope() {
-    if (pipeline_stats_ != NULL) pipeline_stats_->EndPhase();
+    if (pipeline_stats_ != nullptr) pipeline_stats_->EndPhase();
   }
 
  private:
diff --git a/src/compiler/pipeline.cc b/src/compiler/pipeline.cc
index c7432c6..4d6aacd 100644
--- a/src/compiler/pipeline.cc
+++ b/src/compiler/pipeline.cc
@@ -7,27 +7,46 @@
 #include <fstream>  // NOLINT(readability/streams)
 #include <sstream>
 
+#include "src/base/adapters.h"
 #include "src/base/platform/elapsed-timer.h"
 #include "src/compiler/ast-graph-builder.h"
 #include "src/compiler/ast-loop-assignment-analyzer.h"
 #include "src/compiler/basic-block-instrumentor.h"
+#include "src/compiler/branch-elimination.h"
+#include "src/compiler/bytecode-graph-builder.h"
 #include "src/compiler/change-lowering.h"
 #include "src/compiler/code-generator.h"
 #include "src/compiler/common-operator-reducer.h"
-#include "src/compiler/control-reducer.h"
+#include "src/compiler/control-flow-optimizer.h"
+#include "src/compiler/dead-code-elimination.h"
+#include "src/compiler/escape-analysis.h"
+#include "src/compiler/escape-analysis-reducer.h"
+#include "src/compiler/frame-elider.h"
 #include "src/compiler/graph-replay.h"
+#include "src/compiler/graph-trimmer.h"
 #include "src/compiler/graph-visualizer.h"
+#include "src/compiler/greedy-allocator.h"
 #include "src/compiler/instruction.h"
 #include "src/compiler/instruction-selector.h"
 #include "src/compiler/js-builtin-reducer.h"
+#include "src/compiler/js-call-reducer.h"
+#include "src/compiler/js-context-relaxation.h"
 #include "src/compiler/js-context-specialization.h"
+#include "src/compiler/js-frame-specialization.h"
 #include "src/compiler/js-generic-lowering.h"
-#include "src/compiler/js-inlining.h"
+#include "src/compiler/js-global-object-specialization.h"
+#include "src/compiler/js-inlining-heuristic.h"
+#include "src/compiler/js-intrinsic-lowering.h"
+#include "src/compiler/js-native-context-specialization.h"
 #include "src/compiler/js-typed-lowering.h"
 #include "src/compiler/jump-threading.h"
+#include "src/compiler/live-range-separator.h"
 #include "src/compiler/load-elimination.h"
+#include "src/compiler/loop-analysis.h"
+#include "src/compiler/loop-peeling.h"
 #include "src/compiler/machine-operator-reducer.h"
 #include "src/compiler/move-optimizer.h"
+#include "src/compiler/osr.h"
 #include "src/compiler/pipeline-statistics.h"
 #include "src/compiler/register-allocator.h"
 #include "src/compiler/register-allocator-verifier.h"
@@ -35,12 +54,17 @@
 #include "src/compiler/scheduler.h"
 #include "src/compiler/select-lowering.h"
 #include "src/compiler/simplified-lowering.h"
+#include "src/compiler/simplified-operator.h"
 #include "src/compiler/simplified-operator-reducer.h"
+#include "src/compiler/tail-call-optimization.h"
+#include "src/compiler/type-hint-analyzer.h"
 #include "src/compiler/typer.h"
 #include "src/compiler/value-numbering-reducer.h"
 #include "src/compiler/verifier.h"
 #include "src/compiler/zone-pool.h"
 #include "src/ostreams.h"
+#include "src/register-configuration.h"
+#include "src/type-info.h"
 #include "src/utils.h"
 
 namespace v8 {
@@ -49,8 +73,79 @@
 
 class PipelineData {
  public:
-  explicit PipelineData(ZonePool* zone_pool, CompilationInfo* info)
-      : isolate_(info->zone()->isolate()),
+  // For main entry point.
+  PipelineData(ZonePool* zone_pool, CompilationInfo* info,
+               PipelineStatistics* pipeline_statistics)
+      : isolate_(info->isolate()),
+        info_(info),
+        outer_zone_(info_->zone()),
+        zone_pool_(zone_pool),
+        pipeline_statistics_(pipeline_statistics),
+        compilation_failed_(false),
+        code_(Handle<Code>::null()),
+        graph_zone_scope_(zone_pool_),
+        graph_zone_(graph_zone_scope_.zone()),
+        graph_(nullptr),
+        loop_assignment_(nullptr),
+        simplified_(nullptr),
+        machine_(nullptr),
+        common_(nullptr),
+        javascript_(nullptr),
+        jsgraph_(nullptr),
+        schedule_(nullptr),
+        instruction_zone_scope_(zone_pool_),
+        instruction_zone_(instruction_zone_scope_.zone()),
+        sequence_(nullptr),
+        frame_(nullptr),
+        register_allocation_zone_scope_(zone_pool_),
+        register_allocation_zone_(register_allocation_zone_scope_.zone()),
+        register_allocation_data_(nullptr) {
+    PhaseScope scope(pipeline_statistics, "init pipeline data");
+    graph_ = new (graph_zone_) Graph(graph_zone_);
+    source_positions_.Reset(new SourcePositionTable(graph_));
+    simplified_ = new (graph_zone_) SimplifiedOperatorBuilder(graph_zone_);
+    machine_ = new (graph_zone_) MachineOperatorBuilder(
+        graph_zone_, MachineType::PointerRepresentation(),
+        InstructionSelector::SupportedMachineOperatorFlags());
+    common_ = new (graph_zone_) CommonOperatorBuilder(graph_zone_);
+    javascript_ = new (graph_zone_) JSOperatorBuilder(graph_zone_);
+    jsgraph_ = new (graph_zone_)
+        JSGraph(isolate_, graph_, common_, javascript_, simplified_, machine_);
+  }
+
+  // For machine graph testing entry point.
+  PipelineData(ZonePool* zone_pool, CompilationInfo* info, Graph* graph,
+               Schedule* schedule)
+      : isolate_(info->isolate()),
+        info_(info),
+        outer_zone_(nullptr),
+        zone_pool_(zone_pool),
+        pipeline_statistics_(nullptr),
+        compilation_failed_(false),
+        code_(Handle<Code>::null()),
+        graph_zone_scope_(zone_pool_),
+        graph_zone_(nullptr),
+        graph_(graph),
+        source_positions_(new SourcePositionTable(graph_)),
+        loop_assignment_(nullptr),
+        simplified_(nullptr),
+        machine_(nullptr),
+        common_(nullptr),
+        javascript_(nullptr),
+        jsgraph_(nullptr),
+        schedule_(schedule),
+        instruction_zone_scope_(zone_pool_),
+        instruction_zone_(instruction_zone_scope_.zone()),
+        sequence_(nullptr),
+        frame_(nullptr),
+        register_allocation_zone_scope_(zone_pool_),
+        register_allocation_zone_(register_allocation_zone_scope_.zone()),
+        register_allocation_data_(nullptr) {}
+
+  // For register allocation testing entry point.
+  PipelineData(ZonePool* zone_pool, CompilationInfo* info,
+               InstructionSequence* sequence)
+      : isolate_(info->isolate()),
         info_(info),
         outer_zone_(nullptr),
         zone_pool_(zone_pool),
@@ -61,57 +156,26 @@
         graph_zone_(nullptr),
         graph_(nullptr),
         loop_assignment_(nullptr),
+        simplified_(nullptr),
         machine_(nullptr),
         common_(nullptr),
         javascript_(nullptr),
         jsgraph_(nullptr),
-        typer_(nullptr),
-        context_node_(nullptr),
         schedule_(nullptr),
         instruction_zone_scope_(zone_pool_),
-        instruction_zone_(nullptr),
-        sequence_(nullptr),
+        instruction_zone_(sequence->zone()),
+        sequence_(sequence),
         frame_(nullptr),
-        register_allocator_(nullptr) {}
+        register_allocation_zone_scope_(zone_pool_),
+        register_allocation_zone_(register_allocation_zone_scope_.zone()),
+        register_allocation_data_(nullptr) {}
 
   ~PipelineData() {
+    DeleteRegisterAllocationZone();
     DeleteInstructionZone();
     DeleteGraphZone();
   }
 
-  // For main entry point.
-  void Initialize(PipelineStatistics* pipeline_statistics) {
-    PhaseScope scope(pipeline_statistics, "init pipeline data");
-    outer_zone_ = info()->zone();
-    pipeline_statistics_ = pipeline_statistics;
-    graph_zone_ = graph_zone_scope_.zone();
-    graph_ = new (graph_zone()) Graph(graph_zone());
-    source_positions_.Reset(new SourcePositionTable(graph()));
-    machine_ = new (graph_zone()) MachineOperatorBuilder(
-        graph_zone(), kMachPtr,
-        InstructionSelector::SupportedMachineOperatorFlags());
-    common_ = new (graph_zone()) CommonOperatorBuilder(graph_zone());
-    javascript_ = new (graph_zone()) JSOperatorBuilder(graph_zone());
-    jsgraph_ =
-        new (graph_zone()) JSGraph(graph(), common(), javascript(), machine());
-    typer_.Reset(new Typer(graph(), info()->context()));
-    instruction_zone_ = instruction_zone_scope_.zone();
-  }
-
-  // For machine graph testing entry point.
-  void InitializeTorTesting(Graph* graph, Schedule* schedule) {
-    graph_ = graph;
-    source_positions_.Reset(new SourcePositionTable(graph));
-    schedule_ = schedule;
-    instruction_zone_ = instruction_zone_scope_.zone();
-  }
-
-  // For register allocation testing entry point.
-  void InitializeTorTesting(InstructionSequence* sequence) {
-    instruction_zone_ = sequence->zone();
-    sequence_ = sequence;
-  }
-
   Isolate* isolate() const { return isolate_; }
   CompilationInfo* info() const { return info_; }
   ZonePool* zone_pool() const { return zone_pool_; }
@@ -136,46 +200,55 @@
   CommonOperatorBuilder* common() const { return common_; }
   JSOperatorBuilder* javascript() const { return javascript_; }
   JSGraph* jsgraph() const { return jsgraph_; }
-  Typer* typer() const { return typer_.get(); }
+  MaybeHandle<Context> native_context() const {
+    if (info()->is_native_context_specializing()) {
+      return handle(info()->native_context(), isolate());
+    }
+    return MaybeHandle<Context>();
+  }
 
   LoopAssignmentAnalysis* loop_assignment() const { return loop_assignment_; }
   void set_loop_assignment(LoopAssignmentAnalysis* loop_assignment) {
-    DCHECK_EQ(nullptr, loop_assignment_);
+    DCHECK(!loop_assignment_);
     loop_assignment_ = loop_assignment;
   }
 
-  Node* context_node() const { return context_node_; }
-  void set_context_node(Node* context_node) {
-    DCHECK_EQ(nullptr, context_node_);
-    context_node_ = context_node;
+  TypeHintAnalysis* type_hint_analysis() const { return type_hint_analysis_; }
+  void set_type_hint_analysis(TypeHintAnalysis* type_hint_analysis) {
+    DCHECK_NULL(type_hint_analysis_);
+    type_hint_analysis_ = type_hint_analysis;
   }
 
   Schedule* schedule() const { return schedule_; }
   void set_schedule(Schedule* schedule) {
-    DCHECK_EQ(nullptr, schedule_);
+    DCHECK(!schedule_);
     schedule_ = schedule;
   }
 
   Zone* instruction_zone() const { return instruction_zone_; }
   InstructionSequence* sequence() const { return sequence_; }
   Frame* frame() const { return frame_; }
-  RegisterAllocator* register_allocator() const { return register_allocator_; }
+
+  Zone* register_allocation_zone() const { return register_allocation_zone_; }
+  RegisterAllocationData* register_allocation_data() const {
+    return register_allocation_data_;
+  }
 
   void DeleteGraphZone() {
     // Destroy objects with destructors first.
     source_positions_.Reset(nullptr);
-    typer_.Reset(nullptr);
     if (graph_zone_ == nullptr) return;
     // Destroy zone and clear pointers.
     graph_zone_scope_.Destroy();
     graph_zone_ = nullptr;
     graph_ = nullptr;
     loop_assignment_ = nullptr;
+    type_hint_analysis_ = nullptr;
+    simplified_ = nullptr;
     machine_ = nullptr;
     common_ = nullptr;
     javascript_ = nullptr;
     jsgraph_ = nullptr;
-    context_node_ = nullptr;
     schedule_ = nullptr;
   }
 
@@ -185,26 +258,40 @@
     instruction_zone_ = nullptr;
     sequence_ = nullptr;
     frame_ = nullptr;
-    register_allocator_ = nullptr;
+  }
+
+  void DeleteRegisterAllocationZone() {
+    if (register_allocation_zone_ == nullptr) return;
+    register_allocation_zone_scope_.Destroy();
+    register_allocation_zone_ = nullptr;
+    register_allocation_data_ = nullptr;
   }
 
   void InitializeInstructionSequence() {
-    DCHECK_EQ(nullptr, sequence_);
+    DCHECK(sequence_ == nullptr);
     InstructionBlocks* instruction_blocks =
         InstructionSequence::InstructionBlocksFor(instruction_zone(),
                                                   schedule());
-    sequence_ = new (instruction_zone())
-        InstructionSequence(instruction_zone(), instruction_blocks);
+    sequence_ = new (instruction_zone()) InstructionSequence(
+        info()->isolate(), instruction_zone(), instruction_blocks);
   }
 
-  void InitializeRegisterAllocator(Zone* local_zone,
-                                   const RegisterConfiguration* config,
-                                   const char* debug_name) {
-    DCHECK_EQ(nullptr, register_allocator_);
-    DCHECK_EQ(nullptr, frame_);
-    frame_ = new (instruction_zone()) Frame();
-    register_allocator_ = new (instruction_zone())
-        RegisterAllocator(config, local_zone, frame(), sequence(), debug_name);
+  void InitializeRegisterAllocationData(const RegisterConfiguration* config,
+                                        CallDescriptor* descriptor,
+                                        const char* debug_name) {
+    DCHECK(frame_ == nullptr);
+    DCHECK(register_allocation_data_ == nullptr);
+    int fixed_frame_size = 0;
+    if (descriptor != nullptr) {
+      fixed_frame_size = (descriptor->IsCFunctionCall())
+                             ? StandardFrameConstants::kFixedSlotCountAboveFp +
+                                   StandardFrameConstants::kCPSlotCount
+                             : StandardFrameConstants::kFixedSlotCount;
+    }
+    frame_ = new (instruction_zone()) Frame(fixed_frame_size, descriptor);
+    register_allocation_data_ = new (register_allocation_zone())
+        RegisterAllocationData(config, register_allocation_zone(), frame(),
+                               sequence(), debug_name);
   }
 
  private:
@@ -217,43 +304,42 @@
   Handle<Code> code_;
 
   // All objects in the following group of fields are allocated in graph_zone_.
-  // They are all set to NULL when the graph_zone_ is destroyed.
+  // They are all set to nullptr when the graph_zone_ is destroyed.
   ZonePool::Scope graph_zone_scope_;
   Zone* graph_zone_;
   Graph* graph_;
   // TODO(dcarney): make this into a ZoneObject.
-  SmartPointer<SourcePositionTable> source_positions_;
+  base::SmartPointer<SourcePositionTable> source_positions_;
   LoopAssignmentAnalysis* loop_assignment_;
+  TypeHintAnalysis* type_hint_analysis_ = nullptr;
+  SimplifiedOperatorBuilder* simplified_;
   MachineOperatorBuilder* machine_;
   CommonOperatorBuilder* common_;
   JSOperatorBuilder* javascript_;
   JSGraph* jsgraph_;
-  // TODO(dcarney): make this into a ZoneObject.
-  SmartPointer<Typer> typer_;
-  Node* context_node_;
   Schedule* schedule_;
 
   // All objects in the following group of fields are allocated in
-  // instruction_zone_.  They are all set to NULL when the instruction_zone_ is
+  // instruction_zone_.  They are all set to nullptr when the instruction_zone_
+  // is
   // destroyed.
   ZonePool::Scope instruction_zone_scope_;
   Zone* instruction_zone_;
   InstructionSequence* sequence_;
   Frame* frame_;
-  RegisterAllocator* register_allocator_;
+
+  // All objects in the following group of fields are allocated in
+  // register_allocation_zone_.  They are all set to nullptr when the zone is
+  // destroyed.
+  ZonePool::Scope register_allocation_zone_scope_;
+  Zone* register_allocation_zone_;
+  RegisterAllocationData* register_allocation_data_;
 
   DISALLOW_COPY_AND_ASSIGN(PipelineData);
 };
 
 
-static inline bool VerifyGraphs() {
-#ifdef DEBUG
-  return true;
-#else
-  return FLAG_turbo_verify;
-#endif
-}
-
+namespace {
 
 struct TurboCfgFile : public std::ofstream {
   explicit TurboCfgFile(Isolate* isolate)
@@ -262,48 +348,47 @@
 };
 
 
-static void TraceSchedule(Schedule* schedule) {
+void TraceSchedule(CompilationInfo* info, Schedule* schedule) {
+  if (FLAG_trace_turbo) {
+    FILE* json_file = OpenVisualizerLogFile(info, nullptr, "json", "a+");
+    if (json_file != nullptr) {
+      OFStream json_of(json_file);
+      json_of << "{\"name\":\"Schedule\",\"type\":\"schedule\",\"data\":\"";
+      std::stringstream schedule_stream;
+      schedule_stream << *schedule;
+      std::string schedule_string(schedule_stream.str());
+      for (const auto& c : schedule_string) {
+        json_of << AsEscapedUC16ForJSON(c);
+      }
+      json_of << "\"},\n";
+      fclose(json_file);
+    }
+  }
   if (!FLAG_trace_turbo_graph && !FLAG_trace_turbo_scheduler) return;
   OFStream os(stdout);
   os << "-- Schedule --------------------------------------\n" << *schedule;
 }
 
 
-static SmartArrayPointer<char> GetDebugName(CompilationInfo* info) {
-  SmartArrayPointer<char> name;
-  if (info->IsStub()) {
-    if (info->code_stub() != NULL) {
-      CodeStub::Major major_key = info->code_stub()->MajorKey();
-      const char* major_name = CodeStub::MajorName(major_key, false);
-      size_t len = strlen(major_name);
-      name.Reset(new char[len]);
-      memcpy(name.get(), major_name, len);
-    }
-  } else {
-    AllowHandleDereference allow_deref;
-    name = info->function()->debug_name()->ToCString();
-  }
-  return name;
-}
-
-
-class AstGraphBuilderWithPositions : public AstGraphBuilder {
+class AstGraphBuilderWithPositions final : public AstGraphBuilder {
  public:
   AstGraphBuilderWithPositions(Zone* local_zone, CompilationInfo* info,
                                JSGraph* jsgraph,
                                LoopAssignmentAnalysis* loop_assignment,
+                               TypeHintAnalysis* type_hint_analysis,
                                SourcePositionTable* source_positions)
-      : AstGraphBuilder(local_zone, info, jsgraph, loop_assignment),
-        source_positions_(source_positions) {}
+      : AstGraphBuilder(local_zone, info, jsgraph, loop_assignment,
+                        type_hint_analysis),
+        source_positions_(source_positions),
+        start_position_(info->shared_info()->start_position()) {}
 
-  bool CreateGraph() {
-    SourcePositionTable::Scope pos(source_positions_,
-                                   SourcePosition::Unknown());
-    return AstGraphBuilder::CreateGraph();
+  bool CreateGraph(bool stack_check) {
+    SourcePositionTable::Scope pos_scope(source_positions_, start_position_);
+    return AstGraphBuilder::CreateGraph(stack_check);
   }
 
 #define DEF_VISIT(type)                                               \
-  void Visit##type(type* node) OVERRIDE {                             \
+  void Visit##type(type* node) override {                             \
     SourcePositionTable::Scope pos(source_positions_,                 \
                                    SourcePosition(node->position())); \
     AstGraphBuilder::Visit##type(node);                               \
@@ -311,13 +396,55 @@
   AST_NODE_LIST(DEF_VISIT)
 #undef DEF_VISIT
 
-  Node* GetFunctionContext() { return AstGraphBuilder::GetFunctionContext(); }
+ private:
+  SourcePositionTable* const source_positions_;
+  SourcePosition const start_position_;
+};
+
+
+class SourcePositionWrapper final : public Reducer {
+ public:
+  SourcePositionWrapper(Reducer* reducer, SourcePositionTable* table)
+      : reducer_(reducer), table_(table) {}
+  ~SourcePositionWrapper() final {}
+
+  Reduction Reduce(Node* node) final {
+    SourcePosition const pos = table_->GetSourcePosition(node);
+    SourcePositionTable::Scope position(table_, pos);
+    return reducer_->Reduce(node);
+  }
+
+  void Finalize() final { reducer_->Finalize(); }
 
  private:
-  SourcePositionTable* source_positions_;
+  Reducer* const reducer_;
+  SourcePositionTable* const table_;
+
+  DISALLOW_COPY_AND_ASSIGN(SourcePositionWrapper);
 };
 
 
+class JSGraphReducer final : public GraphReducer {
+ public:
+  JSGraphReducer(JSGraph* jsgraph, Zone* zone)
+      : GraphReducer(zone, jsgraph->graph(), jsgraph->Dead()) {}
+  ~JSGraphReducer() final {}
+};
+
+
+void AddReducer(PipelineData* data, GraphReducer* graph_reducer,
+                Reducer* reducer) {
+  if (data->info()->is_source_positions_enabled()) {
+    void* const buffer = data->graph_zone()->New(sizeof(SourcePositionWrapper));
+    SourcePositionWrapper* const wrapper =
+        new (buffer) SourcePositionWrapper(reducer, data->source_positions());
+    graph_reducer->AddReducer(wrapper);
+  } else {
+    graph_reducer->AddReducer(reducer);
+  }
+}
+
+
 class PipelineRunScope {
  public:
   PipelineRunScope(PipelineData* data, const char* phase_name)
@@ -333,6 +460,8 @@
   ZonePool::Scope zone_scope_;
 };
 
+}  // namespace
+
 
 template <typename Phase>
 void Pipeline::Run() {
@@ -361,33 +490,39 @@
 };
 
 
-struct GraphBuilderPhase {
-  static const char* phase_name() { return "graph builder"; }
+struct TypeHintAnalysisPhase {
+  static const char* phase_name() { return "type hint analysis"; }
 
   void Run(PipelineData* data, Zone* temp_zone) {
-    AstGraphBuilderWithPositions graph_builder(
-        temp_zone, data->info(), data->jsgraph(), data->loop_assignment(),
-        data->source_positions());
-    if (graph_builder.CreateGraph()) {
-      data->set_context_node(graph_builder.GetFunctionContext());
-    } else {
-      data->set_compilation_failed();
-    }
+    TypeHintAnalyzer analyzer(data->graph_zone());
+    Handle<Code> code(data->info()->shared_info()->code(), data->isolate());
+    TypeHintAnalysis* type_hint_analysis = analyzer.Analyze(code);
+    data->set_type_hint_analysis(type_hint_analysis);
   }
 };
 
 
-struct ContextSpecializerPhase {
-  static const char* phase_name() { return "context specializing"; }
+struct GraphBuilderPhase {
+  static const char* phase_name() { return "graph builder"; }
 
   void Run(PipelineData* data, Zone* temp_zone) {
-    SourcePositionTable::Scope pos(data->source_positions(),
-                                   SourcePosition::Unknown());
-    JSContextSpecializer spec(data->info(), data->jsgraph(),
-                              data->context_node());
-    GraphReducer graph_reducer(data->graph(), temp_zone);
-    graph_reducer.AddReducer(&spec);
-    graph_reducer.ReduceGraph();
+    bool stack_check = !data->info()->IsStub();
+    bool succeeded = false;
+
+    if (data->info()->shared_info()->HasBytecodeArray()) {
+      BytecodeGraphBuilder graph_builder(temp_zone, data->info(),
+                                         data->jsgraph());
+      succeeded = graph_builder.CreateGraph(stack_check);
+    } else {
+      AstGraphBuilderWithPositions graph_builder(
+          temp_zone, data->info(), data->jsgraph(), data->loop_assignment(),
+          data->type_hint_analysis(), data->source_positions());
+      succeeded = graph_builder.CreateGraph(stack_check);
+    }
+
+    if (!succeeded) {
+      data->set_compilation_failed();
+    }
   }
 };
 
@@ -396,10 +531,51 @@
   static const char* phase_name() { return "inlining"; }
 
   void Run(PipelineData* data, Zone* temp_zone) {
-    SourcePositionTable::Scope pos(data->source_positions(),
-                                   SourcePosition::Unknown());
-    JSInliner inliner(temp_zone, data->info(), data->jsgraph());
-    inliner.Inline();
+    JSGraphReducer graph_reducer(data->jsgraph(), temp_zone);
+    DeadCodeElimination dead_code_elimination(&graph_reducer, data->graph(),
+                                              data->common());
+    CommonOperatorReducer common_reducer(&graph_reducer, data->graph(),
+                                         data->common(), data->machine());
+    JSCallReducer call_reducer(data->jsgraph(),
+                               data->info()->is_deoptimization_enabled()
+                                   ? JSCallReducer::kDeoptimizationEnabled
+                                   : JSCallReducer::kNoFlags,
+                               data->native_context());
+    JSContextSpecialization context_specialization(
+        &graph_reducer, data->jsgraph(),
+        data->info()->is_function_context_specializing()
+            ? data->info()->context()
+            : MaybeHandle<Context>());
+    JSFrameSpecialization frame_specialization(data->info()->osr_frame(),
+                                               data->jsgraph());
+    JSGlobalObjectSpecialization global_object_specialization(
+        &graph_reducer, data->jsgraph(),
+        data->info()->is_deoptimization_enabled()
+            ? JSGlobalObjectSpecialization::kDeoptimizationEnabled
+            : JSGlobalObjectSpecialization::kNoFlags,
+        data->native_context(), data->info()->dependencies());
+    JSNativeContextSpecialization native_context_specialization(
+        &graph_reducer, data->jsgraph(),
+        data->info()->is_deoptimization_enabled()
+            ? JSNativeContextSpecialization::kDeoptimizationEnabled
+            : JSNativeContextSpecialization::kNoFlags,
+        data->native_context(), data->info()->dependencies(), temp_zone);
+    JSInliningHeuristic inlining(&graph_reducer,
+                                 data->info()->is_inlining_enabled()
+                                     ? JSInliningHeuristic::kGeneralInlining
+                                     : JSInliningHeuristic::kRestrictedInlining,
+                                 temp_zone, data->info(), data->jsgraph());
+    AddReducer(data, &graph_reducer, &dead_code_elimination);
+    AddReducer(data, &graph_reducer, &common_reducer);
+    if (data->info()->is_frame_specializing()) {
+      AddReducer(data, &graph_reducer, &frame_specialization);
+    }
+    AddReducer(data, &graph_reducer, &global_object_specialization);
+    AddReducer(data, &graph_reducer, &native_context_specialization);
+    AddReducer(data, &graph_reducer, &context_specialization);
+    AddReducer(data, &graph_reducer, &call_reducer);
+    AddReducer(data, &graph_reducer, &inlining);
+    graph_reducer.ReduceGraph();
   }
 };
 
@@ -407,7 +583,21 @@
 struct TyperPhase {
   static const char* phase_name() { return "typer"; }
 
-  void Run(PipelineData* data, Zone* temp_zone) { data->typer()->Run(); }
+  void Run(PipelineData* data, Zone* temp_zone, Typer* typer) {
+    NodeVector roots(temp_zone);
+    data->jsgraph()->GetCachedNodes(&roots);
+    typer->Run(roots);
+  }
+};
+
+
+struct OsrDeconstructionPhase {
+  static const char* phase_name() { return "OSR deconstruction"; }
+
+  void Run(PipelineData* data, Zone* temp_zone) {
+    OsrHelper osr_helper(data->info());
+    osr_helper.Deconstruct(data->jsgraph(), data->common(), temp_zone);
+  }
 };
 
 
@@ -415,21 +605,66 @@
   static const char* phase_name() { return "typed lowering"; }
 
   void Run(PipelineData* data, Zone* temp_zone) {
-    SourcePositionTable::Scope pos(data->source_positions(),
-                                   SourcePosition::Unknown());
-    ValueNumberingReducer vn_reducer(temp_zone);
-    LoadElimination load_elimination;
-    JSBuiltinReducer builtin_reducer(data->jsgraph());
-    JSTypedLowering typed_lowering(data->jsgraph(), temp_zone);
-    SimplifiedOperatorReducer simple_reducer(data->jsgraph());
-    CommonOperatorReducer common_reducer;
-    GraphReducer graph_reducer(data->graph(), temp_zone);
-    graph_reducer.AddReducer(&vn_reducer);
-    graph_reducer.AddReducer(&builtin_reducer);
-    graph_reducer.AddReducer(&typed_lowering);
-    graph_reducer.AddReducer(&load_elimination);
-    graph_reducer.AddReducer(&simple_reducer);
-    graph_reducer.AddReducer(&common_reducer);
+    JSGraphReducer graph_reducer(data->jsgraph(), temp_zone);
+    DeadCodeElimination dead_code_elimination(&graph_reducer, data->graph(),
+                                              data->common());
+    LoadElimination load_elimination(&graph_reducer);
+    JSBuiltinReducer builtin_reducer(&graph_reducer, data->jsgraph());
+    JSTypedLowering::Flags typed_lowering_flags = JSTypedLowering::kNoFlags;
+    if (data->info()->is_deoptimization_enabled()) {
+      typed_lowering_flags |= JSTypedLowering::kDeoptimizationEnabled;
+    }
+    if (data->info()->shared_info()->HasBytecodeArray()) {
+      typed_lowering_flags |= JSTypedLowering::kDisableBinaryOpReduction;
+    }
+    JSTypedLowering typed_lowering(&graph_reducer, data->info()->dependencies(),
+                                   typed_lowering_flags, data->jsgraph(),
+                                   temp_zone);
+    JSIntrinsicLowering intrinsic_lowering(
+        &graph_reducer, data->jsgraph(),
+        data->info()->is_deoptimization_enabled()
+            ? JSIntrinsicLowering::kDeoptimizationEnabled
+            : JSIntrinsicLowering::kDeoptimizationDisabled);
+    CommonOperatorReducer common_reducer(&graph_reducer, data->graph(),
+                                         data->common(), data->machine());
+    AddReducer(data, &graph_reducer, &dead_code_elimination);
+    AddReducer(data, &graph_reducer, &builtin_reducer);
+    AddReducer(data, &graph_reducer, &typed_lowering);
+    AddReducer(data, &graph_reducer, &intrinsic_lowering);
+    AddReducer(data, &graph_reducer, &load_elimination);
+    AddReducer(data, &graph_reducer, &common_reducer);
+    graph_reducer.ReduceGraph();
+  }
+};
+
+
+struct BranchEliminationPhase {
+  static const char* phase_name() { return "branch condition elimination"; }
+
+  void Run(PipelineData* data, Zone* temp_zone) {
+    JSGraphReducer graph_reducer(data->jsgraph(), temp_zone);
+    BranchElimination branch_condition_elimination(&graph_reducer,
+                                                   data->jsgraph(), temp_zone);
+    DeadCodeElimination dead_code_elimination(&graph_reducer, data->graph(),
+                                              data->common());
+    AddReducer(data, &graph_reducer, &branch_condition_elimination);
+    AddReducer(data, &graph_reducer, &dead_code_elimination);
+    graph_reducer.ReduceGraph();
+  }
+};
+
+
+struct EscapeAnalysisPhase {
+  static const char* phase_name() { return "escape analysis"; }
+
+  void Run(PipelineData* data, Zone* temp_zone) {
+    EscapeAnalysis escape_analysis(data->graph(), data->jsgraph()->common(),
+                                   temp_zone);
+    escape_analysis.Run();
+    JSGraphReducer graph_reducer(data->jsgraph(), temp_zone);
+    EscapeAnalysisReducer escape_reducer(&graph_reducer, data->jsgraph(),
+                                         &escape_analysis, temp_zone);
+    AddReducer(data, &graph_reducer, &escape_reducer);
     graph_reducer.ReduceGraph();
   }
 };
@@ -439,63 +674,96 @@
   static const char* phase_name() { return "simplified lowering"; }
 
   void Run(PipelineData* data, Zone* temp_zone) {
-    SourcePositionTable::Scope pos(data->source_positions(),
-                                   SourcePosition::Unknown());
-    SimplifiedLowering lowering(data->jsgraph(), temp_zone);
+    SimplifiedLowering lowering(data->jsgraph(), temp_zone,
+                                data->source_positions());
     lowering.LowerAllNodes();
-    ValueNumberingReducer vn_reducer(temp_zone);
+    JSGraphReducer graph_reducer(data->jsgraph(), temp_zone);
+    DeadCodeElimination dead_code_elimination(&graph_reducer, data->graph(),
+                                              data->common());
     SimplifiedOperatorReducer simple_reducer(data->jsgraph());
+    ValueNumberingReducer value_numbering(temp_zone);
     MachineOperatorReducer machine_reducer(data->jsgraph());
-    CommonOperatorReducer common_reducer;
-    GraphReducer graph_reducer(data->graph(), temp_zone);
-    graph_reducer.AddReducer(&vn_reducer);
-    graph_reducer.AddReducer(&simple_reducer);
-    graph_reducer.AddReducer(&machine_reducer);
-    graph_reducer.AddReducer(&common_reducer);
+    CommonOperatorReducer common_reducer(&graph_reducer, data->graph(),
+                                         data->common(), data->machine());
+    AddReducer(data, &graph_reducer, &dead_code_elimination);
+    AddReducer(data, &graph_reducer, &simple_reducer);
+    AddReducer(data, &graph_reducer, &value_numbering);
+    AddReducer(data, &graph_reducer, &machine_reducer);
+    AddReducer(data, &graph_reducer, &common_reducer);
     graph_reducer.ReduceGraph();
   }
 };
 
 
+struct ControlFlowOptimizationPhase {
+  static const char* phase_name() { return "control flow optimization"; }
+
+  void Run(PipelineData* data, Zone* temp_zone) {
+    ControlFlowOptimizer optimizer(data->graph(), data->common(),
+                                   data->machine(), temp_zone);
+    optimizer.Optimize();
+  }
+};
+
+
 struct ChangeLoweringPhase {
   static const char* phase_name() { return "change lowering"; }
 
   void Run(PipelineData* data, Zone* temp_zone) {
-    SourcePositionTable::Scope pos(data->source_positions(),
-                                   SourcePosition::Unknown());
-    Linkage linkage(data->graph_zone(), data->info());
-    ValueNumberingReducer vn_reducer(temp_zone);
+    JSGraphReducer graph_reducer(data->jsgraph(), temp_zone);
+    DeadCodeElimination dead_code_elimination(&graph_reducer, data->graph(),
+                                              data->common());
     SimplifiedOperatorReducer simple_reducer(data->jsgraph());
-    ChangeLowering lowering(data->jsgraph(), &linkage);
+    ValueNumberingReducer value_numbering(temp_zone);
+    ChangeLowering lowering(data->jsgraph());
     MachineOperatorReducer machine_reducer(data->jsgraph());
-    CommonOperatorReducer common_reducer;
-    GraphReducer graph_reducer(data->graph(), temp_zone);
-    graph_reducer.AddReducer(&vn_reducer);
-    graph_reducer.AddReducer(&simple_reducer);
-    graph_reducer.AddReducer(&lowering);
-    graph_reducer.AddReducer(&machine_reducer);
-    graph_reducer.AddReducer(&common_reducer);
+    CommonOperatorReducer common_reducer(&graph_reducer, data->graph(),
+                                         data->common(), data->machine());
+    AddReducer(data, &graph_reducer, &dead_code_elimination);
+    AddReducer(data, &graph_reducer, &simple_reducer);
+    AddReducer(data, &graph_reducer, &value_numbering);
+    AddReducer(data, &graph_reducer, &lowering);
+    AddReducer(data, &graph_reducer, &machine_reducer);
+    AddReducer(data, &graph_reducer, &common_reducer);
     graph_reducer.ReduceGraph();
   }
 };
 
 
-struct ControlReductionPhase {
+struct EarlyGraphTrimmingPhase {
+  static const char* phase_name() { return "early graph trimming"; }
   void Run(PipelineData* data, Zone* temp_zone) {
-    SourcePositionTable::Scope pos(data->source_positions(),
-                                   SourcePosition::Unknown());
-    ControlReducer::ReduceGraph(temp_zone, data->jsgraph(), data->common());
+    GraphTrimmer trimmer(temp_zone, data->graph());
+    NodeVector roots(temp_zone);
+    data->jsgraph()->GetCachedNodes(&roots);
+    trimmer.TrimGraph(roots.begin(), roots.end());
   }
 };
 
 
-struct EarlyControlReductionPhase : ControlReductionPhase {
-  static const char* phase_name() { return "early control reduction"; }
+struct LateGraphTrimmingPhase {
+  static const char* phase_name() { return "late graph trimming"; }
+  void Run(PipelineData* data, Zone* temp_zone) {
+    GraphTrimmer trimmer(temp_zone, data->graph());
+    NodeVector roots(temp_zone);
+    data->jsgraph()->GetCachedNodes(&roots);
+    trimmer.TrimGraph(roots.begin(), roots.end());
+  }
 };
 
 
-struct LateControlReductionPhase : ControlReductionPhase {
-  static const char* phase_name() { return "late control reduction"; }
+struct StressLoopPeelingPhase {
+  static const char* phase_name() { return "stress loop peeling"; }
+
+  void Run(PipelineData* data, Zone* temp_zone) {
+    // Peel the first outer loop for testing.
+    // TODO(titzer): peel all loops? the N'th loop? Innermost loops?
+    LoopTree* loop_tree = LoopFinder::BuildLoopTree(data->graph(), temp_zone);
+    if (loop_tree != nullptr && loop_tree->outer_loops().size() > 0) {
+      LoopPeeler::Peel(data->graph(), data->common(), loop_tree,
+                       loop_tree->outer_loops()[0], temp_zone);
+    }
+  }
 };
 
 
@@ -503,13 +771,23 @@
   static const char* phase_name() { return "generic lowering"; }
 
   void Run(PipelineData* data, Zone* temp_zone) {
-    SourcePositionTable::Scope pos(data->source_positions(),
-                                   SourcePosition::Unknown());
-    JSGenericLowering generic(data->info(), data->jsgraph());
-    SelectLowering select(data->jsgraph()->graph(), data->jsgraph()->common());
-    GraphReducer graph_reducer(data->graph(), temp_zone);
-    graph_reducer.AddReducer(&generic);
-    graph_reducer.AddReducer(&select);
+    JSGraphReducer graph_reducer(data->jsgraph(), temp_zone);
+    JSContextRelaxation context_relaxing;
+    DeadCodeElimination dead_code_elimination(&graph_reducer, data->graph(),
+                                              data->common());
+    CommonOperatorReducer common_reducer(&graph_reducer, data->graph(),
+                                         data->common(), data->machine());
+    JSGenericLowering generic_lowering(data->info()->is_typing_enabled(),
+                                       data->jsgraph());
+    SelectLowering select_lowering(data->jsgraph()->graph(),
+                                   data->jsgraph()->common());
+    TailCallOptimization tco(data->common(), data->graph());
+    AddReducer(data, &graph_reducer, &context_relaxing);
+    AddReducer(data, &graph_reducer, &dead_code_elimination);
+    AddReducer(data, &graph_reducer, &common_reducer);
+    AddReducer(data, &graph_reducer, &generic_lowering);
+    AddReducer(data, &graph_reducer, &select_lowering);
+    AddReducer(data, &graph_reducer, &tco);
     graph_reducer.ReduceGraph();
   }
 };
@@ -519,9 +797,11 @@
   static const char* phase_name() { return "scheduling"; }
 
   void Run(PipelineData* data, Zone* temp_zone) {
-    Schedule* schedule = Scheduler::ComputeSchedule(temp_zone, data->graph());
-    TraceSchedule(schedule);
-    if (VerifyGraphs()) ScheduleVerifier::Run(schedule);
+    Schedule* schedule = Scheduler::ComputeSchedule(
+        temp_zone, data->graph(), data->info()->is_splitting_enabled()
+                                      ? Scheduler::kSplitNodes
+                                      : Scheduler::kNoFlags);
+    if (FLAG_turbo_verify) ScheduleVerifier::Run(schedule);
     data->set_schedule(schedule);
   }
 };
@@ -531,9 +811,12 @@
   static const char* phase_name() { return "select instructions"; }
 
   void Run(PipelineData* data, Zone* temp_zone, Linkage* linkage) {
-    InstructionSelector selector(temp_zone, data->graph(), linkage,
-                                 data->sequence(), data->schedule(),
-                                 data->source_positions());
+    InstructionSelector selector(
+        temp_zone, data->graph()->NodeCount(), linkage, data->sequence(),
+        data->schedule(), data->source_positions(),
+        data->info()->is_source_positions_enabled()
+            ? InstructionSelector::kAllSourcePositions
+            : InstructionSelector::kCallSourcePositions);
     selector.SelectInstructions();
   }
 };
@@ -543,7 +826,8 @@
   static const char* phase_name() { return "meet register constraints"; }
 
   void Run(PipelineData* data, Zone* temp_zone) {
-    data->register_allocator()->MeetRegisterConstraints();
+    ConstraintBuilder builder(data->register_allocation_data());
+    builder.MeetRegisterConstraints();
   }
 };
 
@@ -552,7 +836,8 @@
   static const char* phase_name() { return "resolve phis"; }
 
   void Run(PipelineData* data, Zone* temp_zone) {
-    data->register_allocator()->ResolvePhis();
+    ConstraintBuilder builder(data->register_allocation_data());
+    builder.ResolvePhis();
   }
 };
 
@@ -561,34 +846,73 @@
   static const char* phase_name() { return "build live ranges"; }
 
   void Run(PipelineData* data, Zone* temp_zone) {
-    data->register_allocator()->BuildLiveRanges();
+    LiveRangeBuilder builder(data->register_allocation_data(), temp_zone);
+    builder.BuildLiveRanges();
   }
 };
 
 
+struct SplinterLiveRangesPhase {
+  static const char* phase_name() { return "splinter live ranges"; }
+
+  void Run(PipelineData* data, Zone* temp_zone) {
+    LiveRangeSeparator live_range_splinterer(data->register_allocation_data(),
+                                             temp_zone);
+    live_range_splinterer.Splinter();
+  }
+};
+
+
+template <typename RegAllocator>
 struct AllocateGeneralRegistersPhase {
   static const char* phase_name() { return "allocate general registers"; }
 
   void Run(PipelineData* data, Zone* temp_zone) {
-    data->register_allocator()->AllocateGeneralRegisters();
+    RegAllocator allocator(data->register_allocation_data(), GENERAL_REGISTERS,
+                           temp_zone);
+    allocator.AllocateRegisters();
   }
 };
 
 
+template <typename RegAllocator>
 struct AllocateDoubleRegistersPhase {
   static const char* phase_name() { return "allocate double registers"; }
 
   void Run(PipelineData* data, Zone* temp_zone) {
-    data->register_allocator()->AllocateDoubleRegisters();
+    RegAllocator allocator(data->register_allocation_data(), DOUBLE_REGISTERS,
+                           temp_zone);
+    allocator.AllocateRegisters();
   }
 };
 
 
-struct ReuseSpillSlotsPhase {
-  static const char* phase_name() { return "reuse spill slots"; }
+struct MergeSplintersPhase {
+  static const char* phase_name() { return "merge splintered ranges"; }
+  void Run(PipelineData* pipeline_data, Zone* temp_zone) {
+    RegisterAllocationData* data = pipeline_data->register_allocation_data();
+    LiveRangeMerger live_range_merger(data, temp_zone);
+    live_range_merger.Merge();
+  }
+};
+
+
+struct LocateSpillSlotsPhase {
+  static const char* phase_name() { return "locate spill slots"; }
 
   void Run(PipelineData* data, Zone* temp_zone) {
-    data->register_allocator()->ReuseSpillSlots();
+    SpillSlotLocator locator(data->register_allocation_data());
+    locator.LocateSpillSlots();
+  }
+};
+
+
+struct AssignSpillSlotsPhase {
+  static const char* phase_name() { return "assign spill slots"; }
+
+  void Run(PipelineData* data, Zone* temp_zone) {
+    OperandAssigner assigner(data->register_allocation_data());
+    assigner.AssignSpillSlots();
   }
 };
 
@@ -597,16 +921,18 @@
   static const char* phase_name() { return "commit assignment"; }
 
   void Run(PipelineData* data, Zone* temp_zone) {
-    data->register_allocator()->CommitAssignment();
+    OperandAssigner assigner(data->register_allocation_data());
+    assigner.CommitAssignment();
   }
 };
 
 
-struct PopulatePointerMapsPhase {
+struct PopulateReferenceMapsPhase {
   static const char* phase_name() { return "populate pointer maps"; }
 
   void Run(PipelineData* data, Zone* temp_zone) {
-    data->register_allocator()->PopulatePointerMaps();
+    ReferenceMapPopulator populator(data->register_allocation_data());
+    populator.PopulateReferenceMaps();
   }
 };
 
@@ -615,7 +941,8 @@
   static const char* phase_name() { return "connect ranges"; }
 
   void Run(PipelineData* data, Zone* temp_zone) {
-    data->register_allocator()->ConnectRanges();
+    LiveRangeConnector connector(data->register_allocation_data());
+    connector.ConnectRanges(temp_zone);
   }
 };
 
@@ -624,7 +951,8 @@
   static const char* phase_name() { return "resolve control flow"; }
 
   void Run(PipelineData* data, Zone* temp_zone) {
-    data->register_allocator()->ResolveControlFlow();
+    LiveRangeConnector connector(data->register_allocation_data());
+    connector.ResolveControlFlow(temp_zone);
   }
 };
 
@@ -639,11 +967,20 @@
 };
 
 
+struct FrameElisionPhase {
+  static const char* phase_name() { return "frame elision"; }
+
+  void Run(PipelineData* data, Zone* temp_zone) {
+    FrameElider(data->sequence()).Run();
+  }
+};
+
+
 struct JumpThreadingPhase {
   static const char* phase_name() { return "jump threading"; }
 
   void Run(PipelineData* data, Zone* temp_zone) {
-    ZoneVector<BasicBlock::RpoNumber> result(temp_zone);
+    ZoneVector<RpoNumber> result(temp_zone);
     if (JumpThreading::ComputeForwarding(temp_zone, result, data->sequence())) {
       JumpThreading::ApplyForwarding(result, data->sequence());
     }
@@ -668,52 +1005,21 @@
   void Run(PipelineData* data, Zone* temp_zone, const char* phase) {
     CompilationInfo* info = data->info();
     Graph* graph = data->graph();
-    char buffer[256];
-    Vector<char> filename(buffer, sizeof(buffer));
-    SmartArrayPointer<char> functionname;
-    if (!info->shared_info().is_null()) {
-      functionname = info->shared_info()->DebugName()->ToCString();
-      if (strlen(functionname.get()) > 0) {
-        SNPrintF(filename, "turbo-%s-%s", functionname.get(), phase);
-      } else {
-        SNPrintF(filename, "turbo-%p-%s", static_cast<void*>(info), phase);
-      }
-    } else {
-      SNPrintF(filename, "turbo-none-%s", phase);
-    }
-    std::replace(filename.start(), filename.start() + filename.length(), ' ',
-                 '_');
-
-    {  // Print dot.
-      char dot_buffer[256];
-      Vector<char> dot_filename(dot_buffer, sizeof(dot_buffer));
-      SNPrintF(dot_filename, "%s.dot", filename.start());
-      FILE* dot_file = base::OS::FOpen(dot_filename.start(), "w+");
-      if (dot_file == nullptr) return;
-      OFStream dot_of(dot_file);
-      dot_of << AsDOT(*graph);
-      fclose(dot_file);
-    }
 
     {  // Print JSON.
-      char json_buffer[256];
-      Vector<char> json_filename(json_buffer, sizeof(json_buffer));
-      SNPrintF(json_filename, "%s.json", filename.start());
-      FILE* json_file = base::OS::FOpen(json_filename.start(), "w+");
+      FILE* json_file = OpenVisualizerLogFile(info, nullptr, "json", "a+");
       if (json_file == nullptr) return;
       OFStream json_of(json_file);
-      json_of << AsJSON(*graph);
+      json_of << "{\"name\":\"" << phase << "\",\"type\":\"graph\",\"data\":"
+              << AsJSON(*graph, data->source_positions()) << "},\n";
       fclose(json_file);
     }
 
-    OFStream os(stdout);
     if (FLAG_trace_turbo_graph) {  // Simple textual RPO.
+      OFStream os(stdout);
       os << "-- Graph after " << phase << " -- " << std::endl;
       os << AsRPO(*graph);
     }
-
-    os << "-- " << phase << " graph printed to file " << filename.start()
-       << std::endl;
   }
 };
 
@@ -730,7 +1036,7 @@
 
 
 void Pipeline::BeginPhaseKind(const char* phase_kind_name) {
-  if (data_->pipeline_statistics() != NULL) {
+  if (data_->pipeline_statistics() != nullptr) {
     data_->pipeline_statistics()->BeginPhaseKind(phase_kind_name);
   }
 }
@@ -740,45 +1046,62 @@
   if (FLAG_trace_turbo) {
     Run<PrintGraphPhase>(phase);
   }
-  if (VerifyGraphs()) {
+  if (FLAG_turbo_verify) {
     Run<VerifyGraphPhase>(untyped);
   }
 }
 
 
 Handle<Code> Pipeline::GenerateCode() {
-  // This list must be kept in sync with DONT_TURBOFAN_NODE in ast.cc.
-  if (info()->function()->dont_optimize_reason() == kTryCatchStatement ||
-      info()->function()->dont_optimize_reason() == kTryFinallyStatement ||
-      // TODO(turbofan): Make ES6 for-of work and remove this bailout.
-      info()->function()->dont_optimize_reason() == kForOfStatement ||
-      // TODO(turbofan): Make super work and remove this bailout.
-      info()->function()->dont_optimize_reason() == kSuperReference ||
-      // TODO(turbofan): Make class literals work and remove this bailout.
-      info()->function()->dont_optimize_reason() == kClassLiteral ||
-      // TODO(turbofan): Make OSR work and remove this bailout.
-      info()->is_osr()) {
+  // TODO(mstarzinger): This is just a temporary hack to make TurboFan work,
+  // the correct solution is to restore the context register after invoking
+  // builtins from full-codegen.
+  if (Context::IsJSBuiltin(isolate()->native_context(), info()->closure())) {
     return Handle<Code>::null();
   }
 
-  ZonePool zone_pool(isolate());
-  SmartPointer<PipelineStatistics> pipeline_statistics;
+  ZonePool zone_pool;
+  base::SmartPointer<PipelineStatistics> pipeline_statistics;
 
   if (FLAG_turbo_stats) {
     pipeline_statistics.Reset(new PipelineStatistics(info(), &zone_pool));
     pipeline_statistics->BeginPhaseKind("initializing");
   }
 
-  PipelineData data(&zone_pool, info());
+  if (FLAG_trace_turbo) {
+    FILE* json_file = OpenVisualizerLogFile(info(), nullptr, "json", "w+");
+    if (json_file != nullptr) {
+      OFStream json_of(json_file);
+      Handle<Script> script = info()->script();
+      FunctionLiteral* function = info()->literal();
+      base::SmartArrayPointer<char> function_name = info()->GetDebugName();
+      int pos = info()->shared_info()->start_position();
+      json_of << "{\"function\":\"" << function_name.get()
+              << "\", \"sourcePosition\":" << pos << ", \"source\":\"";
+      if (!script->IsUndefined() && !script->source()->IsUndefined()) {
+        DisallowHeapAllocation no_allocation;
+        int start = function->start_position();
+        int len = function->end_position() - start;
+        String::SubStringRange source(String::cast(script->source()), start,
+                                      len);
+        for (const auto& c : source) {
+          json_of << AsEscapedUC16ForJSON(c);
+        }
+      }
+      json_of << "\",\n\"phases\":[";
+      fclose(json_file);
+    }
+  }
+
+  PipelineData data(&zone_pool, info(), pipeline_statistics.get());
   this->data_ = &data;
-  data.Initialize(pipeline_statistics.get());
 
   BeginPhaseKind("graph creation");
 
   if (FLAG_trace_turbo) {
     OFStream os(stdout);
     os << "---------------------------------------------------\n"
-       << "Begin compiling method " << GetDebugName(info()).get()
+       << "Begin compiling method " << info()->GetDebugName().get()
        << " using Turbofan" << std::endl;
     TurboCfgFile tcf(isolate());
     tcf << AsC1VCompilation(info());
@@ -790,35 +1113,42 @@
     Run<LoopAssignmentAnalysisPhase>();
   }
 
+  if (info()->is_typing_enabled()) {
+    Run<TypeHintAnalysisPhase>();
+  }
+
   Run<GraphBuilderPhase>();
   if (data.compilation_failed()) return Handle<Code>::null();
   RunPrintAndVerify("Initial untyped", true);
 
-  Run<EarlyControlReductionPhase>();
-  RunPrintAndVerify("Early Control reduced", true);
-
-  if (info()->is_context_specializing()) {
-    // Specialize the code to the context as aggressively as possible.
-    Run<ContextSpecializerPhase>();
-    RunPrintAndVerify("Context specialized", true);
+  // Perform OSR deconstruction.
+  if (info()->is_osr()) {
+    Run<OsrDeconstructionPhase>();
+    RunPrintAndVerify("OSR deconstruction", true);
   }
 
-  if (info()->is_inlining_enabled()) {
-    Run<InliningPhase>();
-    RunPrintAndVerify("Inlined", true);
-  }
+  // Perform function context specialization and inlining (if enabled).
+  Run<InliningPhase>();
+  RunPrintAndVerify("Inlined", true);
+
+  // Remove dead->live edges from the graph.
+  Run<EarlyGraphTrimmingPhase>();
+  RunPrintAndVerify("Early trimmed", true);
 
   if (FLAG_print_turbo_replay) {
     // Print a replay of the initial graph.
     GraphReplayPrinter::PrintReplay(data.graph());
   }
 
-  // Bailout here in case target architecture is not supported.
-  if (!SupportedTarget()) return Handle<Code>::null();
-
+  base::SmartPointer<Typer> typer;
   if (info()->is_typing_enabled()) {
     // Type the graph.
-    Run<TyperPhase>();
+    typer.Reset(new Typer(isolate(), data.graph(),
+                          info()->is_deoptimization_enabled()
+                              ? Typer::kDeoptimizationEnabled
+                              : Typer::kNoFlags,
+                          info()->dependencies()));
+    Run<TyperPhase>(typer.get());
     RunPrintAndVerify("Typed");
   }
 
@@ -829,17 +1159,33 @@
     Run<TypedLoweringPhase>();
     RunPrintAndVerify("Lowered typed");
 
+    if (FLAG_turbo_stress_loop_peeling) {
+      Run<StressLoopPeelingPhase>();
+      RunPrintAndVerify("Loop peeled");
+    }
+
+    if (FLAG_turbo_escape) {
+      Run<EscapeAnalysisPhase>();
+      RunPrintAndVerify("Escape Analysed");
+    }
+
     // Lower simplified operators and insert changes.
     Run<SimplifiedLoweringPhase>();
     RunPrintAndVerify("Lowered simplified");
 
+    Run<BranchEliminationPhase>();
+    RunPrintAndVerify("Branch conditions eliminated");
+
+    // Optimize control flow.
+    if (FLAG_turbo_cf_optimization) {
+      Run<ControlFlowOptimizationPhase>();
+      RunPrintAndVerify("Control flow optimized");
+    }
+
     // Lower changes that have been inserted before.
     Run<ChangeLoweringPhase>();
-    // // TODO(jarin, rossberg): Remove UNTYPED once machine typing works.
+    // TODO(jarin, rossberg): Remove UNTYPED once machine typing works.
     RunPrintAndVerify("Lowered changes", true);
-
-    Run<LateControlReductionPhase>();
-    RunPrintAndVerify("Late Control reduced");
   }
 
   // Lower any remaining generic JSOperators.
@@ -847,32 +1193,55 @@
   // TODO(jarin, rossberg): Remove UNTYPED once machine typing works.
   RunPrintAndVerify("Lowered generic", true);
 
+  Run<LateGraphTrimmingPhase>();
+  // TODO(jarin, rossberg): Remove UNTYPED once machine typing works.
+  RunPrintAndVerify("Late trimmed", true);
+
   BeginPhaseKind("block building");
 
   data.source_positions()->RemoveDecorator();
 
-  // Compute a schedule.
-  Run<ComputeSchedulePhase>();
+  // Kill the Typer and thereby uninstall the decorator (if any).
+  typer.Reset(nullptr);
 
-  {
-    // Generate optimized code.
-    Linkage linkage(data.instruction_zone(), info());
-    GenerateCode(&linkage);
+  return ScheduleAndGenerateCode(
+      Linkage::ComputeIncoming(data.instruction_zone(), info()));
+}
+
+
+Handle<Code> Pipeline::GenerateCodeForCodeStub(Isolate* isolate,
+                                               CallDescriptor* call_descriptor,
+                                               Graph* graph, Schedule* schedule,
+                                               Code::Kind kind,
+                                               const char* debug_name) {
+  CompilationInfo info(debug_name, isolate, graph->zone());
+  info.set_output_code_kind(kind);
+
+  // Construct a pipeline for scheduling and code generation.
+  ZonePool zone_pool;
+  PipelineData data(&zone_pool, &info, graph, schedule);
+  base::SmartPointer<PipelineStatistics> pipeline_statistics;
+  if (FLAG_turbo_stats) {
+    pipeline_statistics.Reset(new PipelineStatistics(&info, &zone_pool));
+    pipeline_statistics->BeginPhaseKind("stub codegen");
   }
-  Handle<Code> code = data.code();
-  info()->SetCode(code);
 
-  // Print optimized code.
-  v8::internal::CodeGenerator::PrintCode(code, info());
+  Pipeline pipeline(&info);
+  pipeline.data_ = &data;
+  DCHECK_NOT_NULL(data.schedule());
 
   if (FLAG_trace_turbo) {
-    OFStream os(stdout);
-    os << "---------------------------------------------------\n"
-       << "Finished compiling method " << GetDebugName(info()).get()
-       << " using Turbofan" << std::endl;
+    FILE* json_file = OpenVisualizerLogFile(&info, nullptr, "json", "w+");
+    if (json_file != nullptr) {
+      OFStream json_of(json_file);
+      json_of << "{\"function\":\"" << info.GetDebugName().get()
+              << "\", \"source\":\"\",\n\"phases\":[";
+      fclose(json_file);
+    }
+    pipeline.Run<PrintGraphPhase>("Machine");
   }
 
-  return code;
+  return pipeline.ScheduleAndGenerateCode(call_descriptor);
 }
 
 
@@ -885,70 +1254,53 @@
 }
 
 
-Handle<Code> Pipeline::GenerateCodeForTesting(CallDescriptor* call_descriptor,
-                                              Graph* graph,
-                                              Schedule* schedule) {
-  CompilationInfo info(graph->zone()->isolate(), graph->zone());
-  return GenerateCodeForTesting(&info, call_descriptor, graph, schedule);
-}
-
-
 Handle<Code> Pipeline::GenerateCodeForTesting(CompilationInfo* info,
                                               CallDescriptor* call_descriptor,
                                               Graph* graph,
                                               Schedule* schedule) {
-  CHECK(SupportedBackend());
-  ZonePool zone_pool(info->isolate());
+  // Construct a pipeline for scheduling and code generation.
+  ZonePool zone_pool;
+  PipelineData data(&zone_pool, info, graph, schedule);
+  base::SmartPointer<PipelineStatistics> pipeline_statistics;
+  if (FLAG_turbo_stats) {
+    pipeline_statistics.Reset(new PipelineStatistics(info, &zone_pool));
+    pipeline_statistics->BeginPhaseKind("test codegen");
+  }
+
   Pipeline pipeline(info);
-  PipelineData data(&zone_pool, info);
   pipeline.data_ = &data;
-  data.InitializeTorTesting(graph, schedule);
-  if (schedule == NULL) {
+  if (data.schedule() == nullptr) {
     // TODO(rossberg): Should this really be untyped?
     pipeline.RunPrintAndVerify("Machine", true);
-    pipeline.Run<ComputeSchedulePhase>();
-  } else {
-    TraceSchedule(schedule);
   }
 
-  Linkage linkage(info->zone(), call_descriptor);
-  pipeline.GenerateCode(&linkage);
-  Handle<Code> code = data.code();
-
-#if ENABLE_DISASSEMBLER
-  if (!code.is_null() && FLAG_print_opt_code) {
-    CodeTracer::Scope tracing_scope(info->isolate()->GetCodeTracer());
-    OFStream os(tracing_scope.file());
-    code->Disassemble("test code", os);
-  }
-#endif
-  return code;
+  return pipeline.ScheduleAndGenerateCode(call_descriptor);
 }
 
 
 bool Pipeline::AllocateRegistersForTesting(const RegisterConfiguration* config,
                                            InstructionSequence* sequence,
                                            bool run_verifier) {
-  CompilationInfo info(sequence->zone()->isolate(), sequence->zone());
-  ZonePool zone_pool(sequence->zone()->isolate());
-  PipelineData data(&zone_pool, &info);
-  data.InitializeTorTesting(sequence);
+  CompilationInfo info("testing", sequence->isolate(), sequence->zone());
+  ZonePool zone_pool;
+  PipelineData data(&zone_pool, &info, sequence);
   Pipeline pipeline(&info);
   pipeline.data_ = &data;
-  pipeline.AllocateRegisters(config, run_verifier);
+  pipeline.AllocateRegisters(config, nullptr, run_verifier);
   return !data.compilation_failed();
 }
 
 
-void Pipeline::GenerateCode(Linkage* linkage) {
+Handle<Code> Pipeline::ScheduleAndGenerateCode(
+    CallDescriptor* call_descriptor) {
   PipelineData* data = this->data_;
 
-  DCHECK_NOT_NULL(linkage);
   DCHECK_NOT_NULL(data->graph());
-  DCHECK_NOT_NULL(data->schedule());
-  CHECK(SupportedBackend());
 
-  BasicBlockProfiler::Data* profiler_data = NULL;
+  if (data->schedule() == nullptr) Run<ComputeSchedulePhase>();
+  TraceSchedule(data->info(), data->schedule());
+
+  BasicBlockProfiler::Data* profiler_data = nullptr;
   if (FLAG_turbo_profiling) {
     profiler_data = BasicBlockInstrumentor::Instrument(info(), data->graph(),
                                                        data->schedule());
@@ -957,7 +1309,8 @@
   data->InitializeInstructionSequence();
 
   // Select and schedule instructions covering the scheduled graph.
-  Run<InstructionSelectionPhase>(linkage);
+  Linkage linkage(call_descriptor);
+  Run<InstructionSelectionPhase>(&linkage);
 
   if (FLAG_trace_turbo && !data->MayHaveUnverifiableGraph()) {
     TurboCfgFile tcf(isolate());
@@ -965,19 +1318,24 @@
                  data->sequence());
   }
 
+  std::ostringstream source_position_output;
+  if (FLAG_trace_turbo) {
+    // Output source position information before the graph is deleted.
+    data_->source_positions()->Print(source_position_output);
+  }
+
   data->DeleteGraphZone();
 
   BeginPhaseKind("register allocation");
 
-  bool run_verifier = false;
-#ifdef DEBUG
-  run_verifier = true;
-#endif
+  bool run_verifier = FLAG_turbo_verify_allocation;
   // Allocate registers.
-  AllocateRegisters(RegisterConfiguration::ArchDefault(), run_verifier);
+  AllocateRegisters(
+      RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN),
+      call_descriptor, run_verifier);
   if (data->compilation_failed()) {
     info()->AbortOptimization(kNotEnoughVirtualRegistersRegalloc);
-    return;
+    return Handle<Code>();
   }
 
   BeginPhaseKind("code generation");
@@ -988,45 +1346,74 @@
   }
 
   // Generate final machine code.
-  Run<GenerateCodePhase>(linkage);
+  Run<GenerateCodePhase>(&linkage);
 
-  if (profiler_data != NULL) {
+  Handle<Code> code = data->code();
+  if (profiler_data != nullptr) {
 #if ENABLE_DISASSEMBLER
     std::ostringstream os;
-    data->code()->Disassemble(NULL, os);
+    code->Disassemble(nullptr, os);
     profiler_data->SetCode(&os);
 #endif
   }
+
+  info()->SetCode(code);
+  v8::internal::CodeGenerator::PrintCode(code, info());
+
+  if (FLAG_trace_turbo) {
+    FILE* json_file = OpenVisualizerLogFile(info(), nullptr, "json", "a+");
+    if (json_file != nullptr) {
+      OFStream json_of(json_file);
+      json_of
+          << "{\"name\":\"disassembly\",\"type\":\"disassembly\",\"data\":\"";
+#if ENABLE_DISASSEMBLER
+      std::stringstream disassembly_stream;
+      code->Disassemble(nullptr, disassembly_stream);
+      std::string disassembly_string(disassembly_stream.str());
+      for (const auto& c : disassembly_string) {
+        json_of << AsEscapedUC16ForJSON(c);
+      }
+#endif  // ENABLE_DISASSEMBLER
+      json_of << "\"}\n],\n";
+      json_of << "\"nodePositions\":";
+      json_of << source_position_output.str();
+      json_of << "}";
+      fclose(json_file);
+    }
+    OFStream os(stdout);
+    os << "---------------------------------------------------\n"
+       << "Finished compiling method " << info()->GetDebugName().get()
+       << " using Turbofan" << std::endl;
+  }
+
+  return code;
 }
 
 
 void Pipeline::AllocateRegisters(const RegisterConfiguration* config,
+                                 CallDescriptor* descriptor,
                                  bool run_verifier) {
   PipelineData* data = this->data_;
 
-  int node_count = data->sequence()->VirtualRegisterCount();
-  if (node_count > UnallocatedOperand::kMaxVirtualRegisters) {
-    data->set_compilation_failed();
-    return;
-  }
-
   // Don't track usage for this zone in compiler stats.
-  SmartPointer<Zone> verifier_zone;
+  base::SmartPointer<Zone> verifier_zone;
   RegisterAllocatorVerifier* verifier = nullptr;
   if (run_verifier) {
-    verifier_zone.Reset(new Zone(info()->isolate()));
+    verifier_zone.Reset(new Zone());
     verifier = new (verifier_zone.get()) RegisterAllocatorVerifier(
         verifier_zone.get(), config, data->sequence());
   }
 
-  SmartArrayPointer<char> debug_name;
+  base::SmartArrayPointer<char> debug_name;
 #ifdef DEBUG
-  debug_name = GetDebugName(data->info());
+  debug_name = info()->GetDebugName();
 #endif
 
-  ZonePool::Scope zone_scope(data->zone_pool());
-  data->InitializeRegisterAllocator(zone_scope.zone(), config,
-                                    debug_name.get());
+  data->InitializeRegisterAllocationData(config, descriptor, debug_name.get());
+  if (info()->is_osr()) {
+    OsrHelper osr_helper(info());
+    osr_helper.SetupFrame(data->frame());
+  }
 
   Run<MeetRegisterConstraintsPhase>();
   Run<ResolvePhisPhase>();
@@ -1038,23 +1425,36 @@
        << printable;
   }
   if (verifier != nullptr) {
-    CHECK(!data->register_allocator()->ExistsUseWithoutDefinition());
+    CHECK(!data->register_allocation_data()->ExistsUseWithoutDefinition());
+    CHECK(data->register_allocation_data()
+              ->RangesDefinedInDeferredStayInDeferred());
   }
-  Run<AllocateGeneralRegistersPhase>();
-  if (!data->register_allocator()->AllocationOk()) {
-    data->set_compilation_failed();
-    return;
+
+  if (FLAG_turbo_preprocess_ranges) {
+    Run<SplinterLiveRangesPhase>();
   }
-  Run<AllocateDoubleRegistersPhase>();
-  if (!data->register_allocator()->AllocationOk()) {
-    data->set_compilation_failed();
-    return;
+
+  if (FLAG_turbo_greedy_regalloc) {
+    Run<AllocateGeneralRegistersPhase<GreedyAllocator>>();
+    Run<AllocateDoubleRegistersPhase<GreedyAllocator>>();
+  } else {
+    Run<AllocateGeneralRegistersPhase<LinearScanAllocator>>();
+    Run<AllocateDoubleRegistersPhase<LinearScanAllocator>>();
   }
-  if (FLAG_turbo_reuse_spill_slots) {
-    Run<ReuseSpillSlotsPhase>();
+
+  if (FLAG_turbo_preprocess_ranges) {
+    Run<MergeSplintersPhase>();
   }
+
+  if (FLAG_turbo_frame_elision) {
+    Run<LocateSpillSlotsPhase>();
+    Run<FrameElisionPhase>();
+  }
+
+  Run<AssignSpillSlotsPhase>();
+
   Run<CommitAssignmentPhase>();
-  Run<PopulatePointerMapsPhase>();
+  Run<PopulateReferenceMapsPhase>();
   Run<ConnectRangesPhase>();
   Run<ResolveControlFlowPhase>();
   if (FLAG_turbo_move_optimization) {
@@ -1075,18 +1475,11 @@
 
   if (FLAG_trace_turbo && !data->MayHaveUnverifiableGraph()) {
     TurboCfgFile tcf(data->isolate());
-    tcf << AsC1VAllocator("CodeGen", data->register_allocator());
+    tcf << AsC1VRegisterAllocationData("CodeGen",
+                                       data->register_allocation_data());
   }
-}
 
-
-void Pipeline::SetUp() {
-  InstructionOperand::SetUpCaches();
-}
-
-
-void Pipeline::TearDown() {
-  InstructionOperand::TearDownCaches();
+  data->DeleteRegisterAllocationZone();
 }
 
 }  // namespace compiler
diff --git a/src/compiler/pipeline.h b/src/compiler/pipeline.h
index 73053dc..af94018 100644
--- a/src/compiler/pipeline.h
+++ b/src/compiler/pipeline.h
@@ -5,24 +5,22 @@
 #ifndef V8_COMPILER_PIPELINE_H_
 #define V8_COMPILER_PIPELINE_H_
 
-#include "src/v8.h"
-
+// Clients of this interface shouldn't depend on lots of compiler internals.
+// Do not include anything from src/compiler here!
 #include "src/compiler.h"
 
-// Note: TODO(turbofan) implies a performance improvement opportunity,
-//   and TODO(name) implies an incomplete implementation
-
 namespace v8 {
 namespace internal {
+
+class RegisterConfiguration;
+
 namespace compiler {
 
-// Clients of this interface shouldn't depend on lots of compiler internals.
 class CallDescriptor;
 class Graph;
 class InstructionSequence;
 class Linkage;
 class PipelineData;
-class RegisterConfiguration;
 class Schedule;
 
 class Pipeline {
@@ -32,15 +30,17 @@
   // Run the entire pipeline and generate a handle to a code object.
   Handle<Code> GenerateCode();
 
-  // Run the pipeline on a machine graph and generate code. If {schedule} is
-  // {nullptr}, then compute a new schedule for code generation.
-  static Handle<Code> GenerateCodeForTesting(CompilationInfo* info,
-                                             Graph* graph,
-                                             Schedule* schedule = nullptr);
+  // Run the pipeline on a machine graph and generate code. The {schedule} must
+  // be valid, hence the given {graph} does not need to be schedulable.
+  static Handle<Code> GenerateCodeForCodeStub(Isolate* isolate,
+                                              CallDescriptor* call_descriptor,
+                                              Graph* graph, Schedule* schedule,
+                                              Code::Kind kind,
+                                              const char* debug_name);
 
   // Run the pipeline on a machine graph and generate code. If {schedule} is
   // {nullptr}, then compute a new schedule for code generation.
-  static Handle<Code> GenerateCodeForTesting(CallDescriptor* call_descriptor,
+  static Handle<Code> GenerateCodeForTesting(CompilationInfo* info,
                                              Graph* graph,
                                              Schedule* schedule = nullptr);
 
@@ -49,17 +49,14 @@
                                           InstructionSequence* sequence,
                                           bool run_verifier);
 
-  static inline bool SupportedBackend() { return V8_TURBOFAN_BACKEND != 0; }
-  static inline bool SupportedTarget() { return V8_TURBOFAN_TARGET != 0; }
-
-  static void SetUp();
-  static void TearDown();
-
- private:
+  // Run the pipeline on a machine graph and generate code. If {schedule} is
+  // {nullptr}, then compute a new schedule for code generation.
   static Handle<Code> GenerateCodeForTesting(CompilationInfo* info,
                                              CallDescriptor* call_descriptor,
-                                             Graph* graph, Schedule* schedule);
+                                             Graph* graph,
+                                             Schedule* schedule = nullptr);
 
+ private:
   CompilationInfo* info_;
   PipelineData* data_;
 
@@ -74,9 +71,9 @@
 
   void BeginPhaseKind(const char* phase_kind);
   void RunPrintAndVerify(const char* phase, bool untyped = false);
-  void GenerateCode(Linkage* linkage);
+  Handle<Code> ScheduleAndGenerateCode(CallDescriptor* call_descriptor);
   void AllocateRegisters(const RegisterConfiguration* config,
-                         bool run_verifier);
+                         CallDescriptor* descriptor, bool run_verifier);
 };
 
 }  // namespace compiler
diff --git a/src/compiler/ppc/OWNERS b/src/compiler/ppc/OWNERS
new file mode 100644
index 0000000..eb007cb
--- /dev/null
+++ b/src/compiler/ppc/OWNERS
@@ -0,0 +1,5 @@
+jyan@ca.ibm.com
+dstence@us.ibm.com
+joransiu@ca.ibm.com
+mbrandy@us.ibm.com
+michael_dawson@ca.ibm.com
diff --git a/src/compiler/ppc/code-generator-ppc.cc b/src/compiler/ppc/code-generator-ppc.cc
new file mode 100644
index 0000000..154cd64
--- /dev/null
+++ b/src/compiler/ppc/code-generator-ppc.cc
@@ -0,0 +1,1868 @@
+// 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/code-generator.h"
+
+#include "src/ast/scopes.h"
+#include "src/compiler/code-generator-impl.h"
+#include "src/compiler/gap-resolver.h"
+#include "src/compiler/node-matchers.h"
+#include "src/compiler/osr.h"
+#include "src/ppc/macro-assembler-ppc.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+#define __ masm()->
+
+
+#define kScratchReg r11
+
+
+// Adds PPC-specific methods to convert InstructionOperands.
+class PPCOperandConverter final : public InstructionOperandConverter {
+ public:
+  PPCOperandConverter(CodeGenerator* gen, Instruction* instr)
+      : InstructionOperandConverter(gen, instr) {}
+
+  size_t OutputCount() { return instr_->OutputCount(); }
+
+  RCBit OutputRCBit() const {
+    switch (instr_->flags_mode()) {
+      case kFlags_branch:
+      case kFlags_set:
+        return SetRC;
+      case kFlags_none:
+        return LeaveRC;
+    }
+    UNREACHABLE();
+    return LeaveRC;
+  }
+
+  bool CompareLogical() const {
+    switch (instr_->flags_condition()) {
+      case kUnsignedLessThan:
+      case kUnsignedGreaterThanOrEqual:
+      case kUnsignedLessThanOrEqual:
+      case kUnsignedGreaterThan:
+        return true;
+      default:
+        return false;
+    }
+    UNREACHABLE();
+    return false;
+  }
+
+  Operand InputImmediate(size_t index) {
+    Constant constant = ToConstant(instr_->InputAt(index));
+    switch (constant.type()) {
+      case Constant::kInt32:
+        return Operand(constant.ToInt32());
+      case Constant::kFloat32:
+        return Operand(
+            isolate()->factory()->NewNumber(constant.ToFloat32(), TENURED));
+      case Constant::kFloat64:
+        return Operand(
+            isolate()->factory()->NewNumber(constant.ToFloat64(), TENURED));
+      case Constant::kInt64:
+#if V8_TARGET_ARCH_PPC64
+        return Operand(constant.ToInt64());
+#endif
+      case Constant::kExternalReference:
+      case Constant::kHeapObject:
+      case Constant::kRpoNumber:
+        break;
+    }
+    UNREACHABLE();
+    return Operand::Zero();
+  }
+
+  MemOperand MemoryOperand(AddressingMode* mode, size_t* first_index) {
+    const size_t index = *first_index;
+    *mode = AddressingModeField::decode(instr_->opcode());
+    switch (*mode) {
+      case kMode_None:
+        break;
+      case kMode_MRI:
+        *first_index += 2;
+        return MemOperand(InputRegister(index + 0), InputInt32(index + 1));
+      case kMode_MRR:
+        *first_index += 2;
+        return MemOperand(InputRegister(index + 0), InputRegister(index + 1));
+    }
+    UNREACHABLE();
+    return MemOperand(r0);
+  }
+
+  MemOperand MemoryOperand(AddressingMode* mode, size_t first_index = 0) {
+    return MemoryOperand(mode, &first_index);
+  }
+
+  MemOperand ToMemOperand(InstructionOperand* op) const {
+    DCHECK_NOT_NULL(op);
+    DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot());
+    FrameOffset offset = frame_access_state()->GetFrameOffset(
+        AllocatedOperand::cast(op)->index());
+    return MemOperand(offset.from_stack_pointer() ? sp : fp, offset.offset());
+  }
+};
+
+
+static inline bool HasRegisterInput(Instruction* instr, size_t index) {
+  return instr->InputAt(index)->IsRegister();
+}
+
+
+namespace {
+
+class OutOfLineLoadNAN32 final : public OutOfLineCode {
+ public:
+  OutOfLineLoadNAN32(CodeGenerator* gen, DoubleRegister result)
+      : OutOfLineCode(gen), result_(result) {}
+
+  void Generate() final {
+    __ LoadDoubleLiteral(result_, std::numeric_limits<float>::quiet_NaN(),
+                         kScratchReg);
+  }
+
+ private:
+  DoubleRegister const result_;
+};
+
+
+class OutOfLineLoadNAN64 final : public OutOfLineCode {
+ public:
+  OutOfLineLoadNAN64(CodeGenerator* gen, DoubleRegister result)
+      : OutOfLineCode(gen), result_(result) {}
+
+  void Generate() final {
+    __ LoadDoubleLiteral(result_, std::numeric_limits<double>::quiet_NaN(),
+                         kScratchReg);
+  }
+
+ private:
+  DoubleRegister const result_;
+};
+
+
+class OutOfLineLoadZero final : public OutOfLineCode {
+ public:
+  OutOfLineLoadZero(CodeGenerator* gen, Register result)
+      : OutOfLineCode(gen), result_(result) {}
+
+  void Generate() final { __ li(result_, Operand::Zero()); }
+
+ private:
+  Register const result_;
+};
+
+
+class OutOfLineRecordWrite final : public OutOfLineCode {
+ public:
+  OutOfLineRecordWrite(CodeGenerator* gen, Register object, Register offset,
+                       Register value, Register scratch0, Register scratch1,
+                       RecordWriteMode mode)
+      : OutOfLineCode(gen),
+        object_(object),
+        offset_(offset),
+        value_(value),
+        scratch0_(scratch0),
+        scratch1_(scratch1),
+        mode_(mode) {}
+
+  void Generate() final {
+    if (mode_ > RecordWriteMode::kValueIsPointer) {
+      __ JumpIfSmi(value_, exit());
+    }
+    if (mode_ > RecordWriteMode::kValueIsMap) {
+      __ CheckPageFlag(value_, scratch0_,
+                       MemoryChunk::kPointersToHereAreInterestingMask, eq,
+                       exit());
+    }
+    SaveFPRegsMode const save_fp_mode =
+        frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs;
+    // TODO(turbofan): Once we get frame elision working, we need to save
+    // and restore lr properly here if the frame was elided.
+    RecordWriteStub stub(isolate(), object_, scratch0_, scratch1_,
+                         EMIT_REMEMBERED_SET, save_fp_mode);
+    __ add(scratch1_, object_, offset_);
+    __ CallStub(&stub);
+  }
+
+ private:
+  Register const object_;
+  Register const offset_;
+  Register const value_;
+  Register const scratch0_;
+  Register const scratch1_;
+  RecordWriteMode const mode_;
+};
+
+
+Condition FlagsConditionToCondition(FlagsCondition condition, ArchOpcode op) {
+  switch (condition) {
+    case kEqual:
+      return eq;
+    case kNotEqual:
+      return ne;
+    case kSignedLessThan:
+    case kUnsignedLessThan:
+      return lt;
+    case kSignedGreaterThanOrEqual:
+    case kUnsignedGreaterThanOrEqual:
+      return ge;
+    case kSignedLessThanOrEqual:
+    case kUnsignedLessThanOrEqual:
+      return le;
+    case kSignedGreaterThan:
+    case kUnsignedGreaterThan:
+      return gt;
+    case kOverflow:
+      // Overflow checked for add/sub only.
+      switch (op) {
+#if V8_TARGET_ARCH_PPC64
+        case kPPC_Add:
+        case kPPC_Sub:
+          return lt;
+#endif
+        case kPPC_AddWithOverflow32:
+        case kPPC_SubWithOverflow32:
+#if V8_TARGET_ARCH_PPC64
+          return ne;
+#else
+          return lt;
+#endif
+        default:
+          break;
+      }
+      break;
+    case kNotOverflow:
+      switch (op) {
+#if V8_TARGET_ARCH_PPC64
+        case kPPC_Add:
+        case kPPC_Sub:
+          return ge;
+#endif
+        case kPPC_AddWithOverflow32:
+        case kPPC_SubWithOverflow32:
+#if V8_TARGET_ARCH_PPC64
+          return eq;
+#else
+          return ge;
+#endif
+        default:
+          break;
+      }
+      break;
+    default:
+      break;
+  }
+  UNREACHABLE();
+  return kNoCondition;
+}
+
+}  // namespace
+
+#define ASSEMBLE_FLOAT_UNOP_RC(asm_instr)                            \
+  do {                                                               \
+    __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0), \
+                 i.OutputRCBit());                                   \
+  } while (0)
+
+
+#define ASSEMBLE_FLOAT_BINOP_RC(asm_instr)                           \
+  do {                                                               \
+    __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0), \
+                 i.InputDoubleRegister(1), i.OutputRCBit());         \
+  } while (0)
+
+
+#define ASSEMBLE_BINOP(asm_instr_reg, asm_instr_imm)           \
+  do {                                                         \
+    if (HasRegisterInput(instr, 1)) {                          \
+      __ asm_instr_reg(i.OutputRegister(), i.InputRegister(0), \
+                       i.InputRegister(1));                    \
+    } else {                                                   \
+      __ asm_instr_imm(i.OutputRegister(), i.InputRegister(0), \
+                       i.InputImmediate(1));                   \
+    }                                                          \
+  } while (0)
+
+
+#define ASSEMBLE_BINOP_RC(asm_instr_reg, asm_instr_imm)        \
+  do {                                                         \
+    if (HasRegisterInput(instr, 1)) {                          \
+      __ asm_instr_reg(i.OutputRegister(), i.InputRegister(0), \
+                       i.InputRegister(1), i.OutputRCBit());   \
+    } else {                                                   \
+      __ asm_instr_imm(i.OutputRegister(), i.InputRegister(0), \
+                       i.InputImmediate(1), i.OutputRCBit());  \
+    }                                                          \
+  } while (0)
+
+
+#define ASSEMBLE_BINOP_INT_RC(asm_instr_reg, asm_instr_imm)    \
+  do {                                                         \
+    if (HasRegisterInput(instr, 1)) {                          \
+      __ asm_instr_reg(i.OutputRegister(), i.InputRegister(0), \
+                       i.InputRegister(1), i.OutputRCBit());   \
+    } else {                                                   \
+      __ asm_instr_imm(i.OutputRegister(), i.InputRegister(0), \
+                       i.InputInt32(1), i.OutputRCBit());      \
+    }                                                          \
+  } while (0)
+
+
+#define ASSEMBLE_ADD_WITH_OVERFLOW()                                    \
+  do {                                                                  \
+    if (HasRegisterInput(instr, 1)) {                                   \
+      __ AddAndCheckForOverflow(i.OutputRegister(), i.InputRegister(0), \
+                                i.InputRegister(1), kScratchReg, r0);   \
+    } else {                                                            \
+      __ AddAndCheckForOverflow(i.OutputRegister(), i.InputRegister(0), \
+                                i.InputInt32(1), kScratchReg, r0);      \
+    }                                                                   \
+  } while (0)
+
+
+#define ASSEMBLE_SUB_WITH_OVERFLOW()                                    \
+  do {                                                                  \
+    if (HasRegisterInput(instr, 1)) {                                   \
+      __ SubAndCheckForOverflow(i.OutputRegister(), i.InputRegister(0), \
+                                i.InputRegister(1), kScratchReg, r0);   \
+    } else {                                                            \
+      __ AddAndCheckForOverflow(i.OutputRegister(), i.InputRegister(0), \
+                                -i.InputInt32(1), kScratchReg, r0);     \
+    }                                                                   \
+  } while (0)
+
+
+#if V8_TARGET_ARCH_PPC64
+#define ASSEMBLE_ADD_WITH_OVERFLOW32()           \
+  do {                                           \
+    ASSEMBLE_BINOP(add, addi);                   \
+    __ TestIfInt32(i.OutputRegister(), r0, cr0); \
+  } while (0)
+
+
+#define ASSEMBLE_SUB_WITH_OVERFLOW32()           \
+  do {                                           \
+    ASSEMBLE_BINOP(sub, subi);                   \
+    __ TestIfInt32(i.OutputRegister(), r0, cr0); \
+  } while (0)
+#else
+#define ASSEMBLE_ADD_WITH_OVERFLOW32 ASSEMBLE_ADD_WITH_OVERFLOW
+#define ASSEMBLE_SUB_WITH_OVERFLOW32 ASSEMBLE_SUB_WITH_OVERFLOW
+#endif
+
+
+#define ASSEMBLE_COMPARE(cmp_instr, cmpl_instr)                        \
+  do {                                                                 \
+    const CRegister cr = cr0;                                          \
+    if (HasRegisterInput(instr, 1)) {                                  \
+      if (i.CompareLogical()) {                                        \
+        __ cmpl_instr(i.InputRegister(0), i.InputRegister(1), cr);     \
+      } else {                                                         \
+        __ cmp_instr(i.InputRegister(0), i.InputRegister(1), cr);      \
+      }                                                                \
+    } else {                                                           \
+      if (i.CompareLogical()) {                                        \
+        __ cmpl_instr##i(i.InputRegister(0), i.InputImmediate(1), cr); \
+      } else {                                                         \
+        __ cmp_instr##i(i.InputRegister(0), i.InputImmediate(1), cr);  \
+      }                                                                \
+    }                                                                  \
+    DCHECK_EQ(SetRC, i.OutputRCBit());                                 \
+  } while (0)
+
+
+#define ASSEMBLE_FLOAT_COMPARE(cmp_instr)                                 \
+  do {                                                                    \
+    const CRegister cr = cr0;                                             \
+    __ cmp_instr(i.InputDoubleRegister(0), i.InputDoubleRegister(1), cr); \
+    DCHECK_EQ(SetRC, i.OutputRCBit());                                    \
+  } while (0)
+
+
+#define ASSEMBLE_MODULO(div_instr, mul_instr)                        \
+  do {                                                               \
+    const Register scratch = kScratchReg;                            \
+    __ div_instr(scratch, i.InputRegister(0), i.InputRegister(1));   \
+    __ mul_instr(scratch, scratch, i.InputRegister(1));              \
+    __ sub(i.OutputRegister(), i.InputRegister(0), scratch, LeaveOE, \
+           i.OutputRCBit());                                         \
+  } while (0)
+
+
+#define ASSEMBLE_FLOAT_MODULO()                                               \
+  do {                                                                        \
+    FrameScope scope(masm(), StackFrame::MANUAL);                             \
+    __ PrepareCallCFunction(0, 2, kScratchReg);                               \
+    __ MovToFloatParameters(i.InputDoubleRegister(0),                         \
+                            i.InputDoubleRegister(1));                        \
+    __ CallCFunction(ExternalReference::mod_two_doubles_operation(isolate()), \
+                     0, 2);                                                   \
+    __ MovFromFloatResult(i.OutputDoubleRegister());                          \
+    DCHECK_EQ(LeaveRC, i.OutputRCBit());                                      \
+  } while (0)
+
+
+#define ASSEMBLE_FLOAT_MAX(scratch_reg)                                       \
+  do {                                                                        \
+    __ fsub(scratch_reg, i.InputDoubleRegister(0), i.InputDoubleRegister(1)); \
+    __ fsel(i.OutputDoubleRegister(), scratch_reg, i.InputDoubleRegister(0),  \
+            i.InputDoubleRegister(1));                                        \
+  } while (0)
+
+
+#define ASSEMBLE_FLOAT_MIN(scratch_reg)                                       \
+  do {                                                                        \
+    __ fsub(scratch_reg, i.InputDoubleRegister(0), i.InputDoubleRegister(1)); \
+    __ fsel(i.OutputDoubleRegister(), scratch_reg, i.InputDoubleRegister(1),  \
+            i.InputDoubleRegister(0));                                        \
+  } while (0)
+
+
+#define ASSEMBLE_LOAD_FLOAT(asm_instr, asm_instrx)    \
+  do {                                                \
+    DoubleRegister result = i.OutputDoubleRegister(); \
+    AddressingMode mode = kMode_None;                 \
+    MemOperand operand = i.MemoryOperand(&mode);      \
+    if (mode == kMode_MRI) {                          \
+      __ asm_instr(result, operand);                  \
+    } else {                                          \
+      __ asm_instrx(result, operand);                 \
+    }                                                 \
+    DCHECK_EQ(LeaveRC, i.OutputRCBit());              \
+  } while (0)
+
+
+#define ASSEMBLE_LOAD_INTEGER(asm_instr, asm_instrx) \
+  do {                                               \
+    Register result = i.OutputRegister();            \
+    AddressingMode mode = kMode_None;                \
+    MemOperand operand = i.MemoryOperand(&mode);     \
+    if (mode == kMode_MRI) {                         \
+      __ asm_instr(result, operand);                 \
+    } else {                                         \
+      __ asm_instrx(result, operand);                \
+    }                                                \
+    DCHECK_EQ(LeaveRC, i.OutputRCBit());             \
+  } while (0)
+
+
+#define ASSEMBLE_STORE_FLOAT32()                         \
+  do {                                                   \
+    size_t index = 0;                                    \
+    AddressingMode mode = kMode_None;                    \
+    MemOperand operand = i.MemoryOperand(&mode, &index); \
+    DoubleRegister value = i.InputDoubleRegister(index); \
+    __ frsp(kScratchDoubleReg, value);                   \
+    if (mode == kMode_MRI) {                             \
+      __ stfs(kScratchDoubleReg, operand);               \
+    } else {                                             \
+      __ stfsx(kScratchDoubleReg, operand);              \
+    }                                                    \
+    DCHECK_EQ(LeaveRC, i.OutputRCBit());                 \
+  } while (0)
+
+
+#define ASSEMBLE_STORE_DOUBLE()                          \
+  do {                                                   \
+    size_t index = 0;                                    \
+    AddressingMode mode = kMode_None;                    \
+    MemOperand operand = i.MemoryOperand(&mode, &index); \
+    DoubleRegister value = i.InputDoubleRegister(index); \
+    if (mode == kMode_MRI) {                             \
+      __ stfd(value, operand);                           \
+    } else {                                             \
+      __ stfdx(value, operand);                          \
+    }                                                    \
+    DCHECK_EQ(LeaveRC, i.OutputRCBit());                 \
+  } while (0)
+
+
+#define ASSEMBLE_STORE_INTEGER(asm_instr, asm_instrx)    \
+  do {                                                   \
+    size_t index = 0;                                    \
+    AddressingMode mode = kMode_None;                    \
+    MemOperand operand = i.MemoryOperand(&mode, &index); \
+    Register value = i.InputRegister(index);             \
+    if (mode == kMode_MRI) {                             \
+      __ asm_instr(value, operand);                      \
+    } else {                                             \
+      __ asm_instrx(value, operand);                     \
+    }                                                    \
+    DCHECK_EQ(LeaveRC, i.OutputRCBit());                 \
+  } while (0)
+
+
+// TODO(mbrandy): fix paths that produce garbage in offset's upper 32-bits.
+#define ASSEMBLE_CHECKED_LOAD_FLOAT(asm_instr, asm_instrx, width)  \
+  do {                                                             \
+    DoubleRegister result = i.OutputDoubleRegister();              \
+    size_t index = 0;                                              \
+    AddressingMode mode = kMode_None;                              \
+    MemOperand operand = i.MemoryOperand(&mode, index);            \
+    DCHECK_EQ(kMode_MRR, mode);                                    \
+    Register offset = operand.rb();                                \
+    __ extsw(offset, offset);                                      \
+    if (HasRegisterInput(instr, 2)) {                              \
+      __ cmplw(offset, i.InputRegister(2));                        \
+    } else {                                                       \
+      __ cmplwi(offset, i.InputImmediate(2));                      \
+    }                                                              \
+    auto ool = new (zone()) OutOfLineLoadNAN##width(this, result); \
+    __ bge(ool->entry());                                          \
+    if (mode == kMode_MRI) {                                       \
+      __ asm_instr(result, operand);                               \
+    } else {                                                       \
+      __ asm_instrx(result, operand);                              \
+    }                                                              \
+    __ bind(ool->exit());                                          \
+    DCHECK_EQ(LeaveRC, i.OutputRCBit());                           \
+  } while (0)
+
+
+// TODO(mbrandy): fix paths that produce garbage in offset's upper 32-bits.
+#define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr, asm_instrx) \
+  do {                                                       \
+    Register result = i.OutputRegister();                    \
+    size_t index = 0;                                        \
+    AddressingMode mode = kMode_None;                        \
+    MemOperand operand = i.MemoryOperand(&mode, index);      \
+    DCHECK_EQ(kMode_MRR, mode);                              \
+    Register offset = operand.rb();                          \
+    __ extsw(offset, offset);                                \
+    if (HasRegisterInput(instr, 2)) {                        \
+      __ cmplw(offset, i.InputRegister(2));                  \
+    } else {                                                 \
+      __ cmplwi(offset, i.InputImmediate(2));                \
+    }                                                        \
+    auto ool = new (zone()) OutOfLineLoadZero(this, result); \
+    __ bge(ool->entry());                                    \
+    if (mode == kMode_MRI) {                                 \
+      __ asm_instr(result, operand);                         \
+    } else {                                                 \
+      __ asm_instrx(result, operand);                        \
+    }                                                        \
+    __ bind(ool->exit());                                    \
+    DCHECK_EQ(LeaveRC, i.OutputRCBit());                     \
+  } while (0)
+
+
+// TODO(mbrandy): fix paths that produce garbage in offset's upper 32-bits.
+#define ASSEMBLE_CHECKED_STORE_FLOAT32()                \
+  do {                                                  \
+    Label done;                                         \
+    size_t index = 0;                                   \
+    AddressingMode mode = kMode_None;                   \
+    MemOperand operand = i.MemoryOperand(&mode, index); \
+    DCHECK_EQ(kMode_MRR, mode);                         \
+    Register offset = operand.rb();                     \
+    __ extsw(offset, offset);                           \
+    if (HasRegisterInput(instr, 2)) {                   \
+      __ cmplw(offset, i.InputRegister(2));             \
+    } else {                                            \
+      __ cmplwi(offset, i.InputImmediate(2));           \
+    }                                                   \
+    __ bge(&done);                                      \
+    DoubleRegister value = i.InputDoubleRegister(3);    \
+    __ frsp(kScratchDoubleReg, value);                  \
+    if (mode == kMode_MRI) {                            \
+      __ stfs(kScratchDoubleReg, operand);              \
+    } else {                                            \
+      __ stfsx(kScratchDoubleReg, operand);             \
+    }                                                   \
+    __ bind(&done);                                     \
+    DCHECK_EQ(LeaveRC, i.OutputRCBit());                \
+  } while (0)
+
+
+// TODO(mbrandy): fix paths that produce garbage in offset's upper 32-bits.
+#define ASSEMBLE_CHECKED_STORE_DOUBLE()                 \
+  do {                                                  \
+    Label done;                                         \
+    size_t index = 0;                                   \
+    AddressingMode mode = kMode_None;                   \
+    MemOperand operand = i.MemoryOperand(&mode, index); \
+    DCHECK_EQ(kMode_MRR, mode);                         \
+    Register offset = operand.rb();                     \
+    __ extsw(offset, offset);                           \
+    if (HasRegisterInput(instr, 2)) {                   \
+      __ cmplw(offset, i.InputRegister(2));             \
+    } else {                                            \
+      __ cmplwi(offset, i.InputImmediate(2));           \
+    }                                                   \
+    __ bge(&done);                                      \
+    DoubleRegister value = i.InputDoubleRegister(3);    \
+    if (mode == kMode_MRI) {                            \
+      __ stfd(value, operand);                          \
+    } else {                                            \
+      __ stfdx(value, operand);                         \
+    }                                                   \
+    __ bind(&done);                                     \
+    DCHECK_EQ(LeaveRC, i.OutputRCBit());                \
+  } while (0)
+
+
+// TODO(mbrandy): fix paths that produce garbage in offset's upper 32-bits.
+#define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr, asm_instrx) \
+  do {                                                        \
+    Label done;                                               \
+    size_t index = 0;                                         \
+    AddressingMode mode = kMode_None;                         \
+    MemOperand operand = i.MemoryOperand(&mode, index);       \
+    DCHECK_EQ(kMode_MRR, mode);                               \
+    Register offset = operand.rb();                           \
+    __ extsw(offset, offset);                                 \
+    if (HasRegisterInput(instr, 2)) {                         \
+      __ cmplw(offset, i.InputRegister(2));                   \
+    } else {                                                  \
+      __ cmplwi(offset, i.InputImmediate(2));                 \
+    }                                                         \
+    __ bge(&done);                                            \
+    Register value = i.InputRegister(3);                      \
+    if (mode == kMode_MRI) {                                  \
+      __ asm_instr(value, operand);                           \
+    } else {                                                  \
+      __ asm_instrx(value, operand);                          \
+    }                                                         \
+    __ bind(&done);                                           \
+    DCHECK_EQ(LeaveRC, i.OutputRCBit());                      \
+  } while (0)
+
+
+void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) {
+  int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta);
+  if (sp_slot_delta > 0) {
+    __ Add(sp, sp, sp_slot_delta * kPointerSize, r0);
+  }
+  frame_access_state()->SetFrameAccessToDefault();
+}
+
+
+void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) {
+  int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta);
+  if (sp_slot_delta < 0) {
+    __ Add(sp, sp, sp_slot_delta * kPointerSize, r0);
+    frame_access_state()->IncreaseSPDelta(-sp_slot_delta);
+  }
+  if (frame()->needs_frame()) {
+    if (FLAG_enable_embedded_constant_pool) {
+      __ LoadP(kConstantPoolRegister,
+               MemOperand(fp, StandardFrameConstants::kConstantPoolOffset));
+    }
+    __ LoadP(r0, MemOperand(fp, StandardFrameConstants::kCallerPCOffset));
+    __ LoadP(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
+    __ mtlr(r0);
+  }
+  frame_access_state()->SetFrameAccessToSP();
+}
+
+
+// Assembles an instruction after register allocation, producing machine code.
+void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
+  PPCOperandConverter i(this, instr);
+  ArchOpcode opcode = ArchOpcodeField::decode(instr->opcode());
+
+  switch (opcode) {
+    case kArchCallCodeObject: {
+      v8::internal::Assembler::BlockTrampolinePoolScope block_trampoline_pool(
+          masm());
+      EnsureSpaceForLazyDeopt();
+      if (HasRegisterInput(instr, 0)) {
+        __ addi(ip, i.InputRegister(0),
+                Operand(Code::kHeaderSize - kHeapObjectTag));
+        __ Call(ip);
+      } else {
+        __ Call(Handle<Code>::cast(i.InputHeapObject(0)),
+                RelocInfo::CODE_TARGET);
+      }
+      RecordCallPosition(instr);
+      DCHECK_EQ(LeaveRC, i.OutputRCBit());
+      frame_access_state()->ClearSPDelta();
+      break;
+    }
+    case kArchTailCallCodeObject: {
+      int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
+      AssembleDeconstructActivationRecord(stack_param_delta);
+      if (HasRegisterInput(instr, 0)) {
+        __ addi(ip, i.InputRegister(0),
+                Operand(Code::kHeaderSize - kHeapObjectTag));
+        __ Jump(ip);
+      } else {
+        // We cannot use the constant pool to load the target since
+        // we've already restored the caller's frame.
+        ConstantPoolUnavailableScope constant_pool_unavailable(masm());
+        __ Jump(Handle<Code>::cast(i.InputHeapObject(0)),
+                RelocInfo::CODE_TARGET);
+      }
+      DCHECK_EQ(LeaveRC, i.OutputRCBit());
+      frame_access_state()->ClearSPDelta();
+      break;
+    }
+    case kArchCallJSFunction: {
+      v8::internal::Assembler::BlockTrampolinePoolScope block_trampoline_pool(
+          masm());
+      EnsureSpaceForLazyDeopt();
+      Register func = i.InputRegister(0);
+      if (FLAG_debug_code) {
+        // Check the function's context matches the context argument.
+        __ LoadP(kScratchReg,
+                 FieldMemOperand(func, JSFunction::kContextOffset));
+        __ cmp(cp, kScratchReg);
+        __ Assert(eq, kWrongFunctionContext);
+      }
+      __ LoadP(ip, FieldMemOperand(func, JSFunction::kCodeEntryOffset));
+      __ Call(ip);
+      RecordCallPosition(instr);
+      DCHECK_EQ(LeaveRC, i.OutputRCBit());
+      frame_access_state()->ClearSPDelta();
+      break;
+    }
+    case kArchTailCallJSFunction: {
+      Register func = i.InputRegister(0);
+      if (FLAG_debug_code) {
+        // Check the function's context matches the context argument.
+        __ LoadP(kScratchReg,
+                 FieldMemOperand(func, JSFunction::kContextOffset));
+        __ cmp(cp, kScratchReg);
+        __ Assert(eq, kWrongFunctionContext);
+      }
+      int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
+      AssembleDeconstructActivationRecord(stack_param_delta);
+      __ LoadP(ip, FieldMemOperand(func, JSFunction::kCodeEntryOffset));
+      __ Jump(ip);
+      DCHECK_EQ(LeaveRC, i.OutputRCBit());
+      frame_access_state()->ClearSPDelta();
+      break;
+    }
+    case kArchLazyBailout: {
+      v8::internal::Assembler::BlockTrampolinePoolScope block_trampoline_pool(
+          masm());
+      EnsureSpaceForLazyDeopt();
+      RecordCallPosition(instr);
+      break;
+    }
+    case kArchPrepareCallCFunction: {
+      int const num_parameters = MiscField::decode(instr->opcode());
+      __ PrepareCallCFunction(num_parameters, kScratchReg);
+      // Frame alignment requires using FP-relative frame addressing.
+      frame_access_state()->SetFrameAccessToFP();
+      break;
+    }
+    case kArchPrepareTailCall:
+      AssemblePrepareTailCall(i.InputInt32(instr->InputCount() - 1));
+      break;
+    case kArchCallCFunction: {
+      int const num_parameters = MiscField::decode(instr->opcode());
+      if (instr->InputAt(0)->IsImmediate()) {
+        ExternalReference ref = i.InputExternalReference(0);
+        __ CallCFunction(ref, num_parameters);
+      } else {
+        Register func = i.InputRegister(0);
+        __ CallCFunction(func, num_parameters);
+      }
+      frame_access_state()->SetFrameAccessToDefault();
+      frame_access_state()->ClearSPDelta();
+      break;
+    }
+    case kArchJmp:
+      AssembleArchJump(i.InputRpo(0));
+      DCHECK_EQ(LeaveRC, i.OutputRCBit());
+      break;
+    case kArchLookupSwitch:
+      AssembleArchLookupSwitch(instr);
+      DCHECK_EQ(LeaveRC, i.OutputRCBit());
+      break;
+    case kArchTableSwitch:
+      AssembleArchTableSwitch(instr);
+      DCHECK_EQ(LeaveRC, i.OutputRCBit());
+      break;
+    case kArchNop:
+    case kArchThrowTerminator:
+      // don't emit code for nops.
+      DCHECK_EQ(LeaveRC, i.OutputRCBit());
+      break;
+    case kArchDeoptimize: {
+      int deopt_state_id =
+          BuildTranslation(instr, -1, 0, OutputFrameStateCombine::Ignore());
+      Deoptimizer::BailoutType bailout_type =
+          Deoptimizer::BailoutType(MiscField::decode(instr->opcode()));
+      AssembleDeoptimizerCall(deopt_state_id, bailout_type);
+      break;
+    }
+    case kArchRet:
+      AssembleReturn();
+      DCHECK_EQ(LeaveRC, i.OutputRCBit());
+      break;
+    case kArchStackPointer:
+      __ mr(i.OutputRegister(), sp);
+      DCHECK_EQ(LeaveRC, i.OutputRCBit());
+      break;
+    case kArchFramePointer:
+      __ mr(i.OutputRegister(), fp);
+      DCHECK_EQ(LeaveRC, i.OutputRCBit());
+      break;
+    case kArchTruncateDoubleToI:
+      // TODO(mbrandy): move slow call to stub out of line.
+      __ TruncateDoubleToI(i.OutputRegister(), i.InputDoubleRegister(0));
+      DCHECK_EQ(LeaveRC, i.OutputRCBit());
+      break;
+    case kArchStoreWithWriteBarrier: {
+      RecordWriteMode mode =
+          static_cast<RecordWriteMode>(MiscField::decode(instr->opcode()));
+      Register object = i.InputRegister(0);
+      Register offset = i.InputRegister(1);
+      Register value = i.InputRegister(2);
+      Register scratch0 = i.TempRegister(0);
+      Register scratch1 = i.TempRegister(1);
+      auto ool = new (zone()) OutOfLineRecordWrite(this, object, offset, value,
+                                                   scratch0, scratch1, mode);
+      __ StorePX(value, MemOperand(object, offset));
+      __ CheckPageFlag(object, scratch0,
+                       MemoryChunk::kPointersFromHereAreInterestingMask, ne,
+                       ool->entry());
+      __ bind(ool->exit());
+      break;
+    }
+    case kPPC_And:
+      if (HasRegisterInput(instr, 1)) {
+        __ and_(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
+                i.OutputRCBit());
+      } else {
+        __ andi(i.OutputRegister(), i.InputRegister(0), i.InputImmediate(1));
+      }
+      break;
+    case kPPC_AndComplement:
+      __ andc(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
+              i.OutputRCBit());
+      break;
+    case kPPC_Or:
+      if (HasRegisterInput(instr, 1)) {
+        __ orx(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
+               i.OutputRCBit());
+      } else {
+        __ ori(i.OutputRegister(), i.InputRegister(0), i.InputImmediate(1));
+        DCHECK_EQ(LeaveRC, i.OutputRCBit());
+      }
+      break;
+    case kPPC_OrComplement:
+      __ orc(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
+             i.OutputRCBit());
+      break;
+    case kPPC_Xor:
+      if (HasRegisterInput(instr, 1)) {
+        __ xor_(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
+                i.OutputRCBit());
+      } else {
+        __ xori(i.OutputRegister(), i.InputRegister(0), i.InputImmediate(1));
+        DCHECK_EQ(LeaveRC, i.OutputRCBit());
+      }
+      break;
+    case kPPC_ShiftLeft32:
+      ASSEMBLE_BINOP_RC(slw, slwi);
+      break;
+#if V8_TARGET_ARCH_PPC64
+    case kPPC_ShiftLeft64:
+      ASSEMBLE_BINOP_RC(sld, sldi);
+      break;
+#endif
+    case kPPC_ShiftRight32:
+      ASSEMBLE_BINOP_RC(srw, srwi);
+      break;
+#if V8_TARGET_ARCH_PPC64
+    case kPPC_ShiftRight64:
+      ASSEMBLE_BINOP_RC(srd, srdi);
+      break;
+#endif
+    case kPPC_ShiftRightAlg32:
+      ASSEMBLE_BINOP_INT_RC(sraw, srawi);
+      break;
+#if V8_TARGET_ARCH_PPC64
+    case kPPC_ShiftRightAlg64:
+      ASSEMBLE_BINOP_INT_RC(srad, sradi);
+      break;
+#endif
+    case kPPC_RotRight32:
+      if (HasRegisterInput(instr, 1)) {
+        __ subfic(kScratchReg, i.InputRegister(1), Operand(32));
+        __ rotlw(i.OutputRegister(), i.InputRegister(0), kScratchReg,
+                 i.OutputRCBit());
+      } else {
+        int sh = i.InputInt32(1);
+        __ rotrwi(i.OutputRegister(), i.InputRegister(0), sh, i.OutputRCBit());
+      }
+      break;
+#if V8_TARGET_ARCH_PPC64
+    case kPPC_RotRight64:
+      if (HasRegisterInput(instr, 1)) {
+        __ subfic(kScratchReg, i.InputRegister(1), Operand(64));
+        __ rotld(i.OutputRegister(), i.InputRegister(0), kScratchReg,
+                 i.OutputRCBit());
+      } else {
+        int sh = i.InputInt32(1);
+        __ rotrdi(i.OutputRegister(), i.InputRegister(0), sh, i.OutputRCBit());
+      }
+      break;
+#endif
+    case kPPC_Not:
+      __ notx(i.OutputRegister(), i.InputRegister(0), i.OutputRCBit());
+      break;
+    case kPPC_RotLeftAndMask32:
+      __ rlwinm(i.OutputRegister(), i.InputRegister(0), i.InputInt32(1),
+                31 - i.InputInt32(2), 31 - i.InputInt32(3), i.OutputRCBit());
+      break;
+#if V8_TARGET_ARCH_PPC64
+    case kPPC_RotLeftAndClear64:
+      __ rldic(i.OutputRegister(), i.InputRegister(0), i.InputInt32(1),
+               63 - i.InputInt32(2), i.OutputRCBit());
+      break;
+    case kPPC_RotLeftAndClearLeft64:
+      __ rldicl(i.OutputRegister(), i.InputRegister(0), i.InputInt32(1),
+                63 - i.InputInt32(2), i.OutputRCBit());
+      break;
+    case kPPC_RotLeftAndClearRight64:
+      __ rldicr(i.OutputRegister(), i.InputRegister(0), i.InputInt32(1),
+                63 - i.InputInt32(2), i.OutputRCBit());
+      break;
+#endif
+    case kPPC_Add:
+#if V8_TARGET_ARCH_PPC64
+      if (FlagsModeField::decode(instr->opcode()) != kFlags_none) {
+        ASSEMBLE_ADD_WITH_OVERFLOW();
+      } else {
+#endif
+        if (HasRegisterInput(instr, 1)) {
+          __ add(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
+                 LeaveOE, i.OutputRCBit());
+        } else {
+          __ addi(i.OutputRegister(), i.InputRegister(0), i.InputImmediate(1));
+          DCHECK_EQ(LeaveRC, i.OutputRCBit());
+        }
+#if V8_TARGET_ARCH_PPC64
+      }
+#endif
+      break;
+    case kPPC_AddWithOverflow32:
+      ASSEMBLE_ADD_WITH_OVERFLOW32();
+      break;
+    case kPPC_AddDouble:
+      ASSEMBLE_FLOAT_BINOP_RC(fadd);
+      break;
+    case kPPC_Sub:
+#if V8_TARGET_ARCH_PPC64
+      if (FlagsModeField::decode(instr->opcode()) != kFlags_none) {
+        ASSEMBLE_SUB_WITH_OVERFLOW();
+      } else {
+#endif
+        if (HasRegisterInput(instr, 1)) {
+          __ sub(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
+                 LeaveOE, i.OutputRCBit());
+        } else {
+          __ subi(i.OutputRegister(), i.InputRegister(0), i.InputImmediate(1));
+          DCHECK_EQ(LeaveRC, i.OutputRCBit());
+        }
+#if V8_TARGET_ARCH_PPC64
+      }
+#endif
+      break;
+    case kPPC_SubWithOverflow32:
+      ASSEMBLE_SUB_WITH_OVERFLOW32();
+      break;
+    case kPPC_SubDouble:
+      ASSEMBLE_FLOAT_BINOP_RC(fsub);
+      break;
+    case kPPC_Mul32:
+      __ mullw(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
+               LeaveOE, i.OutputRCBit());
+      break;
+#if V8_TARGET_ARCH_PPC64
+    case kPPC_Mul64:
+      __ mulld(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
+               LeaveOE, i.OutputRCBit());
+      break;
+#endif
+    case kPPC_MulHigh32:
+      __ mulhw(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
+               i.OutputRCBit());
+      break;
+    case kPPC_MulHighU32:
+      __ mulhwu(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
+                i.OutputRCBit());
+      break;
+    case kPPC_MulDouble:
+      ASSEMBLE_FLOAT_BINOP_RC(fmul);
+      break;
+    case kPPC_Div32:
+      __ divw(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
+      DCHECK_EQ(LeaveRC, i.OutputRCBit());
+      break;
+#if V8_TARGET_ARCH_PPC64
+    case kPPC_Div64:
+      __ divd(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
+      DCHECK_EQ(LeaveRC, i.OutputRCBit());
+      break;
+#endif
+    case kPPC_DivU32:
+      __ divwu(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
+      DCHECK_EQ(LeaveRC, i.OutputRCBit());
+      break;
+#if V8_TARGET_ARCH_PPC64
+    case kPPC_DivU64:
+      __ divdu(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
+      DCHECK_EQ(LeaveRC, i.OutputRCBit());
+      break;
+#endif
+    case kPPC_DivDouble:
+      ASSEMBLE_FLOAT_BINOP_RC(fdiv);
+      break;
+    case kPPC_Mod32:
+      ASSEMBLE_MODULO(divw, mullw);
+      break;
+#if V8_TARGET_ARCH_PPC64
+    case kPPC_Mod64:
+      ASSEMBLE_MODULO(divd, mulld);
+      break;
+#endif
+    case kPPC_ModU32:
+      ASSEMBLE_MODULO(divwu, mullw);
+      break;
+#if V8_TARGET_ARCH_PPC64
+    case kPPC_ModU64:
+      ASSEMBLE_MODULO(divdu, mulld);
+      break;
+#endif
+    case kPPC_ModDouble:
+      // TODO(bmeurer): We should really get rid of this special instruction,
+      // and generate a CallAddress instruction instead.
+      ASSEMBLE_FLOAT_MODULO();
+      break;
+    case kPPC_Neg:
+      __ neg(i.OutputRegister(), i.InputRegister(0), LeaveOE, i.OutputRCBit());
+      break;
+    case kPPC_MaxDouble:
+      ASSEMBLE_FLOAT_MAX(kScratchDoubleReg);
+      break;
+    case kPPC_MinDouble:
+      ASSEMBLE_FLOAT_MIN(kScratchDoubleReg);
+      break;
+    case kPPC_AbsDouble:
+      ASSEMBLE_FLOAT_UNOP_RC(fabs);
+      break;
+    case kPPC_SqrtDouble:
+      ASSEMBLE_FLOAT_UNOP_RC(fsqrt);
+      break;
+    case kPPC_FloorDouble:
+      ASSEMBLE_FLOAT_UNOP_RC(frim);
+      break;
+    case kPPC_CeilDouble:
+      ASSEMBLE_FLOAT_UNOP_RC(frip);
+      break;
+    case kPPC_TruncateDouble:
+      ASSEMBLE_FLOAT_UNOP_RC(friz);
+      break;
+    case kPPC_RoundDouble:
+      ASSEMBLE_FLOAT_UNOP_RC(frin);
+      break;
+    case kPPC_NegDouble:
+      ASSEMBLE_FLOAT_UNOP_RC(fneg);
+      break;
+    case kPPC_Cntlz32:
+      __ cntlzw_(i.OutputRegister(), i.InputRegister(0));
+      DCHECK_EQ(LeaveRC, i.OutputRCBit());
+      break;
+#if V8_TARGET_ARCH_PPC64
+    case kPPC_Cntlz64:
+      __ cntlzd_(i.OutputRegister(), i.InputRegister(0));
+      DCHECK_EQ(LeaveRC, i.OutputRCBit());
+      break;
+#endif
+    case kPPC_Popcnt32:
+      __ popcntw(i.OutputRegister(), i.InputRegister(0));
+      DCHECK_EQ(LeaveRC, i.OutputRCBit());
+      break;
+#if V8_TARGET_ARCH_PPC64
+    case kPPC_Popcnt64:
+      __ popcntd(i.OutputRegister(), i.InputRegister(0));
+      DCHECK_EQ(LeaveRC, i.OutputRCBit());
+      break;
+#endif
+    case kPPC_Cmp32:
+      ASSEMBLE_COMPARE(cmpw, cmplw);
+      break;
+#if V8_TARGET_ARCH_PPC64
+    case kPPC_Cmp64:
+      ASSEMBLE_COMPARE(cmp, cmpl);
+      break;
+#endif
+    case kPPC_CmpDouble:
+      ASSEMBLE_FLOAT_COMPARE(fcmpu);
+      break;
+    case kPPC_Tst32:
+      if (HasRegisterInput(instr, 1)) {
+        __ and_(r0, i.InputRegister(0), i.InputRegister(1), i.OutputRCBit());
+      } else {
+        __ andi(r0, i.InputRegister(0), i.InputImmediate(1));
+      }
+#if V8_TARGET_ARCH_PPC64
+      __ extsw(r0, r0, i.OutputRCBit());
+#endif
+      DCHECK_EQ(SetRC, i.OutputRCBit());
+      break;
+#if V8_TARGET_ARCH_PPC64
+    case kPPC_Tst64:
+      if (HasRegisterInput(instr, 1)) {
+        __ and_(r0, i.InputRegister(0), i.InputRegister(1), i.OutputRCBit());
+      } else {
+        __ andi(r0, i.InputRegister(0), i.InputImmediate(1));
+      }
+      DCHECK_EQ(SetRC, i.OutputRCBit());
+      break;
+#endif
+    case kPPC_Push:
+      if (instr->InputAt(0)->IsDoubleRegister()) {
+        __ stfdu(i.InputDoubleRegister(0), MemOperand(sp, -kDoubleSize));
+        frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize);
+      } else {
+        __ Push(i.InputRegister(0));
+        frame_access_state()->IncreaseSPDelta(1);
+      }
+      DCHECK_EQ(LeaveRC, i.OutputRCBit());
+      break;
+    case kPPC_PushFrame: {
+      int num_slots = i.InputInt32(1);
+      if (instr->InputAt(0)->IsDoubleRegister()) {
+        __ stfdu(i.InputDoubleRegister(0),
+                 MemOperand(sp, -num_slots * kPointerSize));
+      } else {
+        __ StorePU(i.InputRegister(0),
+                   MemOperand(sp, -num_slots * kPointerSize));
+      }
+      break;
+    }
+    case kPPC_StoreToStackSlot: {
+      int slot = i.InputInt32(1);
+      if (instr->InputAt(0)->IsDoubleRegister()) {
+        __ stfd(i.InputDoubleRegister(0), MemOperand(sp, slot * kPointerSize));
+      } else {
+        __ StoreP(i.InputRegister(0), MemOperand(sp, slot * kPointerSize));
+      }
+      break;
+    }
+    case kPPC_ExtendSignWord8:
+      __ extsb(i.OutputRegister(), i.InputRegister(0));
+      DCHECK_EQ(LeaveRC, i.OutputRCBit());
+      break;
+    case kPPC_ExtendSignWord16:
+      __ extsh(i.OutputRegister(), i.InputRegister(0));
+      DCHECK_EQ(LeaveRC, i.OutputRCBit());
+      break;
+#if V8_TARGET_ARCH_PPC64
+    case kPPC_ExtendSignWord32:
+      __ extsw(i.OutputRegister(), i.InputRegister(0));
+      DCHECK_EQ(LeaveRC, i.OutputRCBit());
+      break;
+    case kPPC_Uint32ToUint64:
+      // Zero extend
+      __ clrldi(i.OutputRegister(), i.InputRegister(0), Operand(32));
+      DCHECK_EQ(LeaveRC, i.OutputRCBit());
+      break;
+    case kPPC_Int64ToInt32:
+      __ extsw(i.OutputRegister(), i.InputRegister(0));
+      DCHECK_EQ(LeaveRC, i.OutputRCBit());
+      break;
+    case kPPC_Int64ToFloat32:
+      __ ConvertInt64ToFloat(i.InputRegister(0), i.OutputDoubleRegister());
+      DCHECK_EQ(LeaveRC, i.OutputRCBit());
+      break;
+    case kPPC_Int64ToDouble:
+      __ ConvertInt64ToDouble(i.InputRegister(0), i.OutputDoubleRegister());
+      DCHECK_EQ(LeaveRC, i.OutputRCBit());
+      break;
+    case kPPC_Uint64ToFloat32:
+      __ ConvertUnsignedInt64ToFloat(i.InputRegister(0),
+                                     i.OutputDoubleRegister());
+      DCHECK_EQ(LeaveRC, i.OutputRCBit());
+      break;
+    case kPPC_Uint64ToDouble:
+      __ ConvertUnsignedInt64ToDouble(i.InputRegister(0),
+                                      i.OutputDoubleRegister());
+      DCHECK_EQ(LeaveRC, i.OutputRCBit());
+      break;
+#endif
+    case kPPC_Int32ToDouble:
+      __ ConvertIntToDouble(i.InputRegister(0), i.OutputDoubleRegister());
+      DCHECK_EQ(LeaveRC, i.OutputRCBit());
+      break;
+    case kPPC_Uint32ToDouble:
+      __ ConvertUnsignedIntToDouble(i.InputRegister(0),
+                                    i.OutputDoubleRegister());
+      DCHECK_EQ(LeaveRC, i.OutputRCBit());
+      break;
+    case kPPC_DoubleToInt32:
+    case kPPC_DoubleToUint32:
+    case kPPC_DoubleToInt64: {
+#if V8_TARGET_ARCH_PPC64
+      bool check_conversion =
+          (opcode == kPPC_DoubleToInt64 && i.OutputCount() > 1);
+      if (check_conversion) {
+        __ mtfsb0(VXCVI);  // clear FPSCR:VXCVI bit
+      }
+#endif
+      __ ConvertDoubleToInt64(i.InputDoubleRegister(0),
+#if !V8_TARGET_ARCH_PPC64
+                              kScratchReg,
+#endif
+                              i.OutputRegister(0), kScratchDoubleReg);
+#if V8_TARGET_ARCH_PPC64
+      if (check_conversion) {
+        // Set 2nd output to zero if conversion fails.
+        CRegister cr = cr7;
+        int crbit = v8::internal::Assembler::encode_crbit(
+            cr, static_cast<CRBit>(VXCVI % CRWIDTH));
+        __ mcrfs(cr, VXCVI);  // extract FPSCR field containing VXCVI into cr7
+        if (CpuFeatures::IsSupported(ISELECT)) {
+          __ li(i.OutputRegister(1), Operand(1));
+          __ isel(i.OutputRegister(1), r0, i.OutputRegister(1), crbit);
+        } else {
+          __ li(i.OutputRegister(1), Operand::Zero());
+          __ bc(v8::internal::Assembler::kInstrSize * 2, BT, crbit);
+          __ li(i.OutputRegister(1), Operand(1));
+        }
+      }
+#endif
+      DCHECK_EQ(LeaveRC, i.OutputRCBit());
+      break;
+    }
+#if V8_TARGET_ARCH_PPC64
+    case kPPC_DoubleToUint64: {
+      bool check_conversion = (i.OutputCount() > 1);
+      if (check_conversion) {
+        __ mtfsb0(VXCVI);  // clear FPSCR:VXCVI bit
+      }
+      __ ConvertDoubleToUnsignedInt64(i.InputDoubleRegister(0),
+                                      i.OutputRegister(0), kScratchDoubleReg);
+      if (check_conversion) {
+        // Set 2nd output to zero if conversion fails.
+        CRegister cr = cr7;
+        int crbit = v8::internal::Assembler::encode_crbit(
+            cr, static_cast<CRBit>(VXCVI % CRWIDTH));
+        __ mcrfs(cr, VXCVI);  // extract FPSCR field containing VXCVI into cr7
+        if (CpuFeatures::IsSupported(ISELECT)) {
+          __ li(i.OutputRegister(1), Operand(1));
+          __ isel(i.OutputRegister(1), r0, i.OutputRegister(1), crbit);
+        } else {
+          __ li(i.OutputRegister(1), Operand::Zero());
+          __ bc(v8::internal::Assembler::kInstrSize * 2, BT, crbit);
+          __ li(i.OutputRegister(1), Operand(1));
+        }
+      }
+      DCHECK_EQ(LeaveRC, i.OutputRCBit());
+      break;
+    }
+#endif
+    case kPPC_DoubleToFloat32:
+      ASSEMBLE_FLOAT_UNOP_RC(frsp);
+      break;
+    case kPPC_Float32ToDouble:
+      // Nothing to do.
+      __ Move(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
+      DCHECK_EQ(LeaveRC, i.OutputRCBit());
+      break;
+    case kPPC_DoubleExtractLowWord32:
+      __ MovDoubleLowToInt(i.OutputRegister(), i.InputDoubleRegister(0));
+      DCHECK_EQ(LeaveRC, i.OutputRCBit());
+      break;
+    case kPPC_DoubleExtractHighWord32:
+      __ MovDoubleHighToInt(i.OutputRegister(), i.InputDoubleRegister(0));
+      DCHECK_EQ(LeaveRC, i.OutputRCBit());
+      break;
+    case kPPC_DoubleInsertLowWord32:
+      __ InsertDoubleLow(i.OutputDoubleRegister(), i.InputRegister(1), r0);
+      DCHECK_EQ(LeaveRC, i.OutputRCBit());
+      break;
+    case kPPC_DoubleInsertHighWord32:
+      __ InsertDoubleHigh(i.OutputDoubleRegister(), i.InputRegister(1), r0);
+      DCHECK_EQ(LeaveRC, i.OutputRCBit());
+      break;
+    case kPPC_DoubleConstruct:
+#if V8_TARGET_ARCH_PPC64
+      __ MovInt64ComponentsToDouble(i.OutputDoubleRegister(),
+                                    i.InputRegister(0), i.InputRegister(1), r0);
+#else
+      __ MovInt64ToDouble(i.OutputDoubleRegister(), i.InputRegister(0),
+                          i.InputRegister(1));
+#endif
+      DCHECK_EQ(LeaveRC, i.OutputRCBit());
+      break;
+    case kPPC_BitcastFloat32ToInt32:
+      __ MovFloatToInt(i.OutputRegister(), i.InputDoubleRegister(0));
+      break;
+    case kPPC_BitcastInt32ToFloat32:
+      __ MovIntToFloat(i.OutputDoubleRegister(), i.InputRegister(0));
+      break;
+#if V8_TARGET_ARCH_PPC64
+    case kPPC_BitcastDoubleToInt64:
+      __ MovDoubleToInt64(i.OutputRegister(), i.InputDoubleRegister(0));
+      break;
+    case kPPC_BitcastInt64ToDouble:
+      __ MovInt64ToDouble(i.OutputDoubleRegister(), i.InputRegister(0));
+      break;
+#endif
+    case kPPC_LoadWordU8:
+      ASSEMBLE_LOAD_INTEGER(lbz, lbzx);
+      break;
+    case kPPC_LoadWordS8:
+      ASSEMBLE_LOAD_INTEGER(lbz, lbzx);
+      __ extsb(i.OutputRegister(), i.OutputRegister());
+      break;
+    case kPPC_LoadWordU16:
+      ASSEMBLE_LOAD_INTEGER(lhz, lhzx);
+      break;
+    case kPPC_LoadWordS16:
+      ASSEMBLE_LOAD_INTEGER(lha, lhax);
+      break;
+    case kPPC_LoadWordS32:
+      ASSEMBLE_LOAD_INTEGER(lwa, lwax);
+      break;
+#if V8_TARGET_ARCH_PPC64
+    case kPPC_LoadWord64:
+      ASSEMBLE_LOAD_INTEGER(ld, ldx);
+      break;
+#endif
+    case kPPC_LoadFloat32:
+      ASSEMBLE_LOAD_FLOAT(lfs, lfsx);
+      break;
+    case kPPC_LoadDouble:
+      ASSEMBLE_LOAD_FLOAT(lfd, lfdx);
+      break;
+    case kPPC_StoreWord8:
+      ASSEMBLE_STORE_INTEGER(stb, stbx);
+      break;
+    case kPPC_StoreWord16:
+      ASSEMBLE_STORE_INTEGER(sth, sthx);
+      break;
+    case kPPC_StoreWord32:
+      ASSEMBLE_STORE_INTEGER(stw, stwx);
+      break;
+#if V8_TARGET_ARCH_PPC64
+    case kPPC_StoreWord64:
+      ASSEMBLE_STORE_INTEGER(std, stdx);
+      break;
+#endif
+    case kPPC_StoreFloat32:
+      ASSEMBLE_STORE_FLOAT32();
+      break;
+    case kPPC_StoreDouble:
+      ASSEMBLE_STORE_DOUBLE();
+      break;
+    case kCheckedLoadInt8:
+      ASSEMBLE_CHECKED_LOAD_INTEGER(lbz, lbzx);
+      __ extsb(i.OutputRegister(), i.OutputRegister());
+      break;
+    case kCheckedLoadUint8:
+      ASSEMBLE_CHECKED_LOAD_INTEGER(lbz, lbzx);
+      break;
+    case kCheckedLoadInt16:
+      ASSEMBLE_CHECKED_LOAD_INTEGER(lha, lhax);
+      break;
+    case kCheckedLoadUint16:
+      ASSEMBLE_CHECKED_LOAD_INTEGER(lhz, lhzx);
+      break;
+    case kCheckedLoadWord32:
+      ASSEMBLE_CHECKED_LOAD_INTEGER(lwa, lwax);
+      break;
+    case kCheckedLoadWord64:
+#if V8_TARGET_ARCH_PPC64
+      ASSEMBLE_CHECKED_LOAD_INTEGER(ld, ldx);
+#else
+      UNREACHABLE();
+#endif
+      break;
+    case kCheckedLoadFloat32:
+      ASSEMBLE_CHECKED_LOAD_FLOAT(lfs, lfsx, 32);
+      break;
+    case kCheckedLoadFloat64:
+      ASSEMBLE_CHECKED_LOAD_FLOAT(lfd, lfdx, 64);
+      break;
+    case kCheckedStoreWord8:
+      ASSEMBLE_CHECKED_STORE_INTEGER(stb, stbx);
+      break;
+    case kCheckedStoreWord16:
+      ASSEMBLE_CHECKED_STORE_INTEGER(sth, sthx);
+      break;
+    case kCheckedStoreWord32:
+      ASSEMBLE_CHECKED_STORE_INTEGER(stw, stwx);
+      break;
+    case kCheckedStoreWord64:
+#if V8_TARGET_ARCH_PPC64
+      ASSEMBLE_CHECKED_STORE_INTEGER(std, stdx);
+#else
+      UNREACHABLE();
+#endif
+      break;
+    case kCheckedStoreFloat32:
+      ASSEMBLE_CHECKED_STORE_FLOAT32();
+      break;
+    case kCheckedStoreFloat64:
+      ASSEMBLE_CHECKED_STORE_DOUBLE();
+      break;
+    default:
+      UNREACHABLE();
+      break;
+  }
+}  // NOLINT(readability/fn_size)
+
+
+// Assembles branches after an instruction.
+void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) {
+  PPCOperandConverter i(this, instr);
+  Label* tlabel = branch->true_label;
+  Label* flabel = branch->false_label;
+  ArchOpcode op = instr->arch_opcode();
+  FlagsCondition condition = branch->condition;
+  CRegister cr = cr0;
+
+  Condition cond = FlagsConditionToCondition(condition, op);
+  if (op == kPPC_CmpDouble) {
+    // check for unordered if necessary
+    if (cond == le) {
+      __ bunordered(flabel, cr);
+      // Unnecessary for eq/lt since only FU bit will be set.
+    } else if (cond == gt) {
+      __ bunordered(tlabel, cr);
+      // Unnecessary for ne/ge since only FU bit will be set.
+    }
+  }
+  __ b(cond, tlabel, cr);
+  if (!branch->fallthru) __ b(flabel);  // no fallthru to flabel.
+}
+
+
+void CodeGenerator::AssembleArchJump(RpoNumber target) {
+  if (!IsNextInAssemblyOrder(target)) __ b(GetLabel(target));
+}
+
+
+// Assembles boolean materializations after an instruction.
+void CodeGenerator::AssembleArchBoolean(Instruction* instr,
+                                        FlagsCondition condition) {
+  PPCOperandConverter i(this, instr);
+  Label done;
+  ArchOpcode op = instr->arch_opcode();
+  CRegister cr = cr0;
+  int reg_value = -1;
+
+  // Materialize a full 32-bit 1 or 0 value. The result register is always the
+  // last output of the instruction.
+  DCHECK_NE(0u, instr->OutputCount());
+  Register reg = i.OutputRegister(instr->OutputCount() - 1);
+
+  Condition cond = FlagsConditionToCondition(condition, op);
+  if (op == kPPC_CmpDouble) {
+    // check for unordered if necessary
+    if (cond == le) {
+      reg_value = 0;
+      __ li(reg, Operand::Zero());
+      __ bunordered(&done, cr);
+    } else if (cond == gt) {
+      reg_value = 1;
+      __ li(reg, Operand(1));
+      __ bunordered(&done, cr);
+    }
+    // Unnecessary for eq/lt & ne/ge since only FU bit will be set.
+  }
+
+  if (CpuFeatures::IsSupported(ISELECT)) {
+    switch (cond) {
+      case eq:
+      case lt:
+      case gt:
+        if (reg_value != 1) __ li(reg, Operand(1));
+        __ li(kScratchReg, Operand::Zero());
+        __ isel(cond, reg, reg, kScratchReg, cr);
+        break;
+      case ne:
+      case ge:
+      case le:
+        if (reg_value != 1) __ li(reg, Operand(1));
+        // r0 implies logical zero in this form
+        __ isel(NegateCondition(cond), reg, r0, reg, cr);
+        break;
+    default:
+      UNREACHABLE();
+      break;
+    }
+  } else {
+    if (reg_value != 0) __ li(reg, Operand::Zero());
+    __ b(NegateCondition(cond), &done, cr);
+    __ li(reg, Operand(1));
+  }
+  __ bind(&done);
+}
+
+
+void CodeGenerator::AssembleArchLookupSwitch(Instruction* instr) {
+  PPCOperandConverter i(this, instr);
+  Register input = i.InputRegister(0);
+  for (size_t index = 2; index < instr->InputCount(); index += 2) {
+    __ Cmpi(input, Operand(i.InputInt32(index + 0)), r0);
+    __ beq(GetLabel(i.InputRpo(index + 1)));
+  }
+  AssembleArchJump(i.InputRpo(1));
+}
+
+
+void CodeGenerator::AssembleArchTableSwitch(Instruction* instr) {
+  PPCOperandConverter i(this, instr);
+  Register input = i.InputRegister(0);
+  int32_t const case_count = static_cast<int32_t>(instr->InputCount() - 2);
+  Label** cases = zone()->NewArray<Label*>(case_count);
+  for (int32_t index = 0; index < case_count; ++index) {
+    cases[index] = GetLabel(i.InputRpo(index + 2));
+  }
+  Label* const table = AddJumpTable(cases, case_count);
+  __ Cmpli(input, Operand(case_count), r0);
+  __ bge(GetLabel(i.InputRpo(1)));
+  __ mov_label_addr(kScratchReg, table);
+  __ ShiftLeftImm(r0, input, Operand(kPointerSizeLog2));
+  __ LoadPX(kScratchReg, MemOperand(kScratchReg, r0));
+  __ Jump(kScratchReg);
+}
+
+
+void CodeGenerator::AssembleDeoptimizerCall(
+    int deoptimization_id, Deoptimizer::BailoutType bailout_type) {
+  Address deopt_entry = Deoptimizer::GetDeoptimizationEntry(
+      isolate(), deoptimization_id, bailout_type);
+  __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY);
+}
+
+
+void CodeGenerator::AssemblePrologue() {
+  CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
+  if (descriptor->IsCFunctionCall()) {
+    __ function_descriptor();
+    __ mflr(r0);
+    if (FLAG_enable_embedded_constant_pool) {
+      __ Push(r0, fp, kConstantPoolRegister);
+      // Adjust FP to point to saved FP.
+      __ subi(fp, sp, Operand(StandardFrameConstants::kConstantPoolOffset));
+    } else {
+      __ Push(r0, fp);
+      __ mr(fp, sp);
+    }
+  } else if (descriptor->IsJSFunctionCall()) {
+    __ Prologue(this->info()->GeneratePreagedPrologue(), ip);
+  } else if (frame()->needs_frame()) {
+    if (!ABI_CALL_VIA_IP && info()->output_code_kind() == Code::WASM_FUNCTION) {
+      // TODO(mbrandy): Restrict only to the wasm wrapper case.
+      __ StubPrologue();
+    } else {
+      __ StubPrologue(ip);
+    }
+  } else {
+    frame()->SetElidedFrameSizeInSlots(0);
+  }
+  frame_access_state()->SetFrameAccessToDefault();
+
+  int stack_shrink_slots = frame()->GetSpillSlotCount();
+  if (info()->is_osr()) {
+    // TurboFan OSR-compiled functions cannot be entered directly.
+    __ Abort(kShouldNotDirectlyEnterOsrFunction);
+
+    // Unoptimized code jumps directly to this entrypoint while the unoptimized
+    // frame is still on the stack. Optimized code uses OSR values directly from
+    // the unoptimized frame. Thus, all that needs to be done is to allocate the
+    // remaining stack slots.
+    if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --");
+    osr_pc_offset_ = __ pc_offset();
+    // TODO(titzer): cannot address target function == local #-1
+    __ LoadP(r4, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
+    stack_shrink_slots -= OsrHelper(info()).UnoptimizedFrameSlots();
+  }
+
+  const RegList double_saves = descriptor->CalleeSavedFPRegisters();
+  if (double_saves != 0) {
+    stack_shrink_slots += frame()->AlignSavedCalleeRegisterSlots();
+  }
+  if (stack_shrink_slots > 0) {
+    __ Add(sp, sp, -stack_shrink_slots * kPointerSize, r0);
+  }
+
+  // Save callee-saved Double registers.
+  if (double_saves != 0) {
+    __ MultiPushDoubles(double_saves);
+    DCHECK(kNumCalleeSavedDoubles ==
+           base::bits::CountPopulation32(double_saves));
+    frame()->AllocateSavedCalleeRegisterSlots(kNumCalleeSavedDoubles *
+                                              (kDoubleSize / kPointerSize));
+  }
+
+  // Save callee-saved registers.
+  const RegList saves =
+      FLAG_enable_embedded_constant_pool
+          ? descriptor->CalleeSavedRegisters() & ~kConstantPoolRegister.bit()
+          : descriptor->CalleeSavedRegisters();
+  if (saves != 0) {
+    __ MultiPush(saves);
+    // register save area does not include the fp or constant pool pointer.
+    const int num_saves =
+        kNumCalleeSaved - 1 - (FLAG_enable_embedded_constant_pool ? 1 : 0);
+    DCHECK(num_saves == base::bits::CountPopulation32(saves));
+    frame()->AllocateSavedCalleeRegisterSlots(num_saves);
+  }
+}
+
+
+void CodeGenerator::AssembleReturn() {
+  CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
+  int pop_count = static_cast<int>(descriptor->StackParameterCount());
+
+  // Restore registers.
+  const RegList saves =
+      FLAG_enable_embedded_constant_pool
+          ? descriptor->CalleeSavedRegisters() & ~kConstantPoolRegister.bit()
+          : descriptor->CalleeSavedRegisters();
+  if (saves != 0) {
+    __ MultiPop(saves);
+  }
+
+  // Restore double registers.
+  const RegList double_saves = descriptor->CalleeSavedFPRegisters();
+  if (double_saves != 0) {
+    __ MultiPopDoubles(double_saves);
+  }
+
+  if (descriptor->IsCFunctionCall()) {
+    __ LeaveFrame(StackFrame::MANUAL, pop_count * kPointerSize);
+  } else if (frame()->needs_frame()) {
+    // Canonicalize JSFunction return sites for now.
+    if (return_label_.is_bound()) {
+      __ b(&return_label_);
+      return;
+    } else {
+      __ bind(&return_label_);
+      __ LeaveFrame(StackFrame::MANUAL, pop_count * kPointerSize);
+    }
+  } else {
+    __ Drop(pop_count);
+  }
+  __ Ret();
+}
+
+
+void CodeGenerator::AssembleMove(InstructionOperand* source,
+                                 InstructionOperand* destination) {
+  PPCOperandConverter g(this, nullptr);
+  // Dispatch on the source and destination operand kinds.  Not all
+  // combinations are possible.
+  if (source->IsRegister()) {
+    DCHECK(destination->IsRegister() || destination->IsStackSlot());
+    Register src = g.ToRegister(source);
+    if (destination->IsRegister()) {
+      __ Move(g.ToRegister(destination), src);
+    } else {
+      __ StoreP(src, g.ToMemOperand(destination), r0);
+    }
+  } else if (source->IsStackSlot()) {
+    DCHECK(destination->IsRegister() || destination->IsStackSlot());
+    MemOperand src = g.ToMemOperand(source);
+    if (destination->IsRegister()) {
+      __ LoadP(g.ToRegister(destination), src, r0);
+    } else {
+      Register temp = kScratchReg;
+      __ LoadP(temp, src, r0);
+      __ StoreP(temp, g.ToMemOperand(destination), r0);
+    }
+  } else if (source->IsConstant()) {
+    Constant src = g.ToConstant(source);
+    if (destination->IsRegister() || destination->IsStackSlot()) {
+      Register dst =
+          destination->IsRegister() ? g.ToRegister(destination) : kScratchReg;
+      switch (src.type()) {
+        case Constant::kInt32:
+          __ mov(dst, Operand(src.ToInt32()));
+          break;
+        case Constant::kInt64:
+          __ mov(dst, Operand(src.ToInt64()));
+          break;
+        case Constant::kFloat32:
+          __ Move(dst,
+                  isolate()->factory()->NewNumber(src.ToFloat32(), TENURED));
+          break;
+        case Constant::kFloat64:
+          __ Move(dst,
+                  isolate()->factory()->NewNumber(src.ToFloat64(), TENURED));
+          break;
+        case Constant::kExternalReference:
+          __ mov(dst, Operand(src.ToExternalReference()));
+          break;
+        case Constant::kHeapObject: {
+          Handle<HeapObject> src_object = src.ToHeapObject();
+          Heap::RootListIndex index;
+          int offset;
+          if (IsMaterializableFromFrame(src_object, &offset)) {
+            __ LoadP(dst, MemOperand(fp, offset));
+          } else if (IsMaterializableFromRoot(src_object, &index)) {
+            __ LoadRoot(dst, index);
+          } else {
+            __ Move(dst, src_object);
+          }
+          break;
+        }
+        case Constant::kRpoNumber:
+          UNREACHABLE();  // TODO(dcarney): loading RPO constants on PPC.
+          break;
+      }
+      if (destination->IsStackSlot()) {
+        __ StoreP(dst, g.ToMemOperand(destination), r0);
+      }
+    } else {
+      DoubleRegister dst = destination->IsDoubleRegister()
+                               ? g.ToDoubleRegister(destination)
+                               : kScratchDoubleReg;
+      double value = (src.type() == Constant::kFloat32) ? src.ToFloat32()
+                                                        : src.ToFloat64();
+      __ LoadDoubleLiteral(dst, value, kScratchReg);
+      if (destination->IsDoubleStackSlot()) {
+        __ StoreDouble(dst, g.ToMemOperand(destination), r0);
+      }
+    }
+  } else if (source->IsDoubleRegister()) {
+    DoubleRegister src = g.ToDoubleRegister(source);
+    if (destination->IsDoubleRegister()) {
+      DoubleRegister dst = g.ToDoubleRegister(destination);
+      __ Move(dst, src);
+    } else {
+      DCHECK(destination->IsDoubleStackSlot());
+      __ StoreDouble(src, g.ToMemOperand(destination), r0);
+    }
+  } else if (source->IsDoubleStackSlot()) {
+    DCHECK(destination->IsDoubleRegister() || destination->IsDoubleStackSlot());
+    MemOperand src = g.ToMemOperand(source);
+    if (destination->IsDoubleRegister()) {
+      __ LoadDouble(g.ToDoubleRegister(destination), src, r0);
+    } else {
+      DoubleRegister temp = kScratchDoubleReg;
+      __ LoadDouble(temp, src, r0);
+      __ StoreDouble(temp, g.ToMemOperand(destination), r0);
+    }
+  } else {
+    UNREACHABLE();
+  }
+}
+
+
+void CodeGenerator::AssembleSwap(InstructionOperand* source,
+                                 InstructionOperand* destination) {
+  PPCOperandConverter g(this, nullptr);
+  // Dispatch on the source and destination operand kinds.  Not all
+  // combinations are possible.
+  if (source->IsRegister()) {
+    // Register-register.
+    Register temp = kScratchReg;
+    Register src = g.ToRegister(source);
+    if (destination->IsRegister()) {
+      Register dst = g.ToRegister(destination);
+      __ mr(temp, src);
+      __ mr(src, dst);
+      __ mr(dst, temp);
+    } else {
+      DCHECK(destination->IsStackSlot());
+      MemOperand dst = g.ToMemOperand(destination);
+      __ mr(temp, src);
+      __ LoadP(src, dst);
+      __ StoreP(temp, dst);
+    }
+#if V8_TARGET_ARCH_PPC64
+  } else if (source->IsStackSlot() || source->IsDoubleStackSlot()) {
+#else
+  } else if (source->IsStackSlot()) {
+    DCHECK(destination->IsStackSlot());
+#endif
+    Register temp_0 = kScratchReg;
+    Register temp_1 = r0;
+    MemOperand src = g.ToMemOperand(source);
+    MemOperand dst = g.ToMemOperand(destination);
+    __ LoadP(temp_0, src);
+    __ LoadP(temp_1, dst);
+    __ StoreP(temp_0, dst);
+    __ StoreP(temp_1, src);
+  } else if (source->IsDoubleRegister()) {
+    DoubleRegister temp = kScratchDoubleReg;
+    DoubleRegister src = g.ToDoubleRegister(source);
+    if (destination->IsDoubleRegister()) {
+      DoubleRegister dst = g.ToDoubleRegister(destination);
+      __ fmr(temp, src);
+      __ fmr(src, dst);
+      __ fmr(dst, temp);
+    } else {
+      DCHECK(destination->IsDoubleStackSlot());
+      MemOperand dst = g.ToMemOperand(destination);
+      __ fmr(temp, src);
+      __ lfd(src, dst);
+      __ stfd(temp, dst);
+    }
+#if !V8_TARGET_ARCH_PPC64
+  } else if (source->IsDoubleStackSlot()) {
+    DCHECK(destination->IsDoubleStackSlot());
+    DoubleRegister temp_0 = kScratchDoubleReg;
+    DoubleRegister temp_1 = d0;
+    MemOperand src = g.ToMemOperand(source);
+    MemOperand dst = g.ToMemOperand(destination);
+    __ lfd(temp_0, src);
+    __ lfd(temp_1, dst);
+    __ stfd(temp_0, dst);
+    __ stfd(temp_1, src);
+#endif
+  } else {
+    // No other combinations are possible.
+    UNREACHABLE();
+  }
+}
+
+
+void CodeGenerator::AssembleJumpTable(Label** targets, size_t target_count) {
+  for (size_t index = 0; index < target_count; ++index) {
+    __ emit_label_addr(targets[index]);
+  }
+}
+
+
+void CodeGenerator::AddNopForSmiCodeInlining() {
+  // We do not insert nops for inlined Smi code.
+}
+
+
+void CodeGenerator::EnsureSpaceForLazyDeopt() {
+  if (!info()->ShouldEnsureSpaceForLazyDeopt()) {
+    return;
+  }
+
+  int space_needed = Deoptimizer::patch_size();
+  // Ensure that we have enough space after the previous lazy-bailout
+  // instruction for patching the code here.
+  int current_pc = masm()->pc_offset();
+  if (current_pc < last_lazy_deopt_pc_ + space_needed) {
+    // Block tramoline pool emission for duration of padding.
+    v8::internal::Assembler::BlockTrampolinePoolScope block_trampoline_pool(
+        masm());
+    int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc;
+    DCHECK_EQ(0, padding_size % v8::internal::Assembler::kInstrSize);
+    while (padding_size > 0) {
+      __ nop();
+      padding_size -= v8::internal::Assembler::kInstrSize;
+    }
+  }
+}
+
+#undef __
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/ppc/instruction-codes-ppc.h b/src/compiler/ppc/instruction-codes-ppc.h
new file mode 100644
index 0000000..a3bf80e
--- /dev/null
+++ b/src/compiler/ppc/instruction-codes-ppc.h
@@ -0,0 +1,139 @@
+// 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.
+
+#ifndef V8_COMPILER_PPC_INSTRUCTION_CODES_PPC_H_
+#define V8_COMPILER_PPC_INSTRUCTION_CODES_PPC_H_
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+// PPC-specific opcodes that specify which assembly sequence to emit.
+// Most opcodes specify a single instruction.
+#define TARGET_ARCH_OPCODE_LIST(V) \
+  V(PPC_And)                       \
+  V(PPC_AndComplement)             \
+  V(PPC_Or)                        \
+  V(PPC_OrComplement)              \
+  V(PPC_Xor)                       \
+  V(PPC_ShiftLeft32)               \
+  V(PPC_ShiftLeft64)               \
+  V(PPC_ShiftRight32)              \
+  V(PPC_ShiftRight64)              \
+  V(PPC_ShiftRightAlg32)           \
+  V(PPC_ShiftRightAlg64)           \
+  V(PPC_RotRight32)                \
+  V(PPC_RotRight64)                \
+  V(PPC_Not)                       \
+  V(PPC_RotLeftAndMask32)          \
+  V(PPC_RotLeftAndClear64)         \
+  V(PPC_RotLeftAndClearLeft64)     \
+  V(PPC_RotLeftAndClearRight64)    \
+  V(PPC_Add)                       \
+  V(PPC_AddWithOverflow32)         \
+  V(PPC_AddDouble)                 \
+  V(PPC_Sub)                       \
+  V(PPC_SubWithOverflow32)         \
+  V(PPC_SubDouble)                 \
+  V(PPC_Mul32)                     \
+  V(PPC_Mul64)                     \
+  V(PPC_MulHigh32)                 \
+  V(PPC_MulHighU32)                \
+  V(PPC_MulDouble)                 \
+  V(PPC_Div32)                     \
+  V(PPC_Div64)                     \
+  V(PPC_DivU32)                    \
+  V(PPC_DivU64)                    \
+  V(PPC_DivDouble)                 \
+  V(PPC_Mod32)                     \
+  V(PPC_Mod64)                     \
+  V(PPC_ModU32)                    \
+  V(PPC_ModU64)                    \
+  V(PPC_ModDouble)                 \
+  V(PPC_Neg)                       \
+  V(PPC_NegDouble)                 \
+  V(PPC_SqrtDouble)                \
+  V(PPC_FloorDouble)               \
+  V(PPC_CeilDouble)                \
+  V(PPC_TruncateDouble)            \
+  V(PPC_RoundDouble)               \
+  V(PPC_MaxDouble)                 \
+  V(PPC_MinDouble)                 \
+  V(PPC_AbsDouble)                 \
+  V(PPC_Cntlz32)                   \
+  V(PPC_Cntlz64)                   \
+  V(PPC_Popcnt32)                  \
+  V(PPC_Popcnt64)                  \
+  V(PPC_Cmp32)                     \
+  V(PPC_Cmp64)                     \
+  V(PPC_CmpDouble)                 \
+  V(PPC_Tst32)                     \
+  V(PPC_Tst64)                     \
+  V(PPC_Push)                      \
+  V(PPC_PushFrame)                 \
+  V(PPC_StoreToStackSlot)          \
+  V(PPC_ExtendSignWord8)           \
+  V(PPC_ExtendSignWord16)          \
+  V(PPC_ExtendSignWord32)          \
+  V(PPC_Uint32ToUint64)            \
+  V(PPC_Int64ToInt32)              \
+  V(PPC_Int64ToFloat32)            \
+  V(PPC_Int64ToDouble)             \
+  V(PPC_Uint64ToFloat32)           \
+  V(PPC_Uint64ToDouble)            \
+  V(PPC_Int32ToDouble)             \
+  V(PPC_Uint32ToDouble)            \
+  V(PPC_Float32ToDouble)           \
+  V(PPC_DoubleToInt32)             \
+  V(PPC_DoubleToUint32)            \
+  V(PPC_DoubleToInt64)             \
+  V(PPC_DoubleToUint64)            \
+  V(PPC_DoubleToFloat32)           \
+  V(PPC_DoubleExtractLowWord32)    \
+  V(PPC_DoubleExtractHighWord32)   \
+  V(PPC_DoubleInsertLowWord32)     \
+  V(PPC_DoubleInsertHighWord32)    \
+  V(PPC_DoubleConstruct)           \
+  V(PPC_BitcastInt32ToFloat32)     \
+  V(PPC_BitcastFloat32ToInt32)     \
+  V(PPC_BitcastInt64ToDouble)      \
+  V(PPC_BitcastDoubleToInt64)      \
+  V(PPC_LoadWordS8)                \
+  V(PPC_LoadWordU8)                \
+  V(PPC_LoadWordS16)               \
+  V(PPC_LoadWordU16)               \
+  V(PPC_LoadWordS32)               \
+  V(PPC_LoadWord64)                \
+  V(PPC_LoadFloat32)               \
+  V(PPC_LoadDouble)                \
+  V(PPC_StoreWord8)                \
+  V(PPC_StoreWord16)               \
+  V(PPC_StoreWord32)               \
+  V(PPC_StoreWord64)               \
+  V(PPC_StoreFloat32)              \
+  V(PPC_StoreDouble)
+
+
+// Addressing modes represent the "shape" of inputs to an instruction.
+// Many instructions support multiple addressing modes. Addressing modes
+// are encoded into the InstructionCode of the instruction and tell the
+// code generator after register allocation which assembler method to call.
+//
+// We use the following local notation for addressing modes:
+//
+// R = register
+// O = register or stack slot
+// D = double register
+// I = immediate (handle, external, int32)
+// MRI = [register + immediate]
+// MRR = [register + register]
+#define TARGET_ADDRESSING_MODE_LIST(V) \
+  V(MRI) /* [%r0 + K] */               \
+  V(MRR) /* [%r0 + %r1] */
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_PPC_INSTRUCTION_CODES_PPC_H_
diff --git a/src/compiler/ppc/instruction-scheduler-ppc.cc b/src/compiler/ppc/instruction-scheduler-ppc.cc
new file mode 100644
index 0000000..fc90cdd
--- /dev/null
+++ b/src/compiler/ppc/instruction-scheduler-ppc.cc
@@ -0,0 +1,143 @@
+// Copyright 2015 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/instruction-scheduler.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+bool InstructionScheduler::SchedulerSupported() { return true; }
+
+
+int InstructionScheduler::GetTargetInstructionFlags(
+    const Instruction* instr) const {
+  switch (instr->arch_opcode()) {
+    case kPPC_And:
+    case kPPC_AndComplement:
+    case kPPC_Or:
+    case kPPC_OrComplement:
+    case kPPC_Xor:
+    case kPPC_ShiftLeft32:
+    case kPPC_ShiftLeft64:
+    case kPPC_ShiftRight32:
+    case kPPC_ShiftRight64:
+    case kPPC_ShiftRightAlg32:
+    case kPPC_ShiftRightAlg64:
+    case kPPC_RotRight32:
+    case kPPC_RotRight64:
+    case kPPC_Not:
+    case kPPC_RotLeftAndMask32:
+    case kPPC_RotLeftAndClear64:
+    case kPPC_RotLeftAndClearLeft64:
+    case kPPC_RotLeftAndClearRight64:
+    case kPPC_Add:
+    case kPPC_AddWithOverflow32:
+    case kPPC_AddDouble:
+    case kPPC_Sub:
+    case kPPC_SubWithOverflow32:
+    case kPPC_SubDouble:
+    case kPPC_Mul32:
+    case kPPC_Mul64:
+    case kPPC_MulHigh32:
+    case kPPC_MulHighU32:
+    case kPPC_MulDouble:
+    case kPPC_Div32:
+    case kPPC_Div64:
+    case kPPC_DivU32:
+    case kPPC_DivU64:
+    case kPPC_DivDouble:
+    case kPPC_Mod32:
+    case kPPC_Mod64:
+    case kPPC_ModU32:
+    case kPPC_ModU64:
+    case kPPC_ModDouble:
+    case kPPC_Neg:
+    case kPPC_NegDouble:
+    case kPPC_SqrtDouble:
+    case kPPC_FloorDouble:
+    case kPPC_CeilDouble:
+    case kPPC_TruncateDouble:
+    case kPPC_RoundDouble:
+    case kPPC_MaxDouble:
+    case kPPC_MinDouble:
+    case kPPC_AbsDouble:
+    case kPPC_Cntlz32:
+    case kPPC_Cntlz64:
+    case kPPC_Popcnt32:
+    case kPPC_Popcnt64:
+    case kPPC_Cmp32:
+    case kPPC_Cmp64:
+    case kPPC_CmpDouble:
+    case kPPC_Tst32:
+    case kPPC_Tst64:
+    case kPPC_ExtendSignWord8:
+    case kPPC_ExtendSignWord16:
+    case kPPC_ExtendSignWord32:
+    case kPPC_Uint32ToUint64:
+    case kPPC_Int64ToInt32:
+    case kPPC_Int64ToFloat32:
+    case kPPC_Int64ToDouble:
+    case kPPC_Uint64ToFloat32:
+    case kPPC_Uint64ToDouble:
+    case kPPC_Int32ToDouble:
+    case kPPC_Uint32ToDouble:
+    case kPPC_Float32ToDouble:
+    case kPPC_DoubleToInt32:
+    case kPPC_DoubleToUint32:
+    case kPPC_DoubleToInt64:
+    case kPPC_DoubleToUint64:
+    case kPPC_DoubleToFloat32:
+    case kPPC_DoubleExtractLowWord32:
+    case kPPC_DoubleExtractHighWord32:
+    case kPPC_DoubleInsertLowWord32:
+    case kPPC_DoubleInsertHighWord32:
+    case kPPC_DoubleConstruct:
+    case kPPC_BitcastInt32ToFloat32:
+    case kPPC_BitcastFloat32ToInt32:
+    case kPPC_BitcastInt64ToDouble:
+    case kPPC_BitcastDoubleToInt64:
+      return kNoOpcodeFlags;
+
+    case kPPC_LoadWordS8:
+    case kPPC_LoadWordU8:
+    case kPPC_LoadWordS16:
+    case kPPC_LoadWordU16:
+    case kPPC_LoadWordS32:
+    case kPPC_LoadWord64:
+    case kPPC_LoadFloat32:
+    case kPPC_LoadDouble:
+      return kIsLoadOperation;
+
+    case kPPC_StoreWord8:
+    case kPPC_StoreWord16:
+    case kPPC_StoreWord32:
+    case kPPC_StoreWord64:
+    case kPPC_StoreFloat32:
+    case kPPC_StoreDouble:
+    case kPPC_Push:
+    case kPPC_PushFrame:
+    case kPPC_StoreToStackSlot:
+      return kHasSideEffect;
+
+#define CASE(Name) case k##Name:
+    COMMON_ARCH_OPCODE_LIST(CASE)
+#undef CASE
+      // Already covered in architecture independent code.
+      UNREACHABLE();
+  }
+
+  UNREACHABLE();
+  return kNoOpcodeFlags;
+}
+
+
+int InstructionScheduler::GetInstructionLatency(const Instruction* instr) {
+  // TODO(all): Add instruction cost modeling.
+  return 1;
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/ppc/instruction-selector-ppc.cc b/src/compiler/ppc/instruction-selector-ppc.cc
new file mode 100644
index 0000000..f6ebbdf
--- /dev/null
+++ b/src/compiler/ppc/instruction-selector-ppc.cc
@@ -0,0 +1,1772 @@
+// 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/base/adapters.h"
+#include "src/compiler/instruction-selector-impl.h"
+#include "src/compiler/node-matchers.h"
+#include "src/compiler/node-properties.h"
+#include "src/ppc/frames-ppc.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+enum ImmediateMode {
+  kInt16Imm,
+  kInt16Imm_Unsigned,
+  kInt16Imm_Negate,
+  kInt16Imm_4ByteAligned,
+  kShift32Imm,
+  kShift64Imm,
+  kNoImmediate
+};
+
+
+// Adds PPC-specific methods for generating operands.
+class PPCOperandGenerator final : public OperandGenerator {
+ public:
+  explicit PPCOperandGenerator(InstructionSelector* selector)
+      : OperandGenerator(selector) {}
+
+  InstructionOperand UseOperand(Node* node, ImmediateMode mode) {
+    if (CanBeImmediate(node, mode)) {
+      return UseImmediate(node);
+    }
+    return UseRegister(node);
+  }
+
+  bool CanBeImmediate(Node* node, ImmediateMode mode) {
+    int64_t value;
+    if (node->opcode() == IrOpcode::kInt32Constant)
+      value = OpParameter<int32_t>(node);
+    else if (node->opcode() == IrOpcode::kInt64Constant)
+      value = OpParameter<int64_t>(node);
+    else
+      return false;
+    return CanBeImmediate(value, mode);
+  }
+
+  bool CanBeImmediate(int64_t value, ImmediateMode mode) {
+    switch (mode) {
+      case kInt16Imm:
+        return is_int16(value);
+      case kInt16Imm_Unsigned:
+        return is_uint16(value);
+      case kInt16Imm_Negate:
+        return is_int16(-value);
+      case kInt16Imm_4ByteAligned:
+        return is_int16(value) && !(value & 3);
+      case kShift32Imm:
+        return 0 <= value && value < 32;
+      case kShift64Imm:
+        return 0 <= value && value < 64;
+      case kNoImmediate:
+        return false;
+    }
+    return false;
+  }
+};
+
+
+namespace {
+
+void VisitRR(InstructionSelector* selector, ArchOpcode opcode, Node* node) {
+  PPCOperandGenerator g(selector);
+  selector->Emit(opcode, g.DefineAsRegister(node),
+                 g.UseRegister(node->InputAt(0)));
+}
+
+
+void VisitRRR(InstructionSelector* selector, ArchOpcode opcode, Node* node) {
+  PPCOperandGenerator g(selector);
+  selector->Emit(opcode, g.DefineAsRegister(node),
+                 g.UseRegister(node->InputAt(0)),
+                 g.UseRegister(node->InputAt(1)));
+}
+
+
+void VisitRRO(InstructionSelector* selector, ArchOpcode opcode, Node* node,
+              ImmediateMode operand_mode) {
+  PPCOperandGenerator g(selector);
+  selector->Emit(opcode, g.DefineAsRegister(node),
+                 g.UseRegister(node->InputAt(0)),
+                 g.UseOperand(node->InputAt(1), operand_mode));
+}
+
+
+#if V8_TARGET_ARCH_PPC64
+void VisitTryTruncateDouble(InstructionSelector* selector, ArchOpcode opcode,
+                            Node* node) {
+  PPCOperandGenerator g(selector);
+  InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0))};
+  InstructionOperand outputs[2];
+  size_t output_count = 0;
+  outputs[output_count++] = g.DefineAsRegister(node);
+
+  Node* success_output = NodeProperties::FindProjection(node, 1);
+  if (success_output) {
+    outputs[output_count++] = g.DefineAsRegister(success_output);
+  }
+
+  selector->Emit(opcode, output_count, outputs, 1, inputs);
+}
+#endif
+
+
+// Shared routine for multiple binary operations.
+template <typename Matcher>
+void VisitBinop(InstructionSelector* selector, Node* node,
+                InstructionCode opcode, ImmediateMode operand_mode,
+                FlagsContinuation* cont) {
+  PPCOperandGenerator g(selector);
+  Matcher m(node);
+  InstructionOperand inputs[4];
+  size_t input_count = 0;
+  InstructionOperand outputs[2];
+  size_t output_count = 0;
+
+  inputs[input_count++] = g.UseRegister(m.left().node());
+  inputs[input_count++] = g.UseOperand(m.right().node(), operand_mode);
+
+  if (cont->IsBranch()) {
+    inputs[input_count++] = g.Label(cont->true_block());
+    inputs[input_count++] = g.Label(cont->false_block());
+  }
+
+  outputs[output_count++] = g.DefineAsRegister(node);
+  if (cont->IsSet()) {
+    outputs[output_count++] = g.DefineAsRegister(cont->result());
+  }
+
+  DCHECK_NE(0u, input_count);
+  DCHECK_NE(0u, output_count);
+  DCHECK_GE(arraysize(inputs), input_count);
+  DCHECK_GE(arraysize(outputs), output_count);
+
+  selector->Emit(cont->Encode(opcode), output_count, outputs, input_count,
+                 inputs);
+}
+
+
+// Shared routine for multiple binary operations.
+template <typename Matcher>
+void VisitBinop(InstructionSelector* selector, Node* node, ArchOpcode opcode,
+                ImmediateMode operand_mode) {
+  FlagsContinuation cont;
+  VisitBinop<Matcher>(selector, node, opcode, operand_mode, &cont);
+}
+
+}  // namespace
+
+
+void InstructionSelector::VisitLoad(Node* node) {
+  LoadRepresentation load_rep = LoadRepresentationOf(node->op());
+  PPCOperandGenerator g(this);
+  Node* base = node->InputAt(0);
+  Node* offset = node->InputAt(1);
+  ArchOpcode opcode = kArchNop;
+  ImmediateMode mode = kInt16Imm;
+  switch (load_rep.representation()) {
+    case MachineRepresentation::kFloat32:
+      opcode = kPPC_LoadFloat32;
+      break;
+    case MachineRepresentation::kFloat64:
+      opcode = kPPC_LoadDouble;
+      break;
+    case MachineRepresentation::kBit:  // Fall through.
+    case MachineRepresentation::kWord8:
+      opcode = load_rep.IsSigned() ? kPPC_LoadWordS8 : kPPC_LoadWordU8;
+      break;
+    case MachineRepresentation::kWord16:
+      opcode = load_rep.IsSigned() ? kPPC_LoadWordS16 : kPPC_LoadWordU16;
+      break;
+#if !V8_TARGET_ARCH_PPC64
+    case MachineRepresentation::kTagged:  // Fall through.
+#endif
+    case MachineRepresentation::kWord32:
+      opcode = kPPC_LoadWordS32;
+#if V8_TARGET_ARCH_PPC64
+      // TODO(mbrandy): this applies to signed loads only (lwa)
+      mode = kInt16Imm_4ByteAligned;
+#endif
+      break;
+#if V8_TARGET_ARCH_PPC64
+    case MachineRepresentation::kTagged:  // Fall through.
+    case MachineRepresentation::kWord64:
+      opcode = kPPC_LoadWord64;
+      mode = kInt16Imm_4ByteAligned;
+      break;
+#else
+    case MachineRepresentation::kWord64:  // Fall through.
+#endif
+    case MachineRepresentation::kNone:
+      UNREACHABLE();
+      return;
+  }
+  if (g.CanBeImmediate(offset, mode)) {
+    Emit(opcode | AddressingModeField::encode(kMode_MRI),
+         g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(offset));
+  } else if (g.CanBeImmediate(base, mode)) {
+    Emit(opcode | AddressingModeField::encode(kMode_MRI),
+         g.DefineAsRegister(node), g.UseRegister(offset), g.UseImmediate(base));
+  } else {
+    Emit(opcode | AddressingModeField::encode(kMode_MRR),
+         g.DefineAsRegister(node), g.UseRegister(base), g.UseRegister(offset));
+  }
+}
+
+
+void InstructionSelector::VisitStore(Node* node) {
+  PPCOperandGenerator g(this);
+  Node* base = node->InputAt(0);
+  Node* offset = node->InputAt(1);
+  Node* value = node->InputAt(2);
+
+  StoreRepresentation store_rep = StoreRepresentationOf(node->op());
+  WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind();
+  MachineRepresentation rep = store_rep.representation();
+
+  // TODO(ppc): I guess this could be done in a better way.
+  if (write_barrier_kind != kNoWriteBarrier) {
+    DCHECK_EQ(MachineRepresentation::kTagged, rep);
+    InstructionOperand inputs[3];
+    size_t input_count = 0;
+    inputs[input_count++] = g.UseUniqueRegister(base);
+    inputs[input_count++] = g.UseUniqueRegister(offset);
+    inputs[input_count++] = (write_barrier_kind == kMapWriteBarrier)
+                                ? g.UseRegister(value)
+                                : g.UseUniqueRegister(value);
+    RecordWriteMode record_write_mode = RecordWriteMode::kValueIsAny;
+    switch (write_barrier_kind) {
+      case kNoWriteBarrier:
+        UNREACHABLE();
+        break;
+      case kMapWriteBarrier:
+        record_write_mode = RecordWriteMode::kValueIsMap;
+        break;
+      case kPointerWriteBarrier:
+        record_write_mode = RecordWriteMode::kValueIsPointer;
+        break;
+      case kFullWriteBarrier:
+        record_write_mode = RecordWriteMode::kValueIsAny;
+        break;
+    }
+    InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()};
+    size_t const temp_count = arraysize(temps);
+    InstructionCode code = kArchStoreWithWriteBarrier;
+    code |= MiscField::encode(static_cast<int>(record_write_mode));
+    Emit(code, 0, nullptr, input_count, inputs, temp_count, temps);
+  } else {
+    ArchOpcode opcode = kArchNop;
+    ImmediateMode mode = kInt16Imm;
+    switch (rep) {
+      case MachineRepresentation::kFloat32:
+        opcode = kPPC_StoreFloat32;
+        break;
+      case MachineRepresentation::kFloat64:
+        opcode = kPPC_StoreDouble;
+        break;
+      case MachineRepresentation::kBit:  // Fall through.
+      case MachineRepresentation::kWord8:
+        opcode = kPPC_StoreWord8;
+        break;
+      case MachineRepresentation::kWord16:
+        opcode = kPPC_StoreWord16;
+        break;
+#if !V8_TARGET_ARCH_PPC64
+      case MachineRepresentation::kTagged:  // Fall through.
+#endif
+      case MachineRepresentation::kWord32:
+        opcode = kPPC_StoreWord32;
+        break;
+#if V8_TARGET_ARCH_PPC64
+      case MachineRepresentation::kTagged:  // Fall through.
+      case MachineRepresentation::kWord64:
+        opcode = kPPC_StoreWord64;
+        mode = kInt16Imm_4ByteAligned;
+        break;
+#else
+      case MachineRepresentation::kWord64:  // Fall through.
+#endif
+      case MachineRepresentation::kNone:
+        UNREACHABLE();
+        return;
+    }
+    if (g.CanBeImmediate(offset, mode)) {
+      Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
+           g.UseRegister(base), g.UseImmediate(offset), g.UseRegister(value));
+    } else if (g.CanBeImmediate(base, mode)) {
+      Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
+           g.UseRegister(offset), g.UseImmediate(base), g.UseRegister(value));
+    } else {
+      Emit(opcode | AddressingModeField::encode(kMode_MRR), g.NoOutput(),
+           g.UseRegister(base), g.UseRegister(offset), g.UseRegister(value));
+    }
+  }
+}
+
+
+void InstructionSelector::VisitCheckedLoad(Node* node) {
+  CheckedLoadRepresentation load_rep = CheckedLoadRepresentationOf(node->op());
+  PPCOperandGenerator g(this);
+  Node* const base = node->InputAt(0);
+  Node* const offset = node->InputAt(1);
+  Node* const length = node->InputAt(2);
+  ArchOpcode opcode = kArchNop;
+  switch (load_rep.representation()) {
+    case MachineRepresentation::kWord8:
+      opcode = load_rep.IsSigned() ? kCheckedLoadInt8 : kCheckedLoadUint8;
+      break;
+    case MachineRepresentation::kWord16:
+      opcode = load_rep.IsSigned() ? kCheckedLoadInt16 : kCheckedLoadUint16;
+      break;
+    case MachineRepresentation::kWord32:
+      opcode = kCheckedLoadWord32;
+      break;
+#if V8_TARGET_ARCH_PPC64
+    case MachineRepresentation::kWord64:
+      opcode = kCheckedLoadWord64;
+      break;
+#endif
+    case MachineRepresentation::kFloat32:
+      opcode = kCheckedLoadFloat32;
+      break;
+    case MachineRepresentation::kFloat64:
+      opcode = kCheckedLoadFloat64;
+      break;
+    case MachineRepresentation::kBit:     // Fall through.
+    case MachineRepresentation::kTagged:  // Fall through.
+#if !V8_TARGET_ARCH_PPC64
+    case MachineRepresentation::kWord64:  // Fall through.
+#endif
+    case MachineRepresentation::kNone:
+      UNREACHABLE();
+      return;
+  }
+  AddressingMode addressingMode = kMode_MRR;
+  Emit(opcode | AddressingModeField::encode(addressingMode),
+       g.DefineAsRegister(node), g.UseRegister(base), g.UseRegister(offset),
+       g.UseOperand(length, kInt16Imm_Unsigned));
+}
+
+
+void InstructionSelector::VisitCheckedStore(Node* node) {
+  MachineRepresentation rep = CheckedStoreRepresentationOf(node->op());
+  PPCOperandGenerator g(this);
+  Node* const base = node->InputAt(0);
+  Node* const offset = node->InputAt(1);
+  Node* const length = node->InputAt(2);
+  Node* const value = node->InputAt(3);
+  ArchOpcode opcode = kArchNop;
+  switch (rep) {
+    case MachineRepresentation::kWord8:
+      opcode = kCheckedStoreWord8;
+      break;
+    case MachineRepresentation::kWord16:
+      opcode = kCheckedStoreWord16;
+      break;
+    case MachineRepresentation::kWord32:
+      opcode = kCheckedStoreWord32;
+      break;
+#if V8_TARGET_ARCH_PPC64
+    case MachineRepresentation::kWord64:
+      opcode = kCheckedStoreWord64;
+      break;
+#endif
+    case MachineRepresentation::kFloat32:
+      opcode = kCheckedStoreFloat32;
+      break;
+    case MachineRepresentation::kFloat64:
+      opcode = kCheckedStoreFloat64;
+      break;
+    case MachineRepresentation::kBit:     // Fall through.
+    case MachineRepresentation::kTagged:  // Fall through.
+#if !V8_TARGET_ARCH_PPC64
+    case MachineRepresentation::kWord64:  // Fall through.
+#endif
+    case MachineRepresentation::kNone:
+      UNREACHABLE();
+      return;
+  }
+  AddressingMode addressingMode = kMode_MRR;
+  Emit(opcode | AddressingModeField::encode(addressingMode), g.NoOutput(),
+       g.UseRegister(base), g.UseRegister(offset),
+       g.UseOperand(length, kInt16Imm_Unsigned), g.UseRegister(value));
+}
+
+
+template <typename Matcher>
+static void VisitLogical(InstructionSelector* selector, Node* node, Matcher* m,
+                         ArchOpcode opcode, bool left_can_cover,
+                         bool right_can_cover, ImmediateMode imm_mode) {
+  PPCOperandGenerator g(selector);
+
+  // Map instruction to equivalent operation with inverted right input.
+  ArchOpcode inv_opcode = opcode;
+  switch (opcode) {
+    case kPPC_And:
+      inv_opcode = kPPC_AndComplement;
+      break;
+    case kPPC_Or:
+      inv_opcode = kPPC_OrComplement;
+      break;
+    default:
+      UNREACHABLE();
+  }
+
+  // Select Logical(y, ~x) for Logical(Xor(x, -1), y).
+  if ((m->left().IsWord32Xor() || m->left().IsWord64Xor()) && left_can_cover) {
+    Matcher mleft(m->left().node());
+    if (mleft.right().Is(-1)) {
+      selector->Emit(inv_opcode, g.DefineAsRegister(node),
+                     g.UseRegister(m->right().node()),
+                     g.UseRegister(mleft.left().node()));
+      return;
+    }
+  }
+
+  // Select Logical(x, ~y) for Logical(x, Xor(y, -1)).
+  if ((m->right().IsWord32Xor() || m->right().IsWord64Xor()) &&
+      right_can_cover) {
+    Matcher mright(m->right().node());
+    if (mright.right().Is(-1)) {
+      // TODO(all): support shifted operand on right.
+      selector->Emit(inv_opcode, g.DefineAsRegister(node),
+                     g.UseRegister(m->left().node()),
+                     g.UseRegister(mright.left().node()));
+      return;
+    }
+  }
+
+  VisitBinop<Matcher>(selector, node, opcode, imm_mode);
+}
+
+
+static inline bool IsContiguousMask32(uint32_t value, int* mb, int* me) {
+  int mask_width = base::bits::CountPopulation32(value);
+  int mask_msb = base::bits::CountLeadingZeros32(value);
+  int mask_lsb = base::bits::CountTrailingZeros32(value);
+  if ((mask_width == 0) || (mask_msb + mask_width + mask_lsb != 32))
+    return false;
+  *mb = mask_lsb + mask_width - 1;
+  *me = mask_lsb;
+  return true;
+}
+
+
+#if V8_TARGET_ARCH_PPC64
+static inline bool IsContiguousMask64(uint64_t value, int* mb, int* me) {
+  int mask_width = base::bits::CountPopulation64(value);
+  int mask_msb = base::bits::CountLeadingZeros64(value);
+  int mask_lsb = base::bits::CountTrailingZeros64(value);
+  if ((mask_width == 0) || (mask_msb + mask_width + mask_lsb != 64))
+    return false;
+  *mb = mask_lsb + mask_width - 1;
+  *me = mask_lsb;
+  return true;
+}
+#endif
+
+
+// TODO(mbrandy): Absorb rotate-right into rlwinm?
+void InstructionSelector::VisitWord32And(Node* node) {
+  PPCOperandGenerator g(this);
+  Int32BinopMatcher m(node);
+  int mb = 0;
+  int me = 0;
+  if (m.right().HasValue() && IsContiguousMask32(m.right().Value(), &mb, &me)) {
+    int sh = 0;
+    Node* left = m.left().node();
+    if ((m.left().IsWord32Shr() || m.left().IsWord32Shl()) &&
+        CanCover(node, left)) {
+      // Try to absorb left/right shift into rlwinm
+      Int32BinopMatcher mleft(m.left().node());
+      if (mleft.right().IsInRange(0, 31)) {
+        left = mleft.left().node();
+        sh = mleft.right().Value();
+        if (m.left().IsWord32Shr()) {
+          // Adjust the mask such that it doesn't include any rotated bits.
+          if (mb > 31 - sh) mb = 31 - sh;
+          sh = (32 - sh) & 0x1f;
+        } else {
+          // Adjust the mask such that it doesn't include any rotated bits.
+          if (me < sh) me = sh;
+        }
+      }
+    }
+    if (mb >= me) {
+      Emit(kPPC_RotLeftAndMask32, g.DefineAsRegister(node), g.UseRegister(left),
+           g.TempImmediate(sh), g.TempImmediate(mb), g.TempImmediate(me));
+      return;
+    }
+  }
+  VisitLogical<Int32BinopMatcher>(
+      this, node, &m, kPPC_And, CanCover(node, m.left().node()),
+      CanCover(node, m.right().node()), kInt16Imm_Unsigned);
+}
+
+
+#if V8_TARGET_ARCH_PPC64
+// TODO(mbrandy): Absorb rotate-right into rldic?
+void InstructionSelector::VisitWord64And(Node* node) {
+  PPCOperandGenerator g(this);
+  Int64BinopMatcher m(node);
+  int mb = 0;
+  int me = 0;
+  if (m.right().HasValue() && IsContiguousMask64(m.right().Value(), &mb, &me)) {
+    int sh = 0;
+    Node* left = m.left().node();
+    if ((m.left().IsWord64Shr() || m.left().IsWord64Shl()) &&
+        CanCover(node, left)) {
+      // Try to absorb left/right shift into rldic
+      Int64BinopMatcher mleft(m.left().node());
+      if (mleft.right().IsInRange(0, 63)) {
+        left = mleft.left().node();
+        sh = mleft.right().Value();
+        if (m.left().IsWord64Shr()) {
+          // Adjust the mask such that it doesn't include any rotated bits.
+          if (mb > 63 - sh) mb = 63 - sh;
+          sh = (64 - sh) & 0x3f;
+        } else {
+          // Adjust the mask such that it doesn't include any rotated bits.
+          if (me < sh) me = sh;
+        }
+      }
+    }
+    if (mb >= me) {
+      bool match = false;
+      ArchOpcode opcode;
+      int mask;
+      if (me == 0) {
+        match = true;
+        opcode = kPPC_RotLeftAndClearLeft64;
+        mask = mb;
+      } else if (mb == 63) {
+        match = true;
+        opcode = kPPC_RotLeftAndClearRight64;
+        mask = me;
+      } else if (sh && me <= sh && m.left().IsWord64Shl()) {
+        match = true;
+        opcode = kPPC_RotLeftAndClear64;
+        mask = mb;
+      }
+      if (match) {
+        Emit(opcode, g.DefineAsRegister(node), g.UseRegister(left),
+             g.TempImmediate(sh), g.TempImmediate(mask));
+        return;
+      }
+    }
+  }
+  VisitLogical<Int64BinopMatcher>(
+      this, node, &m, kPPC_And, CanCover(node, m.left().node()),
+      CanCover(node, m.right().node()), kInt16Imm_Unsigned);
+}
+#endif
+
+
+void InstructionSelector::VisitWord32Or(Node* node) {
+  Int32BinopMatcher m(node);
+  VisitLogical<Int32BinopMatcher>(
+      this, node, &m, kPPC_Or, CanCover(node, m.left().node()),
+      CanCover(node, m.right().node()), kInt16Imm_Unsigned);
+}
+
+
+#if V8_TARGET_ARCH_PPC64
+void InstructionSelector::VisitWord64Or(Node* node) {
+  Int64BinopMatcher m(node);
+  VisitLogical<Int64BinopMatcher>(
+      this, node, &m, kPPC_Or, CanCover(node, m.left().node()),
+      CanCover(node, m.right().node()), kInt16Imm_Unsigned);
+}
+#endif
+
+
+void InstructionSelector::VisitWord32Xor(Node* node) {
+  PPCOperandGenerator g(this);
+  Int32BinopMatcher m(node);
+  if (m.right().Is(-1)) {
+    Emit(kPPC_Not, g.DefineAsRegister(node), g.UseRegister(m.left().node()));
+  } else {
+    VisitBinop<Int32BinopMatcher>(this, node, kPPC_Xor, kInt16Imm_Unsigned);
+  }
+}
+
+
+#if V8_TARGET_ARCH_PPC64
+void InstructionSelector::VisitWord64Xor(Node* node) {
+  PPCOperandGenerator g(this);
+  Int64BinopMatcher m(node);
+  if (m.right().Is(-1)) {
+    Emit(kPPC_Not, g.DefineAsRegister(node), g.UseRegister(m.left().node()));
+  } else {
+    VisitBinop<Int64BinopMatcher>(this, node, kPPC_Xor, kInt16Imm_Unsigned);
+  }
+}
+#endif
+
+
+void InstructionSelector::VisitWord32Shl(Node* node) {
+  PPCOperandGenerator g(this);
+  Int32BinopMatcher m(node);
+  if (m.left().IsWord32And() && m.right().IsInRange(0, 31)) {
+    // Try to absorb logical-and into rlwinm
+    Int32BinopMatcher mleft(m.left().node());
+    int sh = m.right().Value();
+    int mb;
+    int me;
+    if (mleft.right().HasValue() &&
+        IsContiguousMask32(mleft.right().Value() << sh, &mb, &me)) {
+      // Adjust the mask such that it doesn't include any rotated bits.
+      if (me < sh) me = sh;
+      if (mb >= me) {
+        Emit(kPPC_RotLeftAndMask32, g.DefineAsRegister(node),
+             g.UseRegister(mleft.left().node()), g.TempImmediate(sh),
+             g.TempImmediate(mb), g.TempImmediate(me));
+        return;
+      }
+    }
+  }
+  VisitRRO(this, kPPC_ShiftLeft32, node, kShift32Imm);
+}
+
+
+#if V8_TARGET_ARCH_PPC64
+void InstructionSelector::VisitWord64Shl(Node* node) {
+  PPCOperandGenerator g(this);
+  Int64BinopMatcher m(node);
+  // TODO(mbrandy): eliminate left sign extension if right >= 32
+  if (m.left().IsWord64And() && m.right().IsInRange(0, 63)) {
+    // Try to absorb logical-and into rldic
+    Int64BinopMatcher mleft(m.left().node());
+    int sh = m.right().Value();
+    int mb;
+    int me;
+    if (mleft.right().HasValue() &&
+        IsContiguousMask64(mleft.right().Value() << sh, &mb, &me)) {
+      // Adjust the mask such that it doesn't include any rotated bits.
+      if (me < sh) me = sh;
+      if (mb >= me) {
+        bool match = false;
+        ArchOpcode opcode;
+        int mask;
+        if (me == 0) {
+          match = true;
+          opcode = kPPC_RotLeftAndClearLeft64;
+          mask = mb;
+        } else if (mb == 63) {
+          match = true;
+          opcode = kPPC_RotLeftAndClearRight64;
+          mask = me;
+        } else if (sh && me <= sh) {
+          match = true;
+          opcode = kPPC_RotLeftAndClear64;
+          mask = mb;
+        }
+        if (match) {
+          Emit(opcode, g.DefineAsRegister(node),
+               g.UseRegister(mleft.left().node()), g.TempImmediate(sh),
+               g.TempImmediate(mask));
+          return;
+        }
+      }
+    }
+  }
+  VisitRRO(this, kPPC_ShiftLeft64, node, kShift64Imm);
+}
+#endif
+
+
+void InstructionSelector::VisitWord32Shr(Node* node) {
+  PPCOperandGenerator g(this);
+  Int32BinopMatcher m(node);
+  if (m.left().IsWord32And() && m.right().IsInRange(0, 31)) {
+    // Try to absorb logical-and into rlwinm
+    Int32BinopMatcher mleft(m.left().node());
+    int sh = m.right().Value();
+    int mb;
+    int me;
+    if (mleft.right().HasValue() &&
+        IsContiguousMask32((uint32_t)(mleft.right().Value()) >> sh, &mb, &me)) {
+      // Adjust the mask such that it doesn't include any rotated bits.
+      if (mb > 31 - sh) mb = 31 - sh;
+      sh = (32 - sh) & 0x1f;
+      if (mb >= me) {
+        Emit(kPPC_RotLeftAndMask32, g.DefineAsRegister(node),
+             g.UseRegister(mleft.left().node()), g.TempImmediate(sh),
+             g.TempImmediate(mb), g.TempImmediate(me));
+        return;
+      }
+    }
+  }
+  VisitRRO(this, kPPC_ShiftRight32, node, kShift32Imm);
+}
+
+
+#if V8_TARGET_ARCH_PPC64
+void InstructionSelector::VisitWord64Shr(Node* node) {
+  PPCOperandGenerator g(this);
+  Int64BinopMatcher m(node);
+  if (m.left().IsWord64And() && m.right().IsInRange(0, 63)) {
+    // Try to absorb logical-and into rldic
+    Int64BinopMatcher mleft(m.left().node());
+    int sh = m.right().Value();
+    int mb;
+    int me;
+    if (mleft.right().HasValue() &&
+        IsContiguousMask64((uint64_t)(mleft.right().Value()) >> sh, &mb, &me)) {
+      // Adjust the mask such that it doesn't include any rotated bits.
+      if (mb > 63 - sh) mb = 63 - sh;
+      sh = (64 - sh) & 0x3f;
+      if (mb >= me) {
+        bool match = false;
+        ArchOpcode opcode;
+        int mask;
+        if (me == 0) {
+          match = true;
+          opcode = kPPC_RotLeftAndClearLeft64;
+          mask = mb;
+        } else if (mb == 63) {
+          match = true;
+          opcode = kPPC_RotLeftAndClearRight64;
+          mask = me;
+        }
+        if (match) {
+          Emit(opcode, g.DefineAsRegister(node),
+               g.UseRegister(mleft.left().node()), g.TempImmediate(sh),
+               g.TempImmediate(mask));
+          return;
+        }
+      }
+    }
+  }
+  VisitRRO(this, kPPC_ShiftRight64, node, kShift64Imm);
+}
+#endif
+
+
+void InstructionSelector::VisitWord32Sar(Node* node) {
+  PPCOperandGenerator g(this);
+  Int32BinopMatcher m(node);
+  // Replace with sign extension for (x << K) >> K where K is 16 or 24.
+  if (CanCover(node, m.left().node()) && m.left().IsWord32Shl()) {
+    Int32BinopMatcher mleft(m.left().node());
+    if (mleft.right().Is(16) && m.right().Is(16)) {
+      Emit(kPPC_ExtendSignWord16, g.DefineAsRegister(node),
+           g.UseRegister(mleft.left().node()));
+      return;
+    } else if (mleft.right().Is(24) && m.right().Is(24)) {
+      Emit(kPPC_ExtendSignWord8, g.DefineAsRegister(node),
+           g.UseRegister(mleft.left().node()));
+      return;
+    }
+  }
+  VisitRRO(this, kPPC_ShiftRightAlg32, node, kShift32Imm);
+}
+
+
+#if V8_TARGET_ARCH_PPC64
+void InstructionSelector::VisitWord64Sar(Node* node) {
+  VisitRRO(this, kPPC_ShiftRightAlg64, node, kShift64Imm);
+}
+#endif
+
+
+// TODO(mbrandy): Absorb logical-and into rlwinm?
+void InstructionSelector::VisitWord32Ror(Node* node) {
+  VisitRRO(this, kPPC_RotRight32, node, kShift32Imm);
+}
+
+
+#if V8_TARGET_ARCH_PPC64
+// TODO(mbrandy): Absorb logical-and into rldic?
+void InstructionSelector::VisitWord64Ror(Node* node) {
+  VisitRRO(this, kPPC_RotRight64, node, kShift64Imm);
+}
+#endif
+
+
+void InstructionSelector::VisitWord32Clz(Node* node) {
+  PPCOperandGenerator g(this);
+  Emit(kPPC_Cntlz32, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)));
+}
+
+
+#if V8_TARGET_ARCH_PPC64
+void InstructionSelector::VisitWord64Clz(Node* node) {
+  PPCOperandGenerator g(this);
+  Emit(kPPC_Cntlz64, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)));
+}
+#endif
+
+
+void InstructionSelector::VisitWord32Popcnt(Node* node) {
+  PPCOperandGenerator g(this);
+  Emit(kPPC_Popcnt32, g.DefineAsRegister(node),
+       g.UseRegister(node->InputAt(0)));
+}
+
+
+#if V8_TARGET_ARCH_PPC64
+void InstructionSelector::VisitWord64Popcnt(Node* node) {
+  PPCOperandGenerator g(this);
+  Emit(kPPC_Popcnt64, g.DefineAsRegister(node),
+       g.UseRegister(node->InputAt(0)));
+}
+#endif
+
+
+void InstructionSelector::VisitWord32Ctz(Node* node) { UNREACHABLE(); }
+
+
+#if V8_TARGET_ARCH_PPC64
+void InstructionSelector::VisitWord64Ctz(Node* node) { UNREACHABLE(); }
+#endif
+
+
+void InstructionSelector::VisitInt32Add(Node* node) {
+  VisitBinop<Int32BinopMatcher>(this, node, kPPC_Add, kInt16Imm);
+}
+
+
+#if V8_TARGET_ARCH_PPC64
+void InstructionSelector::VisitInt64Add(Node* node) {
+  VisitBinop<Int64BinopMatcher>(this, node, kPPC_Add, kInt16Imm);
+}
+#endif
+
+
+void InstructionSelector::VisitInt32Sub(Node* node) {
+  PPCOperandGenerator g(this);
+  Int32BinopMatcher m(node);
+  if (m.left().Is(0)) {
+    Emit(kPPC_Neg, g.DefineAsRegister(node), g.UseRegister(m.right().node()));
+  } else {
+    VisitBinop<Int32BinopMatcher>(this, node, kPPC_Sub, kInt16Imm_Negate);
+  }
+}
+
+
+#if V8_TARGET_ARCH_PPC64
+void InstructionSelector::VisitInt64Sub(Node* node) {
+  PPCOperandGenerator g(this);
+  Int64BinopMatcher m(node);
+  if (m.left().Is(0)) {
+    Emit(kPPC_Neg, g.DefineAsRegister(node), g.UseRegister(m.right().node()));
+  } else {
+    VisitBinop<Int64BinopMatcher>(this, node, kPPC_Sub, kInt16Imm_Negate);
+  }
+}
+#endif
+
+
+void InstructionSelector::VisitInt32Mul(Node* node) {
+  VisitRRR(this, kPPC_Mul32, node);
+}
+
+
+#if V8_TARGET_ARCH_PPC64
+void InstructionSelector::VisitInt64Mul(Node* node) {
+  VisitRRR(this, kPPC_Mul64, node);
+}
+#endif
+
+
+void InstructionSelector::VisitInt32MulHigh(Node* node) {
+  PPCOperandGenerator g(this);
+  Emit(kPPC_MulHigh32, g.DefineAsRegister(node),
+       g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)));
+}
+
+
+void InstructionSelector::VisitUint32MulHigh(Node* node) {
+  PPCOperandGenerator g(this);
+  Emit(kPPC_MulHighU32, g.DefineAsRegister(node),
+       g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)));
+}
+
+
+void InstructionSelector::VisitInt32Div(Node* node) {
+  VisitRRR(this, kPPC_Div32, node);
+}
+
+
+#if V8_TARGET_ARCH_PPC64
+void InstructionSelector::VisitInt64Div(Node* node) {
+  VisitRRR(this, kPPC_Div64, node);
+}
+#endif
+
+
+void InstructionSelector::VisitUint32Div(Node* node) {
+  VisitRRR(this, kPPC_DivU32, node);
+}
+
+
+#if V8_TARGET_ARCH_PPC64
+void InstructionSelector::VisitUint64Div(Node* node) {
+  VisitRRR(this, kPPC_DivU64, node);
+}
+#endif
+
+
+void InstructionSelector::VisitInt32Mod(Node* node) {
+  VisitRRR(this, kPPC_Mod32, node);
+}
+
+
+#if V8_TARGET_ARCH_PPC64
+void InstructionSelector::VisitInt64Mod(Node* node) {
+  VisitRRR(this, kPPC_Mod64, node);
+}
+#endif
+
+
+void InstructionSelector::VisitUint32Mod(Node* node) {
+  VisitRRR(this, kPPC_ModU32, node);
+}
+
+
+#if V8_TARGET_ARCH_PPC64
+void InstructionSelector::VisitUint64Mod(Node* node) {
+  VisitRRR(this, kPPC_ModU64, node);
+}
+#endif
+
+
+void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) {
+  VisitRR(this, kPPC_Float32ToDouble, node);
+}
+
+
+void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) {
+  VisitRR(this, kPPC_Int32ToDouble, node);
+}
+
+
+void InstructionSelector::VisitChangeUint32ToFloat64(Node* node) {
+  VisitRR(this, kPPC_Uint32ToDouble, node);
+}
+
+
+void InstructionSelector::VisitChangeFloat64ToInt32(Node* node) {
+  VisitRR(this, kPPC_DoubleToInt32, node);
+}
+
+
+void InstructionSelector::VisitChangeFloat64ToUint32(Node* node) {
+  VisitRR(this, kPPC_DoubleToUint32, node);
+}
+
+
+#if V8_TARGET_ARCH_PPC64
+void InstructionSelector::VisitTryTruncateFloat32ToInt64(Node* node) {
+  VisitTryTruncateDouble(this, kPPC_DoubleToInt64, node);
+}
+
+
+void InstructionSelector::VisitTryTruncateFloat64ToInt64(Node* node) {
+  VisitTryTruncateDouble(this, kPPC_DoubleToInt64, node);
+}
+
+
+void InstructionSelector::VisitTryTruncateFloat32ToUint64(Node* node) {
+  VisitTryTruncateDouble(this, kPPC_DoubleToUint64, node);
+}
+
+
+void InstructionSelector::VisitTryTruncateFloat64ToUint64(Node* node) {
+  VisitTryTruncateDouble(this, kPPC_DoubleToUint64, node);
+}
+
+
+void InstructionSelector::VisitChangeInt32ToInt64(Node* node) {
+  // TODO(mbrandy): inspect input to see if nop is appropriate.
+  VisitRR(this, kPPC_ExtendSignWord32, node);
+}
+
+
+void InstructionSelector::VisitChangeUint32ToUint64(Node* node) {
+  // TODO(mbrandy): inspect input to see if nop is appropriate.
+  VisitRR(this, kPPC_Uint32ToUint64, node);
+}
+#endif
+
+
+void InstructionSelector::VisitTruncateFloat64ToFloat32(Node* node) {
+  VisitRR(this, kPPC_DoubleToFloat32, node);
+}
+
+
+void InstructionSelector::VisitTruncateFloat64ToInt32(Node* node) {
+  switch (TruncationModeOf(node->op())) {
+    case TruncationMode::kJavaScript:
+      return VisitRR(this, kArchTruncateDoubleToI, node);
+    case TruncationMode::kRoundToZero:
+      return VisitRR(this, kPPC_DoubleToInt32, node);
+  }
+  UNREACHABLE();
+}
+
+
+#if V8_TARGET_ARCH_PPC64
+void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) {
+  // TODO(mbrandy): inspect input to see if nop is appropriate.
+  VisitRR(this, kPPC_Int64ToInt32, node);
+}
+
+
+void InstructionSelector::VisitRoundInt64ToFloat32(Node* node) {
+  VisitRR(this, kPPC_Int64ToFloat32, node);
+}
+
+
+void InstructionSelector::VisitRoundInt64ToFloat64(Node* node) {
+  VisitRR(this, kPPC_Int64ToDouble, node);
+}
+
+
+void InstructionSelector::VisitRoundUint64ToFloat32(Node* node) {
+  VisitRR(this, kPPC_Uint64ToFloat32, node);
+}
+
+
+void InstructionSelector::VisitRoundUint64ToFloat64(Node* node) {
+  VisitRR(this, kPPC_Uint64ToDouble, node);
+}
+#endif
+
+
+void InstructionSelector::VisitBitcastFloat32ToInt32(Node* node) {
+  VisitRR(this, kPPC_BitcastFloat32ToInt32, node);
+}
+
+
+#if V8_TARGET_ARCH_PPC64
+void InstructionSelector::VisitBitcastFloat64ToInt64(Node* node) {
+  VisitRR(this, kPPC_BitcastDoubleToInt64, node);
+}
+#endif
+
+
+void InstructionSelector::VisitBitcastInt32ToFloat32(Node* node) {
+  VisitRR(this, kPPC_BitcastInt32ToFloat32, node);
+}
+
+
+#if V8_TARGET_ARCH_PPC64
+void InstructionSelector::VisitBitcastInt64ToFloat64(Node* node) {
+  VisitRR(this, kPPC_BitcastInt64ToDouble, node);
+}
+#endif
+
+
+void InstructionSelector::VisitFloat32Add(Node* node) {
+  VisitRRR(this, kPPC_AddDouble, node);
+}
+
+
+void InstructionSelector::VisitFloat64Add(Node* node) {
+  // TODO(mbrandy): detect multiply-add
+  VisitRRR(this, kPPC_AddDouble, node);
+}
+
+
+void InstructionSelector::VisitFloat32Sub(Node* node) {
+  PPCOperandGenerator g(this);
+  Float32BinopMatcher m(node);
+  if (m.left().IsMinusZero()) {
+    Emit(kPPC_NegDouble, g.DefineAsRegister(node),
+         g.UseRegister(m.right().node()));
+    return;
+  }
+  VisitRRR(this, kPPC_SubDouble, node);
+}
+
+
+void InstructionSelector::VisitFloat64Sub(Node* node) {
+  // TODO(mbrandy): detect multiply-subtract
+  PPCOperandGenerator g(this);
+  Float64BinopMatcher m(node);
+  if (m.left().IsMinusZero()) {
+    if (m.right().IsFloat64RoundDown() &&
+        CanCover(m.node(), m.right().node())) {
+      if (m.right().InputAt(0)->opcode() == IrOpcode::kFloat64Sub &&
+          CanCover(m.right().node(), m.right().InputAt(0))) {
+        Float64BinopMatcher mright0(m.right().InputAt(0));
+        if (mright0.left().IsMinusZero()) {
+          // -floor(-x) = ceil(x)
+          Emit(kPPC_CeilDouble, g.DefineAsRegister(node),
+               g.UseRegister(mright0.right().node()));
+          return;
+        }
+      }
+    }
+    Emit(kPPC_NegDouble, g.DefineAsRegister(node),
+         g.UseRegister(m.right().node()));
+    return;
+  }
+  VisitRRR(this, kPPC_SubDouble, node);
+}
+
+
+void InstructionSelector::VisitFloat32Mul(Node* node) {
+  VisitRRR(this, kPPC_MulDouble, node);
+}
+
+
+void InstructionSelector::VisitFloat64Mul(Node* node) {
+  // TODO(mbrandy): detect negate
+  VisitRRR(this, kPPC_MulDouble, node);
+}
+
+
+void InstructionSelector::VisitFloat32Div(Node* node) {
+  VisitRRR(this, kPPC_DivDouble, node);
+}
+
+
+void InstructionSelector::VisitFloat64Div(Node* node) {
+  VisitRRR(this, kPPC_DivDouble, node);
+}
+
+
+void InstructionSelector::VisitFloat64Mod(Node* node) {
+  PPCOperandGenerator g(this);
+  Emit(kPPC_ModDouble, g.DefineAsFixed(node, d1),
+       g.UseFixed(node->InputAt(0), d1),
+       g.UseFixed(node->InputAt(1), d2))->MarkAsCall();
+}
+
+
+void InstructionSelector::VisitFloat32Max(Node* node) { UNREACHABLE(); }
+
+
+void InstructionSelector::VisitFloat64Max(Node* node) { UNREACHABLE(); }
+
+
+void InstructionSelector::VisitFloat32Min(Node* node) { UNREACHABLE(); }
+
+
+void InstructionSelector::VisitFloat64Min(Node* node) { UNREACHABLE(); }
+
+
+void InstructionSelector::VisitFloat32Abs(Node* node) {
+  VisitRR(this, kPPC_AbsDouble, node);
+}
+
+
+void InstructionSelector::VisitFloat64Abs(Node* node) {
+  VisitRR(this, kPPC_AbsDouble, node);
+}
+
+
+void InstructionSelector::VisitFloat32Sqrt(Node* node) {
+  VisitRR(this, kPPC_SqrtDouble, node);
+}
+
+
+void InstructionSelector::VisitFloat64Sqrt(Node* node) {
+  VisitRR(this, kPPC_SqrtDouble, node);
+}
+
+
+void InstructionSelector::VisitFloat32RoundDown(Node* node) {
+  VisitRR(this, kPPC_FloorDouble, node);
+}
+
+
+void InstructionSelector::VisitFloat64RoundDown(Node* node) {
+  VisitRR(this, kPPC_FloorDouble, node);
+}
+
+
+void InstructionSelector::VisitFloat32RoundUp(Node* node) {
+  VisitRR(this, kPPC_CeilDouble, node);
+}
+
+
+void InstructionSelector::VisitFloat64RoundUp(Node* node) {
+  VisitRR(this, kPPC_CeilDouble, node);
+}
+
+
+void InstructionSelector::VisitFloat32RoundTruncate(Node* node) {
+  VisitRR(this, kPPC_TruncateDouble, node);
+}
+
+
+void InstructionSelector::VisitFloat64RoundTruncate(Node* node) {
+  VisitRR(this, kPPC_TruncateDouble, node);
+}
+
+
+void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) {
+  VisitRR(this, kPPC_RoundDouble, node);
+}
+
+
+void InstructionSelector::VisitFloat32RoundTiesEven(Node* node) {
+  UNREACHABLE();
+}
+
+
+void InstructionSelector::VisitFloat64RoundTiesEven(Node* node) {
+  UNREACHABLE();
+}
+
+
+void InstructionSelector::VisitInt32AddWithOverflow(Node* node) {
+  if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
+    FlagsContinuation cont(kOverflow, ovf);
+    return VisitBinop<Int32BinopMatcher>(this, node, kPPC_AddWithOverflow32,
+                                         kInt16Imm, &cont);
+  }
+  FlagsContinuation cont;
+  VisitBinop<Int32BinopMatcher>(this, node, kPPC_AddWithOverflow32, kInt16Imm,
+                                &cont);
+}
+
+
+void InstructionSelector::VisitInt32SubWithOverflow(Node* node) {
+  if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
+    FlagsContinuation cont(kOverflow, ovf);
+    return VisitBinop<Int32BinopMatcher>(this, node, kPPC_SubWithOverflow32,
+                                         kInt16Imm_Negate, &cont);
+  }
+  FlagsContinuation cont;
+  VisitBinop<Int32BinopMatcher>(this, node, kPPC_SubWithOverflow32,
+                                kInt16Imm_Negate, &cont);
+}
+
+
+#if V8_TARGET_ARCH_PPC64
+void InstructionSelector::VisitInt64AddWithOverflow(Node* node) {
+  if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
+    FlagsContinuation cont(kOverflow, ovf);
+    return VisitBinop<Int64BinopMatcher>(this, node, kPPC_Add, kInt16Imm,
+                                         &cont);
+  }
+  FlagsContinuation cont;
+  VisitBinop<Int64BinopMatcher>(this, node, kPPC_Add, kInt16Imm, &cont);
+}
+
+
+void InstructionSelector::VisitInt64SubWithOverflow(Node* node) {
+  if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
+    FlagsContinuation cont(kOverflow, ovf);
+    return VisitBinop<Int64BinopMatcher>(this, node, kPPC_Sub, kInt16Imm_Negate,
+                                         &cont);
+  }
+  FlagsContinuation cont;
+  VisitBinop<Int64BinopMatcher>(this, node, kPPC_Sub, kInt16Imm_Negate, &cont);
+}
+#endif
+
+
+static bool CompareLogical(FlagsContinuation* cont) {
+  switch (cont->condition()) {
+    case kUnsignedLessThan:
+    case kUnsignedGreaterThanOrEqual:
+    case kUnsignedLessThanOrEqual:
+    case kUnsignedGreaterThan:
+      return true;
+    default:
+      return false;
+  }
+  UNREACHABLE();
+  return false;
+}
+
+
+namespace {
+
+// Shared routine for multiple compare operations.
+void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
+                  InstructionOperand left, InstructionOperand right,
+                  FlagsContinuation* cont) {
+  PPCOperandGenerator g(selector);
+  opcode = cont->Encode(opcode);
+  if (cont->IsBranch()) {
+    selector->Emit(opcode, g.NoOutput(), left, right,
+                   g.Label(cont->true_block()), g.Label(cont->false_block()));
+  } else {
+    DCHECK(cont->IsSet());
+    selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right);
+  }
+}
+
+
+// Shared routine for multiple word compare operations.
+void VisitWordCompare(InstructionSelector* selector, Node* node,
+                      InstructionCode opcode, FlagsContinuation* cont,
+                      bool commutative, ImmediateMode immediate_mode) {
+  PPCOperandGenerator g(selector);
+  Node* left = node->InputAt(0);
+  Node* right = node->InputAt(1);
+
+  // Match immediates on left or right side of comparison.
+  if (g.CanBeImmediate(right, immediate_mode)) {
+    VisitCompare(selector, opcode, g.UseRegister(left), g.UseImmediate(right),
+                 cont);
+  } else if (g.CanBeImmediate(left, immediate_mode)) {
+    if (!commutative) cont->Commute();
+    VisitCompare(selector, opcode, g.UseRegister(right), g.UseImmediate(left),
+                 cont);
+  } else {
+    VisitCompare(selector, opcode, g.UseRegister(left), g.UseRegister(right),
+                 cont);
+  }
+}
+
+
+void VisitWord32Compare(InstructionSelector* selector, Node* node,
+                        FlagsContinuation* cont) {
+  ImmediateMode mode = (CompareLogical(cont) ? kInt16Imm_Unsigned : kInt16Imm);
+  VisitWordCompare(selector, node, kPPC_Cmp32, cont, false, mode);
+}
+
+
+#if V8_TARGET_ARCH_PPC64
+void VisitWord64Compare(InstructionSelector* selector, Node* node,
+                        FlagsContinuation* cont) {
+  ImmediateMode mode = (CompareLogical(cont) ? kInt16Imm_Unsigned : kInt16Imm);
+  VisitWordCompare(selector, node, kPPC_Cmp64, cont, false, mode);
+}
+#endif
+
+
+// Shared routine for multiple float32 compare operations.
+void VisitFloat32Compare(InstructionSelector* selector, Node* node,
+                         FlagsContinuation* cont) {
+  PPCOperandGenerator g(selector);
+  Node* left = node->InputAt(0);
+  Node* right = node->InputAt(1);
+  VisitCompare(selector, kPPC_CmpDouble, g.UseRegister(left),
+               g.UseRegister(right), cont);
+}
+
+
+// Shared routine for multiple float64 compare operations.
+void VisitFloat64Compare(InstructionSelector* selector, Node* node,
+                         FlagsContinuation* cont) {
+  PPCOperandGenerator g(selector);
+  Node* left = node->InputAt(0);
+  Node* right = node->InputAt(1);
+  VisitCompare(selector, kPPC_CmpDouble, g.UseRegister(left),
+               g.UseRegister(right), cont);
+}
+
+
+// Shared routine for word comparisons against zero.
+void VisitWordCompareZero(InstructionSelector* selector, Node* user,
+                          Node* value, InstructionCode opcode,
+                          FlagsContinuation* cont) {
+  while (selector->CanCover(user, value)) {
+    switch (value->opcode()) {
+      case IrOpcode::kWord32Equal: {
+        // Combine with comparisons against 0 by simply inverting the
+        // continuation.
+        Int32BinopMatcher m(value);
+        if (m.right().Is(0)) {
+          user = value;
+          value = m.left().node();
+          cont->Negate();
+          continue;
+        }
+        cont->OverwriteAndNegateIfEqual(kEqual);
+        return VisitWord32Compare(selector, value, cont);
+      }
+      case IrOpcode::kInt32LessThan:
+        cont->OverwriteAndNegateIfEqual(kSignedLessThan);
+        return VisitWord32Compare(selector, value, cont);
+      case IrOpcode::kInt32LessThanOrEqual:
+        cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual);
+        return VisitWord32Compare(selector, value, cont);
+      case IrOpcode::kUint32LessThan:
+        cont->OverwriteAndNegateIfEqual(kUnsignedLessThan);
+        return VisitWord32Compare(selector, value, cont);
+      case IrOpcode::kUint32LessThanOrEqual:
+        cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
+        return VisitWord32Compare(selector, value, cont);
+#if V8_TARGET_ARCH_PPC64
+      case IrOpcode::kWord64Equal:
+        cont->OverwriteAndNegateIfEqual(kEqual);
+        return VisitWord64Compare(selector, value, cont);
+      case IrOpcode::kInt64LessThan:
+        cont->OverwriteAndNegateIfEqual(kSignedLessThan);
+        return VisitWord64Compare(selector, value, cont);
+      case IrOpcode::kInt64LessThanOrEqual:
+        cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual);
+        return VisitWord64Compare(selector, value, cont);
+      case IrOpcode::kUint64LessThan:
+        cont->OverwriteAndNegateIfEqual(kUnsignedLessThan);
+        return VisitWord64Compare(selector, value, cont);
+      case IrOpcode::kUint64LessThanOrEqual:
+        cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
+        return VisitWord64Compare(selector, value, cont);
+#endif
+      case IrOpcode::kFloat32Equal:
+        cont->OverwriteAndNegateIfEqual(kEqual);
+        return VisitFloat32Compare(selector, value, cont);
+      case IrOpcode::kFloat32LessThan:
+        cont->OverwriteAndNegateIfEqual(kUnsignedLessThan);
+        return VisitFloat32Compare(selector, value, cont);
+      case IrOpcode::kFloat32LessThanOrEqual:
+        cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
+        return VisitFloat32Compare(selector, value, cont);
+      case IrOpcode::kFloat64Equal:
+        cont->OverwriteAndNegateIfEqual(kEqual);
+        return VisitFloat64Compare(selector, value, cont);
+      case IrOpcode::kFloat64LessThan:
+        cont->OverwriteAndNegateIfEqual(kUnsignedLessThan);
+        return VisitFloat64Compare(selector, value, cont);
+      case IrOpcode::kFloat64LessThanOrEqual:
+        cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
+        return VisitFloat64Compare(selector, value, cont);
+      case IrOpcode::kProjection:
+        // Check if this is the overflow output projection of an
+        // <Operation>WithOverflow node.
+        if (ProjectionIndexOf(value->op()) == 1u) {
+          // We cannot combine the <Operation>WithOverflow with this branch
+          // unless the 0th projection (the use of the actual value of the
+          // <Operation> is either nullptr, which means there's no use of the
+          // actual value, or was already defined, which means it is scheduled
+          // *AFTER* this branch).
+          Node* const node = value->InputAt(0);
+          Node* const result = NodeProperties::FindProjection(node, 0);
+          if (result == nullptr || selector->IsDefined(result)) {
+            switch (node->opcode()) {
+              case IrOpcode::kInt32AddWithOverflow:
+                cont->OverwriteAndNegateIfEqual(kOverflow);
+                return VisitBinop<Int32BinopMatcher>(
+                    selector, node, kPPC_AddWithOverflow32, kInt16Imm, cont);
+              case IrOpcode::kInt32SubWithOverflow:
+                cont->OverwriteAndNegateIfEqual(kOverflow);
+                return VisitBinop<Int32BinopMatcher>(selector, node,
+                                                     kPPC_SubWithOverflow32,
+                                                     kInt16Imm_Negate, cont);
+#if V8_TARGET_ARCH_PPC64
+              case IrOpcode::kInt64AddWithOverflow:
+                cont->OverwriteAndNegateIfEqual(kOverflow);
+                return VisitBinop<Int64BinopMatcher>(selector, node, kPPC_Add,
+                                                     kInt16Imm, cont);
+              case IrOpcode::kInt64SubWithOverflow:
+                cont->OverwriteAndNegateIfEqual(kOverflow);
+                return VisitBinop<Int64BinopMatcher>(selector, node, kPPC_Sub,
+                                                     kInt16Imm_Negate, cont);
+#endif
+              default:
+                break;
+            }
+          }
+        }
+        break;
+      case IrOpcode::kInt32Sub:
+        return VisitWord32Compare(selector, value, cont);
+      case IrOpcode::kWord32And:
+        // TODO(mbandy): opportunity for rlwinm?
+        return VisitWordCompare(selector, value, kPPC_Tst32, cont, true,
+                                kInt16Imm_Unsigned);
+// TODO(mbrandy): Handle?
+// case IrOpcode::kInt32Add:
+// case IrOpcode::kWord32Or:
+// case IrOpcode::kWord32Xor:
+// case IrOpcode::kWord32Sar:
+// case IrOpcode::kWord32Shl:
+// case IrOpcode::kWord32Shr:
+// case IrOpcode::kWord32Ror:
+#if V8_TARGET_ARCH_PPC64
+      case IrOpcode::kInt64Sub:
+        return VisitWord64Compare(selector, value, cont);
+      case IrOpcode::kWord64And:
+        // TODO(mbandy): opportunity for rldic?
+        return VisitWordCompare(selector, value, kPPC_Tst64, cont, true,
+                                kInt16Imm_Unsigned);
+// TODO(mbrandy): Handle?
+// case IrOpcode::kInt64Add:
+// case IrOpcode::kWord64Or:
+// case IrOpcode::kWord64Xor:
+// case IrOpcode::kWord64Sar:
+// case IrOpcode::kWord64Shl:
+// case IrOpcode::kWord64Shr:
+// case IrOpcode::kWord64Ror:
+#endif
+      default:
+        break;
+    }
+    break;
+  }
+
+  // Branch could not be combined with a compare, emit compare against 0.
+  PPCOperandGenerator g(selector);
+  VisitCompare(selector, opcode, g.UseRegister(value), g.TempImmediate(0),
+               cont);
+}
+
+
+void VisitWord32CompareZero(InstructionSelector* selector, Node* user,
+                            Node* value, FlagsContinuation* cont) {
+  VisitWordCompareZero(selector, user, value, kPPC_Cmp32, cont);
+}
+
+
+#if V8_TARGET_ARCH_PPC64
+void VisitWord64CompareZero(InstructionSelector* selector, Node* user,
+                            Node* value, FlagsContinuation* cont) {
+  VisitWordCompareZero(selector, user, value, kPPC_Cmp64, cont);
+}
+#endif
+
+}  // namespace
+
+
+void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
+                                      BasicBlock* fbranch) {
+  FlagsContinuation cont(kNotEqual, tbranch, fbranch);
+  VisitWord32CompareZero(this, branch, branch->InputAt(0), &cont);
+}
+
+
+void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) {
+  PPCOperandGenerator g(this);
+  InstructionOperand value_operand = g.UseRegister(node->InputAt(0));
+
+  // Emit either ArchTableSwitch or ArchLookupSwitch.
+  size_t table_space_cost = 4 + sw.value_range;
+  size_t table_time_cost = 3;
+  size_t lookup_space_cost = 3 + 2 * sw.case_count;
+  size_t lookup_time_cost = sw.case_count;
+  if (sw.case_count > 0 &&
+      table_space_cost + 3 * table_time_cost <=
+          lookup_space_cost + 3 * lookup_time_cost &&
+      sw.min_value > std::numeric_limits<int32_t>::min()) {
+    InstructionOperand index_operand = value_operand;
+    if (sw.min_value) {
+      index_operand = g.TempRegister();
+      Emit(kPPC_Sub, index_operand, value_operand,
+           g.TempImmediate(sw.min_value));
+    }
+    // Generate a table lookup.
+    return EmitTableSwitch(sw, index_operand);
+  }
+
+  // Generate a sequence of conditional jumps.
+  return EmitLookupSwitch(sw, value_operand);
+}
+
+
+void InstructionSelector::VisitWord32Equal(Node* const node) {
+  FlagsContinuation cont(kEqual, node);
+  Int32BinopMatcher m(node);
+  if (m.right().Is(0)) {
+    return VisitWord32CompareZero(this, m.node(), m.left().node(), &cont);
+  }
+  VisitWord32Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitInt32LessThan(Node* node) {
+  FlagsContinuation cont(kSignedLessThan, node);
+  VisitWord32Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitInt32LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kSignedLessThanOrEqual, node);
+  VisitWord32Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitUint32LessThan(Node* node) {
+  FlagsContinuation cont(kUnsignedLessThan, node);
+  VisitWord32Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitUint32LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kUnsignedLessThanOrEqual, node);
+  VisitWord32Compare(this, node, &cont);
+}
+
+
+#if V8_TARGET_ARCH_PPC64
+void InstructionSelector::VisitWord64Equal(Node* const node) {
+  FlagsContinuation cont(kEqual, node);
+  Int64BinopMatcher m(node);
+  if (m.right().Is(0)) {
+    return VisitWord64CompareZero(this, m.node(), m.left().node(), &cont);
+  }
+  VisitWord64Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitInt64LessThan(Node* node) {
+  FlagsContinuation cont(kSignedLessThan, node);
+  VisitWord64Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitInt64LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kSignedLessThanOrEqual, node);
+  VisitWord64Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitUint64LessThan(Node* node) {
+  FlagsContinuation cont(kUnsignedLessThan, node);
+  VisitWord64Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitUint64LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kUnsignedLessThanOrEqual, node);
+  VisitWord64Compare(this, node, &cont);
+}
+#endif
+
+
+void InstructionSelector::VisitFloat32Equal(Node* node) {
+  FlagsContinuation cont(kEqual, node);
+  VisitFloat32Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitFloat32LessThan(Node* node) {
+  FlagsContinuation cont(kUnsignedLessThan, node);
+  VisitFloat32Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitFloat32LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kUnsignedLessThanOrEqual, node);
+  VisitFloat32Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitFloat64Equal(Node* node) {
+  FlagsContinuation cont(kEqual, node);
+  VisitFloat64Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitFloat64LessThan(Node* node) {
+  FlagsContinuation cont(kUnsignedLessThan, node);
+  VisitFloat64Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kUnsignedLessThanOrEqual, node);
+  VisitFloat64Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::EmitPrepareArguments(
+    ZoneVector<PushParameter>* arguments, const CallDescriptor* descriptor,
+    Node* node) {
+  PPCOperandGenerator g(this);
+
+  // Prepare for C function call.
+  if (descriptor->IsCFunctionCall()) {
+    Emit(kArchPrepareCallCFunction |
+             MiscField::encode(static_cast<int>(descriptor->CParameterCount())),
+         0, nullptr, 0, nullptr);
+
+    // Poke any stack arguments.
+    int slot = kStackFrameExtraParamSlot;
+    for (PushParameter input : (*arguments)) {
+      Emit(kPPC_StoreToStackSlot, g.NoOutput(), g.UseRegister(input.node()),
+           g.TempImmediate(slot));
+      ++slot;
+    }
+  } else {
+    // Push any stack arguments.
+    int num_slots = static_cast<int>(descriptor->StackParameterCount());
+    int slot = 0;
+    for (PushParameter input : (*arguments)) {
+      if (slot == 0) {
+        DCHECK(input.node());
+        Emit(kPPC_PushFrame, g.NoOutput(), g.UseRegister(input.node()),
+             g.TempImmediate(num_slots));
+      } else {
+        // Skip any alignment holes in pushed nodes.
+        if (input.node()) {
+          Emit(kPPC_StoreToStackSlot, g.NoOutput(), g.UseRegister(input.node()),
+               g.TempImmediate(slot));
+        }
+      }
+      ++slot;
+    }
+  }
+}
+
+
+bool InstructionSelector::IsTailCallAddressImmediate() { return false; }
+
+
+void InstructionSelector::VisitFloat64ExtractLowWord32(Node* node) {
+  PPCOperandGenerator g(this);
+  Emit(kPPC_DoubleExtractLowWord32, g.DefineAsRegister(node),
+       g.UseRegister(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitFloat64ExtractHighWord32(Node* node) {
+  PPCOperandGenerator g(this);
+  Emit(kPPC_DoubleExtractHighWord32, g.DefineAsRegister(node),
+       g.UseRegister(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitFloat64InsertLowWord32(Node* node) {
+  PPCOperandGenerator g(this);
+  Node* left = node->InputAt(0);
+  Node* right = node->InputAt(1);
+  if (left->opcode() == IrOpcode::kFloat64InsertHighWord32 &&
+      CanCover(node, left)) {
+    left = left->InputAt(1);
+    Emit(kPPC_DoubleConstruct, g.DefineAsRegister(node), g.UseRegister(left),
+         g.UseRegister(right));
+    return;
+  }
+  Emit(kPPC_DoubleInsertLowWord32, g.DefineSameAsFirst(node),
+       g.UseRegister(left), g.UseRegister(right));
+}
+
+
+void InstructionSelector::VisitFloat64InsertHighWord32(Node* node) {
+  PPCOperandGenerator g(this);
+  Node* left = node->InputAt(0);
+  Node* right = node->InputAt(1);
+  if (left->opcode() == IrOpcode::kFloat64InsertLowWord32 &&
+      CanCover(node, left)) {
+    left = left->InputAt(1);
+    Emit(kPPC_DoubleConstruct, g.DefineAsRegister(node), g.UseRegister(right),
+         g.UseRegister(left));
+    return;
+  }
+  Emit(kPPC_DoubleInsertHighWord32, g.DefineSameAsFirst(node),
+       g.UseRegister(left), g.UseRegister(right));
+}
+
+
+// static
+MachineOperatorBuilder::Flags
+InstructionSelector::SupportedMachineOperatorFlags() {
+  return MachineOperatorBuilder::kFloat32RoundDown |
+         MachineOperatorBuilder::kFloat64RoundDown |
+         MachineOperatorBuilder::kFloat32RoundUp |
+         MachineOperatorBuilder::kFloat64RoundUp |
+         MachineOperatorBuilder::kFloat32RoundTruncate |
+         MachineOperatorBuilder::kFloat64RoundTruncate |
+         MachineOperatorBuilder::kFloat64RoundTiesAway |
+         MachineOperatorBuilder::kWord32Popcnt |
+         MachineOperatorBuilder::kWord64Popcnt;
+  // We omit kWord32ShiftIsSafe as s[rl]w use 0x3f as a mask rather than 0x1f.
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/raw-machine-assembler.cc b/src/compiler/raw-machine-assembler.cc
index b93ec66..4df2bde 100644
--- a/src/compiler/raw-machine-assembler.cc
+++ b/src/compiler/raw-machine-assembler.cc
@@ -2,38 +2,37 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "src/code-factory.h"
-#include "src/compiler/pipeline.h"
 #include "src/compiler/raw-machine-assembler.h"
+
+#include "src/code-factory.h"
+#include "src/compiler/node-properties.h"
+#include "src/compiler/pipeline.h"
 #include "src/compiler/scheduler.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
-RawMachineAssembler::RawMachineAssembler(Graph* graph,
-                                         MachineSignature* machine_sig,
-                                         MachineType word,
+RawMachineAssembler::RawMachineAssembler(Isolate* isolate, Graph* graph,
+                                         CallDescriptor* call_descriptor,
+                                         MachineRepresentation word,
                                          MachineOperatorBuilder::Flags flags)
-    : GraphBuilder(graph),
+    : isolate_(isolate),
+      graph_(graph),
       schedule_(new (zone()) Schedule(zone())),
       machine_(zone(), word, flags),
       common_(zone()),
-      machine_sig_(machine_sig),
-      call_descriptor_(
-          Linkage::GetSimplifiedCDescriptor(graph->zone(), machine_sig)),
-      parameters_(NULL),
-      exit_label_(schedule()->end()),
+      call_descriptor_(call_descriptor),
+      parameters_(parameter_count(), zone()),
       current_block_(schedule()->start()) {
   int param_count = static_cast<int>(parameter_count());
-  Node* s = graph->NewNode(common_.Start(param_count));
-  graph->SetStart(s);
-  if (parameter_count() == 0) return;
-  parameters_ = zone()->NewArray<Node*>(param_count);
+  // Add an extra input for the JSFunction parameter to the start node.
+  graph->SetStart(graph->NewNode(common_.Start(param_count + 1)));
   for (size_t i = 0; i < parameter_count(); ++i) {
     parameters_[i] =
-        NewNode(common()->Parameter(static_cast<int>(i)), graph->start());
+        AddNode(common()->Parameter(static_cast<int>(i)), graph->start());
   }
+  graph->SetEnd(graph->NewNode(common_.End(0)));
 }
 
 
@@ -41,9 +40,9 @@
   // Compute the correct codegen order.
   DCHECK(schedule_->rpo_order()->empty());
   Scheduler::ComputeSpecialRPO(zone(), schedule_);
-  // Invalidate MachineAssembler.
+  // Invalidate RawMachineAssembler.
   Schedule* schedule = schedule_;
-  schedule_ = NULL;
+  schedule_ = nullptr;
   return schedule;
 }
 
@@ -54,94 +53,298 @@
 }
 
 
-RawMachineAssembler::Label* RawMachineAssembler::Exit() {
-  exit_label_.used_ = true;
-  return &exit_label_;
-}
-
-
-void RawMachineAssembler::Goto(Label* label) {
+void RawMachineAssembler::Goto(RawMachineLabel* label) {
   DCHECK(current_block_ != schedule()->end());
   schedule()->AddGoto(CurrentBlock(), Use(label));
-  current_block_ = NULL;
+  current_block_ = nullptr;
 }
 
 
-void RawMachineAssembler::Branch(Node* condition, Label* true_val,
-                                 Label* false_val) {
+void RawMachineAssembler::Branch(Node* condition, RawMachineLabel* true_val,
+                                 RawMachineLabel* false_val) {
   DCHECK(current_block_ != schedule()->end());
-  Node* branch = NewNode(common()->Branch(), condition);
+  Node* branch = AddNode(common()->Branch(), condition);
   schedule()->AddBranch(CurrentBlock(), branch, Use(true_val), Use(false_val));
-  current_block_ = NULL;
+  current_block_ = nullptr;
+}
+
+
+void RawMachineAssembler::Switch(Node* index, RawMachineLabel* default_label,
+                                 int32_t* case_values,
+                                 RawMachineLabel** case_labels,
+                                 size_t case_count) {
+  DCHECK_NE(schedule()->end(), current_block_);
+  size_t succ_count = case_count + 1;
+  Node* switch_node = AddNode(common()->Switch(succ_count), index);
+  BasicBlock** succ_blocks = zone()->NewArray<BasicBlock*>(succ_count);
+  for (size_t index = 0; index < case_count; ++index) {
+    int32_t case_value = case_values[index];
+    BasicBlock* case_block = Use(case_labels[index]);
+    Node* case_node =
+        graph()->NewNode(common()->IfValue(case_value), switch_node);
+    schedule()->AddNode(case_block, case_node);
+    succ_blocks[index] = case_block;
+  }
+  BasicBlock* default_block = Use(default_label);
+  Node* default_node = graph()->NewNode(common()->IfDefault(), switch_node);
+  schedule()->AddNode(default_block, default_node);
+  succ_blocks[case_count] = default_block;
+  schedule()->AddSwitch(CurrentBlock(), switch_node, succ_blocks, succ_count);
+  current_block_ = nullptr;
 }
 
 
 void RawMachineAssembler::Return(Node* value) {
-  schedule()->AddReturn(CurrentBlock(), value);
-  current_block_ = NULL;
+  Node* ret = MakeNode(common()->Return(), 1, &value);
+  NodeProperties::MergeControlToEnd(graph(), common(), ret);
+  schedule()->AddReturn(CurrentBlock(), ret);
+  current_block_ = nullptr;
 }
 
 
-Node* RawMachineAssembler::CallFunctionStub0(Node* function, Node* receiver,
-                                             Node* context, Node* frame_state,
-                                             CallFunctionFlags flags) {
-  Callable callable = CodeFactory::CallFunction(isolate(), 0, flags);
-  CallDescriptor* desc = Linkage::GetStubCallDescriptor(
-      callable.descriptor(), 1, CallDescriptor::kNeedsFrameState,
-      Operator::kNoProperties, zone());
-  Node* stub_code = HeapConstant(callable.code());
-  Node* call = graph()->NewNode(common()->Call(desc), stub_code, function,
-                                receiver, context, frame_state);
-  schedule()->AddNode(CurrentBlock(), call);
-  return call;
+void RawMachineAssembler::Return(Node* v1, Node* v2) {
+  Node* values[] = {v1, v2};
+  Node* ret = MakeNode(common()->Return(2), 2, values);
+  NodeProperties::MergeControlToEnd(graph(), common(), ret);
+  schedule()->AddReturn(CurrentBlock(), ret);
+  current_block_ = nullptr;
 }
 
 
-Node* RawMachineAssembler::CallJS0(Node* function, Node* receiver,
-                                   Node* context, Node* frame_state) {
-  CallDescriptor* descriptor =
-      Linkage::GetJSCallDescriptor(1, zone(), CallDescriptor::kNeedsFrameState);
-  Node* call = graph()->NewNode(common()->Call(descriptor), function, receiver,
-                                context, frame_state);
-  schedule()->AddNode(CurrentBlock(), call);
-  return call;
+void RawMachineAssembler::Return(Node* v1, Node* v2, Node* v3) {
+  Node* values[] = {v1, v2, v3};
+  Node* ret = MakeNode(common()->Return(3), 3, values);
+  NodeProperties::MergeControlToEnd(graph(), common(), ret);
+  schedule()->AddReturn(CurrentBlock(), ret);
+  current_block_ = nullptr;
+}
+
+
+Node* RawMachineAssembler::CallN(CallDescriptor* desc, Node* function,
+                                 Node** args) {
+  int param_count =
+      static_cast<int>(desc->GetMachineSignature()->parameter_count());
+  int input_count = param_count + 1;
+  Node** buffer = zone()->NewArray<Node*>(input_count);
+  int index = 0;
+  buffer[index++] = function;
+  for (int i = 0; i < param_count; i++) {
+    buffer[index++] = args[i];
+  }
+  return AddNode(common()->Call(desc), input_count, buffer);
+}
+
+
+Node* RawMachineAssembler::CallNWithFrameState(CallDescriptor* desc,
+                                               Node* function, Node** args,
+                                               Node* frame_state) {
+  DCHECK(desc->NeedsFrameState());
+  int param_count =
+      static_cast<int>(desc->GetMachineSignature()->parameter_count());
+  int input_count = param_count + 2;
+  Node** buffer = zone()->NewArray<Node*>(input_count);
+  int index = 0;
+  buffer[index++] = function;
+  for (int i = 0; i < param_count; i++) {
+    buffer[index++] = args[i];
+  }
+  buffer[index++] = frame_state;
+  return AddNode(common()->Call(desc), input_count, buffer);
 }
 
 
 Node* RawMachineAssembler::CallRuntime1(Runtime::FunctionId function,
-                                        Node* arg0, Node* context,
-                                        Node* frame_state) {
+                                        Node* arg1, Node* context) {
   CallDescriptor* descriptor = Linkage::GetRuntimeCallDescriptor(
-      function, 1, Operator::kNoProperties, zone());
+      zone(), function, 1, Operator::kNoProperties, CallDescriptor::kNoFlags);
+  int return_count = static_cast<int>(descriptor->ReturnCount());
 
-  Node* centry = HeapConstant(CEntryStub(isolate(), 1).GetCode());
-  Node* ref = NewNode(
+  Node* centry = HeapConstant(CEntryStub(isolate(), return_count).GetCode());
+  Node* ref = AddNode(
       common()->ExternalConstant(ExternalReference(function, isolate())));
   Node* arity = Int32Constant(1);
 
-  Node* call = graph()->NewNode(common()->Call(descriptor), centry, arg0, ref,
-                                arity, context, frame_state);
-  schedule()->AddNode(CurrentBlock(), call);
-  return call;
+  return AddNode(common()->Call(descriptor), centry, arg1, ref, arity, context);
 }
 
 
-void RawMachineAssembler::Bind(Label* label) {
-  DCHECK(current_block_ == NULL);
+Node* RawMachineAssembler::CallRuntime2(Runtime::FunctionId function,
+                                        Node* arg1, Node* arg2, Node* context) {
+  CallDescriptor* descriptor = Linkage::GetRuntimeCallDescriptor(
+      zone(), function, 2, Operator::kNoProperties, CallDescriptor::kNoFlags);
+  int return_count = static_cast<int>(descriptor->ReturnCount());
+
+  Node* centry = HeapConstant(CEntryStub(isolate(), return_count).GetCode());
+  Node* ref = AddNode(
+      common()->ExternalConstant(ExternalReference(function, isolate())));
+  Node* arity = Int32Constant(2);
+
+  return AddNode(common()->Call(descriptor), centry, arg1, arg2, ref, arity,
+                 context);
+}
+
+
+Node* RawMachineAssembler::CallRuntime4(Runtime::FunctionId function,
+                                        Node* arg1, Node* arg2, Node* arg3,
+                                        Node* arg4, Node* context) {
+  CallDescriptor* descriptor = Linkage::GetRuntimeCallDescriptor(
+      zone(), function, 4, Operator::kNoProperties, CallDescriptor::kNoFlags);
+  int return_count = static_cast<int>(descriptor->ReturnCount());
+
+  Node* centry = HeapConstant(CEntryStub(isolate(), return_count).GetCode());
+  Node* ref = AddNode(
+      common()->ExternalConstant(ExternalReference(function, isolate())));
+  Node* arity = Int32Constant(4);
+
+  return AddNode(common()->Call(descriptor), centry, arg1, arg2, arg3, arg4,
+                 ref, arity, context);
+}
+
+
+Node* RawMachineAssembler::TailCallN(CallDescriptor* desc, Node* function,
+                                     Node** args) {
+  int param_count =
+      static_cast<int>(desc->GetMachineSignature()->parameter_count());
+  int input_count = param_count + 1;
+  Node** buffer = zone()->NewArray<Node*>(input_count);
+  int index = 0;
+  buffer[index++] = function;
+  for (int i = 0; i < param_count; i++) {
+    buffer[index++] = args[i];
+  }
+  Node* tail_call = MakeNode(common()->TailCall(desc), input_count, buffer);
+  NodeProperties::MergeControlToEnd(graph(), common(), tail_call);
+  schedule()->AddTailCall(CurrentBlock(), tail_call);
+  current_block_ = nullptr;
+  return tail_call;
+}
+
+
+Node* RawMachineAssembler::TailCallRuntime1(Runtime::FunctionId function,
+                                            Node* arg1, Node* context) {
+  const int kArity = 1;
+  CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor(
+      zone(), function, kArity, Operator::kNoProperties,
+      CallDescriptor::kSupportsTailCalls);
+  int return_count = static_cast<int>(desc->ReturnCount());
+
+  Node* centry = HeapConstant(CEntryStub(isolate(), return_count).GetCode());
+  Node* ref = AddNode(
+      common()->ExternalConstant(ExternalReference(function, isolate())));
+  Node* arity = Int32Constant(kArity);
+
+  Node* nodes[] = {centry, arg1, ref, arity, context};
+  Node* tail_call = MakeNode(common()->TailCall(desc), arraysize(nodes), nodes);
+
+  NodeProperties::MergeControlToEnd(graph(), common(), tail_call);
+  schedule()->AddTailCall(CurrentBlock(), tail_call);
+  current_block_ = nullptr;
+  return tail_call;
+}
+
+
+Node* RawMachineAssembler::TailCallRuntime2(Runtime::FunctionId function,
+                                            Node* arg1, Node* arg2,
+                                            Node* context) {
+  const int kArity = 2;
+  CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor(
+      zone(), function, kArity, Operator::kNoProperties,
+      CallDescriptor::kSupportsTailCalls);
+  int return_count = static_cast<int>(desc->ReturnCount());
+
+  Node* centry = HeapConstant(CEntryStub(isolate(), return_count).GetCode());
+  Node* ref = AddNode(
+      common()->ExternalConstant(ExternalReference(function, isolate())));
+  Node* arity = Int32Constant(kArity);
+
+  Node* nodes[] = {centry, arg1, arg2, ref, arity, context};
+  Node* tail_call = MakeNode(common()->TailCall(desc), arraysize(nodes), nodes);
+
+  NodeProperties::MergeControlToEnd(graph(), common(), tail_call);
+  schedule()->AddTailCall(CurrentBlock(), tail_call);
+  current_block_ = nullptr;
+  return tail_call;
+}
+
+
+Node* RawMachineAssembler::CallCFunction0(MachineType return_type,
+                                          Node* function) {
+  MachineSignature::Builder builder(zone(), 1, 0);
+  builder.AddReturn(return_type);
+  const CallDescriptor* descriptor =
+      Linkage::GetSimplifiedCDescriptor(zone(), builder.Build());
+
+  return AddNode(common()->Call(descriptor), function);
+}
+
+
+Node* RawMachineAssembler::CallCFunction1(MachineType return_type,
+                                          MachineType arg0_type, Node* function,
+                                          Node* arg0) {
+  MachineSignature::Builder builder(zone(), 1, 1);
+  builder.AddReturn(return_type);
+  builder.AddParam(arg0_type);
+  const CallDescriptor* descriptor =
+      Linkage::GetSimplifiedCDescriptor(zone(), builder.Build());
+
+  return AddNode(common()->Call(descriptor), function, arg0);
+}
+
+
+Node* RawMachineAssembler::CallCFunction2(MachineType return_type,
+                                          MachineType arg0_type,
+                                          MachineType arg1_type, Node* function,
+                                          Node* arg0, Node* arg1) {
+  MachineSignature::Builder builder(zone(), 1, 2);
+  builder.AddReturn(return_type);
+  builder.AddParam(arg0_type);
+  builder.AddParam(arg1_type);
+  const CallDescriptor* descriptor =
+      Linkage::GetSimplifiedCDescriptor(zone(), builder.Build());
+
+  return AddNode(common()->Call(descriptor), function, arg0, arg1);
+}
+
+
+Node* RawMachineAssembler::CallCFunction8(
+    MachineType return_type, MachineType arg0_type, MachineType arg1_type,
+    MachineType arg2_type, MachineType arg3_type, MachineType arg4_type,
+    MachineType arg5_type, MachineType arg6_type, MachineType arg7_type,
+    Node* function, Node* arg0, Node* arg1, Node* arg2, Node* arg3, Node* arg4,
+    Node* arg5, Node* arg6, Node* arg7) {
+  MachineSignature::Builder builder(zone(), 1, 8);
+  builder.AddReturn(return_type);
+  builder.AddParam(arg0_type);
+  builder.AddParam(arg1_type);
+  builder.AddParam(arg2_type);
+  builder.AddParam(arg3_type);
+  builder.AddParam(arg4_type);
+  builder.AddParam(arg5_type);
+  builder.AddParam(arg6_type);
+  builder.AddParam(arg7_type);
+  Node* args[] = {function, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7};
+  const CallDescriptor* descriptor =
+      Linkage::GetSimplifiedCDescriptor(zone(), builder.Build());
+  return AddNode(common()->Call(descriptor), arraysize(args), args);
+}
+
+
+void RawMachineAssembler::Bind(RawMachineLabel* label) {
+  DCHECK(current_block_ == nullptr);
   DCHECK(!label->bound_);
   label->bound_ = true;
   current_block_ = EnsureBlock(label);
 }
 
 
-BasicBlock* RawMachineAssembler::Use(Label* label) {
+BasicBlock* RawMachineAssembler::Use(RawMachineLabel* label) {
   label->used_ = true;
   return EnsureBlock(label);
 }
 
 
-BasicBlock* RawMachineAssembler::EnsureBlock(Label* label) {
-  if (label->block_ == NULL) label->block_ = schedule()->NewBasicBlock();
+BasicBlock* RawMachineAssembler::EnsureBlock(RawMachineLabel* label) {
+  if (label->block_ == nullptr) label->block_ = schedule()->NewBasicBlock();
   return label->block_;
 }
 
@@ -152,17 +355,30 @@
 }
 
 
-Node* RawMachineAssembler::MakeNode(const Operator* op, int input_count,
-                                    Node** inputs, bool incomplete) {
-  DCHECK(ScheduleValid());
-  DCHECK(current_block_ != NULL);
-  Node* node = graph()->NewNode(op, input_count, inputs, incomplete);
-  BasicBlock* block = op->opcode() == IrOpcode::kParameter ? schedule()->start()
-                                                           : CurrentBlock();
-  schedule()->AddNode(block, node);
+Node* RawMachineAssembler::AddNode(const Operator* op, int input_count,
+                                   Node** inputs) {
+  DCHECK_NOT_NULL(schedule_);
+  DCHECK_NOT_NULL(current_block_);
+  Node* node = MakeNode(op, input_count, inputs);
+  schedule()->AddNode(CurrentBlock(), node);
   return node;
 }
 
+
+Node* RawMachineAssembler::MakeNode(const Operator* op, int input_count,
+                                    Node** inputs) {
+  // The raw machine assembler nodes do not have effect and control inputs,
+  // so we disable checking input counts here.
+  return graph()->NewNodeUnchecked(op, input_count, inputs);
+}
+
+
+RawMachineLabel::RawMachineLabel()
+    : block_(nullptr), used_(false), bound_(false) {}
+
+
+RawMachineLabel::~RawMachineLabel() { DCHECK(bound_ || !used_); }
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/src/compiler/raw-machine-assembler.h b/src/compiler/raw-machine-assembler.h
index 5455814..5c232ed 100644
--- a/src/compiler/raw-machine-assembler.h
+++ b/src/compiler/raw-machine-assembler.h
@@ -5,63 +5,66 @@
 #ifndef V8_COMPILER_RAW_MACHINE_ASSEMBLER_H_
 #define V8_COMPILER_RAW_MACHINE_ASSEMBLER_H_
 
-#include "src/v8.h"
-
+#include "src/assembler.h"
 #include "src/compiler/common-operator.h"
-#include "src/compiler/graph-builder.h"
+#include "src/compiler/graph.h"
 #include "src/compiler/linkage.h"
 #include "src/compiler/machine-operator.h"
 #include "src/compiler/node.h"
 #include "src/compiler/operator.h"
-
+#include "src/factory.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
 class BasicBlock;
+class RawMachineLabel;
 class Schedule;
 
 
-class RawMachineAssembler : public GraphBuilder {
+// The RawMachineAssembler produces a low-level IR graph. All nodes are wired
+// into a graph and also placed into a schedule immediately, hence subsequent
+// code generation can happen without the need for scheduling.
+//
+// In order to create a schedule on-the-fly, the assembler keeps track of basic
+// blocks by having one current basic block being populated and by referencing
+// other basic blocks through the use of labels.
+//
+// Also note that the generated graph is only valid together with the generated
+// schedule, using one without the other is invalid as the graph is inherently
+// non-schedulable due to missing control and effect dependencies.
+class RawMachineAssembler {
  public:
-  class Label {
-   public:
-    Label() : block_(NULL), used_(false), bound_(false) {}
-    ~Label() { DCHECK(bound_ || !used_); }
+  RawMachineAssembler(
+      Isolate* isolate, Graph* graph, CallDescriptor* call_descriptor,
+      MachineRepresentation word = MachineType::PointerRepresentation(),
+      MachineOperatorBuilder::Flags flags =
+          MachineOperatorBuilder::Flag::kNoFlags);
+  ~RawMachineAssembler() {}
 
-    BasicBlock* block() { return block_; }
-
-   private:
-    // Private constructor for exit label.
-    explicit Label(BasicBlock* block)
-        : block_(block), used_(false), bound_(false) {}
-
-    BasicBlock* block_;
-    bool used_;
-    bool bound_;
-    friend class RawMachineAssembler;
-    DISALLOW_COPY_AND_ASSIGN(Label);
-  };
-
-  RawMachineAssembler(Graph* graph, MachineSignature* machine_sig,
-                      MachineType word = kMachPtr,
-                      MachineOperatorBuilder::Flags flags =
-                          MachineOperatorBuilder::Flag::kNoFlags);
-  ~RawMachineAssembler() OVERRIDE {}
-
-  Isolate* isolate() const { return zone()->isolate(); }
+  Isolate* isolate() const { return isolate_; }
+  Graph* graph() const { return graph_; }
   Zone* zone() const { return graph()->zone(); }
   MachineOperatorBuilder* machine() { return &machine_; }
   CommonOperatorBuilder* common() { return &common_; }
   CallDescriptor* call_descriptor() const { return call_descriptor_; }
-  size_t parameter_count() const { return machine_sig_->parameter_count(); }
-  MachineSignature* machine_sig() const { return machine_sig_; }
+
+  // Finalizes the schedule and exports it to be used for code generation. Note
+  // that this RawMachineAssembler becomes invalid after export.
+  Schedule* Export();
+
+  // ===========================================================================
+  // The following utility methods create new nodes with specific operators and
+  // place them into the current basic block. They don't perform control flow,
+  // hence will not switch the current basic block.
+
+  Node* NullConstant() {
+    return HeapConstant(isolate()->factory()->null_value());
+  }
 
   Node* UndefinedConstant() {
-    Unique<HeapObject> unique = Unique<HeapObject>::CreateImmovable(
-        isolate()->factory()->undefined_value());
-    return NewNode(common()->HeapConstant(unique));
+    return HeapConstant(isolate()->factory()->undefined_value());
   }
 
   // Constants.
@@ -74,66 +77,74 @@
                              : Int32Constant(static_cast<int>(value));
   }
   Node* Int32Constant(int32_t value) {
-    return NewNode(common()->Int32Constant(value));
+    return AddNode(common()->Int32Constant(value));
   }
   Node* Int64Constant(int64_t value) {
-    return NewNode(common()->Int64Constant(value));
+    return AddNode(common()->Int64Constant(value));
   }
   Node* NumberConstant(double value) {
-    return NewNode(common()->NumberConstant(value));
+    return AddNode(common()->NumberConstant(value));
   }
   Node* Float32Constant(float value) {
-    return NewNode(common()->Float32Constant(value));
+    return AddNode(common()->Float32Constant(value));
   }
   Node* Float64Constant(double value) {
-    return NewNode(common()->Float64Constant(value));
+    return AddNode(common()->Float64Constant(value));
   }
   Node* HeapConstant(Handle<HeapObject> object) {
-    Unique<HeapObject> val = Unique<HeapObject>::CreateUninitialized(object);
-    return NewNode(common()->HeapConstant(val));
+    return AddNode(common()->HeapConstant(object));
+  }
+  Node* BooleanConstant(bool value) {
+    Handle<Object> object = isolate()->factory()->ToBoolean(value);
+    return HeapConstant(Handle<HeapObject>::cast(object));
+  }
+  Node* ExternalConstant(ExternalReference address) {
+    return AddNode(common()->ExternalConstant(address));
   }
 
   Node* Projection(int index, Node* a) {
-    return NewNode(common()->Projection(index), a);
+    return AddNode(common()->Projection(index), a);
   }
 
   // Memory Operations.
   Node* Load(MachineType rep, Node* base) {
-    return Load(rep, base, Int32Constant(0));
+    return Load(rep, base, IntPtrConstant(0));
   }
   Node* Load(MachineType rep, Node* base, Node* index) {
-    return NewNode(machine()->Load(rep), base, index, graph()->start(),
-                   graph()->start());
+    return AddNode(machine()->Load(rep), base, index);
   }
-  void Store(MachineType rep, Node* base, Node* value) {
-    Store(rep, base, Int32Constant(0), value);
+  Node* Store(MachineRepresentation rep, Node* base, Node* value,
+              WriteBarrierKind write_barrier) {
+    return Store(rep, base, IntPtrConstant(0), value, write_barrier);
   }
-  void Store(MachineType rep, Node* base, Node* index, Node* value) {
-    NewNode(machine()->Store(StoreRepresentation(rep, kNoWriteBarrier)), base,
-            index, value, graph()->start(), graph()->start());
+  Node* Store(MachineRepresentation rep, Node* base, Node* index, Node* value,
+              WriteBarrierKind write_barrier) {
+    return AddNode(machine()->Store(StoreRepresentation(rep, write_barrier)),
+                   base, index, value);
   }
+
   // Arithmetic Operations.
   Node* WordAnd(Node* a, Node* b) {
-    return NewNode(machine()->WordAnd(), a, b);
+    return AddNode(machine()->WordAnd(), a, b);
   }
-  Node* WordOr(Node* a, Node* b) { return NewNode(machine()->WordOr(), a, b); }
+  Node* WordOr(Node* a, Node* b) { return AddNode(machine()->WordOr(), a, b); }
   Node* WordXor(Node* a, Node* b) {
-    return NewNode(machine()->WordXor(), a, b);
+    return AddNode(machine()->WordXor(), a, b);
   }
   Node* WordShl(Node* a, Node* b) {
-    return NewNode(machine()->WordShl(), a, b);
+    return AddNode(machine()->WordShl(), a, b);
   }
   Node* WordShr(Node* a, Node* b) {
-    return NewNode(machine()->WordShr(), a, b);
+    return AddNode(machine()->WordShr(), a, b);
   }
   Node* WordSar(Node* a, Node* b) {
-    return NewNode(machine()->WordSar(), a, b);
+    return AddNode(machine()->WordSar(), a, b);
   }
   Node* WordRor(Node* a, Node* b) {
-    return NewNode(machine()->WordRor(), a, b);
+    return AddNode(machine()->WordRor(), a, b);
   }
   Node* WordEqual(Node* a, Node* b) {
-    return NewNode(machine()->WordEqual(), a, b);
+    return AddNode(machine()->WordEqual(), a, b);
   }
   Node* WordNotEqual(Node* a, Node* b) {
     return WordBinaryNot(WordEqual(a, b));
@@ -154,28 +165,29 @@
   }
 
   Node* Word32And(Node* a, Node* b) {
-    return NewNode(machine()->Word32And(), a, b);
+    return AddNode(machine()->Word32And(), a, b);
   }
   Node* Word32Or(Node* a, Node* b) {
-    return NewNode(machine()->Word32Or(), a, b);
+    return AddNode(machine()->Word32Or(), a, b);
   }
   Node* Word32Xor(Node* a, Node* b) {
-    return NewNode(machine()->Word32Xor(), a, b);
+    return AddNode(machine()->Word32Xor(), a, b);
   }
   Node* Word32Shl(Node* a, Node* b) {
-    return NewNode(machine()->Word32Shl(), a, b);
+    return AddNode(machine()->Word32Shl(), a, b);
   }
   Node* Word32Shr(Node* a, Node* b) {
-    return NewNode(machine()->Word32Shr(), a, b);
+    return AddNode(machine()->Word32Shr(), a, b);
   }
   Node* Word32Sar(Node* a, Node* b) {
-    return NewNode(machine()->Word32Sar(), a, b);
+    return AddNode(machine()->Word32Sar(), a, b);
   }
   Node* Word32Ror(Node* a, Node* b) {
-    return NewNode(machine()->Word32Ror(), a, b);
+    return AddNode(machine()->Word32Ror(), a, b);
   }
+  Node* Word32Clz(Node* a) { return AddNode(machine()->Word32Clz(), a); }
   Node* Word32Equal(Node* a, Node* b) {
-    return NewNode(machine()->Word32Equal(), a, b);
+    return AddNode(machine()->Word32Equal(), a, b);
   }
   Node* Word32NotEqual(Node* a, Node* b) {
     return Word32BinaryNot(Word32Equal(a, b));
@@ -184,28 +196,29 @@
   Node* Word32BinaryNot(Node* a) { return Word32Equal(a, Int32Constant(0)); }
 
   Node* Word64And(Node* a, Node* b) {
-    return NewNode(machine()->Word64And(), a, b);
+    return AddNode(machine()->Word64And(), a, b);
   }
   Node* Word64Or(Node* a, Node* b) {
-    return NewNode(machine()->Word64Or(), a, b);
+    return AddNode(machine()->Word64Or(), a, b);
   }
   Node* Word64Xor(Node* a, Node* b) {
-    return NewNode(machine()->Word64Xor(), a, b);
+    return AddNode(machine()->Word64Xor(), a, b);
   }
   Node* Word64Shl(Node* a, Node* b) {
-    return NewNode(machine()->Word64Shl(), a, b);
+    return AddNode(machine()->Word64Shl(), a, b);
   }
   Node* Word64Shr(Node* a, Node* b) {
-    return NewNode(machine()->Word64Shr(), a, b);
+    return AddNode(machine()->Word64Shr(), a, b);
   }
   Node* Word64Sar(Node* a, Node* b) {
-    return NewNode(machine()->Word64Sar(), a, b);
+    return AddNode(machine()->Word64Sar(), a, b);
   }
   Node* Word64Ror(Node* a, Node* b) {
-    return NewNode(machine()->Word64Ror(), a, b);
+    return AddNode(machine()->Word64Ror(), a, b);
   }
+  Node* Word64Clz(Node* a) { return AddNode(machine()->Word64Clz(), a); }
   Node* Word64Equal(Node* a, Node* b) {
-    return NewNode(machine()->Word64Equal(), a, b);
+    return AddNode(machine()->Word64Equal(), a, b);
   }
   Node* Word64NotEqual(Node* a, Node* b) {
     return Word64BinaryNot(Word64Equal(a, b));
@@ -214,49 +227,49 @@
   Node* Word64BinaryNot(Node* a) { return Word64Equal(a, Int64Constant(0)); }
 
   Node* Int32Add(Node* a, Node* b) {
-    return NewNode(machine()->Int32Add(), a, b);
+    return AddNode(machine()->Int32Add(), a, b);
   }
   Node* Int32AddWithOverflow(Node* a, Node* b) {
-    return NewNode(machine()->Int32AddWithOverflow(), a, b);
+    return AddNode(machine()->Int32AddWithOverflow(), a, b);
   }
   Node* Int32Sub(Node* a, Node* b) {
-    return NewNode(machine()->Int32Sub(), a, b);
+    return AddNode(machine()->Int32Sub(), a, b);
   }
   Node* Int32SubWithOverflow(Node* a, Node* b) {
-    return NewNode(machine()->Int32SubWithOverflow(), a, b);
+    return AddNode(machine()->Int32SubWithOverflow(), a, b);
   }
   Node* Int32Mul(Node* a, Node* b) {
-    return NewNode(machine()->Int32Mul(), a, b);
+    return AddNode(machine()->Int32Mul(), a, b);
   }
   Node* Int32MulHigh(Node* a, Node* b) {
-    return NewNode(machine()->Int32MulHigh(), a, b);
+    return AddNode(machine()->Int32MulHigh(), a, b);
   }
   Node* Int32Div(Node* a, Node* b) {
-    return NewNode(machine()->Int32Div(), a, b, graph()->start());
+    return AddNode(machine()->Int32Div(), a, b);
   }
   Node* Int32Mod(Node* a, Node* b) {
-    return NewNode(machine()->Int32Mod(), a, b, graph()->start());
+    return AddNode(machine()->Int32Mod(), a, b);
   }
   Node* Int32LessThan(Node* a, Node* b) {
-    return NewNode(machine()->Int32LessThan(), a, b);
+    return AddNode(machine()->Int32LessThan(), a, b);
   }
   Node* Int32LessThanOrEqual(Node* a, Node* b) {
-    return NewNode(machine()->Int32LessThanOrEqual(), a, b);
+    return AddNode(machine()->Int32LessThanOrEqual(), a, b);
   }
   Node* Uint32Div(Node* a, Node* b) {
-    return NewNode(machine()->Uint32Div(), a, b, graph()->start());
+    return AddNode(machine()->Uint32Div(), a, b);
   }
   Node* Uint32LessThan(Node* a, Node* b) {
-    return NewNode(machine()->Uint32LessThan(), a, b);
+    return AddNode(machine()->Uint32LessThan(), a, b);
   }
   Node* Uint32LessThanOrEqual(Node* a, Node* b) {
-    return NewNode(machine()->Uint32LessThanOrEqual(), a, b);
+    return AddNode(machine()->Uint32LessThanOrEqual(), a, b);
   }
   Node* Uint32Mod(Node* a, Node* b) {
-    return NewNode(machine()->Uint32Mod(), a, b, graph()->start());
+    return AddNode(machine()->Uint32Mod(), a, b);
   }
   Node* Uint32MulHigh(Node* a, Node* b) {
-    return NewNode(machine()->Uint32MulHigh(), a, b);
+    return AddNode(machine()->Uint32MulHigh(), a, b);
   }
   Node* Int32GreaterThan(Node* a, Node* b) { return Int32LessThan(b, a); }
   Node* Int32GreaterThanOrEqual(Node* a, Node* b) {
@@ -265,45 +278,48 @@
   Node* Int32Neg(Node* a) { return Int32Sub(Int32Constant(0), a); }
 
   Node* Int64Add(Node* a, Node* b) {
-    return NewNode(machine()->Int64Add(), a, b);
+    return AddNode(machine()->Int64Add(), a, b);
+  }
+  Node* Int64AddWithOverflow(Node* a, Node* b) {
+    return AddNode(machine()->Int64AddWithOverflow(), a, b);
   }
   Node* Int64Sub(Node* a, Node* b) {
-    return NewNode(machine()->Int64Sub(), a, b);
+    return AddNode(machine()->Int64Sub(), a, b);
+  }
+  Node* Int64SubWithOverflow(Node* a, Node* b) {
+    return AddNode(machine()->Int64SubWithOverflow(), a, b);
   }
   Node* Int64Mul(Node* a, Node* b) {
-    return NewNode(machine()->Int64Mul(), a, b);
+    return AddNode(machine()->Int64Mul(), a, b);
   }
   Node* Int64Div(Node* a, Node* b) {
-    return NewNode(machine()->Int64Div(), a, b);
+    return AddNode(machine()->Int64Div(), a, b);
   }
   Node* Int64Mod(Node* a, Node* b) {
-    return NewNode(machine()->Int64Mod(), a, b);
+    return AddNode(machine()->Int64Mod(), a, b);
   }
   Node* Int64Neg(Node* a) { return Int64Sub(Int64Constant(0), a); }
   Node* Int64LessThan(Node* a, Node* b) {
-    return NewNode(machine()->Int64LessThan(), a, b);
+    return AddNode(machine()->Int64LessThan(), a, b);
   }
   Node* Int64LessThanOrEqual(Node* a, Node* b) {
-    return NewNode(machine()->Int64LessThanOrEqual(), a, b);
+    return AddNode(machine()->Int64LessThanOrEqual(), a, b);
+  }
+  Node* Uint64LessThan(Node* a, Node* b) {
+    return AddNode(machine()->Uint64LessThan(), a, b);
+  }
+  Node* Uint64LessThanOrEqual(Node* a, Node* b) {
+    return AddNode(machine()->Uint64LessThanOrEqual(), a, b);
   }
   Node* Int64GreaterThan(Node* a, Node* b) { return Int64LessThan(b, a); }
   Node* Int64GreaterThanOrEqual(Node* a, Node* b) {
     return Int64LessThanOrEqual(b, a);
   }
   Node* Uint64Div(Node* a, Node* b) {
-    return NewNode(machine()->Uint64Div(), a, b);
+    return AddNode(machine()->Uint64Div(), a, b);
   }
   Node* Uint64Mod(Node* a, Node* b) {
-    return NewNode(machine()->Uint64Mod(), a, b);
-  }
-
-  // TODO(turbofan): What is this used for?
-  Node* ConvertIntPtrToInt32(Node* a) {
-    return kPointerSize == 8 ? NewNode(machine()->TruncateInt64ToInt32(), a)
-                             : a;
-  }
-  Node* ConvertInt32ToIntPtr(Node* a) {
-    return kPointerSize == 8 ? NewNode(machine()->ChangeInt32ToInt64(), a) : a;
+    return AddNode(machine()->Uint64Mod(), a, b);
   }
 
 #define INTPTR_BINOP(prefix, name)                     \
@@ -323,32 +339,77 @@
 
 #undef INTPTR_BINOP
 
+  Node* Float32Add(Node* a, Node* b) {
+    return AddNode(machine()->Float32Add(), a, b);
+  }
+  Node* Float32Sub(Node* a, Node* b) {
+    return AddNode(machine()->Float32Sub(), a, b);
+  }
+  Node* Float32Mul(Node* a, Node* b) {
+    return AddNode(machine()->Float32Mul(), a, b);
+  }
+  Node* Float32Div(Node* a, Node* b) {
+    return AddNode(machine()->Float32Div(), a, b);
+  }
+  Node* Float32Max(Node* a, Node* b) {
+    return AddNode(machine()->Float32Max().op(), a, b);
+  }
+  Node* Float32Min(Node* a, Node* b) {
+    return AddNode(machine()->Float32Min().op(), a, b);
+  }
+  Node* Float32Abs(Node* a) { return AddNode(machine()->Float32Abs(), a); }
+  Node* Float32Sqrt(Node* a) { return AddNode(machine()->Float32Sqrt(), a); }
+  Node* Float32Equal(Node* a, Node* b) {
+    return AddNode(machine()->Float32Equal(), a, b);
+  }
+  Node* Float32NotEqual(Node* a, Node* b) {
+    return WordBinaryNot(Float32Equal(a, b));
+  }
+  Node* Float32LessThan(Node* a, Node* b) {
+    return AddNode(machine()->Float32LessThan(), a, b);
+  }
+  Node* Float32LessThanOrEqual(Node* a, Node* b) {
+    return AddNode(machine()->Float32LessThanOrEqual(), a, b);
+  }
+  Node* Float32GreaterThan(Node* a, Node* b) { return Float32LessThan(b, a); }
+  Node* Float32GreaterThanOrEqual(Node* a, Node* b) {
+    return Float32LessThanOrEqual(b, a);
+  }
+
   Node* Float64Add(Node* a, Node* b) {
-    return NewNode(machine()->Float64Add(), a, b);
+    return AddNode(machine()->Float64Add(), a, b);
   }
   Node* Float64Sub(Node* a, Node* b) {
-    return NewNode(machine()->Float64Sub(), a, b);
+    return AddNode(machine()->Float64Sub(), a, b);
   }
   Node* Float64Mul(Node* a, Node* b) {
-    return NewNode(machine()->Float64Mul(), a, b);
+    return AddNode(machine()->Float64Mul(), a, b);
   }
   Node* Float64Div(Node* a, Node* b) {
-    return NewNode(machine()->Float64Div(), a, b);
+    return AddNode(machine()->Float64Div(), a, b);
   }
   Node* Float64Mod(Node* a, Node* b) {
-    return NewNode(machine()->Float64Mod(), a, b);
+    return AddNode(machine()->Float64Mod(), a, b);
   }
+  Node* Float64Max(Node* a, Node* b) {
+    return AddNode(machine()->Float64Max().op(), a, b);
+  }
+  Node* Float64Min(Node* a, Node* b) {
+    return AddNode(machine()->Float64Min().op(), a, b);
+  }
+  Node* Float64Abs(Node* a) { return AddNode(machine()->Float64Abs(), a); }
+  Node* Float64Sqrt(Node* a) { return AddNode(machine()->Float64Sqrt(), a); }
   Node* Float64Equal(Node* a, Node* b) {
-    return NewNode(machine()->Float64Equal(), a, b);
+    return AddNode(machine()->Float64Equal(), a, b);
   }
   Node* Float64NotEqual(Node* a, Node* b) {
     return WordBinaryNot(Float64Equal(a, b));
   }
   Node* Float64LessThan(Node* a, Node* b) {
-    return NewNode(machine()->Float64LessThan(), a, b);
+    return AddNode(machine()->Float64LessThan(), a, b);
   }
   Node* Float64LessThanOrEqual(Node* a, Node* b) {
-    return NewNode(machine()->Float64LessThanOrEqual(), a, b);
+    return AddNode(machine()->Float64LessThanOrEqual(), a, b);
   }
   Node* Float64GreaterThan(Node* a, Node* b) { return Float64LessThan(b, a); }
   Node* Float64GreaterThanOrEqual(Node* a, Node* b) {
@@ -357,106 +418,274 @@
 
   // Conversions.
   Node* ChangeFloat32ToFloat64(Node* a) {
-    return NewNode(machine()->ChangeFloat32ToFloat64(), a);
+    return AddNode(machine()->ChangeFloat32ToFloat64(), a);
   }
   Node* ChangeInt32ToFloat64(Node* a) {
-    return NewNode(machine()->ChangeInt32ToFloat64(), a);
+    return AddNode(machine()->ChangeInt32ToFloat64(), a);
   }
   Node* ChangeUint32ToFloat64(Node* a) {
-    return NewNode(machine()->ChangeUint32ToFloat64(), a);
+    return AddNode(machine()->ChangeUint32ToFloat64(), a);
   }
   Node* ChangeFloat64ToInt32(Node* a) {
-    return NewNode(machine()->ChangeFloat64ToInt32(), a);
+    return AddNode(machine()->ChangeFloat64ToInt32(), a);
   }
   Node* ChangeFloat64ToUint32(Node* a) {
-    return NewNode(machine()->ChangeFloat64ToUint32(), a);
+    return AddNode(machine()->ChangeFloat64ToUint32(), a);
+  }
+  Node* TruncateFloat32ToInt64(Node* a) {
+    // TODO(ahaas): Remove this function as soon as it is not used anymore in
+    // WebAssembly.
+    return AddNode(machine()->TryTruncateFloat32ToInt64(), a);
+  }
+  Node* TryTruncateFloat32ToInt64(Node* a) {
+    return AddNode(machine()->TryTruncateFloat32ToInt64(), a);
+  }
+  Node* TruncateFloat64ToInt64(Node* a) {
+    // TODO(ahaas): Remove this function as soon as it is not used anymore in
+    // WebAssembly.
+    return AddNode(machine()->TryTruncateFloat64ToInt64(), a);
+  }
+  Node* TryTruncateFloat64ToInt64(Node* a) {
+    return AddNode(machine()->TryTruncateFloat64ToInt64(), a);
+  }
+  Node* TruncateFloat32ToUint64(Node* a) {
+    // TODO(ahaas): Remove this function as soon as it is not used anymore in
+    // WebAssembly.
+    return AddNode(machine()->TryTruncateFloat32ToUint64(), a);
+  }
+  Node* TryTruncateFloat32ToUint64(Node* a) {
+    return AddNode(machine()->TryTruncateFloat32ToUint64(), a);
+  }
+  Node* TruncateFloat64ToUint64(Node* a) {
+    // TODO(ahaas): Remove this function as soon as it is not used anymore in
+    // WebAssembly.
+    return AddNode(machine()->TryTruncateFloat64ToUint64(), a);
+  }
+  Node* TryTruncateFloat64ToUint64(Node* a) {
+    return AddNode(machine()->TryTruncateFloat64ToUint64(), a);
   }
   Node* ChangeInt32ToInt64(Node* a) {
-    return NewNode(machine()->ChangeInt32ToInt64(), a);
+    return AddNode(machine()->ChangeInt32ToInt64(), a);
   }
   Node* ChangeUint32ToUint64(Node* a) {
-    return NewNode(machine()->ChangeUint32ToUint64(), a);
+    return AddNode(machine()->ChangeUint32ToUint64(), a);
   }
   Node* TruncateFloat64ToFloat32(Node* a) {
-    return NewNode(machine()->TruncateFloat64ToFloat32(), a);
+    return AddNode(machine()->TruncateFloat64ToFloat32(), a);
   }
-  Node* TruncateFloat64ToInt32(Node* a) {
-    return NewNode(machine()->TruncateFloat64ToInt32(), a);
+  Node* TruncateFloat64ToInt32(TruncationMode mode, Node* a) {
+    return AddNode(machine()->TruncateFloat64ToInt32(mode), a);
   }
   Node* TruncateInt64ToInt32(Node* a) {
-    return NewNode(machine()->TruncateInt64ToInt32(), a);
+    return AddNode(machine()->TruncateInt64ToInt32(), a);
   }
-  Node* Float64Floor(Node* a) { return NewNode(machine()->Float64Floor(), a); }
-  Node* Float64Ceil(Node* a) { return NewNode(machine()->Float64Ceil(), a); }
+  Node* RoundInt64ToFloat32(Node* a) {
+    return AddNode(machine()->RoundInt64ToFloat32(), a);
+  }
+  Node* RoundInt64ToFloat64(Node* a) {
+    return AddNode(machine()->RoundInt64ToFloat64(), a);
+  }
+  Node* RoundUint64ToFloat32(Node* a) {
+    return AddNode(machine()->RoundUint64ToFloat32(), a);
+  }
+  Node* RoundUint64ToFloat64(Node* a) {
+    return AddNode(machine()->RoundUint64ToFloat64(), a);
+  }
+  Node* BitcastFloat32ToInt32(Node* a) {
+    return AddNode(machine()->BitcastFloat32ToInt32(), a);
+  }
+  Node* BitcastFloat64ToInt64(Node* a) {
+    return AddNode(machine()->BitcastFloat64ToInt64(), a);
+  }
+  Node* BitcastInt32ToFloat32(Node* a) {
+    return AddNode(machine()->BitcastInt32ToFloat32(), a);
+  }
+  Node* BitcastInt64ToFloat64(Node* a) {
+    return AddNode(machine()->BitcastInt64ToFloat64(), a);
+  }
+  Node* Float32RoundDown(Node* a) {
+    return AddNode(machine()->Float32RoundDown().op(), a);
+  }
+  Node* Float64RoundDown(Node* a) {
+    return AddNode(machine()->Float64RoundDown().op(), a);
+  }
+  Node* Float32RoundUp(Node* a) {
+    return AddNode(machine()->Float32RoundUp().op(), a);
+  }
+  Node* Float64RoundUp(Node* a) {
+    return AddNode(machine()->Float64RoundUp().op(), a);
+  }
+  Node* Float32RoundTruncate(Node* a) {
+    return AddNode(machine()->Float32RoundTruncate().op(), a);
+  }
   Node* Float64RoundTruncate(Node* a) {
-    return NewNode(machine()->Float64RoundTruncate(), a);
+    return AddNode(machine()->Float64RoundTruncate().op(), a);
   }
   Node* Float64RoundTiesAway(Node* a) {
-    return NewNode(machine()->Float64RoundTiesAway(), a);
+    return AddNode(machine()->Float64RoundTiesAway().op(), a);
   }
+  Node* Float32RoundTiesEven(Node* a) {
+    return AddNode(machine()->Float32RoundTiesEven().op(), a);
+  }
+  Node* Float64RoundTiesEven(Node* a) {
+    return AddNode(machine()->Float64RoundTiesEven().op(), a);
+  }
+
+  // Float64 bit operations.
+  Node* Float64ExtractLowWord32(Node* a) {
+    return AddNode(machine()->Float64ExtractLowWord32(), a);
+  }
+  Node* Float64ExtractHighWord32(Node* a) {
+    return AddNode(machine()->Float64ExtractHighWord32(), a);
+  }
+  Node* Float64InsertLowWord32(Node* a, Node* b) {
+    return AddNode(machine()->Float64InsertLowWord32(), a, b);
+  }
+  Node* Float64InsertHighWord32(Node* a, Node* b) {
+    return AddNode(machine()->Float64InsertHighWord32(), a, b);
+  }
+
+  // Stack operations.
+  Node* LoadStackPointer() { return AddNode(machine()->LoadStackPointer()); }
+  Node* LoadFramePointer() { return AddNode(machine()->LoadFramePointer()); }
 
   // Parameters.
   Node* Parameter(size_t index);
 
+  // Pointer utilities.
+  Node* LoadFromPointer(void* address, MachineType rep, int32_t offset = 0) {
+    return Load(rep, PointerConstant(address), Int32Constant(offset));
+  }
+  Node* StoreToPointer(void* address, MachineRepresentation rep, Node* node) {
+    return Store(rep, PointerConstant(address), node, kNoWriteBarrier);
+  }
+  Node* StringConstant(const char* string) {
+    return HeapConstant(isolate()->factory()->InternalizeUtf8String(string));
+  }
+
+  // Call a given call descriptor and the given arguments.
+  Node* CallN(CallDescriptor* desc, Node* function, Node** args);
+  // Call a given call descriptor and the given arguments and frame-state.
+  Node* CallNWithFrameState(CallDescriptor* desc, Node* function, Node** args,
+                            Node* frame_state);
+  // Call to a runtime function with one arguments.
+  Node* CallRuntime1(Runtime::FunctionId function, Node* arg0, Node* context);
+  // Call to a runtime function with two arguments.
+  Node* CallRuntime2(Runtime::FunctionId function, Node* arg1, Node* arg2,
+                     Node* context);
+  // Call to a runtime function with four arguments.
+  Node* CallRuntime4(Runtime::FunctionId function, Node* arg1, Node* arg2,
+                     Node* arg3, Node* arg4, Node* context);
+  // Call to a C function with zero arguments.
+  Node* CallCFunction0(MachineType return_type, Node* function);
+  // Call to a C function with one parameter.
+  Node* CallCFunction1(MachineType return_type, MachineType arg0_type,
+                       Node* function, Node* arg0);
+  // Call to a C function with two arguments.
+  Node* CallCFunction2(MachineType return_type, MachineType arg0_type,
+                       MachineType arg1_type, Node* function, Node* arg0,
+                       Node* arg1);
+  // Call to a C function with eight arguments.
+  Node* CallCFunction8(MachineType return_type, MachineType arg0_type,
+                       MachineType arg1_type, MachineType arg2_type,
+                       MachineType arg3_type, MachineType arg4_type,
+                       MachineType arg5_type, MachineType arg6_type,
+                       MachineType arg7_type, Node* function, Node* arg0,
+                       Node* arg1, Node* arg2, Node* arg3, Node* arg4,
+                       Node* arg5, Node* arg6, Node* arg7);
+
+  // Tail call the given call descriptor and the given arguments.
+  Node* TailCallN(CallDescriptor* call_descriptor, Node* function, Node** args);
+  // Tail call to a runtime function with one argument.
+  Node* TailCallRuntime1(Runtime::FunctionId function, Node* arg0,
+                         Node* context);
+  // Tail call to a runtime function with two arguments.
+  Node* TailCallRuntime2(Runtime::FunctionId function, Node* arg1, Node* arg2,
+                         Node* context);
+
+
+  // ===========================================================================
+  // The following utility methods deal with control flow, hence might switch
+  // the current basic block or create new basic blocks for labels.
+
   // Control flow.
-  Label* Exit();
-  void Goto(Label* label);
-  void Branch(Node* condition, Label* true_val, Label* false_val);
-  // Call through CallFunctionStub with lazy deopt and frame-state.
-  Node* CallFunctionStub0(Node* function, Node* receiver, Node* context,
-                          Node* frame_state, CallFunctionFlags flags);
-  // Call to a JS function with zero parameters.
-  Node* CallJS0(Node* function, Node* receiver, Node* context,
-                Node* frame_state);
-  // Call to a runtime function with zero parameters.
-  Node* CallRuntime1(Runtime::FunctionId function, Node* arg0, Node* context,
-                     Node* frame_state);
+  void Goto(RawMachineLabel* label);
+  void Branch(Node* condition, RawMachineLabel* true_val,
+              RawMachineLabel* false_val);
+  void Switch(Node* index, RawMachineLabel* default_label, int32_t* case_values,
+              RawMachineLabel** case_labels, size_t case_count);
   void Return(Node* value);
-  void Bind(Label* label);
+  void Return(Node* v1, Node* v2);
+  void Return(Node* v1, Node* v2, Node* v3);
+  void Bind(RawMachineLabel* label);
   void Deoptimize(Node* state);
 
   // Variables.
-  Node* Phi(MachineType type, Node* n1, Node* n2) {
-    return NewNode(common()->Phi(type, 2), n1, n2);
+  Node* Phi(MachineRepresentation rep, Node* n1, Node* n2) {
+    return AddNode(common()->Phi(rep, 2), n1, n2);
   }
-  Node* Phi(MachineType type, Node* n1, Node* n2, Node* n3) {
-    return NewNode(common()->Phi(type, 3), n1, n2, n3);
+  Node* Phi(MachineRepresentation rep, Node* n1, Node* n2, Node* n3) {
+    return AddNode(common()->Phi(rep, 3), n1, n2, n3);
   }
-  Node* Phi(MachineType type, Node* n1, Node* n2, Node* n3, Node* n4) {
-    return NewNode(common()->Phi(type, 4), n1, n2, n3, n4);
+  Node* Phi(MachineRepresentation rep, Node* n1, Node* n2, Node* n3, Node* n4) {
+    return AddNode(common()->Phi(rep, 4), n1, n2, n3, n4);
   }
 
-  // MachineAssembler is invalid after export.
-  Schedule* Export();
+  // ===========================================================================
+  // The following generic node creation methods can be used for operators that
+  // are not covered by the above utility methods. There should rarely be a need
+  // to do that outside of testing though.
 
- protected:
-  Node* MakeNode(const Operator* op, int input_count, Node** inputs,
-                 bool incomplete) FINAL;
+  Node* AddNode(const Operator* op, int input_count, Node** inputs);
 
-  bool ScheduleValid() { return schedule_ != NULL; }
+  Node* AddNode(const Operator* op) {
+    return AddNode(op, 0, static_cast<Node**>(nullptr));
+  }
 
-  Schedule* schedule() {
-    DCHECK(ScheduleValid());
-    return schedule_;
+  template <class... TArgs>
+  Node* AddNode(const Operator* op, Node* n1, TArgs... args) {
+    Node* buffer[] = {n1, args...};
+    return AddNode(op, sizeof...(args) + 1, buffer);
   }
 
  private:
-  BasicBlock* Use(Label* label);
-  BasicBlock* EnsureBlock(Label* label);
+  Node* MakeNode(const Operator* op, int input_count, Node** inputs);
+  BasicBlock* Use(RawMachineLabel* label);
+  BasicBlock* EnsureBlock(RawMachineLabel* label);
   BasicBlock* CurrentBlock();
 
+  Schedule* schedule() { return schedule_; }
+  size_t parameter_count() const { return machine_sig()->parameter_count(); }
+  const MachineSignature* machine_sig() const {
+    return call_descriptor_->GetMachineSignature();
+  }
+
+  Isolate* isolate_;
+  Graph* graph_;
   Schedule* schedule_;
   MachineOperatorBuilder machine_;
   CommonOperatorBuilder common_;
-  MachineSignature* machine_sig_;
   CallDescriptor* call_descriptor_;
-  Node** parameters_;
-  Label exit_label_;
+  NodeVector parameters_;
   BasicBlock* current_block_;
 
   DISALLOW_COPY_AND_ASSIGN(RawMachineAssembler);
 };
 
+
+class RawMachineLabel final {
+ public:
+  RawMachineLabel();
+  ~RawMachineLabel();
+
+ private:
+  BasicBlock* block_;
+  bool used_;
+  bool bound_;
+  friend class RawMachineAssembler;
+  DISALLOW_COPY_AND_ASSIGN(RawMachineLabel);
+};
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/src/compiler/register-allocator-verifier.cc b/src/compiler/register-allocator-verifier.cc
index dabfd59..463795e 100644
--- a/src/compiler/register-allocator-verifier.cc
+++ b/src/compiler/register-allocator-verifier.cc
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "src/bit-vector.h"
 #include "src/compiler/instruction.h"
 #include "src/compiler/register-allocator-verifier.h"
 
@@ -9,26 +10,46 @@
 namespace internal {
 namespace compiler {
 
-static size_t OperandCount(const Instruction* instr) {
+namespace {
+
+size_t OperandCount(const Instruction* instr) {
   return instr->InputCount() + instr->OutputCount() + instr->TempCount();
 }
 
 
-static void VerifyGapEmpty(const GapInstruction* gap) {
-  for (int i = GapInstruction::FIRST_INNER_POSITION;
-       i <= GapInstruction::LAST_INNER_POSITION; i++) {
-    GapInstruction::InnerPosition inner_pos =
-        static_cast<GapInstruction::InnerPosition>(i);
-    CHECK_EQ(NULL, gap->GetParallelMove(inner_pos));
+void VerifyEmptyGaps(const Instruction* instr) {
+  for (int i = Instruction::FIRST_GAP_POSITION;
+       i <= Instruction::LAST_GAP_POSITION; i++) {
+    Instruction::GapPosition inner_pos =
+        static_cast<Instruction::GapPosition>(i);
+    CHECK(instr->GetParallelMove(inner_pos) == nullptr);
   }
 }
 
 
+void VerifyAllocatedGaps(const Instruction* instr) {
+  for (int i = Instruction::FIRST_GAP_POSITION;
+       i <= Instruction::LAST_GAP_POSITION; i++) {
+    Instruction::GapPosition inner_pos =
+        static_cast<Instruction::GapPosition>(i);
+    auto moves = instr->GetParallelMove(inner_pos);
+    if (moves == nullptr) continue;
+    for (auto move : *moves) {
+      if (move->IsRedundant()) continue;
+      CHECK(move->source().IsAllocated() || move->source().IsConstant());
+      CHECK(move->destination().IsAllocated());
+    }
+  }
+}
+
+}  // namespace
+
+
 void RegisterAllocatorVerifier::VerifyInput(
     const OperandConstraint& constraint) {
   CHECK_NE(kSameAsFirst, constraint.type_);
-  if (constraint.type_ != kImmediate) {
-    CHECK_NE(UnallocatedOperand::kInvalidVirtualRegister,
+  if (constraint.type_ != kImmediate && constraint.type_ != kExplicit) {
+    CHECK_NE(InstructionOperand::kInvalidVirtualRegister,
              constraint.virtual_register_);
   }
 }
@@ -38,16 +59,16 @@
     const OperandConstraint& constraint) {
   CHECK_NE(kSameAsFirst, constraint.type_);
   CHECK_NE(kImmediate, constraint.type_);
+  CHECK_NE(kExplicit, constraint.type_);
   CHECK_NE(kConstant, constraint.type_);
-  CHECK_EQ(UnallocatedOperand::kInvalidVirtualRegister,
-           constraint.virtual_register_);
 }
 
 
 void RegisterAllocatorVerifier::VerifyOutput(
     const OperandConstraint& constraint) {
   CHECK_NE(kImmediate, constraint.type_);
-  CHECK_NE(UnallocatedOperand::kInvalidVirtualRegister,
+  CHECK_NE(kExplicit, constraint.type_);
+  CHECK_NE(InstructionOperand::kInvalidVirtualRegister,
            constraint.virtual_register_);
 }
 
@@ -61,9 +82,10 @@
   // Construct OperandConstraints for all InstructionOperands, eliminating
   // kSameAsFirst along the way.
   for (const auto* instr : sequence->instructions()) {
+    // All gaps should be totally unallocated at this point.
+    VerifyEmptyGaps(instr);
     const size_t operand_count = OperandCount(instr);
-    auto* op_constraints =
-        zone->NewArray<OperandConstraint>(static_cast<int>(operand_count));
+    auto* op_constraints = zone->NewArray<OperandConstraint>(operand_count);
     size_t count = 0;
     for (size_t i = 0; i < instr->InputCount(); ++i, ++count) {
       BuildConstraint(instr->InputAt(i), &op_constraints[count]);
@@ -82,11 +104,6 @@
       }
       VerifyOutput(op_constraints[count]);
     }
-    // All gaps should be totally unallocated at this point.
-    if (instr->IsGapMoves()) {
-      CHECK(operand_count == 0);
-      VerifyGapEmpty(GapInstruction::cast(instr));
-    }
     InstructionConstraint instr_constraint = {instr, operand_count,
                                               op_constraints};
     constraints()->push_back(instr_constraint);
@@ -99,6 +116,8 @@
   auto instr_it = sequence()->begin();
   for (const auto& instr_constraint : *constraints()) {
     const auto* instr = instr_constraint.instruction_;
+    // All gaps should be totally allocated at this point.
+    VerifyAllocatedGaps(instr);
     const size_t operand_count = instr_constraint.operand_constaints_size_;
     const auto* op_constraints = instr_constraint.operand_constraints_;
     CHECK_EQ(instr, *instr_it);
@@ -121,36 +140,44 @@
 void RegisterAllocatorVerifier::BuildConstraint(const InstructionOperand* op,
                                                 OperandConstraint* constraint) {
   constraint->value_ = kMinInt;
-  constraint->virtual_register_ = UnallocatedOperand::kInvalidVirtualRegister;
+  constraint->virtual_register_ = InstructionOperand::kInvalidVirtualRegister;
   if (op->IsConstant()) {
     constraint->type_ = kConstant;
-    constraint->value_ = ConstantOperand::cast(op)->index();
+    constraint->value_ = ConstantOperand::cast(op)->virtual_register();
     constraint->virtual_register_ = constraint->value_;
+  } else if (op->IsExplicit()) {
+    constraint->type_ = kExplicit;
   } else if (op->IsImmediate()) {
+    auto imm = ImmediateOperand::cast(op);
+    int value = imm->type() == ImmediateOperand::INLINE ? imm->inline_value()
+                                                        : imm->indexed_value();
     constraint->type_ = kImmediate;
-    constraint->value_ = ImmediateOperand::cast(op)->index();
+    constraint->value_ = value;
   } else {
     CHECK(op->IsUnallocated());
     const auto* unallocated = UnallocatedOperand::cast(op);
     int vreg = unallocated->virtual_register();
     constraint->virtual_register_ = vreg;
     if (unallocated->basic_policy() == UnallocatedOperand::FIXED_SLOT) {
-      constraint->type_ = kFixedSlot;
+      constraint->type_ = sequence()->IsFloat(vreg) ? kDoubleSlot : kSlot;
       constraint->value_ = unallocated->fixed_slot_index();
     } else {
       switch (unallocated->extended_policy()) {
         case UnallocatedOperand::ANY:
-          CHECK(false);
-          break;
         case UnallocatedOperand::NONE:
-          if (sequence()->IsDouble(vreg)) {
+          if (sequence()->IsFloat(vreg)) {
             constraint->type_ = kNoneDouble;
           } else {
             constraint->type_ = kNone;
           }
           break;
         case UnallocatedOperand::FIXED_REGISTER:
-          constraint->type_ = kFixedRegister;
+          if (unallocated->HasSecondaryStorage()) {
+            constraint->type_ = kRegisterAndSlot;
+            constraint->spilled_slot_ = unallocated->GetSecondaryStorage();
+          } else {
+            constraint->type_ = kFixedRegister;
+          }
           constraint->value_ = unallocated->fixed_register_index();
           break;
         case UnallocatedOperand::FIXED_DOUBLE_REGISTER:
@@ -158,12 +185,15 @@
           constraint->value_ = unallocated->fixed_register_index();
           break;
         case UnallocatedOperand::MUST_HAVE_REGISTER:
-          if (sequence()->IsDouble(vreg)) {
+          if (sequence()->IsFloat(vreg)) {
             constraint->type_ = kDoubleRegister;
           } else {
             constraint->type_ = kRegister;
           }
           break;
+        case UnallocatedOperand::MUST_HAVE_SLOT:
+          constraint->type_ = sequence()->IsFloat(vreg) ? kDoubleSlot : kSlot;
+          break;
         case UnallocatedOperand::SAME_AS_FIRST_INPUT:
           constraint->type_ = kSameAsFirst;
           break;
@@ -178,29 +208,47 @@
   switch (constraint->type_) {
     case kConstant:
       CHECK(op->IsConstant());
-      CHECK_EQ(op->index(), constraint->value_);
+      CHECK_EQ(ConstantOperand::cast(op)->virtual_register(),
+               constraint->value_);
       return;
-    case kImmediate:
+    case kImmediate: {
       CHECK(op->IsImmediate());
-      CHECK_EQ(op->index(), constraint->value_);
+      auto imm = ImmediateOperand::cast(op);
+      int value = imm->type() == ImmediateOperand::INLINE
+                      ? imm->inline_value()
+                      : imm->indexed_value();
+      CHECK_EQ(value, constraint->value_);
       return;
+    }
     case kRegister:
       CHECK(op->IsRegister());
       return;
-    case kFixedRegister:
-      CHECK(op->IsRegister());
-      CHECK_EQ(op->index(), constraint->value_);
-      return;
     case kDoubleRegister:
       CHECK(op->IsDoubleRegister());
       return;
+    case kExplicit:
+      CHECK(op->IsExplicit());
+      return;
+    case kFixedRegister:
+    case kRegisterAndSlot:
+      CHECK(op->IsRegister());
+      CHECK_EQ(LocationOperand::cast(op)->GetRegister().code(),
+               constraint->value_);
+      return;
     case kFixedDoubleRegister:
       CHECK(op->IsDoubleRegister());
-      CHECK_EQ(op->index(), constraint->value_);
+      CHECK_EQ(LocationOperand::cast(op)->GetDoubleRegister().code(),
+               constraint->value_);
       return;
     case kFixedSlot:
       CHECK(op->IsStackSlot());
-      CHECK_EQ(op->index(), constraint->value_);
+      CHECK_EQ(LocationOperand::cast(op)->index(), constraint->value_);
+      return;
+    case kSlot:
+      CHECK(op->IsStackSlot());
+      return;
+    case kDoubleSlot:
+      CHECK(op->IsDoubleStackSlot());
       return;
     case kNone:
       CHECK(op->IsRegister() || op->IsStackSlot());
@@ -214,227 +262,447 @@
   }
 }
 
+namespace {
 
-class RegisterAllocatorVerifier::OutgoingMapping : public ZoneObject {
+typedef RpoNumber Rpo;
+
+static const int kInvalidVreg = InstructionOperand::kInvalidVirtualRegister;
+
+struct PhiData : public ZoneObject {
+  PhiData(Rpo definition_rpo, const PhiInstruction* phi, int first_pred_vreg,
+          const PhiData* first_pred_phi, Zone* zone)
+      : definition_rpo(definition_rpo),
+        virtual_register(phi->virtual_register()),
+        first_pred_vreg(first_pred_vreg),
+        first_pred_phi(first_pred_phi),
+        operands(zone) {
+    operands.reserve(phi->operands().size());
+    operands.insert(operands.begin(), phi->operands().begin(),
+                    phi->operands().end());
+  }
+  const Rpo definition_rpo;
+  const int virtual_register;
+  const int first_pred_vreg;
+  const PhiData* first_pred_phi;
+  IntVector operands;
+};
+
+class PhiMap : public ZoneMap<int, PhiData*>, public ZoneObject {
  public:
-  struct OperandLess {
-    bool operator()(const InstructionOperand* a,
-                    const InstructionOperand* b) const {
-      if (a->kind() == b->kind()) return a->index() < b->index();
-      return a->kind() < b->kind();
+  explicit PhiMap(Zone* zone) : ZoneMap<int, PhiData*>(zone) {}
+};
+
+struct OperandLess {
+  bool operator()(const InstructionOperand* a,
+                  const InstructionOperand* b) const {
+    return a->CompareCanonicalized(*b);
+  }
+};
+
+class OperandMap : public ZoneObject {
+ public:
+  struct MapValue : public ZoneObject {
+    MapValue()
+        : incoming(nullptr),
+          define_vreg(kInvalidVreg),
+          use_vreg(kInvalidVreg),
+          succ_vreg(kInvalidVreg) {}
+    MapValue* incoming;  // value from first predecessor block.
+    int define_vreg;     // valid if this value was defined in this block.
+    int use_vreg;        // valid if this value was used in this block.
+    int succ_vreg;       // valid if propagated back from successor block.
+  };
+
+  class Map
+      : public ZoneMap<const InstructionOperand*, MapValue*, OperandLess> {
+   public:
+    explicit Map(Zone* zone)
+        : ZoneMap<const InstructionOperand*, MapValue*, OperandLess>(zone) {}
+
+    // Remove all entries with keys not in other.
+    void Intersect(const Map& other) {
+      if (this->empty()) return;
+      auto it = this->begin();
+      OperandLess less;
+      for (const auto& o : other) {
+        while (less(it->first, o.first)) {
+          this->erase(it++);
+          if (it == this->end()) return;
+        }
+        if (it->first->EqualsCanonicalized(*o.first)) {
+          ++it;
+          if (it == this->end()) return;
+        } else {
+          CHECK(less(o.first, it->first));
+        }
+      }
     }
   };
 
-  typedef std::map<
-      const InstructionOperand*, int, OperandLess,
-      zone_allocator<std::pair<const InstructionOperand*, const int>>>
-      LocationMap;
+  explicit OperandMap(Zone* zone) : map_(zone) {}
 
-  explicit OutgoingMapping(Zone* zone)
-      : locations_(LocationMap::key_compare(),
-                   LocationMap::allocator_type(zone)),
-        predecessor_intersection_(LocationMap::key_compare(),
-                                  LocationMap::allocator_type(zone)) {}
+  Map& map() { return map_; }
 
-  LocationMap* locations() { return &locations_; }
-
-  void RunPhis(const InstructionSequence* sequence,
-               const InstructionBlock* block, size_t phi_index) {
-    // This operation is only valid in edge split form.
-    size_t predecessor_index = block->predecessors()[phi_index].ToSize();
-    CHECK(sequence->instruction_blocks()[predecessor_index]->SuccessorCount() ==
-          1);
-    for (const auto* phi : block->phis()) {
-      auto input = phi->inputs()[phi_index];
-      CHECK(locations()->find(input) != locations()->end());
-      auto it = locations()->find(phi->output());
-      CHECK(it != locations()->end());
-      if (input->IsConstant()) {
-        CHECK_EQ(it->second, input->index());
-      } else {
-        CHECK_EQ(it->second, phi->operands()[phi_index]);
-      }
-      it->second = phi->virtual_register();
+  void RunParallelMoves(Zone* zone, const ParallelMove* moves) {
+    // Compute outgoing mappings.
+    Map to_insert(zone);
+    for (auto move : *moves) {
+      if (move->IsEliminated()) continue;
+      auto cur = map().find(&move->source());
+      CHECK(cur != map().end());
+      auto res =
+          to_insert.insert(std::make_pair(&move->destination(), cur->second));
+      // Ensure injectivity of moves.
+      CHECK(res.second);
     }
+    // Drop current mappings.
+    for (auto move : *moves) {
+      if (move->IsEliminated()) continue;
+      auto cur = map().find(&move->destination());
+      if (cur != map().end()) map().erase(cur);
+    }
+    // Insert new values.
+    map().insert(to_insert.begin(), to_insert.end());
   }
 
-  void RunGapInstruction(Zone* zone, const GapInstruction* gap) {
-    for (int i = GapInstruction::FIRST_INNER_POSITION;
-         i <= GapInstruction::LAST_INNER_POSITION; i++) {
-      GapInstruction::InnerPosition inner_pos =
-          static_cast<GapInstruction::InnerPosition>(i);
-      const ParallelMove* move = gap->GetParallelMove(inner_pos);
+  void RunGaps(Zone* zone, const Instruction* instr) {
+    for (int i = Instruction::FIRST_GAP_POSITION;
+         i <= Instruction::LAST_GAP_POSITION; i++) {
+      auto inner_pos = static_cast<Instruction::GapPosition>(i);
+      auto move = instr->GetParallelMove(inner_pos);
       if (move == nullptr) continue;
       RunParallelMoves(zone, move);
     }
   }
 
-  void RunParallelMoves(Zone* zone, const ParallelMove* move) {
-    // Compute outgoing mappings.
-    LocationMap to_insert((LocationMap::key_compare()),
-                          LocationMap::allocator_type(zone));
-    auto* moves = move->move_operands();
-    for (auto i = moves->begin(); i != moves->end(); ++i) {
-      if (i->IsEliminated()) continue;
-      auto cur = locations()->find(i->source());
-      CHECK(cur != locations()->end());
-      to_insert.insert(std::make_pair(i->destination(), cur->second));
-    }
-    // Drop current mappings.
-    for (auto i = moves->begin(); i != moves->end(); ++i) {
-      if (i->IsEliminated()) continue;
-      auto cur = locations()->find(i->destination());
-      if (cur != locations()->end()) locations()->erase(cur);
-    }
-    // Insert new values.
-    locations()->insert(to_insert.begin(), to_insert.end());
-  }
-
-  void Map(const InstructionOperand* op, int virtual_register) {
-    locations()->insert(std::make_pair(op, virtual_register));
-  }
-
   void Drop(const InstructionOperand* op) {
-    auto it = locations()->find(op);
-    if (it != locations()->end()) locations()->erase(it);
+    auto it = map().find(op);
+    if (it != map().end()) map().erase(it);
   }
 
   void DropRegisters(const RegisterConfiguration* config) {
-    for (int i = 0; i < config->num_general_registers(); ++i) {
-      InstructionOperand op(InstructionOperand::REGISTER, i);
-      Drop(&op);
-    }
-    for (int i = 0; i < config->num_double_registers(); ++i) {
-      InstructionOperand op(InstructionOperand::DOUBLE_REGISTER, i);
-      Drop(&op);
-    }
-  }
-
-  void InitializeFromFirstPredecessor(const InstructionSequence* sequence,
-                                      const OutgoingMappings* outgoing_mappings,
-                                      const InstructionBlock* block) {
-    if (block->predecessors().empty()) return;
-    size_t predecessor_index = block->predecessors()[0].ToSize();
-    CHECK(predecessor_index < block->rpo_number().ToSize());
-    auto* incoming = outgoing_mappings->at(predecessor_index);
-    if (block->PredecessorCount() > 1) {
-      // Update incoming map with phis. The remaining phis will be checked later
-      // as their mappings are not guaranteed to exist yet.
-      incoming->RunPhis(sequence, block, 0);
-    }
-    // Now initialize outgoing mapping for this block with incoming mapping.
-    CHECK(locations_.empty());
-    locations_ = incoming->locations_;
-  }
-
-  void InitializeFromIntersection() { locations_ = predecessor_intersection_; }
-
-  void InitializeIntersection(const OutgoingMapping* incoming) {
-    CHECK(predecessor_intersection_.empty());
-    predecessor_intersection_ = incoming->locations_;
-  }
-
-  void Intersect(const OutgoingMapping* other) {
-    if (predecessor_intersection_.empty()) return;
-    auto it = predecessor_intersection_.begin();
-    OperandLess less;
-    for (const auto& o : other->locations_) {
-      while (less(it->first, o.first)) {
+    // TODO(dcarney): sort map by kind and drop range.
+    for (auto it = map().begin(); it != map().end();) {
+      auto op = it->first;
+      if (op->IsRegister() || op->IsDoubleRegister()) {
+        map().erase(it++);
+      } else {
         ++it;
-        if (it == predecessor_intersection_.end()) return;
       }
-      if (it->first->Equals(o.first)) {
-        if (o.second != it->second) {
-          predecessor_intersection_.erase(it++);
-        } else {
-          ++it;
+    }
+  }
+
+  MapValue* Define(Zone* zone, const InstructionOperand* op,
+                   int virtual_register) {
+    auto value = new (zone) MapValue();
+    value->define_vreg = virtual_register;
+    auto res = map().insert(std::make_pair(op, value));
+    if (!res.second) res.first->second = value;
+    return value;
+  }
+
+  void Use(const InstructionOperand* op, int use_vreg, bool initial_pass) {
+    auto it = map().find(op);
+    CHECK(it != map().end());
+    auto v = it->second;
+    if (v->define_vreg != kInvalidVreg) {
+      CHECK_EQ(v->define_vreg, use_vreg);
+    }
+    // Already used this vreg in this block.
+    if (v->use_vreg != kInvalidVreg) {
+      CHECK_EQ(v->use_vreg, use_vreg);
+      return;
+    }
+    if (!initial_pass) {
+      // A value may be defined and used in this block or the use must have
+      // propagated up.
+      if (v->succ_vreg != kInvalidVreg) {
+        CHECK_EQ(v->succ_vreg, use_vreg);
+      } else {
+        CHECK_EQ(v->define_vreg, use_vreg);
+      }
+      // Mark the use.
+      it->second->use_vreg = use_vreg;
+      return;
+    }
+    // Go up block list and ensure the correct definition is reached.
+    for (; v != nullptr; v = v->incoming) {
+      // Value unused in block.
+      if (v->define_vreg == kInvalidVreg && v->use_vreg == kInvalidVreg) {
+        continue;
+      }
+      // Found correct definition or use.
+      CHECK(v->define_vreg == use_vreg || v->use_vreg == use_vreg);
+      // Mark the use.
+      it->second->use_vreg = use_vreg;
+      return;
+    }
+    // Use of a non-phi value without definition.
+    CHECK(false);
+  }
+
+  void UsePhi(const InstructionOperand* op, const PhiData* phi,
+              bool initial_pass) {
+    auto it = map().find(op);
+    CHECK(it != map().end());
+    auto v = it->second;
+    int use_vreg = phi->virtual_register;
+    // Phis are not defined.
+    CHECK_EQ(kInvalidVreg, v->define_vreg);
+    // Already used this vreg in this block.
+    if (v->use_vreg != kInvalidVreg) {
+      CHECK_EQ(v->use_vreg, use_vreg);
+      return;
+    }
+    if (!initial_pass) {
+      // A used phi must have propagated its use to a predecessor.
+      CHECK_EQ(v->succ_vreg, use_vreg);
+      // Mark the use.
+      v->use_vreg = use_vreg;
+      return;
+    }
+    // Go up the block list starting at the first predecessor and ensure this
+    // phi has a correct use or definition.
+    for (v = v->incoming; v != nullptr; v = v->incoming) {
+      // Value unused in block.
+      if (v->define_vreg == kInvalidVreg && v->use_vreg == kInvalidVreg) {
+        continue;
+      }
+      // Found correct definition or use.
+      if (v->define_vreg != kInvalidVreg) {
+        CHECK(v->define_vreg == phi->first_pred_vreg);
+      } else if (v->use_vreg != phi->first_pred_vreg) {
+        // Walk the phi chain, hunting for a matching phi use.
+        auto p = phi;
+        for (; p != nullptr; p = p->first_pred_phi) {
+          if (p->virtual_register == v->use_vreg) break;
         }
-        if (it == predecessor_intersection_.end()) return;
+        CHECK(p);
+      }
+      // Mark the use.
+      it->second->use_vreg = use_vreg;
+      return;
+    }
+    // Use of a phi value without definition.
+    UNREACHABLE();
+  }
+
+ private:
+  Map map_;
+  DISALLOW_COPY_AND_ASSIGN(OperandMap);
+};
+
+}  // namespace
+
+
+class RegisterAllocatorVerifier::BlockMaps {
+ public:
+  BlockMaps(Zone* zone, const InstructionSequence* sequence)
+      : zone_(zone),
+        sequence_(sequence),
+        phi_map_guard_(sequence->VirtualRegisterCount(), zone),
+        phi_map_(zone),
+        incoming_maps_(zone),
+        outgoing_maps_(zone) {
+    InitializePhis();
+    InitializeOperandMaps();
+  }
+
+  bool IsPhi(int virtual_register) {
+    return phi_map_guard_.Contains(virtual_register);
+  }
+
+  const PhiData* GetPhi(int virtual_register) {
+    auto it = phi_map_.find(virtual_register);
+    CHECK(it != phi_map_.end());
+    return it->second;
+  }
+
+  OperandMap* InitializeIncoming(size_t block_index, bool initial_pass) {
+    return initial_pass ? InitializeFromFirstPredecessor(block_index)
+                        : InitializeFromIntersection(block_index);
+  }
+
+  void PropagateUsesBackwards() {
+    typedef std::set<size_t, std::greater<size_t>, zone_allocator<size_t>>
+        BlockIds;
+    BlockIds block_ids((BlockIds::key_compare()),
+                       zone_allocator<size_t>(zone()));
+    // First ensure that incoming contains only keys in all predecessors.
+    for (auto block : sequence()->instruction_blocks()) {
+      size_t index = block->rpo_number().ToSize();
+      block_ids.insert(index);
+      auto& succ_map = incoming_maps_[index]->map();
+      for (size_t i = 0; i < block->PredecessorCount(); ++i) {
+        auto pred_rpo = block->predecessors()[i];
+        succ_map.Intersect(outgoing_maps_[pred_rpo.ToSize()]->map());
+      }
+    }
+    // Back propagation fixpoint.
+    while (!block_ids.empty()) {
+      // Pop highest block_id.
+      auto block_id_it = block_ids.begin();
+      const size_t succ_index = *block_id_it;
+      block_ids.erase(block_id_it);
+      // Propagate uses back to their definition blocks using succ_vreg.
+      auto block = sequence()->instruction_blocks()[succ_index];
+      auto& succ_map = incoming_maps_[succ_index]->map();
+      for (size_t i = 0; i < block->PredecessorCount(); ++i) {
+        for (auto& succ_val : succ_map) {
+          // An incoming map contains no defines.
+          CHECK_EQ(kInvalidVreg, succ_val.second->define_vreg);
+          // Compute succ_vreg.
+          int succ_vreg = succ_val.second->succ_vreg;
+          if (succ_vreg == kInvalidVreg) {
+            succ_vreg = succ_val.second->use_vreg;
+            // Initialize succ_vreg in back propagation chain.
+            succ_val.second->succ_vreg = succ_vreg;
+          }
+          if (succ_vreg == kInvalidVreg) continue;
+          // May need to transition phi.
+          if (IsPhi(succ_vreg)) {
+            auto phi = GetPhi(succ_vreg);
+            if (phi->definition_rpo.ToSize() == succ_index) {
+              // phi definition block, transition to pred value.
+              succ_vreg = phi->operands[i];
+            }
+          }
+          // Push succ_vreg up to all predecessors.
+          auto pred_rpo = block->predecessors()[i];
+          auto& pred_map = outgoing_maps_[pred_rpo.ToSize()]->map();
+          auto& pred_val = *pred_map.find(succ_val.first);
+          if (pred_val.second->use_vreg != kInvalidVreg) {
+            CHECK_EQ(succ_vreg, pred_val.second->use_vreg);
+          }
+          if (pred_val.second->define_vreg != kInvalidVreg) {
+            CHECK_EQ(succ_vreg, pred_val.second->define_vreg);
+          }
+          if (pred_val.second->succ_vreg != kInvalidVreg) {
+            CHECK_EQ(succ_vreg, pred_val.second->succ_vreg);
+          } else {
+            pred_val.second->succ_vreg = succ_vreg;
+            block_ids.insert(pred_rpo.ToSize());
+          }
+        }
+      }
+    }
+    // Clear uses and back links for second pass.
+    for (auto operand_map : incoming_maps_) {
+      for (auto& succ_val : operand_map->map()) {
+        succ_val.second->incoming = nullptr;
+        succ_val.second->use_vreg = kInvalidVreg;
       }
     }
   }
 
  private:
-  LocationMap locations_;
-  LocationMap predecessor_intersection_;
+  OperandMap* InitializeFromFirstPredecessor(size_t block_index) {
+    auto to_init = outgoing_maps_[block_index];
+    CHECK(to_init->map().empty());
+    auto block = sequence()->instruction_blocks()[block_index];
+    if (block->predecessors().empty()) return to_init;
+    size_t predecessor_index = block->predecessors()[0].ToSize();
+    // Ensure not a backedge.
+    CHECK(predecessor_index < block->rpo_number().ToSize());
+    auto incoming = outgoing_maps_[predecessor_index];
+    // Copy map and replace values.
+    to_init->map() = incoming->map();
+    for (auto& it : to_init->map()) {
+      auto incoming = it.second;
+      it.second = new (zone()) OperandMap::MapValue();
+      it.second->incoming = incoming;
+    }
+    // Copy to incoming map for second pass.
+    incoming_maps_[block_index]->map() = to_init->map();
+    return to_init;
+  }
 
-  DISALLOW_COPY_AND_ASSIGN(OutgoingMapping);
+  OperandMap* InitializeFromIntersection(size_t block_index) {
+    return incoming_maps_[block_index];
+  }
+
+  void InitializeOperandMaps() {
+    size_t block_count = sequence()->instruction_blocks().size();
+    incoming_maps_.reserve(block_count);
+    outgoing_maps_.reserve(block_count);
+    for (size_t i = 0; i < block_count; ++i) {
+      incoming_maps_.push_back(new (zone()) OperandMap(zone()));
+      outgoing_maps_.push_back(new (zone()) OperandMap(zone()));
+    }
+  }
+
+  void InitializePhis() {
+    const size_t block_count = sequence()->instruction_blocks().size();
+    for (size_t block_index = 0; block_index < block_count; ++block_index) {
+      const auto block = sequence()->instruction_blocks()[block_index];
+      for (auto phi : block->phis()) {
+        int first_pred_vreg = phi->operands()[0];
+        const PhiData* first_pred_phi = nullptr;
+        if (IsPhi(first_pred_vreg)) {
+          first_pred_phi = GetPhi(first_pred_vreg);
+          first_pred_vreg = first_pred_phi->first_pred_vreg;
+        }
+        CHECK(!IsPhi(first_pred_vreg));
+        auto phi_data = new (zone()) PhiData(
+            block->rpo_number(), phi, first_pred_vreg, first_pred_phi, zone());
+        auto res =
+            phi_map_.insert(std::make_pair(phi->virtual_register(), phi_data));
+        CHECK(res.second);
+        phi_map_guard_.Add(phi->virtual_register());
+      }
+    }
+  }
+
+  typedef ZoneVector<OperandMap*> OperandMaps;
+  typedef ZoneVector<PhiData*> PhiVector;
+
+  Zone* zone() const { return zone_; }
+  const InstructionSequence* sequence() const { return sequence_; }
+
+  Zone* const zone_;
+  const InstructionSequence* const sequence_;
+  BitVector phi_map_guard_;
+  PhiMap phi_map_;
+  OperandMaps incoming_maps_;
+  OperandMaps outgoing_maps_;
 };
 
 
-// Verify that all gap moves move the operands for a virtual register into the
-// correct location for every instruction.
 void RegisterAllocatorVerifier::VerifyGapMoves() {
-  typedef ZoneVector<OutgoingMapping*> OutgoingMappings;
-  OutgoingMappings outgoing_mappings(
-      static_cast<int>(sequence()->instruction_blocks().size()), nullptr,
-      zone());
-  // Construct all mappings, ignoring back edges and multiple entries.
-  ConstructOutgoingMappings(&outgoing_mappings, true);
-  // Run all remaining phis and compute the intersection of all predecessor
-  // mappings.
-  for (const auto* block : sequence()->instruction_blocks()) {
-    if (block->PredecessorCount() == 0) continue;
-    const size_t block_index = block->rpo_number().ToSize();
-    auto* mapping = outgoing_mappings[block_index];
-    bool initialized = false;
-    // Walk predecessors in reverse to ensure Intersect is correctly working.
-    // If it did nothing, the second pass would do exactly what the first pass
-    // did.
-    for (size_t phi_input = block->PredecessorCount() - 1; true; --phi_input) {
-      const size_t pred_block_index = block->predecessors()[phi_input].ToSize();
-      auto* incoming = outgoing_mappings[pred_block_index];
-      if (phi_input != 0) incoming->RunPhis(sequence(), block, phi_input);
-      if (!initialized) {
-        mapping->InitializeIntersection(incoming);
-        initialized = true;
-      } else {
-        mapping->Intersect(incoming);
-      }
-      if (phi_input == 0) break;
-    }
-  }
-  // Construct all mappings again, this time using the instersection mapping
-  // above as the incoming mapping instead of the result from the first
-  // predecessor.
-  ConstructOutgoingMappings(&outgoing_mappings, false);
+  BlockMaps block_maps(zone(), sequence());
+  VerifyGapMoves(&block_maps, true);
+  block_maps.PropagateUsesBackwards();
+  VerifyGapMoves(&block_maps, false);
 }
 
 
-void RegisterAllocatorVerifier::ConstructOutgoingMappings(
-    OutgoingMappings* outgoing_mappings, bool initial_pass) {
-  // Compute the locations of all virtual registers leaving every block, using
-  // only the first predecessor as source for the input mapping.
-  for (const auto* block : sequence()->instruction_blocks()) {
-    const size_t block_index = block->rpo_number().ToSize();
-    auto* current = outgoing_mappings->at(block_index);
-    CHECK(initial_pass == (current == nullptr));
-    // Initialize current.
-    if (!initial_pass) {
-      // Skip check second time around for blocks without multiple predecessors
-      // as we have already executed this in the initial run.
-      if (block->PredecessorCount() <= 1) continue;
-      current->InitializeFromIntersection();
-    } else {
-      current = new (zone()) OutgoingMapping(zone());
-      outgoing_mappings->at(block_index) = current;
-      // Copy outgoing values from predecessor block.
-      current->InitializeFromFirstPredecessor(sequence(), outgoing_mappings,
-                                              block);
-    }
-    // Update current with gaps and operands for all instructions in block.
+// Compute and verify outgoing values for every block.
+void RegisterAllocatorVerifier::VerifyGapMoves(BlockMaps* block_maps,
+                                               bool initial_pass) {
+  const size_t block_count = sequence()->instruction_blocks().size();
+  for (size_t block_index = 0; block_index < block_count; ++block_index) {
+    auto current = block_maps->InitializeIncoming(block_index, initial_pass);
+    const auto block = sequence()->instruction_blocks()[block_index];
     for (int instr_index = block->code_start(); instr_index < block->code_end();
          ++instr_index) {
       const auto& instr_constraint = constraints_[instr_index];
-      const auto* instr = instr_constraint.instruction_;
-      const auto* op_constraints = instr_constraint.operand_constraints_;
+      const auto instr = instr_constraint.instruction_;
+      current->RunGaps(zone(), instr);
+      const auto op_constraints = instr_constraint.operand_constraints_;
       size_t count = 0;
       for (size_t i = 0; i < instr->InputCount(); ++i, ++count) {
-        if (op_constraints[count].type_ == kImmediate) continue;
-        auto it = current->locations()->find(instr->InputAt(i));
+        if (op_constraints[count].type_ == kImmediate ||
+            op_constraints[count].type_ == kExplicit) {
+          continue;
+        }
         int virtual_register = op_constraints[count].virtual_register_;
-        CHECK(it != current->locations()->end());
-        CHECK_EQ(it->second, virtual_register);
+        auto op = instr->InputAt(i);
+        if (!block_maps->IsPhi(virtual_register)) {
+          current->Use(op, virtual_register, initial_pass);
+        } else {
+          auto phi = block_maps->GetPhi(virtual_register);
+          current->UsePhi(op, phi, initial_pass);
+        }
       }
       for (size_t i = 0; i < instr->TempCount(); ++i, ++count) {
         current->Drop(instr->TempAt(i));
@@ -443,13 +711,21 @@
         current->DropRegisters(config());
       }
       for (size_t i = 0; i < instr->OutputCount(); ++i, ++count) {
-        current->Drop(instr->OutputAt(i));
         int virtual_register = op_constraints[count].virtual_register_;
-        current->Map(instr->OutputAt(i), virtual_register);
-      }
-      if (instr->IsGapMoves()) {
-        const auto* gap = GapInstruction::cast(instr);
-        current->RunGapInstruction(zone(), gap);
+        OperandMap::MapValue* value =
+            current->Define(zone(), instr->OutputAt(i), virtual_register);
+        if (op_constraints[count].type_ == kRegisterAndSlot) {
+          const AllocatedOperand* reg_op =
+              AllocatedOperand::cast(instr->OutputAt(i));
+          MachineRepresentation rep = reg_op->representation();
+          const AllocatedOperand* stack_op = AllocatedOperand::New(
+              zone(), LocationOperand::LocationKind::STACK_SLOT, rep,
+              op_constraints[i].spilled_slot_);
+          auto insert_result =
+              current->map().insert(std::make_pair(stack_op, value));
+          DCHECK(insert_result.second);
+          USE(insert_result);
+        }
       }
     }
   }
diff --git a/src/compiler/register-allocator-verifier.h b/src/compiler/register-allocator-verifier.h
index 4e35dc2..f3ab54f 100644
--- a/src/compiler/register-allocator-verifier.h
+++ b/src/compiler/register-allocator-verifier.h
@@ -5,7 +5,6 @@
 #ifndef V8_REGISTER_ALLOCATOR_VERIFIER_H_
 #define V8_REGISTER_ALLOCATOR_VERIFIER_H_
 
-#include "src/v8.h"
 #include "src/zone-containers.h"
 
 namespace v8 {
@@ -15,7 +14,7 @@
 class InstructionOperand;
 class InstructionSequence;
 
-class RegisterAllocatorVerifier FINAL : public ZoneObject {
+class RegisterAllocatorVerifier final : public ZoneObject {
  public:
   RegisterAllocatorVerifier(Zone* zone, const RegisterConfiguration* config,
                             const InstructionSequence* sequence);
@@ -31,15 +30,20 @@
     kFixedRegister,
     kDoubleRegister,
     kFixedDoubleRegister,
+    kSlot,
+    kDoubleSlot,
     kFixedSlot,
     kNone,
     kNoneDouble,
-    kSameAsFirst
+    kExplicit,
+    kSameAsFirst,
+    kRegisterAndSlot
   };
 
   struct OperandConstraint {
     ConstraintType type_;
     int value_;  // subkind index when relevant
+    int spilled_slot_;
     int virtual_register_;
   };
 
@@ -49,10 +53,9 @@
     OperandConstraint* operand_constraints_;
   };
 
-  class OutgoingMapping;
+  class BlockMaps;
 
   typedef ZoneVector<InstructionConstraint> Constraints;
-  typedef ZoneVector<OutgoingMapping*> OutgoingMappings;
 
   Zone* zone() const { return zone_; }
   const RegisterConfiguration* config() { return config_; }
@@ -68,8 +71,7 @@
   void CheckConstraint(const InstructionOperand* op,
                        const OperandConstraint* constraint);
 
-  void ConstructOutgoingMappings(OutgoingMappings* outgoing_mappings,
-                                 bool initial_pass);
+  void VerifyGapMoves(BlockMaps* outgoing_mappings, bool initial_pass);
 
   Zone* const zone_;
   const RegisterConfiguration* config_;
diff --git a/src/compiler/register-allocator.cc b/src/compiler/register-allocator.cc
index 9eb4a47..232ad9f 100644
--- a/src/compiler/register-allocator.cc
+++ b/src/compiler/register-allocator.cc
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "src/base/adapters.h"
 #include "src/compiler/linkage.h"
 #include "src/compiler/register-allocator.h"
 #include "src/string-stream.h"
@@ -10,198 +11,343 @@
 namespace internal {
 namespace compiler {
 
-static inline LifetimePosition Min(LifetimePosition a, LifetimePosition b) {
-  return a.Value() < b.Value() ? a : b;
-}
+#define TRACE(...)                             \
+  do {                                         \
+    if (FLAG_trace_alloc) PrintF(__VA_ARGS__); \
+  } while (false)
 
 
-static inline LifetimePosition Max(LifetimePosition a, LifetimePosition b) {
-  return a.Value() > b.Value() ? a : b;
-}
+namespace {
 
-
-static void TraceAlloc(const char* msg, ...) {
-  if (FLAG_trace_alloc) {
-    va_list arguments;
-    va_start(arguments, msg);
-    base::OS::VPrint(msg, arguments);
-    va_end(arguments);
-  }
-}
-
-
-static void RemoveElement(ZoneVector<LiveRange*>* v, LiveRange* range) {
+void RemoveElement(ZoneVector<LiveRange*>* v, LiveRange* range) {
   auto it = std::find(v->begin(), v->end(), range);
   DCHECK(it != v->end());
   v->erase(it);
 }
 
 
-UsePosition::UsePosition(LifetimePosition pos, InstructionOperand* operand,
-                         InstructionOperand* hint)
-    : operand_(operand),
-      hint_(hint),
-      pos_(pos),
-      next_(nullptr),
-      requires_reg_(false),
-      register_beneficial_(true) {
-  if (operand_ != nullptr && operand_->IsUnallocated()) {
-    const UnallocatedOperand* unalloc = UnallocatedOperand::cast(operand_);
-    requires_reg_ = unalloc->HasRegisterPolicy();
-    register_beneficial_ = !unalloc->HasAnyPolicy();
-  }
-  DCHECK(pos_.IsValid());
+int GetRegisterCount(const RegisterConfiguration* cfg, RegisterKind kind) {
+  return kind == DOUBLE_REGISTERS ? cfg->num_double_registers()
+                                  : cfg->num_general_registers();
 }
 
 
-bool UsePosition::HasHint() const {
-  return hint_ != nullptr && !hint_->IsUnallocated();
+int GetAllocatableRegisterCount(const RegisterConfiguration* cfg,
+                                RegisterKind kind) {
+  return kind == DOUBLE_REGISTERS
+             ? cfg->num_allocatable_aliased_double_registers()
+             : cfg->num_allocatable_general_registers();
 }
 
 
-bool UsePosition::RequiresRegister() const { return requires_reg_; }
-
-
-bool UsePosition::RegisterIsBeneficial() const { return register_beneficial_; }
-
-
-void UseInterval::SplitAt(LifetimePosition pos, Zone* zone) {
-  DCHECK(Contains(pos) && pos.Value() != start().Value());
-  auto after = new (zone) UseInterval(pos, end_);
-  after->next_ = next_;
-  next_ = after;
-  end_ = pos;
+const int* GetAllocatableRegisterCodes(const RegisterConfiguration* cfg,
+                                       RegisterKind kind) {
+  return kind == DOUBLE_REGISTERS ? cfg->allocatable_double_codes()
+                                  : cfg->allocatable_general_codes();
 }
 
 
-struct LiveRange::SpillAtDefinitionList : ZoneObject {
-  SpillAtDefinitionList(int gap_index, InstructionOperand* operand,
-                        SpillAtDefinitionList* next)
-      : gap_index(gap_index), operand(operand), next(next) {}
-  const int gap_index;
-  InstructionOperand* const operand;
-  SpillAtDefinitionList* const next;
-};
-
-
-#ifdef DEBUG
-
-
-void LiveRange::Verify() const {
-  UsePosition* cur = first_pos_;
-  while (cur != nullptr) {
-    DCHECK(Start().Value() <= cur->pos().Value() &&
-           cur->pos().Value() <= End().Value());
-    cur = cur->next();
-  }
+const InstructionBlock* GetContainingLoop(const InstructionSequence* sequence,
+                                          const InstructionBlock* block) {
+  RpoNumber index = block->loop_header();
+  if (!index.IsValid()) return nullptr;
+  return sequence->InstructionBlockAt(index);
 }
 
 
-bool LiveRange::HasOverlap(UseInterval* target) const {
-  UseInterval* current_interval = first_interval_;
-  while (current_interval != nullptr) {
-    // Intervals overlap if the start of one is contained in the other.
-    if (current_interval->Contains(target->start()) ||
-        target->Contains(current_interval->start())) {
+const InstructionBlock* GetInstructionBlock(const InstructionSequence* code,
+                                            LifetimePosition pos) {
+  return code->GetInstructionBlock(pos.ToInstructionIndex());
+}
+
+
+Instruction* GetLastInstruction(InstructionSequence* code,
+                                const InstructionBlock* block) {
+  return code->InstructionAt(block->last_instruction_index());
+}
+
+
+bool IsOutputRegisterOf(Instruction* instr, Register reg) {
+  for (size_t i = 0; i < instr->OutputCount(); i++) {
+    InstructionOperand* output = instr->OutputAt(i);
+    if (output->IsRegister() &&
+        LocationOperand::cast(output)->GetRegister().is(reg)) {
       return true;
     }
-    current_interval = current_interval->next();
   }
   return false;
 }
 
 
-#endif
+bool IsOutputDoubleRegisterOf(Instruction* instr, DoubleRegister reg) {
+  for (size_t i = 0; i < instr->OutputCount(); i++) {
+    InstructionOperand* output = instr->OutputAt(i);
+    if (output->IsDoubleRegister() &&
+        LocationOperand::cast(output)->GetDoubleRegister().is(reg)) {
+      return true;
+    }
+  }
+  return false;
+}
 
 
-LiveRange::LiveRange(int id, Zone* zone)
-    : id_(id),
-      spilled_(false),
-      is_phi_(false),
-      is_non_loop_phi_(false),
-      kind_(UNALLOCATED_REGISTERS),
-      assigned_register_(kInvalidAssignment),
+// TODO(dcarney): fix frame to allow frame accesses to half size location.
+int GetByteWidth(MachineRepresentation rep) {
+  switch (rep) {
+    case MachineRepresentation::kBit:
+    case MachineRepresentation::kWord8:
+    case MachineRepresentation::kWord16:
+    case MachineRepresentation::kWord32:
+    case MachineRepresentation::kTagged:
+      return kPointerSize;
+    case MachineRepresentation::kFloat32:
+    case MachineRepresentation::kWord64:
+    case MachineRepresentation::kFloat64:
+      return 8;
+    case MachineRepresentation::kNone:
+      break;
+  }
+  UNREACHABLE();
+  return 0;
+}
+
+}  // namespace
+
+
+UsePosition::UsePosition(LifetimePosition pos, InstructionOperand* operand,
+                         void* hint, UsePositionHintType hint_type)
+    : operand_(operand), hint_(hint), next_(nullptr), pos_(pos), flags_(0) {
+  DCHECK_IMPLIES(hint == nullptr, hint_type == UsePositionHintType::kNone);
+  bool register_beneficial = true;
+  UsePositionType type = UsePositionType::kAny;
+  if (operand_ != nullptr && operand_->IsUnallocated()) {
+    const UnallocatedOperand* unalloc = UnallocatedOperand::cast(operand_);
+    if (unalloc->HasRegisterPolicy()) {
+      type = UsePositionType::kRequiresRegister;
+    } else if (unalloc->HasSlotPolicy()) {
+      type = UsePositionType::kRequiresSlot;
+      register_beneficial = false;
+    } else {
+      register_beneficial = !unalloc->HasAnyPolicy();
+    }
+  }
+  flags_ = TypeField::encode(type) | HintTypeField::encode(hint_type) |
+           RegisterBeneficialField::encode(register_beneficial) |
+           AssignedRegisterField::encode(kUnassignedRegister);
+  DCHECK(pos_.IsValid());
+}
+
+
+bool UsePosition::HasHint() const {
+  int hint_register;
+  return HintRegister(&hint_register);
+}
+
+
+bool UsePosition::HintRegister(int* register_code) const {
+  if (hint_ == nullptr) return false;
+  switch (HintTypeField::decode(flags_)) {
+    case UsePositionHintType::kNone:
+    case UsePositionHintType::kUnresolved:
+      return false;
+    case UsePositionHintType::kUsePos: {
+      UsePosition* use_pos = reinterpret_cast<UsePosition*>(hint_);
+      int assigned_register = AssignedRegisterField::decode(use_pos->flags_);
+      if (assigned_register == kUnassignedRegister) return false;
+      *register_code = assigned_register;
+      return true;
+    }
+    case UsePositionHintType::kOperand: {
+      InstructionOperand* operand =
+          reinterpret_cast<InstructionOperand*>(hint_);
+      int assigned_register =
+          operand->IsRegister()
+              ? LocationOperand::cast(operand)->GetRegister().code()
+              : LocationOperand::cast(operand)->GetDoubleRegister().code();
+      *register_code = assigned_register;
+      return true;
+    }
+    case UsePositionHintType::kPhi: {
+      RegisterAllocationData::PhiMapValue* phi =
+          reinterpret_cast<RegisterAllocationData::PhiMapValue*>(hint_);
+      int assigned_register = phi->assigned_register();
+      if (assigned_register == kUnassignedRegister) return false;
+      *register_code = assigned_register;
+      return true;
+    }
+  }
+  UNREACHABLE();
+  return false;
+}
+
+
+UsePositionHintType UsePosition::HintTypeForOperand(
+    const InstructionOperand& op) {
+  switch (op.kind()) {
+    case InstructionOperand::CONSTANT:
+    case InstructionOperand::IMMEDIATE:
+    case InstructionOperand::EXPLICIT:
+      return UsePositionHintType::kNone;
+    case InstructionOperand::UNALLOCATED:
+      return UsePositionHintType::kUnresolved;
+    case InstructionOperand::ALLOCATED:
+      if (op.IsRegister() || op.IsDoubleRegister()) {
+        return UsePositionHintType::kOperand;
+      } else {
+        DCHECK(op.IsStackSlot() || op.IsDoubleStackSlot());
+        return UsePositionHintType::kNone;
+      }
+    case InstructionOperand::INVALID:
+      break;
+  }
+  UNREACHABLE();
+  return UsePositionHintType::kNone;
+}
+
+
+void UsePosition::ResolveHint(UsePosition* use_pos) {
+  DCHECK_NOT_NULL(use_pos);
+  if (HintTypeField::decode(flags_) != UsePositionHintType::kUnresolved) return;
+  hint_ = use_pos;
+  flags_ = HintTypeField::update(flags_, UsePositionHintType::kUsePos);
+}
+
+
+void UsePosition::set_type(UsePositionType type, bool register_beneficial) {
+  DCHECK_IMPLIES(type == UsePositionType::kRequiresSlot, !register_beneficial);
+  DCHECK_EQ(kUnassignedRegister, AssignedRegisterField::decode(flags_));
+  flags_ = TypeField::encode(type) |
+           RegisterBeneficialField::encode(register_beneficial) |
+           HintTypeField::encode(HintTypeField::decode(flags_)) |
+           AssignedRegisterField::encode(kUnassignedRegister);
+}
+
+
+UseInterval* UseInterval::SplitAt(LifetimePosition pos, Zone* zone) {
+  DCHECK(Contains(pos) && pos != start());
+  UseInterval* after = new (zone) UseInterval(pos, end_);
+  after->next_ = next_;
+  next_ = nullptr;
+  end_ = pos;
+  return after;
+}
+
+
+void LifetimePosition::Print() const {
+  OFStream os(stdout);
+  os << *this << std::endl;
+}
+
+
+std::ostream& operator<<(std::ostream& os, const LifetimePosition pos) {
+  os << '@' << pos.ToInstructionIndex();
+  if (pos.IsGapPosition()) {
+    os << 'g';
+  } else {
+    os << 'i';
+  }
+  if (pos.IsStart()) {
+    os << 's';
+  } else {
+    os << 'e';
+  }
+  return os;
+}
+
+
+const float LiveRange::kInvalidWeight = -1;
+const float LiveRange::kMaxWeight = std::numeric_limits<float>::max();
+
+
+LiveRange::LiveRange(int relative_id, MachineRepresentation rep,
+                     TopLevelLiveRange* top_level)
+    : relative_id_(relative_id),
+      bits_(0),
       last_interval_(nullptr),
       first_interval_(nullptr),
       first_pos_(nullptr),
-      parent_(nullptr),
+      top_level_(top_level),
       next_(nullptr),
       current_interval_(nullptr),
       last_processed_use_(nullptr),
-      current_hint_operand_(nullptr),
-      spill_start_index_(kMaxInt),
-      spill_type_(SpillType::kNoSpillType),
-      spill_operand_(nullptr),
-      spills_at_definition_(nullptr) {}
-
-
-void LiveRange::set_assigned_register(int reg, Zone* zone) {
-  DCHECK(!HasRegisterAssigned() && !IsSpilled());
-  assigned_register_ = reg;
-  // TODO(dcarney): stop aliasing hint operands.
-  ConvertUsesToOperand(CreateAssignedOperand(zone));
+      current_hint_position_(nullptr),
+      splitting_pointer_(nullptr),
+      size_(kInvalidSize),
+      weight_(kInvalidWeight),
+      group_(nullptr) {
+  DCHECK(AllocatedOperand::IsSupportedRepresentation(rep));
+  bits_ = AssignedRegisterField::encode(kUnassignedRegister) |
+          RepresentationField::encode(rep);
 }
 
 
-void LiveRange::MakeSpilled() {
-  DCHECK(!IsSpilled());
-  DCHECK(!TopLevel()->HasNoSpillType());
-  spilled_ = true;
-  assigned_register_ = kInvalidAssignment;
-}
-
-
-void LiveRange::SpillAtDefinition(Zone* zone, int gap_index,
-                                  InstructionOperand* operand) {
-  DCHECK(HasNoSpillType());
-  spills_at_definition_ = new (zone)
-      SpillAtDefinitionList(gap_index, operand, spills_at_definition_);
-}
-
-
-void LiveRange::CommitSpillsAtDefinition(InstructionSequence* sequence,
-                                         InstructionOperand* op) {
-  auto to_spill = TopLevel()->spills_at_definition_;
-  if (to_spill == nullptr) return;
-  auto zone = sequence->zone();
-  for (; to_spill != nullptr; to_spill = to_spill->next) {
-    auto gap = sequence->GapAt(to_spill->gap_index);
-    auto move = gap->GetOrCreateParallelMove(GapInstruction::START, zone);
-    move->AddMove(to_spill->operand, op, zone);
+void LiveRange::VerifyPositions() const {
+  // Walk the positions, verifying that each is in an interval.
+  UseInterval* interval = first_interval_;
+  for (UsePosition* pos = first_pos_; pos != nullptr; pos = pos->next()) {
+    CHECK(Start() <= pos->pos());
+    CHECK(pos->pos() <= End());
+    CHECK_NOT_NULL(interval);
+    while (!interval->Contains(pos->pos()) && interval->end() != pos->pos()) {
+      interval = interval->next();
+      CHECK_NOT_NULL(interval);
+    }
   }
-  TopLevel()->spills_at_definition_ = nullptr;
 }
 
 
-void LiveRange::SetSpillOperand(InstructionOperand* operand) {
-  DCHECK(HasNoSpillType());
-  DCHECK(!operand->IsUnallocated());
-  spill_type_ = SpillType::kSpillOperand;
-  spill_operand_ = operand;
+void LiveRange::VerifyIntervals() const {
+  DCHECK(first_interval()->start() == Start());
+  LifetimePosition last_end = first_interval()->end();
+  for (UseInterval* interval = first_interval()->next(); interval != nullptr;
+       interval = interval->next()) {
+    DCHECK(last_end <= interval->start());
+    last_end = interval->end();
+  }
+  DCHECK(last_end == End());
 }
 
 
-void LiveRange::SetSpillRange(SpillRange* spill_range) {
-  DCHECK(HasNoSpillType() || HasSpillRange());
-  DCHECK_NE(spill_range, nullptr);
-  spill_type_ = SpillType::kSpillRange;
-  spill_range_ = spill_range;
+void LiveRange::set_assigned_register(int reg) {
+  DCHECK(!HasRegisterAssigned() && !spilled());
+  bits_ = AssignedRegisterField::update(bits_, reg);
 }
 
 
-void LiveRange::CommitSpillOperand(InstructionOperand* operand) {
-  DCHECK(HasSpillRange());
-  DCHECK(!operand->IsUnallocated());
-  DCHECK(!IsChild());
-  spill_type_ = SpillType::kSpillOperand;
-  spill_operand_ = operand;
+void LiveRange::UnsetAssignedRegister() {
+  DCHECK(HasRegisterAssigned() && !spilled());
+  bits_ = AssignedRegisterField::update(bits_, kUnassignedRegister);
 }
 
 
-UsePosition* LiveRange::NextUsePosition(LifetimePosition start) {
+void LiveRange::Spill() {
+  DCHECK(!spilled());
+  DCHECK(!TopLevel()->HasNoSpillType());
+  set_spilled(true);
+  bits_ = AssignedRegisterField::update(bits_, kUnassignedRegister);
+}
+
+
+RegisterKind LiveRange::kind() const {
+  return IsFloatingPoint(representation()) ? DOUBLE_REGISTERS
+                                           : GENERAL_REGISTERS;
+}
+
+
+UsePosition* LiveRange::FirstHintPosition(int* register_index) const {
+  for (UsePosition* pos = first_pos_; pos != nullptr; pos = pos->next()) {
+    if (pos->HintRegister(register_index)) return pos;
+  }
+  return nullptr;
+}
+
+
+UsePosition* LiveRange::NextUsePosition(LifetimePosition start) const {
   UsePosition* use_pos = last_processed_use_;
-  if (use_pos == nullptr) use_pos = first_pos();
-  while (use_pos != nullptr && use_pos->pos().Value() < start.Value()) {
+  if (use_pos == nullptr || use_pos->pos() > start) {
+    use_pos = first_pos();
+  }
+  while (use_pos != nullptr && use_pos->pos() < start) {
     use_pos = use_pos->next();
   }
   last_processed_use_ = use_pos;
@@ -210,7 +356,7 @@
 
 
 UsePosition* LiveRange::NextUsePositionRegisterIsBeneficial(
-    LifetimePosition start) {
+    LifetimePosition start) const {
   UsePosition* pos = NextUsePosition(start);
   while (pos != nullptr && !pos->RegisterIsBeneficial()) {
     pos = pos->next();
@@ -220,10 +366,10 @@
 
 
 UsePosition* LiveRange::PreviousUsePositionRegisterIsBeneficial(
-    LifetimePosition start) {
-  auto pos = first_pos();
+    LifetimePosition start) const {
+  UsePosition* pos = first_pos();
   UsePosition* prev = nullptr;
-  while (pos != nullptr && pos->pos().Value() < start.Value()) {
+  while (pos != nullptr && pos->pos() < start) {
     if (pos->RegisterIsBeneficial()) prev = pos;
     pos = pos->next();
   }
@@ -231,53 +377,58 @@
 }
 
 
-UsePosition* LiveRange::NextRegisterPosition(LifetimePosition start) {
+UsePosition* LiveRange::NextRegisterPosition(LifetimePosition start) const {
   UsePosition* pos = NextUsePosition(start);
-  while (pos != nullptr && !pos->RequiresRegister()) {
+  while (pos != nullptr && pos->type() != UsePositionType::kRequiresRegister) {
     pos = pos->next();
   }
   return pos;
 }
 
 
-bool LiveRange::CanBeSpilled(LifetimePosition pos) {
-  // We cannot spill a live range that has a use requiring a register
-  // at the current or the immediate next position.
-  auto use_pos = NextRegisterPosition(pos);
-  if (use_pos == nullptr) return true;
-  return use_pos->pos().Value() >
-         pos.NextInstruction().InstructionEnd().Value();
+UsePosition* LiveRange::NextSlotPosition(LifetimePosition start) const {
+  for (UsePosition* pos = NextUsePosition(start); pos != nullptr;
+       pos = pos->next()) {
+    if (pos->type() != UsePositionType::kRequiresSlot) continue;
+    return pos;
+  }
+  return nullptr;
 }
 
 
-InstructionOperand* LiveRange::CreateAssignedOperand(Zone* zone) const {
-  InstructionOperand* op = nullptr;
+bool LiveRange::CanBeSpilled(LifetimePosition pos) const {
+  // We cannot spill a live range that has a use requiring a register
+  // at the current or the immediate next position.
+  UsePosition* use_pos = NextRegisterPosition(pos);
+  if (use_pos == nullptr) return true;
+  return use_pos->pos() > pos.NextStart().End();
+}
+
+
+bool LiveRange::IsTopLevel() const { return top_level_ == this; }
+
+
+InstructionOperand LiveRange::GetAssignedOperand() const {
   if (HasRegisterAssigned()) {
-    DCHECK(!IsSpilled());
-    switch (Kind()) {
-      case GENERAL_REGISTERS:
-        op = RegisterOperand::Create(assigned_register(), zone);
-        break;
-      case DOUBLE_REGISTERS:
-        op = DoubleRegisterOperand::Create(assigned_register(), zone);
-        break;
-      default:
-        UNREACHABLE();
-    }
-  } else {
-    DCHECK(IsSpilled());
-    DCHECK(!HasRegisterAssigned());
-    op = TopLevel()->GetSpillOperand();
-    DCHECK(!op->IsUnallocated());
+    DCHECK(!spilled());
+    return AllocatedOperand(LocationOperand::REGISTER, representation(),
+                            assigned_register());
   }
-  return op;
+  DCHECK(spilled());
+  DCHECK(!HasRegisterAssigned());
+  if (TopLevel()->HasSpillOperand()) {
+    InstructionOperand* op = TopLevel()->GetSpillOperand();
+    DCHECK(!op->IsUnallocated());
+    return *op;
+  }
+  return TopLevel()->GetSpillRangeOperand();
 }
 
 
 UseInterval* LiveRange::FirstSearchIntervalForPosition(
     LifetimePosition position) const {
   if (current_interval_ == nullptr) return first_interval_;
-  if (current_interval_->start().Value() > position.Value()) {
+  if (current_interval_->start() > position) {
     current_interval_ = nullptr;
     return first_interval_;
   }
@@ -288,49 +439,66 @@
 void LiveRange::AdvanceLastProcessedMarker(
     UseInterval* to_start_of, LifetimePosition but_not_past) const {
   if (to_start_of == nullptr) return;
-  if (to_start_of->start().Value() > but_not_past.Value()) return;
-  auto start = current_interval_ == nullptr ? LifetimePosition::Invalid()
-                                            : current_interval_->start();
-  if (to_start_of->start().Value() > start.Value()) {
+  if (to_start_of->start() > but_not_past) return;
+  LifetimePosition start = current_interval_ == nullptr
+                               ? LifetimePosition::Invalid()
+                               : current_interval_->start();
+  if (to_start_of->start() > start) {
     current_interval_ = to_start_of;
   }
 }
 
 
-void LiveRange::SplitAt(LifetimePosition position, LiveRange* result,
-                        Zone* zone) {
-  DCHECK(Start().Value() < position.Value());
+LiveRange* LiveRange::SplitAt(LifetimePosition position, Zone* zone) {
+  int new_id = TopLevel()->GetNextChildId();
+  LiveRange* child = new (zone) LiveRange(new_id, representation(), TopLevel());
+  DetachAt(position, child, zone);
+
+  child->top_level_ = TopLevel();
+  child->next_ = next_;
+  next_ = child;
+  return child;
+}
+
+
+UsePosition* LiveRange::DetachAt(LifetimePosition position, LiveRange* result,
+                                 Zone* zone) {
+  DCHECK(Start() < position);
+  DCHECK(End() > position);
   DCHECK(result->IsEmpty());
   // Find the last interval that ends before the position. If the
   // position is contained in one of the intervals in the chain, we
   // split that interval and use the first part.
-  auto current = FirstSearchIntervalForPosition(position);
+  UseInterval* current = FirstSearchIntervalForPosition(position);
 
   // If the split position coincides with the beginning of a use interval
   // we need to split use positons in a special way.
   bool split_at_start = false;
 
-  if (current->start().Value() == position.Value()) {
+  if (current->start() == position) {
     // When splitting at start we need to locate the previous use interval.
     current = first_interval_;
   }
 
+  UseInterval* after = nullptr;
   while (current != nullptr) {
     if (current->Contains(position)) {
-      current->SplitAt(position, zone);
+      after = current->SplitAt(position, zone);
       break;
     }
-    auto next = current->next();
-    if (next->start().Value() >= position.Value()) {
-      split_at_start = (next->start().Value() == position.Value());
+    UseInterval* next = current->next();
+    if (next->start() >= position) {
+      split_at_start = (next->start() == position);
+      after = next;
+      current->set_next(nullptr);
       break;
     }
     current = next;
   }
+  DCHECK(nullptr != after);
 
   // Partition original use intervals to the two live ranges.
-  auto before = current;
-  auto after = before->next();
+  UseInterval* before = current;
   result->last_interval_ =
       (last_interval_ == before)
           ? after            // Only interval in the range after split.
@@ -340,20 +508,21 @@
 
   // Find the last use position before the split and the first use
   // position after it.
-  auto use_after = first_pos_;
+  UsePosition* use_after =
+      splitting_pointer_ == nullptr || splitting_pointer_->pos() > position
+          ? first_pos()
+          : splitting_pointer_;
   UsePosition* use_before = nullptr;
   if (split_at_start) {
     // The split position coincides with the beginning of a use interval (the
     // end of a lifetime hole). Use at this position should be attributed to
     // the split child because split child owns use interval covering it.
-    while (use_after != nullptr &&
-           use_after->pos().Value() < position.Value()) {
+    while (use_after != nullptr && use_after->pos() < position) {
       use_before = use_after;
       use_after = use_after->next();
     }
   } else {
-    while (use_after != nullptr &&
-           use_after->pos().Value() <= position.Value()) {
+    while (use_after != nullptr && use_after->pos() <= position) {
       use_before = use_after;
       use_after = use_after->next();
     }
@@ -361,7 +530,7 @@
 
   // Partition original use positions to the two live ranges.
   if (use_before != nullptr) {
-    use_before->next_ = nullptr;
+    use_before->set_next(nullptr);
   } else {
     first_pos_ = nullptr;
   }
@@ -372,17 +541,44 @@
   last_processed_use_ = nullptr;
   current_interval_ = nullptr;
 
-  // Link the new live range in the chain before any of the other
-  // ranges linked from the range before the split.
-  result->parent_ = (parent_ == nullptr) ? this : parent_;
-  result->kind_ = result->parent_->kind_;
-  result->next_ = next_;
-  next_ = result;
-
+  // Invalidate size and weight of this range. The child range has them
+  // invalid at construction.
+  size_ = kInvalidSize;
+  weight_ = kInvalidWeight;
 #ifdef DEBUG
-  Verify();
-  result->Verify();
+  VerifyChildStructure();
+  result->VerifyChildStructure();
 #endif
+  return use_before;
+}
+
+
+void LiveRange::UpdateParentForAllChildren(TopLevelLiveRange* new_top_level) {
+  LiveRange* child = this;
+  for (; child != nullptr; child = child->next()) {
+    child->top_level_ = new_top_level;
+  }
+}
+
+
+void LiveRange::ConvertUsesToOperand(const InstructionOperand& op,
+                                     const InstructionOperand& spill_op) {
+  for (UsePosition* pos = first_pos(); pos != nullptr; pos = pos->next()) {
+    DCHECK(Start() <= pos->pos() && pos->pos() <= End());
+    if (!pos->HasOperand()) continue;
+    switch (pos->type()) {
+      case UsePositionType::kRequiresSlot:
+        DCHECK(spill_op.IsStackSlot() || spill_op.IsDoubleStackSlot());
+        InstructionOperand::ReplaceWith(pos->operand(), &spill_op);
+        break;
+      case UsePositionType::kRequiresRegister:
+        DCHECK(op.IsRegister() || op.IsDoubleRegister());
+      // Fall through.
+      case UsePositionType::kAny:
+        InstructionOperand::ReplaceWith(pos->operand(), &op);
+        break;
+    }
+  }
 }
 
 
@@ -394,156 +590,68 @@
 bool LiveRange::ShouldBeAllocatedBefore(const LiveRange* other) const {
   LifetimePosition start = Start();
   LifetimePosition other_start = other->Start();
-  if (start.Value() == other_start.Value()) {
+  if (start == other_start) {
     UsePosition* pos = first_pos();
     if (pos == nullptr) return false;
     UsePosition* other_pos = other->first_pos();
     if (other_pos == nullptr) return true;
-    return pos->pos().Value() < other_pos->pos().Value();
+    return pos->pos() < other_pos->pos();
   }
-  return start.Value() < other_start.Value();
+  return start < other_start;
 }
 
 
-void LiveRange::ShortenTo(LifetimePosition start) {
-  TraceAlloc("Shorten live range %d to [%d\n", id_, start.Value());
-  DCHECK(first_interval_ != nullptr);
-  DCHECK(first_interval_->start().Value() <= start.Value());
-  DCHECK(start.Value() < first_interval_->end().Value());
-  first_interval_->set_start(start);
-}
-
-
-void LiveRange::EnsureInterval(LifetimePosition start, LifetimePosition end,
-                               Zone* zone) {
-  TraceAlloc("Ensure live range %d in interval [%d %d[\n", id_, start.Value(),
-             end.Value());
-  auto new_end = end;
-  while (first_interval_ != nullptr &&
-         first_interval_->start().Value() <= end.Value()) {
-    if (first_interval_->end().Value() > end.Value()) {
-      new_end = first_interval_->end();
+void LiveRange::SetUseHints(int register_index) {
+  for (UsePosition* pos = first_pos(); pos != nullptr; pos = pos->next()) {
+    if (!pos->HasOperand()) continue;
+    switch (pos->type()) {
+      case UsePositionType::kRequiresSlot:
+        break;
+      case UsePositionType::kRequiresRegister:
+      case UsePositionType::kAny:
+        pos->set_assigned_register(register_index);
+        break;
     }
-    first_interval_ = first_interval_->next();
-  }
-
-  auto new_interval = new (zone) UseInterval(start, new_end);
-  new_interval->next_ = first_interval_;
-  first_interval_ = new_interval;
-  if (new_interval->next() == nullptr) {
-    last_interval_ = new_interval;
-  }
-}
-
-
-void LiveRange::AddUseInterval(LifetimePosition start, LifetimePosition end,
-                               Zone* zone) {
-  TraceAlloc("Add to live range %d interval [%d %d[\n", id_, start.Value(),
-             end.Value());
-  if (first_interval_ == nullptr) {
-    auto interval = new (zone) UseInterval(start, end);
-    first_interval_ = interval;
-    last_interval_ = interval;
-  } else {
-    if (end.Value() == first_interval_->start().Value()) {
-      first_interval_->set_start(start);
-    } else if (end.Value() < first_interval_->start().Value()) {
-      auto interval = new (zone) UseInterval(start, end);
-      interval->set_next(first_interval_);
-      first_interval_ = interval;
-    } else {
-      // Order of instruction's processing (see ProcessInstructions) guarantees
-      // that each new use interval either precedes or intersects with
-      // last added interval.
-      DCHECK(start.Value() < first_interval_->end().Value());
-      first_interval_->start_ = Min(start, first_interval_->start_);
-      first_interval_->end_ = Max(end, first_interval_->end_);
-    }
-  }
-}
-
-
-void LiveRange::AddUsePosition(LifetimePosition pos,
-                               InstructionOperand* operand,
-                               InstructionOperand* hint, Zone* zone) {
-  TraceAlloc("Add to live range %d use position %d\n", id_, pos.Value());
-  auto use_pos = new (zone) UsePosition(pos, operand, hint);
-  UsePosition* prev_hint = nullptr;
-  UsePosition* prev = nullptr;
-  auto current = first_pos_;
-  while (current != nullptr && current->pos().Value() < pos.Value()) {
-    prev_hint = current->HasHint() ? current : prev_hint;
-    prev = current;
-    current = current->next();
-  }
-
-  if (prev == nullptr) {
-    use_pos->set_next(first_pos_);
-    first_pos_ = use_pos;
-  } else {
-    use_pos->next_ = prev->next_;
-    prev->next_ = use_pos;
-  }
-
-  if (prev_hint == nullptr && use_pos->HasHint()) {
-    current_hint_operand_ = hint;
-  }
-}
-
-
-void LiveRange::ConvertUsesToOperand(InstructionOperand* op) {
-  auto use_pos = first_pos();
-  while (use_pos != nullptr) {
-    DCHECK(Start().Value() <= use_pos->pos().Value() &&
-           use_pos->pos().Value() <= End().Value());
-
-    if (use_pos->HasOperand()) {
-      DCHECK(op->IsRegister() || op->IsDoubleRegister() ||
-             !use_pos->RequiresRegister());
-      use_pos->operand()->ConvertTo(op->kind(), op->index());
-    }
-    use_pos = use_pos->next();
   }
 }
 
 
 bool LiveRange::CanCover(LifetimePosition position) const {
   if (IsEmpty()) return false;
-  return Start().Value() <= position.Value() &&
-         position.Value() < End().Value();
+  return Start() <= position && position < End();
 }
 
 
-bool LiveRange::Covers(LifetimePosition position) {
+bool LiveRange::Covers(LifetimePosition position) const {
   if (!CanCover(position)) return false;
-  auto start_search = FirstSearchIntervalForPosition(position);
-  for (auto interval = start_search; interval != nullptr;
+  UseInterval* start_search = FirstSearchIntervalForPosition(position);
+  for (UseInterval* interval = start_search; interval != nullptr;
        interval = interval->next()) {
     DCHECK(interval->next() == nullptr ||
-           interval->next()->start().Value() >= interval->start().Value());
+           interval->next()->start() >= interval->start());
     AdvanceLastProcessedMarker(interval, position);
     if (interval->Contains(position)) return true;
-    if (interval->start().Value() > position.Value()) return false;
+    if (interval->start() > position) return false;
   }
   return false;
 }
 
 
-LifetimePosition LiveRange::FirstIntersection(LiveRange* other) {
-  auto b = other->first_interval();
+LifetimePosition LiveRange::FirstIntersection(LiveRange* other) const {
+  UseInterval* b = other->first_interval();
   if (b == nullptr) return LifetimePosition::Invalid();
-  auto advance_last_processed_up_to = b->start();
-  auto a = FirstSearchIntervalForPosition(b->start());
+  LifetimePosition advance_last_processed_up_to = b->start();
+  UseInterval* a = FirstSearchIntervalForPosition(b->start());
   while (a != nullptr && b != nullptr) {
-    if (a->start().Value() > other->End().Value()) break;
-    if (b->start().Value() > End().Value()) break;
-    auto cur_intersection = a->Intersect(b);
+    if (a->start() > other->End()) break;
+    if (b->start() > End()) break;
+    LifetimePosition cur_intersection = a->Intersect(b);
     if (cur_intersection.IsValid()) {
       return cur_intersection;
     }
-    if (a->start().Value() < b->start().Value()) {
+    if (a->start() < b->start()) {
       a = a->next();
-      if (a == nullptr || a->start().Value() > other->End().Value()) break;
+      if (a == nullptr || a->start() > other->End()) break;
       AdvanceLastProcessedMarker(a, advance_last_processed_up_to);
     } else {
       b = b->next();
@@ -553,250 +661,433 @@
 }
 
 
-RegisterAllocator::RegisterAllocator(const RegisterConfiguration* config,
-                                     Zone* zone, Frame* frame,
-                                     InstructionSequence* code,
-                                     const char* debug_name)
-    : local_zone_(zone),
-      frame_(frame),
-      code_(code),
-      debug_name_(debug_name),
-      config_(config),
-      phi_map_(PhiMap::key_compare(), PhiMap::allocator_type(local_zone())),
-      live_in_sets_(code->InstructionBlockCount(), nullptr, local_zone()),
-      live_ranges_(code->VirtualRegisterCount() * 2, nullptr, local_zone()),
-      fixed_live_ranges_(this->config()->num_general_registers(), nullptr,
-                         local_zone()),
-      fixed_double_live_ranges_(this->config()->num_double_registers(), nullptr,
-                                local_zone()),
-      unhandled_live_ranges_(local_zone()),
-      active_live_ranges_(local_zone()),
-      inactive_live_ranges_(local_zone()),
-      reusable_slots_(local_zone()),
-      spill_ranges_(local_zone()),
-      mode_(UNALLOCATED_REGISTERS),
-      num_registers_(-1),
-      allocation_ok_(true) {
-  DCHECK(this->config()->num_general_registers() <=
-         RegisterConfiguration::kMaxGeneralRegisters);
-  DCHECK(this->config()->num_double_registers() <=
-         RegisterConfiguration::kMaxDoubleRegisters);
-  // TryAllocateFreeReg and AllocateBlockedReg assume this
-  // when allocating local arrays.
-  DCHECK(RegisterConfiguration::kMaxDoubleRegisters >=
-         this->config()->num_general_registers());
-  unhandled_live_ranges().reserve(
-      static_cast<size_t>(code->VirtualRegisterCount() * 2));
-  active_live_ranges().reserve(8);
-  inactive_live_ranges().reserve(8);
-  reusable_slots().reserve(8);
-  spill_ranges().reserve(8);
-  assigned_registers_ =
-      new (code_zone()) BitVector(config->num_general_registers(), code_zone());
-  assigned_double_registers_ = new (code_zone())
-      BitVector(config->num_aliased_double_registers(), code_zone());
-  frame->SetAllocatedRegisters(assigned_registers_);
-  frame->SetAllocatedDoubleRegisters(assigned_double_registers_);
-}
-
-
-BitVector* RegisterAllocator::ComputeLiveOut(const InstructionBlock* block) {
-  // Compute live out for the given block, except not including backward
-  // successor edges.
-  auto live_out = new (local_zone())
-      BitVector(code()->VirtualRegisterCount(), local_zone());
-
-  // Process all successor blocks.
-  for (auto succ : block->successors()) {
-    // Add values live on entry to the successor. Note the successor's
-    // live_in will not be computed yet for backwards edges.
-    auto live_in = live_in_sets_[succ.ToSize()];
-    if (live_in != nullptr) live_out->Union(*live_in);
-
-    // All phi input operands corresponding to this successor edge are live
-    // out from this block.
-    auto successor = code()->InstructionBlockAt(succ);
-    size_t index = successor->PredecessorIndexOf(block->rpo_number());
-    DCHECK(index < successor->PredecessorCount());
-    for (auto phi : successor->phis()) {
-      live_out->Add(phi->operands()[index]);
+unsigned LiveRange::GetSize() {
+  if (size_ == kInvalidSize) {
+    size_ = 0;
+    for (const UseInterval* interval = first_interval(); interval != nullptr;
+         interval = interval->next()) {
+      size_ += (interval->end().value() - interval->start().value());
     }
   }
-  return live_out;
+
+  return static_cast<unsigned>(size_);
 }
 
 
-void RegisterAllocator::AddInitialIntervals(const InstructionBlock* block,
-                                            BitVector* live_out) {
-  // Add an interval that includes the entire block to the live range for
-  // each live_out value.
-  auto start =
-      LifetimePosition::FromInstructionIndex(block->first_instruction_index());
-  auto end = LifetimePosition::FromInstructionIndex(
-                 block->last_instruction_index()).NextInstruction();
-  BitVector::Iterator iterator(live_out);
-  while (!iterator.Done()) {
-    int operand_index = iterator.Current();
-    auto range = LiveRangeFor(operand_index);
-    range->AddUseInterval(start, end, local_zone());
-    iterator.Advance();
+void LiveRange::Print(const RegisterConfiguration* config,
+                      bool with_children) const {
+  OFStream os(stdout);
+  PrintableLiveRange wrapper;
+  wrapper.register_configuration_ = config;
+  for (const LiveRange* i = this; i != nullptr; i = i->next()) {
+    wrapper.range_ = i;
+    os << wrapper << std::endl;
+    if (!with_children) break;
   }
 }
 
 
-int RegisterAllocator::FixedDoubleLiveRangeID(int index) {
-  return -index - 1 - config()->num_general_registers();
+void LiveRange::Print(bool with_children) const {
+  const RegisterConfiguration* config =
+      RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN);
+  Print(config, with_children);
 }
 
 
-InstructionOperand* RegisterAllocator::AllocateFixed(
-    UnallocatedOperand* operand, int pos, bool is_tagged) {
-  TraceAlloc("Allocating fixed reg for op %d\n", operand->virtual_register());
-  DCHECK(operand->HasFixedPolicy());
-  if (operand->HasFixedSlotPolicy()) {
-    operand->ConvertTo(InstructionOperand::STACK_SLOT,
-                       operand->fixed_slot_index());
-  } else if (operand->HasFixedRegisterPolicy()) {
-    int reg_index = operand->fixed_register_index();
-    operand->ConvertTo(InstructionOperand::REGISTER, reg_index);
-  } else if (operand->HasFixedDoubleRegisterPolicy()) {
-    int reg_index = operand->fixed_register_index();
-    operand->ConvertTo(InstructionOperand::DOUBLE_REGISTER, reg_index);
-  } else {
-    UNREACHABLE();
-  }
-  if (is_tagged) {
-    TraceAlloc("Fixed reg is tagged at %d\n", pos);
-    auto instr = InstructionAt(pos);
-    if (instr->HasPointerMap()) {
-      instr->pointer_map()->RecordPointer(operand, code_zone());
+struct TopLevelLiveRange::SpillMoveInsertionList : ZoneObject {
+  SpillMoveInsertionList(int gap_index, InstructionOperand* operand,
+                         SpillMoveInsertionList* next)
+      : gap_index(gap_index), operand(operand), next(next) {}
+  const int gap_index;
+  InstructionOperand* const operand;
+  SpillMoveInsertionList* const next;
+};
+
+
+TopLevelLiveRange::TopLevelLiveRange(int vreg, MachineRepresentation rep)
+    : LiveRange(0, rep, this),
+      vreg_(vreg),
+      last_child_id_(0),
+      splintered_from_(nullptr),
+      spill_operand_(nullptr),
+      spill_move_insertion_locations_(nullptr),
+      spilled_in_deferred_blocks_(false),
+      spill_start_index_(kMaxInt),
+      last_pos_(nullptr),
+      splinter_(nullptr),
+      has_preassigned_slot_(false) {
+  bits_ |= SpillTypeField::encode(SpillType::kNoSpillType);
+}
+
+
+#if DEBUG
+int TopLevelLiveRange::debug_virt_reg() const {
+  return IsSplinter() ? splintered_from()->vreg() : vreg();
+}
+#endif
+
+
+void TopLevelLiveRange::RecordSpillLocation(Zone* zone, int gap_index,
+                                            InstructionOperand* operand) {
+  DCHECK(HasNoSpillType());
+  spill_move_insertion_locations_ = new (zone) SpillMoveInsertionList(
+      gap_index, operand, spill_move_insertion_locations_);
+}
+
+
+bool TopLevelLiveRange::TryCommitSpillInDeferredBlock(
+    InstructionSequence* code, const InstructionOperand& spill_operand) {
+  if (!IsSpilledOnlyInDeferredBlocks()) return false;
+
+  TRACE("Live Range %d will be spilled only in deferred blocks.\n", vreg());
+  // If we have ranges that aren't spilled but require the operand on the stack,
+  // make sure we insert the spill.
+  for (const LiveRange* child = this; child != nullptr; child = child->next()) {
+    if (!child->spilled() &&
+        child->NextSlotPosition(child->Start()) != nullptr) {
+      Instruction* instr =
+          code->InstructionAt(child->Start().ToInstructionIndex());
+      // Insert spill at the end to let live range connections happen at START.
+      ParallelMove* move =
+          instr->GetOrCreateParallelMove(Instruction::END, code->zone());
+      InstructionOperand assigned = child->GetAssignedOperand();
+      if (TopLevel()->has_slot_use()) {
+        bool found = false;
+        for (MoveOperands* move_op : *move) {
+          if (move_op->IsEliminated()) continue;
+          if (move_op->source().Equals(assigned) &&
+              move_op->destination().Equals(spill_operand)) {
+            found = true;
+            break;
+          }
+        }
+        if (found) continue;
+      }
+
+      move->AddMove(assigned, spill_operand);
     }
   }
-  return operand;
+
+  return true;
 }
 
 
-LiveRange* RegisterAllocator::FixedLiveRangeFor(int index) {
-  DCHECK(index < config()->num_general_registers());
-  auto result = fixed_live_ranges()[index];
-  if (result == nullptr) {
-    // TODO(titzer): add a utility method to allocate a new LiveRange:
-    // The LiveRange object itself can go in this zone, but the
-    // InstructionOperand needs
-    // to go in the code zone, since it may survive register allocation.
-    result = new (local_zone()) LiveRange(FixedLiveRangeID(index), code_zone());
-    DCHECK(result->IsFixed());
-    result->kind_ = GENERAL_REGISTERS;
-    SetLiveRangeAssignedRegister(result, index);
-    fixed_live_ranges()[index] = result;
+void TopLevelLiveRange::CommitSpillMoves(InstructionSequence* sequence,
+                                         const InstructionOperand& op,
+                                         bool might_be_duplicated) {
+  DCHECK_IMPLIES(op.IsConstant(), spill_move_insertion_locations() == nullptr);
+  Zone* zone = sequence->zone();
+
+  for (SpillMoveInsertionList* to_spill = spill_move_insertion_locations();
+       to_spill != nullptr; to_spill = to_spill->next) {
+    Instruction* instr = sequence->InstructionAt(to_spill->gap_index);
+    ParallelMove* move =
+        instr->GetOrCreateParallelMove(Instruction::START, zone);
+    // Skip insertion if it's possible that the move exists already as a
+    // constraint move from a fixed output register to a slot.
+    if (might_be_duplicated || has_preassigned_slot()) {
+      bool found = false;
+      for (MoveOperands* move_op : *move) {
+        if (move_op->IsEliminated()) continue;
+        if (move_op->source().Equals(*to_spill->operand) &&
+            move_op->destination().Equals(op)) {
+          found = true;
+          if (has_preassigned_slot()) move_op->Eliminate();
+          break;
+        }
+      }
+      if (found) continue;
+    }
+    if (!has_preassigned_slot()) {
+      move->AddMove(*to_spill->operand, op);
+    }
   }
-  return result;
 }
 
 
-LiveRange* RegisterAllocator::FixedDoubleLiveRangeFor(int index) {
-  DCHECK(index < config()->num_aliased_double_registers());
-  auto result = fixed_double_live_ranges()[index];
-  if (result == nullptr) {
-    result = new (local_zone())
-        LiveRange(FixedDoubleLiveRangeID(index), code_zone());
-    DCHECK(result->IsFixed());
-    result->kind_ = DOUBLE_REGISTERS;
-    SetLiveRangeAssignedRegister(result, index);
-    fixed_double_live_ranges()[index] = result;
-  }
-  return result;
+void TopLevelLiveRange::SetSpillOperand(InstructionOperand* operand) {
+  DCHECK(HasNoSpillType());
+  DCHECK(!operand->IsUnallocated() && !operand->IsImmediate());
+  set_spill_type(SpillType::kSpillOperand);
+  spill_operand_ = operand;
 }
 
 
-LiveRange* RegisterAllocator::LiveRangeFor(int index) {
-  if (index >= static_cast<int>(live_ranges().size())) {
-    live_ranges().resize(index + 1, nullptr);
-  }
-  auto result = live_ranges()[index];
-  if (result == nullptr) {
-    result = new (local_zone()) LiveRange(index, code_zone());
-    live_ranges()[index] = result;
-  }
-  return result;
+void TopLevelLiveRange::SetSpillRange(SpillRange* spill_range) {
+  DCHECK(!HasSpillOperand());
+  DCHECK(spill_range);
+  spill_range_ = spill_range;
 }
 
 
-GapInstruction* RegisterAllocator::GetLastGap(const InstructionBlock* block) {
-  int last_instruction = block->last_instruction_index();
-  return code()->GapAt(last_instruction - 1);
+AllocatedOperand TopLevelLiveRange::GetSpillRangeOperand() const {
+  SpillRange* spill_range = GetSpillRange();
+  int index = spill_range->assigned_slot();
+  return AllocatedOperand(LocationOperand::STACK_SLOT, representation(), index);
 }
 
 
-LiveRange* RegisterAllocator::LiveRangeFor(InstructionOperand* operand) {
-  if (operand->IsUnallocated()) {
-    return LiveRangeFor(UnallocatedOperand::cast(operand)->virtual_register());
-  } else if (operand->IsRegister()) {
-    return FixedLiveRangeFor(operand->index());
-  } else if (operand->IsDoubleRegister()) {
-    return FixedDoubleLiveRangeFor(operand->index());
+void TopLevelLiveRange::Splinter(LifetimePosition start, LifetimePosition end,
+                                 Zone* zone) {
+  DCHECK(start != Start() || end != End());
+  DCHECK(start < end);
+
+  TopLevelLiveRange splinter_temp(-1, representation());
+  UsePosition* last_in_splinter = nullptr;
+  // Live ranges defined in deferred blocks stay in deferred blocks, so we
+  // don't need to splinter them. That means that start should always be
+  // after the beginning of the range.
+  DCHECK(start > Start());
+
+  if (end >= End()) {
+    DCHECK(start > Start());
+    DetachAt(start, &splinter_temp, zone);
+    next_ = nullptr;
   } else {
-    return nullptr;
+    DCHECK(start < End() && Start() < end);
+
+    const int kInvalidId = std::numeric_limits<int>::max();
+
+    UsePosition* last = DetachAt(start, &splinter_temp, zone);
+
+    LiveRange end_part(kInvalidId, this->representation(), nullptr);
+    last_in_splinter = splinter_temp.DetachAt(end, &end_part, zone);
+
+    next_ = end_part.next_;
+    last_interval_->set_next(end_part.first_interval_);
+    // The next splinter will happen either at or after the current interval.
+    // We can optimize DetachAt by setting current_interval_ accordingly,
+    // which will then be picked up by FirstSearchIntervalForPosition.
+    current_interval_ = last_interval_;
+    last_interval_ = end_part.last_interval_;
+
+    if (first_pos_ == nullptr) {
+      first_pos_ = end_part.first_pos_;
+    } else {
+      splitting_pointer_ = last;
+      if (last != nullptr) last->set_next(end_part.first_pos_);
+    }
   }
-}
 
-
-void RegisterAllocator::Define(LifetimePosition position,
-                               InstructionOperand* operand,
-                               InstructionOperand* hint) {
-  auto range = LiveRangeFor(operand);
-  if (range == nullptr) return;
-
-  if (range->IsEmpty() || range->Start().Value() > position.Value()) {
-    // Can happen if there is a definition without use.
-    range->AddUseInterval(position, position.NextInstruction(), local_zone());
-    range->AddUsePosition(position.NextInstruction(), nullptr, nullptr,
-                          local_zone());
+  if (splinter()->IsEmpty()) {
+    splinter()->first_interval_ = splinter_temp.first_interval_;
+    splinter()->last_interval_ = splinter_temp.last_interval_;
   } else {
-    range->ShortenTo(position);
+    splinter()->last_interval_->set_next(splinter_temp.first_interval_);
+    splinter()->last_interval_ = splinter_temp.last_interval_;
   }
+  if (splinter()->first_pos() == nullptr) {
+    splinter()->first_pos_ = splinter_temp.first_pos_;
+  } else {
+    splinter()->last_pos_->set_next(splinter_temp.first_pos_);
+  }
+  if (last_in_splinter != nullptr) {
+    splinter()->last_pos_ = last_in_splinter;
+  } else {
+    if (splinter()->first_pos() != nullptr &&
+        splinter()->last_pos_ == nullptr) {
+      splinter()->last_pos_ = splinter()->first_pos();
+      for (UsePosition* pos = splinter()->first_pos(); pos != nullptr;
+           pos = pos->next()) {
+        splinter()->last_pos_ = pos;
+      }
+    }
+  }
+#if DEBUG
+  Verify();
+  splinter()->Verify();
+#endif
+}
 
-  if (operand->IsUnallocated()) {
-    auto unalloc_operand = UnallocatedOperand::cast(operand);
-    range->AddUsePosition(position, unalloc_operand, hint, local_zone());
+
+void TopLevelLiveRange::SetSplinteredFrom(TopLevelLiveRange* splinter_parent) {
+  splintered_from_ = splinter_parent;
+  if (!HasSpillOperand() && splinter_parent->spill_range_ != nullptr) {
+    SetSpillRange(splinter_parent->spill_range_);
   }
 }
 
 
-void RegisterAllocator::Use(LifetimePosition block_start,
-                            LifetimePosition position,
-                            InstructionOperand* operand,
-                            InstructionOperand* hint) {
-  auto range = LiveRangeFor(operand);
-  if (range == nullptr) return;
-  if (operand->IsUnallocated()) {
-    UnallocatedOperand* unalloc_operand = UnallocatedOperand::cast(operand);
-    range->AddUsePosition(position, unalloc_operand, hint, local_zone());
+void TopLevelLiveRange::UpdateSpillRangePostMerge(TopLevelLiveRange* merged) {
+  DCHECK(merged->TopLevel() == this);
+
+  if (HasNoSpillType() && merged->HasSpillRange()) {
+    set_spill_type(merged->spill_type());
+    DCHECK(GetSpillRange()->live_ranges().size() > 0);
+    merged->spill_range_ = nullptr;
+    merged->bits_ =
+        SpillTypeField::update(merged->bits_, SpillType::kNoSpillType);
   }
-  range->AddUseInterval(block_start, position, local_zone());
 }
 
 
-void RegisterAllocator::AddGapMove(int index,
-                                   GapInstruction::InnerPosition position,
-                                   InstructionOperand* from,
-                                   InstructionOperand* to) {
-  auto gap = code()->GapAt(index);
-  auto move = gap->GetOrCreateParallelMove(position, code_zone());
-  move->AddMove(from, to, code_zone());
+void TopLevelLiveRange::Merge(TopLevelLiveRange* other, Zone* zone) {
+  DCHECK(Start() < other->Start());
+  DCHECK(other->splintered_from() == this);
+
+  LiveRange* first = this;
+  LiveRange* second = other;
+  DCHECK(first->Start() < second->Start());
+  while (first != nullptr && second != nullptr) {
+    DCHECK(first != second);
+    // Make sure the ranges are in order each time we iterate.
+    if (second->Start() < first->Start()) {
+      LiveRange* tmp = second;
+      second = first;
+      first = tmp;
+      continue;
+    }
+
+    if (first->End() <= second->Start()) {
+      if (first->next() == nullptr ||
+          first->next()->Start() > second->Start()) {
+        // First is in order before second.
+        LiveRange* temp = first->next();
+        first->next_ = second;
+        first = temp;
+      } else {
+        // First is in order before its successor (or second), so advance first.
+        first = first->next();
+      }
+      continue;
+    }
+
+    DCHECK(first->Start() < second->Start());
+    // If first and second intersect, split first.
+    if (first->Start() < second->End() && second->Start() < first->End()) {
+      LiveRange* temp = first->SplitAt(second->Start(), zone);
+      CHECK(temp != first);
+      temp->set_spilled(first->spilled());
+      if (!temp->spilled())
+        temp->set_assigned_register(first->assigned_register());
+
+      first->next_ = second;
+      first = temp;
+      continue;
+    }
+    DCHECK(first->End() <= second->Start());
+  }
+
+  TopLevel()->UpdateParentForAllChildren(TopLevel());
+  TopLevel()->UpdateSpillRangePostMerge(other);
+
+#if DEBUG
+  Verify();
+#endif
+}
+
+
+void TopLevelLiveRange::VerifyChildrenInOrder() const {
+  LifetimePosition last_end = End();
+  for (const LiveRange* child = this->next(); child != nullptr;
+       child = child->next()) {
+    DCHECK(last_end <= child->Start());
+    last_end = child->End();
+  }
+}
+
+
+void TopLevelLiveRange::Verify() const {
+  VerifyChildrenInOrder();
+  for (const LiveRange* child = this; child != nullptr; child = child->next()) {
+    VerifyChildStructure();
+  }
+}
+
+
+void TopLevelLiveRange::ShortenTo(LifetimePosition start) {
+  TRACE("Shorten live range %d to [%d\n", vreg(), start.value());
+  DCHECK(first_interval_ != nullptr);
+  DCHECK(first_interval_->start() <= start);
+  DCHECK(start < first_interval_->end());
+  first_interval_->set_start(start);
+}
+
+
+void TopLevelLiveRange::EnsureInterval(LifetimePosition start,
+                                       LifetimePosition end, Zone* zone) {
+  TRACE("Ensure live range %d in interval [%d %d[\n", vreg(), start.value(),
+        end.value());
+  LifetimePosition new_end = end;
+  while (first_interval_ != nullptr && first_interval_->start() <= end) {
+    if (first_interval_->end() > end) {
+      new_end = first_interval_->end();
+    }
+    first_interval_ = first_interval_->next();
+  }
+
+  UseInterval* new_interval = new (zone) UseInterval(start, new_end);
+  new_interval->set_next(first_interval_);
+  first_interval_ = new_interval;
+  if (new_interval->next() == nullptr) {
+    last_interval_ = new_interval;
+  }
+}
+
+
+void TopLevelLiveRange::AddUseInterval(LifetimePosition start,
+                                       LifetimePosition end, Zone* zone) {
+  TRACE("Add to live range %d interval [%d %d[\n", vreg(), start.value(),
+        end.value());
+  if (first_interval_ == nullptr) {
+    UseInterval* interval = new (zone) UseInterval(start, end);
+    first_interval_ = interval;
+    last_interval_ = interval;
+  } else {
+    if (end == first_interval_->start()) {
+      first_interval_->set_start(start);
+    } else if (end < first_interval_->start()) {
+      UseInterval* interval = new (zone) UseInterval(start, end);
+      interval->set_next(first_interval_);
+      first_interval_ = interval;
+    } else {
+      // Order of instruction's processing (see ProcessInstructions) guarantees
+      // that each new use interval either precedes or intersects with
+      // last added interval.
+      DCHECK(start < first_interval_->end());
+      first_interval_->set_start(Min(start, first_interval_->start()));
+      first_interval_->set_end(Max(end, first_interval_->end()));
+    }
+  }
+}
+
+
+void TopLevelLiveRange::AddUsePosition(UsePosition* use_pos) {
+  LifetimePosition pos = use_pos->pos();
+  TRACE("Add to live range %d use position %d\n", vreg(), pos.value());
+  UsePosition* prev_hint = nullptr;
+  UsePosition* prev = nullptr;
+  UsePosition* current = first_pos_;
+  while (current != nullptr && current->pos() < pos) {
+    prev_hint = current->HasHint() ? current : prev_hint;
+    prev = current;
+    current = current->next();
+  }
+
+  if (prev == nullptr) {
+    use_pos->set_next(first_pos_);
+    first_pos_ = use_pos;
+  } else {
+    use_pos->set_next(prev->next());
+    prev->set_next(use_pos);
+  }
+
+  if (prev_hint == nullptr && use_pos->HasHint()) {
+    current_hint_position_ = use_pos;
+  }
 }
 
 
 static bool AreUseIntervalsIntersecting(UseInterval* interval1,
                                         UseInterval* interval2) {
   while (interval1 != nullptr && interval2 != nullptr) {
-    if (interval1->start().Value() < interval2->start().Value()) {
-      if (interval1->end().Value() > interval2->start().Value()) {
+    if (interval1->start() < interval2->start()) {
+      if (interval1->end() > interval2->start()) {
         return true;
       }
       interval1 = interval1->next();
     } else {
-      if (interval2->end().Value() > interval1->start().Value()) {
+      if (interval2->end() > interval1->start()) {
         return true;
       }
       interval2 = interval2->next();
@@ -806,33 +1097,79 @@
 }
 
 
-SpillRange::SpillRange(LiveRange* range, Zone* zone) : live_ranges_(zone) {
-  auto src = range->first_interval();
+std::ostream& operator<<(std::ostream& os,
+                         const PrintableLiveRange& printable_range) {
+  const LiveRange* range = printable_range.range_;
+  os << "Range: " << range->TopLevel()->vreg() << ":" << range->relative_id()
+     << " ";
+  if (range->TopLevel()->is_phi()) os << "phi ";
+  if (range->TopLevel()->is_non_loop_phi()) os << "nlphi ";
+
+  os << "{" << std::endl;
+  UseInterval* interval = range->first_interval();
+  UsePosition* use_pos = range->first_pos();
+  PrintableInstructionOperand pio;
+  pio.register_configuration_ = printable_range.register_configuration_;
+  while (use_pos != nullptr) {
+    if (use_pos->HasOperand()) {
+      pio.op_ = *use_pos->operand();
+      os << pio << use_pos->pos() << " ";
+    }
+    use_pos = use_pos->next();
+  }
+  os << std::endl;
+
+  while (interval != nullptr) {
+    os << '[' << interval->start() << ", " << interval->end() << ')'
+       << std::endl;
+    interval = interval->next();
+  }
+  os << "}";
+  return os;
+}
+
+
+SpillRange::SpillRange(TopLevelLiveRange* parent, Zone* zone)
+    : live_ranges_(zone),
+      assigned_slot_(kUnassignedSlot),
+      byte_width_(GetByteWidth(parent->representation())),
+      kind_(parent->kind()) {
+  // Spill ranges are created for top level, non-splintered ranges. This is so
+  // that, when merging decisions are made, we consider the full extent of the
+  // virtual register, and avoid clobbering it.
+  DCHECK(!parent->IsSplinter());
   UseInterval* result = nullptr;
   UseInterval* node = nullptr;
-  // Copy the nodes
-  while (src != nullptr) {
-    auto new_node = new (zone) UseInterval(src->start(), src->end());
-    if (result == nullptr) {
-      result = new_node;
-    } else {
-      node->set_next(new_node);
+  // Copy the intervals for all ranges.
+  for (LiveRange* range = parent; range != nullptr; range = range->next()) {
+    UseInterval* src = range->first_interval();
+    while (src != nullptr) {
+      UseInterval* new_node = new (zone) UseInterval(src->start(), src->end());
+      if (result == nullptr) {
+        result = new_node;
+      } else {
+        node->set_next(new_node);
+      }
+      node = new_node;
+      src = src->next();
     }
-    node = new_node;
-    src = src->next();
   }
   use_interval_ = result;
-  live_ranges().push_back(range);
+  live_ranges().push_back(parent);
   end_position_ = node->end();
-  DCHECK(!range->HasSpillRange());
-  range->SetSpillRange(this);
+  parent->SetSpillRange(this);
+}
+
+
+int SpillRange::ByteWidth() const {
+  return GetByteWidth(live_ranges_[0]->representation());
 }
 
 
 bool SpillRange::IsIntersectingWith(SpillRange* other) const {
   if (this->use_interval_ == nullptr || other->use_interval_ == nullptr ||
-      this->End().Value() <= other->use_interval_->start().Value() ||
-      other->End().Value() <= this->use_interval_->start().Value()) {
+      this->End() <= other->use_interval_->start() ||
+      other->End() <= this->use_interval_->start()) {
     return false;
   }
   return AreUseIntervalsIntersecting(use_interval_, other->use_interval_);
@@ -840,11 +1177,15 @@
 
 
 bool SpillRange::TryMerge(SpillRange* other) {
-  if (Kind() != other->Kind() || IsIntersectingWith(other)) return false;
+  if (HasSlot() || other->HasSlot()) return false;
+  // TODO(dcarney): byte widths should be compared here not kinds.
+  if (live_ranges_[0]->kind() != other->live_ranges_[0]->kind() ||
+      IsIntersectingWith(other)) {
+    return false;
+  }
 
-  auto max = LifetimePosition::MaxPosition();
-  if (End().Value() < other->End().Value() &&
-      other->End().Value() != max.Value()) {
+  LifetimePosition max = LifetimePosition::MaxPosition();
+  if (End() < other->End() && other->End() != max) {
     end_position_ = other->End();
   }
   other->end_position_ = max;
@@ -852,7 +1193,7 @@
   MergeDisjointIntervals(other->use_interval_);
   other->use_interval_ = nullptr;
 
-  for (auto range : other->live_ranges()) {
+  for (TopLevelLiveRange* range : other->live_ranges()) {
     DCHECK(range->GetSpillRange() == other);
     range->SetSpillRange(this);
   }
@@ -865,26 +1206,16 @@
 }
 
 
-void SpillRange::SetOperand(InstructionOperand* op) {
-  for (auto range : live_ranges()) {
-    DCHECK(range->GetSpillRange() == this);
-    range->CommitSpillOperand(op);
-  }
-}
-
-
 void SpillRange::MergeDisjointIntervals(UseInterval* other) {
   UseInterval* tail = nullptr;
-  auto current = use_interval_;
+  UseInterval* current = use_interval_;
   while (other != nullptr) {
     // Make sure the 'current' list starts first
-    if (current == nullptr ||
-        current->start().Value() > other->start().Value()) {
+    if (current == nullptr || current->start() > other->start()) {
       std::swap(current, other);
     }
     // Check disjointness
-    DCHECK(other == nullptr ||
-           current->end().Value() <= other->start().Value());
+    DCHECK(other == nullptr || current->end() <= other->start());
     // Append the 'current' node to the result accumulator and move forward
     if (tail == nullptr) {
       use_interval_ = current;
@@ -898,81 +1229,1617 @@
 }
 
 
-void RegisterAllocator::ReuseSpillSlots() {
-  DCHECK(FLAG_turbo_reuse_spill_slots);
+void SpillRange::Print() const {
+  OFStream os(stdout);
+  os << "{" << std::endl;
+  for (TopLevelLiveRange* range : live_ranges()) {
+    os << range->vreg() << " ";
+  }
+  os << std::endl;
 
-  // Merge disjoint spill ranges
-  for (size_t i = 0; i < spill_ranges().size(); i++) {
-    auto range = spill_ranges()[i];
-    if (range->IsEmpty()) continue;
-    for (size_t j = i + 1; j < spill_ranges().size(); j++) {
-      auto other = spill_ranges()[j];
-      if (!other->IsEmpty()) {
-        range->TryMerge(other);
+  for (UseInterval* i = interval(); i != nullptr; i = i->next()) {
+    os << '[' << i->start() << ", " << i->end() << ')' << std::endl;
+  }
+  os << "}" << std::endl;
+}
+
+
+RegisterAllocationData::PhiMapValue::PhiMapValue(PhiInstruction* phi,
+                                                 const InstructionBlock* block,
+                                                 Zone* zone)
+    : phi_(phi),
+      block_(block),
+      incoming_operands_(zone),
+      assigned_register_(kUnassignedRegister) {
+  incoming_operands_.reserve(phi->operands().size());
+}
+
+
+void RegisterAllocationData::PhiMapValue::AddOperand(
+    InstructionOperand* operand) {
+  incoming_operands_.push_back(operand);
+}
+
+
+void RegisterAllocationData::PhiMapValue::CommitAssignment(
+    const InstructionOperand& assigned) {
+  for (InstructionOperand* operand : incoming_operands_) {
+    InstructionOperand::ReplaceWith(operand, &assigned);
+  }
+}
+
+
+RegisterAllocationData::RegisterAllocationData(
+    const RegisterConfiguration* config, Zone* zone, Frame* frame,
+    InstructionSequence* code, const char* debug_name)
+    : allocation_zone_(zone),
+      frame_(frame),
+      code_(code),
+      debug_name_(debug_name),
+      config_(config),
+      phi_map_(allocation_zone()),
+      allocatable_codes_(this->config()->num_general_registers(), -1,
+                         allocation_zone()),
+      allocatable_double_codes_(this->config()->num_double_registers(), -1,
+                                allocation_zone()),
+      live_in_sets_(code->InstructionBlockCount(), nullptr, allocation_zone()),
+      live_out_sets_(code->InstructionBlockCount(), nullptr, allocation_zone()),
+      live_ranges_(code->VirtualRegisterCount() * 2, nullptr,
+                   allocation_zone()),
+      fixed_live_ranges_(this->config()->num_general_registers(), nullptr,
+                         allocation_zone()),
+      fixed_double_live_ranges_(this->config()->num_double_registers(), nullptr,
+                                allocation_zone()),
+      spill_ranges_(code->VirtualRegisterCount(), nullptr, allocation_zone()),
+      delayed_references_(allocation_zone()),
+      assigned_registers_(nullptr),
+      assigned_double_registers_(nullptr),
+      virtual_register_count_(code->VirtualRegisterCount()),
+      preassigned_slot_ranges_(zone) {
+  DCHECK(this->config()->num_general_registers() <=
+         RegisterConfiguration::kMaxGeneralRegisters);
+  DCHECK(this->config()->num_double_registers() <=
+         RegisterConfiguration::kMaxDoubleRegisters);
+  assigned_registers_ = new (code_zone())
+      BitVector(this->config()->num_general_registers(), code_zone());
+  assigned_double_registers_ = new (code_zone())
+      BitVector(this->config()->num_double_registers(), code_zone());
+  this->frame()->SetAllocatedRegisters(assigned_registers_);
+  this->frame()->SetAllocatedDoubleRegisters(assigned_double_registers_);
+}
+
+
+MoveOperands* RegisterAllocationData::AddGapMove(
+    int index, Instruction::GapPosition position,
+    const InstructionOperand& from, const InstructionOperand& to) {
+  Instruction* instr = code()->InstructionAt(index);
+  ParallelMove* moves = instr->GetOrCreateParallelMove(position, code_zone());
+  return moves->AddMove(from, to);
+}
+
+
+MachineRepresentation RegisterAllocationData::RepresentationFor(
+    int virtual_register) {
+  DCHECK_LT(virtual_register, code()->VirtualRegisterCount());
+  return code()->GetRepresentation(virtual_register);
+}
+
+
+TopLevelLiveRange* RegisterAllocationData::GetOrCreateLiveRangeFor(int index) {
+  if (index >= static_cast<int>(live_ranges().size())) {
+    live_ranges().resize(index + 1, nullptr);
+  }
+  TopLevelLiveRange* result = live_ranges()[index];
+  if (result == nullptr) {
+    result = NewLiveRange(index, RepresentationFor(index));
+    live_ranges()[index] = result;
+  }
+  return result;
+}
+
+
+TopLevelLiveRange* RegisterAllocationData::NewLiveRange(
+    int index, MachineRepresentation rep) {
+  return new (allocation_zone()) TopLevelLiveRange(index, rep);
+}
+
+
+int RegisterAllocationData::GetNextLiveRangeId() {
+  int vreg = virtual_register_count_++;
+  if (vreg >= static_cast<int>(live_ranges().size())) {
+    live_ranges().resize(vreg + 1, nullptr);
+  }
+  return vreg;
+}
+
+
+TopLevelLiveRange* RegisterAllocationData::NextLiveRange(
+    MachineRepresentation rep) {
+  int vreg = GetNextLiveRangeId();
+  TopLevelLiveRange* ret = NewLiveRange(vreg, rep);
+  return ret;
+}
+
+
+RegisterAllocationData::PhiMapValue* RegisterAllocationData::InitializePhiMap(
+    const InstructionBlock* block, PhiInstruction* phi) {
+  RegisterAllocationData::PhiMapValue* map_value = new (allocation_zone())
+      RegisterAllocationData::PhiMapValue(phi, block, allocation_zone());
+  auto res =
+      phi_map_.insert(std::make_pair(phi->virtual_register(), map_value));
+  DCHECK(res.second);
+  USE(res);
+  return map_value;
+}
+
+
+RegisterAllocationData::PhiMapValue* RegisterAllocationData::GetPhiMapValueFor(
+    int virtual_register) {
+  auto it = phi_map_.find(virtual_register);
+  DCHECK(it != phi_map_.end());
+  return it->second;
+}
+
+
+RegisterAllocationData::PhiMapValue* RegisterAllocationData::GetPhiMapValueFor(
+    TopLevelLiveRange* top_range) {
+  return GetPhiMapValueFor(top_range->vreg());
+}
+
+
+bool RegisterAllocationData::ExistsUseWithoutDefinition() {
+  bool found = false;
+  BitVector::Iterator iterator(live_in_sets()[0]);
+  while (!iterator.Done()) {
+    found = true;
+    int operand_index = iterator.Current();
+    PrintF("Register allocator error: live v%d reached first block.\n",
+           operand_index);
+    LiveRange* range = GetOrCreateLiveRangeFor(operand_index);
+    PrintF("  (first use is at %d)\n", range->first_pos()->pos().value());
+    if (debug_name() == nullptr) {
+      PrintF("\n");
+    } else {
+      PrintF("  (function: %s)\n", debug_name());
+    }
+    iterator.Advance();
+  }
+  return found;
+}
+
+
+// If a range is defined in a deferred block, we can expect all the range
+// to only cover positions in deferred blocks. Otherwise, a block on the
+// hot path would be dominated by a deferred block, meaning it is unreachable
+// without passing through the deferred block, which is contradictory.
+// In particular, when such a range contributes a result back on the hot
+// path, it will be as one of the inputs of a phi. In that case, the value
+// will be transferred via a move in the Gap::END's of the last instruction
+// of a deferred block.
+bool RegisterAllocationData::RangesDefinedInDeferredStayInDeferred() {
+  for (const TopLevelLiveRange* range : live_ranges()) {
+    if (range == nullptr || range->IsEmpty() ||
+        !code()
+             ->GetInstructionBlock(range->Start().ToInstructionIndex())
+             ->IsDeferred()) {
+      continue;
+    }
+    for (const UseInterval* i = range->first_interval(); i != nullptr;
+         i = i->next()) {
+      int first = i->FirstGapIndex();
+      int last = i->LastGapIndex();
+      for (int instr = first; instr <= last;) {
+        const InstructionBlock* block = code()->GetInstructionBlock(instr);
+        if (!block->IsDeferred()) return false;
+        instr = block->last_instruction_index() + 1;
       }
     }
   }
-
-  // Allocate slots for the merged spill ranges.
-  for (auto range : spill_ranges()) {
-    if (range->IsEmpty()) continue;
-    // Allocate a new operand referring to the spill slot.
-    auto kind = range->Kind();
-    int index = frame()->AllocateSpillSlot(kind == DOUBLE_REGISTERS);
-    auto op_kind = kind == DOUBLE_REGISTERS
-                       ? InstructionOperand::DOUBLE_STACK_SLOT
-                       : InstructionOperand::STACK_SLOT;
-    auto op = new (code_zone()) InstructionOperand(op_kind, index);
-    range->SetOperand(op);
-  }
+  return true;
 }
 
 
-void RegisterAllocator::CommitAssignment() {
-  for (auto range : live_ranges()) {
-    if (range == nullptr || range->IsEmpty()) continue;
-    // Register assignments were committed in set_assigned_register.
-    if (range->HasRegisterAssigned()) continue;
-    auto assigned = range->CreateAssignedOperand(code_zone());
-    range->ConvertUsesToOperand(assigned);
-    if (range->IsSpilled()) {
-      range->CommitSpillsAtDefinition(code(), assigned);
-    }
+SpillRange* RegisterAllocationData::AssignSpillRangeToLiveRange(
+    TopLevelLiveRange* range) {
+  DCHECK(!range->HasSpillOperand());
+
+  SpillRange* spill_range = range->GetAllocatedSpillRange();
+  if (spill_range == nullptr) {
+    DCHECK(!range->IsSplinter());
+    spill_range = new (allocation_zone()) SpillRange(range, allocation_zone());
   }
-}
+  range->set_spill_type(TopLevelLiveRange::SpillType::kSpillRange);
 
+  int spill_range_index =
+      range->IsSplinter() ? range->splintered_from()->vreg() : range->vreg();
 
-SpillRange* RegisterAllocator::AssignSpillRangeToLiveRange(LiveRange* range) {
-  DCHECK(FLAG_turbo_reuse_spill_slots);
-  auto spill_range = new (local_zone()) SpillRange(range, local_zone());
-  spill_ranges().push_back(spill_range);
+  spill_ranges()[spill_range_index] = spill_range;
+
   return spill_range;
 }
 
 
-bool RegisterAllocator::TryReuseSpillForPhi(LiveRange* range) {
-  DCHECK(FLAG_turbo_reuse_spill_slots);
-  if (range->IsChild() || !range->is_phi()) return false;
-  DCHECK(range->HasNoSpillType());
+SpillRange* RegisterAllocationData::CreateSpillRangeForLiveRange(
+    TopLevelLiveRange* range) {
+  DCHECK(!range->HasSpillOperand());
+  DCHECK(!range->IsSplinter());
+  SpillRange* spill_range =
+      new (allocation_zone()) SpillRange(range, allocation_zone());
+  return spill_range;
+}
 
-  auto lookup = phi_map_.find(range->id());
-  DCHECK(lookup != phi_map_.end());
-  auto phi = lookup->second.phi;
-  auto block = lookup->second.block;
+
+void RegisterAllocationData::MarkAllocated(RegisterKind kind, int index) {
+  if (kind == DOUBLE_REGISTERS) {
+    assigned_double_registers_->Add(index);
+  } else {
+    DCHECK(kind == GENERAL_REGISTERS);
+    assigned_registers_->Add(index);
+  }
+}
+
+
+bool RegisterAllocationData::IsBlockBoundary(LifetimePosition pos) const {
+  return pos.IsFullStart() &&
+         code()->GetInstructionBlock(pos.ToInstructionIndex())->code_start() ==
+             pos.ToInstructionIndex();
+}
+
+
+ConstraintBuilder::ConstraintBuilder(RegisterAllocationData* data)
+    : data_(data) {}
+
+
+InstructionOperand* ConstraintBuilder::AllocateFixed(
+    UnallocatedOperand* operand, int pos, bool is_tagged) {
+  TRACE("Allocating fixed reg for op %d\n", operand->virtual_register());
+  DCHECK(operand->HasFixedPolicy());
+  InstructionOperand allocated;
+  MachineRepresentation rep = InstructionSequence::DefaultRepresentation();
+  int virtual_register = operand->virtual_register();
+  if (virtual_register != InstructionOperand::kInvalidVirtualRegister) {
+    rep = data()->RepresentationFor(virtual_register);
+  }
+  if (operand->HasFixedSlotPolicy()) {
+    allocated = AllocatedOperand(AllocatedOperand::STACK_SLOT, rep,
+                                 operand->fixed_slot_index());
+  } else if (operand->HasFixedRegisterPolicy()) {
+    DCHECK(!IsFloatingPoint(rep));
+    allocated = AllocatedOperand(AllocatedOperand::REGISTER, rep,
+                                 operand->fixed_register_index());
+  } else if (operand->HasFixedDoubleRegisterPolicy()) {
+    DCHECK(IsFloatingPoint(rep));
+    DCHECK_NE(InstructionOperand::kInvalidVirtualRegister, virtual_register);
+    allocated = AllocatedOperand(AllocatedOperand::REGISTER, rep,
+                                 operand->fixed_register_index());
+  } else {
+    UNREACHABLE();
+  }
+  InstructionOperand::ReplaceWith(operand, &allocated);
+  if (is_tagged) {
+    TRACE("Fixed reg is tagged at %d\n", pos);
+    Instruction* instr = code()->InstructionAt(pos);
+    if (instr->HasReferenceMap()) {
+      instr->reference_map()->RecordReference(*AllocatedOperand::cast(operand));
+    }
+  }
+  return operand;
+}
+
+
+void ConstraintBuilder::MeetRegisterConstraints() {
+  for (InstructionBlock* block : code()->instruction_blocks()) {
+    MeetRegisterConstraints(block);
+  }
+}
+
+
+void ConstraintBuilder::MeetRegisterConstraints(const InstructionBlock* block) {
+  int start = block->first_instruction_index();
+  int end = block->last_instruction_index();
+  DCHECK_NE(-1, start);
+  for (int i = start; i <= end; ++i) {
+    MeetConstraintsBefore(i);
+    if (i != end) MeetConstraintsAfter(i);
+  }
+  // Meet register constraints for the instruction in the end.
+  MeetRegisterConstraintsForLastInstructionInBlock(block);
+}
+
+
+void ConstraintBuilder::MeetRegisterConstraintsForLastInstructionInBlock(
+    const InstructionBlock* block) {
+  int end = block->last_instruction_index();
+  Instruction* last_instruction = code()->InstructionAt(end);
+  for (size_t i = 0; i < last_instruction->OutputCount(); i++) {
+    InstructionOperand* output_operand = last_instruction->OutputAt(i);
+    DCHECK(!output_operand->IsConstant());
+    UnallocatedOperand* output = UnallocatedOperand::cast(output_operand);
+    int output_vreg = output->virtual_register();
+    TopLevelLiveRange* range = data()->GetOrCreateLiveRangeFor(output_vreg);
+    bool assigned = false;
+    if (output->HasFixedPolicy()) {
+      AllocateFixed(output, -1, false);
+      // This value is produced on the stack, we never need to spill it.
+      if (output->IsStackSlot()) {
+        DCHECK(LocationOperand::cast(output)->index() <
+               data()->frame()->GetSpillSlotCount());
+        range->SetSpillOperand(LocationOperand::cast(output));
+        range->SetSpillStartIndex(end);
+        assigned = true;
+      }
+
+      for (const RpoNumber& succ : block->successors()) {
+        const InstructionBlock* successor = code()->InstructionBlockAt(succ);
+        DCHECK(successor->PredecessorCount() == 1);
+        int gap_index = successor->first_instruction_index();
+        // Create an unconstrained operand for the same virtual register
+        // and insert a gap move from the fixed output to the operand.
+        UnallocatedOperand output_copy(UnallocatedOperand::ANY, output_vreg);
+        data()->AddGapMove(gap_index, Instruction::START, *output, output_copy);
+      }
+    }
+
+    if (!assigned) {
+      for (const RpoNumber& succ : block->successors()) {
+        const InstructionBlock* successor = code()->InstructionBlockAt(succ);
+        DCHECK(successor->PredecessorCount() == 1);
+        int gap_index = successor->first_instruction_index();
+        range->RecordSpillLocation(allocation_zone(), gap_index, output);
+        range->SetSpillStartIndex(gap_index);
+      }
+    }
+  }
+}
+
+
+void ConstraintBuilder::MeetConstraintsAfter(int instr_index) {
+  Instruction* first = code()->InstructionAt(instr_index);
+  // Handle fixed temporaries.
+  for (size_t i = 0; i < first->TempCount(); i++) {
+    UnallocatedOperand* temp = UnallocatedOperand::cast(first->TempAt(i));
+    if (temp->HasFixedPolicy()) AllocateFixed(temp, instr_index, false);
+  }
+  // Handle constant/fixed output operands.
+  for (size_t i = 0; i < first->OutputCount(); i++) {
+    InstructionOperand* output = first->OutputAt(i);
+    if (output->IsConstant()) {
+      int output_vreg = ConstantOperand::cast(output)->virtual_register();
+      TopLevelLiveRange* range = data()->GetOrCreateLiveRangeFor(output_vreg);
+      range->SetSpillStartIndex(instr_index + 1);
+      range->SetSpillOperand(output);
+      continue;
+    }
+    UnallocatedOperand* first_output = UnallocatedOperand::cast(output);
+    TopLevelLiveRange* range =
+        data()->GetOrCreateLiveRangeFor(first_output->virtual_register());
+    bool assigned = false;
+    if (first_output->HasFixedPolicy()) {
+      int output_vreg = first_output->virtual_register();
+      UnallocatedOperand output_copy(UnallocatedOperand::ANY, output_vreg);
+      bool is_tagged = code()->IsReference(output_vreg);
+      if (first_output->HasSecondaryStorage()) {
+        range->MarkHasPreassignedSlot();
+        data()->preassigned_slot_ranges().push_back(
+            std::make_pair(range, first_output->GetSecondaryStorage()));
+      }
+      AllocateFixed(first_output, instr_index, is_tagged);
+
+      // This value is produced on the stack, we never need to spill it.
+      if (first_output->IsStackSlot()) {
+        DCHECK(LocationOperand::cast(first_output)->index() <
+               data()->frame()->GetTotalFrameSlotCount());
+        range->SetSpillOperand(LocationOperand::cast(first_output));
+        range->SetSpillStartIndex(instr_index + 1);
+        assigned = true;
+      }
+      data()->AddGapMove(instr_index + 1, Instruction::START, *first_output,
+                         output_copy);
+    }
+    // Make sure we add a gap move for spilling (if we have not done
+    // so already).
+    if (!assigned) {
+      range->RecordSpillLocation(allocation_zone(), instr_index + 1,
+                                 first_output);
+      range->SetSpillStartIndex(instr_index + 1);
+    }
+  }
+}
+
+
+void ConstraintBuilder::MeetConstraintsBefore(int instr_index) {
+  Instruction* second = code()->InstructionAt(instr_index);
+  // Handle fixed input operands of second instruction.
+  for (size_t i = 0; i < second->InputCount(); i++) {
+    InstructionOperand* input = second->InputAt(i);
+    if (input->IsImmediate() || input->IsExplicit()) {
+      continue;  // Ignore immediates and explicitly reserved registers.
+    }
+    UnallocatedOperand* cur_input = UnallocatedOperand::cast(input);
+    if (cur_input->HasFixedPolicy()) {
+      int input_vreg = cur_input->virtual_register();
+      UnallocatedOperand input_copy(UnallocatedOperand::ANY, input_vreg);
+      bool is_tagged = code()->IsReference(input_vreg);
+      AllocateFixed(cur_input, instr_index, is_tagged);
+      data()->AddGapMove(instr_index, Instruction::END, input_copy, *cur_input);
+    }
+  }
+  // Handle "output same as input" for second instruction.
+  for (size_t i = 0; i < second->OutputCount(); i++) {
+    InstructionOperand* output = second->OutputAt(i);
+    if (!output->IsUnallocated()) continue;
+    UnallocatedOperand* second_output = UnallocatedOperand::cast(output);
+    if (!second_output->HasSameAsInputPolicy()) continue;
+    DCHECK(i == 0);  // Only valid for first output.
+    UnallocatedOperand* cur_input =
+        UnallocatedOperand::cast(second->InputAt(0));
+    int output_vreg = second_output->virtual_register();
+    int input_vreg = cur_input->virtual_register();
+    UnallocatedOperand input_copy(UnallocatedOperand::ANY, input_vreg);
+    cur_input->set_virtual_register(second_output->virtual_register());
+    MoveOperands* gap_move = data()->AddGapMove(instr_index, Instruction::END,
+                                                input_copy, *cur_input);
+    if (code()->IsReference(input_vreg) && !code()->IsReference(output_vreg)) {
+      if (second->HasReferenceMap()) {
+        RegisterAllocationData::DelayedReference delayed_reference = {
+            second->reference_map(), &gap_move->source()};
+        data()->delayed_references().push_back(delayed_reference);
+      }
+    } else if (!code()->IsReference(input_vreg) &&
+               code()->IsReference(output_vreg)) {
+      // The input is assumed to immediately have a tagged representation,
+      // before the pointer map can be used. I.e. the pointer map at the
+      // instruction will include the output operand (whose value at the
+      // beginning of the instruction is equal to the input operand). If
+      // this is not desired, then the pointer map at this instruction needs
+      // to be adjusted manually.
+    }
+  }
+}
+
+
+void ConstraintBuilder::ResolvePhis() {
+  // Process the blocks in reverse order.
+  for (InstructionBlock* block : base::Reversed(code()->instruction_blocks())) {
+    ResolvePhis(block);
+  }
+}
+
+
+void ConstraintBuilder::ResolvePhis(const InstructionBlock* block) {
+  for (PhiInstruction* phi : block->phis()) {
+    int phi_vreg = phi->virtual_register();
+    RegisterAllocationData::PhiMapValue* map_value =
+        data()->InitializePhiMap(block, phi);
+    InstructionOperand& output = phi->output();
+    // Map the destination operands, so the commitment phase can find them.
+    for (size_t i = 0; i < phi->operands().size(); ++i) {
+      InstructionBlock* cur_block =
+          code()->InstructionBlockAt(block->predecessors()[i]);
+      UnallocatedOperand input(UnallocatedOperand::ANY, phi->operands()[i]);
+      MoveOperands* move = data()->AddGapMove(
+          cur_block->last_instruction_index(), Instruction::END, input, output);
+      map_value->AddOperand(&move->destination());
+      DCHECK(!code()
+                  ->InstructionAt(cur_block->last_instruction_index())
+                  ->HasReferenceMap());
+    }
+    TopLevelLiveRange* live_range = data()->GetOrCreateLiveRangeFor(phi_vreg);
+    int gap_index = block->first_instruction_index();
+    live_range->RecordSpillLocation(allocation_zone(), gap_index, &output);
+    live_range->SetSpillStartIndex(gap_index);
+    // We use the phi-ness of some nodes in some later heuristics.
+    live_range->set_is_phi(true);
+    live_range->set_is_non_loop_phi(!block->IsLoopHeader());
+  }
+}
+
+
+LiveRangeBuilder::LiveRangeBuilder(RegisterAllocationData* data,
+                                   Zone* local_zone)
+    : data_(data), phi_hints_(local_zone) {}
+
+
+BitVector* LiveRangeBuilder::ComputeLiveOut(const InstructionBlock* block,
+                                            RegisterAllocationData* data) {
+  size_t block_index = block->rpo_number().ToSize();
+  BitVector* live_out = data->live_out_sets()[block_index];
+  if (live_out == nullptr) {
+    // Compute live out for the given block, except not including backward
+    // successor edges.
+    Zone* zone = data->allocation_zone();
+    const InstructionSequence* code = data->code();
+
+    live_out = new (zone) BitVector(code->VirtualRegisterCount(), zone);
+
+    // Process all successor blocks.
+    for (const RpoNumber& succ : block->successors()) {
+      // Add values live on entry to the successor.
+      if (succ <= block->rpo_number()) continue;
+      BitVector* live_in = data->live_in_sets()[succ.ToSize()];
+      if (live_in != nullptr) live_out->Union(*live_in);
+
+      // All phi input operands corresponding to this successor edge are live
+      // out from this block.
+      const InstructionBlock* successor = code->InstructionBlockAt(succ);
+      size_t index = successor->PredecessorIndexOf(block->rpo_number());
+      DCHECK(index < successor->PredecessorCount());
+      for (PhiInstruction* phi : successor->phis()) {
+        live_out->Add(phi->operands()[index]);
+      }
+    }
+    data->live_out_sets()[block_index] = live_out;
+  }
+  return live_out;
+}
+
+
+void LiveRangeBuilder::AddInitialIntervals(const InstructionBlock* block,
+                                           BitVector* live_out) {
+  // Add an interval that includes the entire block to the live range for
+  // each live_out value.
+  LifetimePosition start = LifetimePosition::GapFromInstructionIndex(
+      block->first_instruction_index());
+  LifetimePosition end = LifetimePosition::InstructionFromInstructionIndex(
+                             block->last_instruction_index())
+                             .NextStart();
+  BitVector::Iterator iterator(live_out);
+  while (!iterator.Done()) {
+    int operand_index = iterator.Current();
+    TopLevelLiveRange* range = data()->GetOrCreateLiveRangeFor(operand_index);
+    range->AddUseInterval(start, end, allocation_zone());
+    iterator.Advance();
+  }
+}
+
+
+int LiveRangeBuilder::FixedDoubleLiveRangeID(int index) {
+  return -index - 1 - config()->num_general_registers();
+}
+
+
+TopLevelLiveRange* LiveRangeBuilder::FixedLiveRangeFor(int index) {
+  DCHECK(index < config()->num_general_registers());
+  TopLevelLiveRange* result = data()->fixed_live_ranges()[index];
+  if (result == nullptr) {
+    result = data()->NewLiveRange(FixedLiveRangeID(index),
+                                  InstructionSequence::DefaultRepresentation());
+    DCHECK(result->IsFixed());
+    result->set_assigned_register(index);
+    data()->MarkAllocated(GENERAL_REGISTERS, index);
+    data()->fixed_live_ranges()[index] = result;
+  }
+  return result;
+}
+
+
+TopLevelLiveRange* LiveRangeBuilder::FixedDoubleLiveRangeFor(int index) {
+  DCHECK(index < config()->num_double_registers());
+  TopLevelLiveRange* result = data()->fixed_double_live_ranges()[index];
+  if (result == nullptr) {
+    result = data()->NewLiveRange(FixedDoubleLiveRangeID(index),
+                                  MachineRepresentation::kFloat64);
+    DCHECK(result->IsFixed());
+    result->set_assigned_register(index);
+    data()->MarkAllocated(DOUBLE_REGISTERS, index);
+    data()->fixed_double_live_ranges()[index] = result;
+  }
+  return result;
+}
+
+
+TopLevelLiveRange* LiveRangeBuilder::LiveRangeFor(InstructionOperand* operand) {
+  if (operand->IsUnallocated()) {
+    return data()->GetOrCreateLiveRangeFor(
+        UnallocatedOperand::cast(operand)->virtual_register());
+  } else if (operand->IsConstant()) {
+    return data()->GetOrCreateLiveRangeFor(
+        ConstantOperand::cast(operand)->virtual_register());
+  } else if (operand->IsRegister()) {
+    return FixedLiveRangeFor(
+        LocationOperand::cast(operand)->GetRegister().code());
+  } else if (operand->IsDoubleRegister()) {
+    return FixedDoubleLiveRangeFor(
+        LocationOperand::cast(operand)->GetDoubleRegister().code());
+  } else {
+    return nullptr;
+  }
+}
+
+
+UsePosition* LiveRangeBuilder::NewUsePosition(LifetimePosition pos,
+                                              InstructionOperand* operand,
+                                              void* hint,
+                                              UsePositionHintType hint_type) {
+  return new (allocation_zone()) UsePosition(pos, operand, hint, hint_type);
+}
+
+
+UsePosition* LiveRangeBuilder::Define(LifetimePosition position,
+                                      InstructionOperand* operand, void* hint,
+                                      UsePositionHintType hint_type) {
+  TopLevelLiveRange* range = LiveRangeFor(operand);
+  if (range == nullptr) return nullptr;
+
+  if (range->IsEmpty() || range->Start() > position) {
+    // Can happen if there is a definition without use.
+    range->AddUseInterval(position, position.NextStart(), allocation_zone());
+    range->AddUsePosition(NewUsePosition(position.NextStart()));
+  } else {
+    range->ShortenTo(position);
+  }
+  if (!operand->IsUnallocated()) return nullptr;
+  UnallocatedOperand* unalloc_operand = UnallocatedOperand::cast(operand);
+  UsePosition* use_pos =
+      NewUsePosition(position, unalloc_operand, hint, hint_type);
+  range->AddUsePosition(use_pos);
+  return use_pos;
+}
+
+
+UsePosition* LiveRangeBuilder::Use(LifetimePosition block_start,
+                                   LifetimePosition position,
+                                   InstructionOperand* operand, void* hint,
+                                   UsePositionHintType hint_type) {
+  TopLevelLiveRange* range = LiveRangeFor(operand);
+  if (range == nullptr) return nullptr;
+  UsePosition* use_pos = nullptr;
+  if (operand->IsUnallocated()) {
+    UnallocatedOperand* unalloc_operand = UnallocatedOperand::cast(operand);
+    use_pos = NewUsePosition(position, unalloc_operand, hint, hint_type);
+    range->AddUsePosition(use_pos);
+  }
+  range->AddUseInterval(block_start, position, allocation_zone());
+  return use_pos;
+}
+
+
+void LiveRangeBuilder::ProcessInstructions(const InstructionBlock* block,
+                                           BitVector* live) {
+  int block_start = block->first_instruction_index();
+  LifetimePosition block_start_position =
+      LifetimePosition::GapFromInstructionIndex(block_start);
+
+  for (int index = block->last_instruction_index(); index >= block_start;
+       index--) {
+    LifetimePosition curr_position =
+        LifetimePosition::InstructionFromInstructionIndex(index);
+    Instruction* instr = code()->InstructionAt(index);
+    DCHECK(instr != nullptr);
+    DCHECK(curr_position.IsInstructionPosition());
+    // Process output, inputs, and temps of this instruction.
+    for (size_t i = 0; i < instr->OutputCount(); i++) {
+      InstructionOperand* output = instr->OutputAt(i);
+      if (output->IsUnallocated()) {
+        // Unsupported.
+        DCHECK(!UnallocatedOperand::cast(output)->HasSlotPolicy());
+        int out_vreg = UnallocatedOperand::cast(output)->virtual_register();
+        live->Remove(out_vreg);
+      } else if (output->IsConstant()) {
+        int out_vreg = ConstantOperand::cast(output)->virtual_register();
+        live->Remove(out_vreg);
+      }
+      if (block->IsHandler() && index == block_start && output->IsAllocated() &&
+          output->IsRegister() &&
+          AllocatedOperand::cast(output)->GetRegister().is(
+              v8::internal::kReturnRegister0)) {
+        // The register defined here is blocked from gap start - it is the
+        // exception value.
+        // TODO(mtrofin): should we explore an explicit opcode for
+        // the first instruction in the handler?
+        Define(LifetimePosition::GapFromInstructionIndex(index), output);
+      } else {
+        Define(curr_position, output);
+      }
+    }
+
+    if (instr->ClobbersRegisters()) {
+      for (int i = 0; i < config()->num_allocatable_general_registers(); ++i) {
+        int code = config()->GetAllocatableGeneralCode(i);
+        if (!IsOutputRegisterOf(instr, Register::from_code(code))) {
+          TopLevelLiveRange* range = FixedLiveRangeFor(code);
+          range->AddUseInterval(curr_position, curr_position.End(),
+                                allocation_zone());
+        }
+      }
+    }
+
+    if (instr->ClobbersDoubleRegisters()) {
+      for (int i = 0; i < config()->num_allocatable_aliased_double_registers();
+           ++i) {
+        int code = config()->GetAllocatableDoubleCode(i);
+        if (!IsOutputDoubleRegisterOf(instr, DoubleRegister::from_code(code))) {
+          TopLevelLiveRange* range = FixedDoubleLiveRangeFor(code);
+          range->AddUseInterval(curr_position, curr_position.End(),
+                                allocation_zone());
+        }
+      }
+    }
+
+    for (size_t i = 0; i < instr->InputCount(); i++) {
+      InstructionOperand* input = instr->InputAt(i);
+      if (input->IsImmediate() || input->IsExplicit()) {
+        continue;  // Ignore immediates and explicitly reserved registers.
+      }
+      LifetimePosition use_pos;
+      if (input->IsUnallocated() &&
+          UnallocatedOperand::cast(input)->IsUsedAtStart()) {
+        use_pos = curr_position;
+      } else {
+        use_pos = curr_position.End();
+      }
+
+      if (input->IsUnallocated()) {
+        UnallocatedOperand* unalloc = UnallocatedOperand::cast(input);
+        int vreg = unalloc->virtual_register();
+        live->Add(vreg);
+        if (unalloc->HasSlotPolicy()) {
+          data()->GetOrCreateLiveRangeFor(vreg)->set_has_slot_use(true);
+        }
+      }
+      Use(block_start_position, use_pos, input);
+    }
+
+    for (size_t i = 0; i < instr->TempCount(); i++) {
+      InstructionOperand* temp = instr->TempAt(i);
+      // Unsupported.
+      DCHECK_IMPLIES(temp->IsUnallocated(),
+                     !UnallocatedOperand::cast(temp)->HasSlotPolicy());
+      if (instr->ClobbersTemps()) {
+        if (temp->IsRegister()) continue;
+        if (temp->IsUnallocated()) {
+          UnallocatedOperand* temp_unalloc = UnallocatedOperand::cast(temp);
+          if (temp_unalloc->HasFixedPolicy()) {
+            continue;
+          }
+        }
+      }
+      Use(block_start_position, curr_position.End(), temp);
+      Define(curr_position, temp);
+    }
+
+    // Process the moves of the instruction's gaps, making their sources live.
+    const Instruction::GapPosition kPositions[] = {Instruction::END,
+                                                   Instruction::START};
+    curr_position = curr_position.PrevStart();
+    DCHECK(curr_position.IsGapPosition());
+    for (const Instruction::GapPosition& position : kPositions) {
+      ParallelMove* move = instr->GetParallelMove(position);
+      if (move == nullptr) continue;
+      if (position == Instruction::END) {
+        curr_position = curr_position.End();
+      } else {
+        curr_position = curr_position.Start();
+      }
+      for (MoveOperands* cur : *move) {
+        InstructionOperand& from = cur->source();
+        InstructionOperand& to = cur->destination();
+        void* hint = &to;
+        UsePositionHintType hint_type = UsePosition::HintTypeForOperand(to);
+        UsePosition* to_use = nullptr;
+        int phi_vreg = -1;
+        if (to.IsUnallocated()) {
+          int to_vreg = UnallocatedOperand::cast(to).virtual_register();
+          TopLevelLiveRange* to_range =
+              data()->GetOrCreateLiveRangeFor(to_vreg);
+          if (to_range->is_phi()) {
+            phi_vreg = to_vreg;
+            if (to_range->is_non_loop_phi()) {
+              hint = to_range->current_hint_position();
+              hint_type = hint == nullptr ? UsePositionHintType::kNone
+                                          : UsePositionHintType::kUsePos;
+            } else {
+              hint_type = UsePositionHintType::kPhi;
+              hint = data()->GetPhiMapValueFor(to_vreg);
+            }
+          } else {
+            if (live->Contains(to_vreg)) {
+              to_use = Define(curr_position, &to, &from,
+                              UsePosition::HintTypeForOperand(from));
+              live->Remove(to_vreg);
+            } else {
+              cur->Eliminate();
+              continue;
+            }
+          }
+        } else {
+          Define(curr_position, &to);
+        }
+        UsePosition* from_use =
+            Use(block_start_position, curr_position, &from, hint, hint_type);
+        // Mark range live.
+        if (from.IsUnallocated()) {
+          live->Add(UnallocatedOperand::cast(from).virtual_register());
+        }
+        // Resolve use position hints just created.
+        if (to_use != nullptr && from_use != nullptr) {
+          to_use->ResolveHint(from_use);
+          from_use->ResolveHint(to_use);
+        }
+        DCHECK_IMPLIES(to_use != nullptr, to_use->IsResolved());
+        DCHECK_IMPLIES(from_use != nullptr, from_use->IsResolved());
+        // Potentially resolve phi hint.
+        if (phi_vreg != -1) ResolvePhiHint(&from, from_use);
+      }
+    }
+  }
+}
+
+
+void LiveRangeBuilder::ProcessPhis(const InstructionBlock* block,
+                                   BitVector* live) {
+  for (PhiInstruction* phi : block->phis()) {
+    // The live range interval already ends at the first instruction of the
+    // block.
+    int phi_vreg = phi->virtual_register();
+    live->Remove(phi_vreg);
+    InstructionOperand* hint = nullptr;
+    Instruction* instr = GetLastInstruction(
+        code(), code()->InstructionBlockAt(block->predecessors()[0]));
+    for (MoveOperands* move : *instr->GetParallelMove(Instruction::END)) {
+      InstructionOperand& to = move->destination();
+      if (to.IsUnallocated() &&
+          UnallocatedOperand::cast(to).virtual_register() == phi_vreg) {
+        hint = &move->source();
+        break;
+      }
+    }
+    DCHECK(hint != nullptr);
+    LifetimePosition block_start = LifetimePosition::GapFromInstructionIndex(
+        block->first_instruction_index());
+    UsePosition* use_pos = Define(block_start, &phi->output(), hint,
+                                  UsePosition::HintTypeForOperand(*hint));
+    MapPhiHint(hint, use_pos);
+  }
+}
+
+
+void LiveRangeBuilder::ProcessLoopHeader(const InstructionBlock* block,
+                                         BitVector* live) {
+  DCHECK(block->IsLoopHeader());
+  // Add a live range stretching from the first loop instruction to the last
+  // for each value live on entry to the header.
+  BitVector::Iterator iterator(live);
+  LifetimePosition start = LifetimePosition::GapFromInstructionIndex(
+      block->first_instruction_index());
+  LifetimePosition end = LifetimePosition::GapFromInstructionIndex(
+                             code()->LastLoopInstructionIndex(block))
+                             .NextFullStart();
+  while (!iterator.Done()) {
+    int operand_index = iterator.Current();
+    TopLevelLiveRange* range = data()->GetOrCreateLiveRangeFor(operand_index);
+    range->EnsureInterval(start, end, allocation_zone());
+    iterator.Advance();
+  }
+  // Insert all values into the live in sets of all blocks in the loop.
+  for (int i = block->rpo_number().ToInt() + 1; i < block->loop_end().ToInt();
+       ++i) {
+    live_in_sets()[i]->Union(*live);
+  }
+}
+
+
+void LiveRangeBuilder::BuildLiveRanges() {
+  // Process the blocks in reverse order.
+  for (int block_id = code()->InstructionBlockCount() - 1; block_id >= 0;
+       --block_id) {
+    InstructionBlock* block =
+        code()->InstructionBlockAt(RpoNumber::FromInt(block_id));
+    BitVector* live = ComputeLiveOut(block, data());
+    // Initially consider all live_out values live for the entire block. We
+    // will shorten these intervals if necessary.
+    AddInitialIntervals(block, live);
+    // Process the instructions in reverse order, generating and killing
+    // live values.
+    ProcessInstructions(block, live);
+    // All phi output operands are killed by this block.
+    ProcessPhis(block, live);
+    // Now live is live_in for this block except not including values live
+    // out on backward successor edges.
+    if (block->IsLoopHeader()) ProcessLoopHeader(block, live);
+    live_in_sets()[block_id] = live;
+  }
+  // Postprocess the ranges.
+  for (TopLevelLiveRange* range : data()->live_ranges()) {
+    if (range == nullptr) continue;
+    // Give slots to all ranges with a non fixed slot use.
+    if (range->has_slot_use() && range->HasNoSpillType()) {
+      data()->AssignSpillRangeToLiveRange(range);
+    }
+    // TODO(bmeurer): This is a horrible hack to make sure that for constant
+    // live ranges, every use requires the constant to be in a register.
+    // Without this hack, all uses with "any" policy would get the constant
+    // operand assigned.
+    if (range->HasSpillOperand() && range->GetSpillOperand()->IsConstant()) {
+      for (UsePosition* pos = range->first_pos(); pos != nullptr;
+           pos = pos->next()) {
+        if (pos->type() == UsePositionType::kRequiresSlot) continue;
+        UsePositionType new_type = UsePositionType::kAny;
+        // Can't mark phis as needing a register.
+        if (!pos->pos().IsGapPosition()) {
+          new_type = UsePositionType::kRequiresRegister;
+        }
+        pos->set_type(new_type, true);
+      }
+    }
+  }
+  for (auto preassigned : data()->preassigned_slot_ranges()) {
+    TopLevelLiveRange* range = preassigned.first;
+    int slot_id = preassigned.second;
+    SpillRange* spill = range->HasSpillRange()
+                            ? range->GetSpillRange()
+                            : data()->AssignSpillRangeToLiveRange(range);
+    spill->set_assigned_slot(slot_id);
+  }
+#ifdef DEBUG
+  Verify();
+#endif
+}
+
+
+void LiveRangeBuilder::MapPhiHint(InstructionOperand* operand,
+                                  UsePosition* use_pos) {
+  DCHECK(!use_pos->IsResolved());
+  auto res = phi_hints_.insert(std::make_pair(operand, use_pos));
+  DCHECK(res.second);
+  USE(res);
+}
+
+
+void LiveRangeBuilder::ResolvePhiHint(InstructionOperand* operand,
+                                      UsePosition* use_pos) {
+  auto it = phi_hints_.find(operand);
+  if (it == phi_hints_.end()) return;
+  DCHECK(!it->second->IsResolved());
+  it->second->ResolveHint(use_pos);
+}
+
+
+void LiveRangeBuilder::Verify() const {
+  for (auto& hint : phi_hints_) {
+    CHECK(hint.second->IsResolved());
+  }
+  for (TopLevelLiveRange* current : data()->live_ranges()) {
+    if (current != nullptr && !current->IsEmpty()) current->Verify();
+  }
+}
+
+
+RegisterAllocator::RegisterAllocator(RegisterAllocationData* data,
+                                     RegisterKind kind)
+    : data_(data),
+      mode_(kind),
+      num_registers_(GetRegisterCount(data->config(), kind)),
+      num_allocatable_registers_(
+          GetAllocatableRegisterCount(data->config(), kind)),
+      allocatable_register_codes_(
+          GetAllocatableRegisterCodes(data->config(), kind)) {}
+
+
+LifetimePosition RegisterAllocator::GetSplitPositionForInstruction(
+    const LiveRange* range, int instruction_index) {
+  LifetimePosition ret = LifetimePosition::Invalid();
+
+  ret = LifetimePosition::GapFromInstructionIndex(instruction_index);
+  if (range->Start() >= ret || ret >= range->End()) {
+    return LifetimePosition::Invalid();
+  }
+  return ret;
+}
+
+
+void RegisterAllocator::SplitAndSpillRangesDefinedByMemoryOperand(
+    bool operands_only) {
+  size_t initial_range_count = data()->live_ranges().size();
+  for (size_t i = 0; i < initial_range_count; ++i) {
+    TopLevelLiveRange* range = data()->live_ranges()[i];
+    if (!CanProcessRange(range)) continue;
+    if (range->HasNoSpillType() || (operands_only && range->HasSpillRange())) {
+      continue;
+    }
+
+    LifetimePosition start = range->Start();
+    TRACE("Live range %d:%d is defined by a spill operand.\n",
+          range->TopLevel()->vreg(), range->relative_id());
+    LifetimePosition next_pos = start;
+    if (next_pos.IsGapPosition()) {
+      next_pos = next_pos.NextStart();
+    }
+    UsePosition* pos = range->NextUsePositionRegisterIsBeneficial(next_pos);
+    // If the range already has a spill operand and it doesn't need a
+    // register immediately, split it and spill the first part of the range.
+    if (pos == nullptr) {
+      Spill(range);
+    } else if (pos->pos() > range->Start().NextStart()) {
+      // Do not spill live range eagerly if use position that can benefit from
+      // the register is too close to the start of live range.
+      LifetimePosition split_pos = GetSplitPositionForInstruction(
+          range, pos->pos().ToInstructionIndex());
+      // There is no place to split, so we can't split and spill.
+      if (!split_pos.IsValid()) continue;
+
+      split_pos =
+          FindOptimalSplitPos(range->Start().NextFullStart(), split_pos);
+
+      SplitRangeAt(range, split_pos);
+      Spill(range);
+    }
+  }
+}
+
+
+LiveRange* RegisterAllocator::SplitRangeAt(LiveRange* range,
+                                           LifetimePosition pos) {
+  DCHECK(!range->TopLevel()->IsFixed());
+  TRACE("Splitting live range %d:%d at %d\n", range->TopLevel()->vreg(),
+        range->relative_id(), pos.value());
+
+  if (pos <= range->Start()) return range;
+
+  // We can't properly connect liveranges if splitting occurred at the end
+  // a block.
+  DCHECK(pos.IsStart() || pos.IsGapPosition() ||
+         (GetInstructionBlock(code(), pos)->last_instruction_index() !=
+          pos.ToInstructionIndex()));
+
+  LiveRange* result = range->SplitAt(pos, allocation_zone());
+  return result;
+}
+
+
+LiveRange* RegisterAllocator::SplitBetween(LiveRange* range,
+                                           LifetimePosition start,
+                                           LifetimePosition end) {
+  DCHECK(!range->TopLevel()->IsFixed());
+  TRACE("Splitting live range %d:%d in position between [%d, %d]\n",
+        range->TopLevel()->vreg(), range->relative_id(), start.value(),
+        end.value());
+
+  LifetimePosition split_pos = FindOptimalSplitPos(start, end);
+  DCHECK(split_pos >= start);
+  return SplitRangeAt(range, split_pos);
+}
+
+
+LifetimePosition RegisterAllocator::FindOptimalSplitPos(LifetimePosition start,
+                                                        LifetimePosition end) {
+  int start_instr = start.ToInstructionIndex();
+  int end_instr = end.ToInstructionIndex();
+  DCHECK(start_instr <= end_instr);
+
+  // We have no choice
+  if (start_instr == end_instr) return end;
+
+  const InstructionBlock* start_block = GetInstructionBlock(code(), start);
+  const InstructionBlock* end_block = GetInstructionBlock(code(), end);
+
+  if (end_block == start_block) {
+    // The interval is split in the same basic block. Split at the latest
+    // possible position.
+    return end;
+  }
+
+  const InstructionBlock* block = end_block;
+  // Find header of outermost loop.
+  // TODO(titzer): fix redundancy below.
+  while (GetContainingLoop(code(), block) != nullptr &&
+         GetContainingLoop(code(), block)->rpo_number().ToInt() >
+             start_block->rpo_number().ToInt()) {
+    block = GetContainingLoop(code(), block);
+  }
+
+  // We did not find any suitable outer loop. Split at the latest possible
+  // position unless end_block is a loop header itself.
+  if (block == end_block && !end_block->IsLoopHeader()) return end;
+
+  return LifetimePosition::GapFromInstructionIndex(
+      block->first_instruction_index());
+}
+
+
+LifetimePosition RegisterAllocator::FindOptimalSpillingPos(
+    LiveRange* range, LifetimePosition pos) {
+  const InstructionBlock* block = GetInstructionBlock(code(), pos.Start());
+  const InstructionBlock* loop_header =
+      block->IsLoopHeader() ? block : GetContainingLoop(code(), block);
+
+  if (loop_header == nullptr) return pos;
+
+  const UsePosition* prev_use =
+      range->PreviousUsePositionRegisterIsBeneficial(pos);
+
+  while (loop_header != nullptr) {
+    // We are going to spill live range inside the loop.
+    // If possible try to move spilling position backwards to loop header.
+    // This will reduce number of memory moves on the back edge.
+    LifetimePosition loop_start = LifetimePosition::GapFromInstructionIndex(
+        loop_header->first_instruction_index());
+
+    if (range->Covers(loop_start)) {
+      if (prev_use == nullptr || prev_use->pos() < loop_start) {
+        // No register beneficial use inside the loop before the pos.
+        pos = loop_start;
+      }
+    }
+
+    // Try hoisting out to an outer loop.
+    loop_header = GetContainingLoop(code(), loop_header);
+  }
+
+  return pos;
+}
+
+
+void RegisterAllocator::Spill(LiveRange* range) {
+  DCHECK(!range->spilled());
+  TopLevelLiveRange* first = range->TopLevel();
+  TRACE("Spilling live range %d:%d\n", first->vreg(), range->relative_id());
+
+  if (first->HasNoSpillType()) {
+    data()->AssignSpillRangeToLiveRange(first);
+  }
+  range->Spill();
+}
+
+
+const ZoneVector<TopLevelLiveRange*>& RegisterAllocator::GetFixedRegisters()
+    const {
+  return mode() == DOUBLE_REGISTERS ? data()->fixed_double_live_ranges()
+                                    : data()->fixed_live_ranges();
+}
+
+
+const char* RegisterAllocator::RegisterName(int register_code) const {
+  if (mode() == GENERAL_REGISTERS) {
+    return data()->config()->GetGeneralRegisterName(register_code);
+  } else {
+    return data()->config()->GetDoubleRegisterName(register_code);
+  }
+}
+
+
+LinearScanAllocator::LinearScanAllocator(RegisterAllocationData* data,
+                                         RegisterKind kind, Zone* local_zone)
+    : RegisterAllocator(data, kind),
+      unhandled_live_ranges_(local_zone),
+      active_live_ranges_(local_zone),
+      inactive_live_ranges_(local_zone) {
+  unhandled_live_ranges().reserve(
+      static_cast<size_t>(code()->VirtualRegisterCount() * 2));
+  active_live_ranges().reserve(8);
+  inactive_live_ranges().reserve(8);
+  // TryAllocateFreeReg and AllocateBlockedReg assume this
+  // when allocating local arrays.
+  DCHECK(RegisterConfiguration::kMaxDoubleRegisters >=
+         this->data()->config()->num_general_registers());
+}
+
+
+void LinearScanAllocator::AllocateRegisters() {
+  DCHECK(unhandled_live_ranges().empty());
+  DCHECK(active_live_ranges().empty());
+  DCHECK(inactive_live_ranges().empty());
+
+  SplitAndSpillRangesDefinedByMemoryOperand(code()->VirtualRegisterCount() <=
+                                            num_allocatable_registers());
+
+  for (TopLevelLiveRange* range : data()->live_ranges()) {
+    if (!CanProcessRange(range)) continue;
+    for (LiveRange* to_add = range; to_add != nullptr;
+         to_add = to_add->next()) {
+      if (!to_add->spilled()) {
+        AddToUnhandledUnsorted(to_add);
+      }
+    }
+  }
+  SortUnhandled();
+  DCHECK(UnhandledIsSorted());
+
+  auto& fixed_ranges = GetFixedRegisters();
+  for (TopLevelLiveRange* current : fixed_ranges) {
+    if (current != nullptr) {
+      DCHECK_EQ(mode(), current->kind());
+      AddToInactive(current);
+    }
+  }
+
+  while (!unhandled_live_ranges().empty()) {
+    DCHECK(UnhandledIsSorted());
+    LiveRange* current = unhandled_live_ranges().back();
+    unhandled_live_ranges().pop_back();
+    DCHECK(UnhandledIsSorted());
+    LifetimePosition position = current->Start();
+#ifdef DEBUG
+    allocation_finger_ = position;
+#endif
+    TRACE("Processing interval %d:%d start=%d\n", current->TopLevel()->vreg(),
+          current->relative_id(), position.value());
+
+    if (current->IsTopLevel() && TryReuseSpillForPhi(current->TopLevel()))
+      continue;
+
+    for (size_t i = 0; i < active_live_ranges().size(); ++i) {
+      LiveRange* cur_active = active_live_ranges()[i];
+      if (cur_active->End() <= position) {
+        ActiveToHandled(cur_active);
+        --i;  // The live range was removed from the list of active live ranges.
+      } else if (!cur_active->Covers(position)) {
+        ActiveToInactive(cur_active);
+        --i;  // The live range was removed from the list of active live ranges.
+      }
+    }
+
+    for (size_t i = 0; i < inactive_live_ranges().size(); ++i) {
+      LiveRange* cur_inactive = inactive_live_ranges()[i];
+      if (cur_inactive->End() <= position) {
+        InactiveToHandled(cur_inactive);
+        --i;  // Live range was removed from the list of inactive live ranges.
+      } else if (cur_inactive->Covers(position)) {
+        InactiveToActive(cur_inactive);
+        --i;  // Live range was removed from the list of inactive live ranges.
+      }
+    }
+
+    DCHECK(!current->HasRegisterAssigned() && !current->spilled());
+
+    bool result = TryAllocateFreeReg(current);
+    if (!result) AllocateBlockedReg(current);
+    if (current->HasRegisterAssigned()) {
+      AddToActive(current);
+    }
+  }
+}
+
+
+void LinearScanAllocator::SetLiveRangeAssignedRegister(LiveRange* range,
+                                                       int reg) {
+  data()->MarkAllocated(range->kind(), reg);
+  range->set_assigned_register(reg);
+  range->SetUseHints(reg);
+  if (range->IsTopLevel() && range->TopLevel()->is_phi()) {
+    data()->GetPhiMapValueFor(range->TopLevel())->set_assigned_register(reg);
+  }
+}
+
+
+void LinearScanAllocator::AddToActive(LiveRange* range) {
+  TRACE("Add live range %d:%d to active\n", range->TopLevel()->vreg(),
+        range->relative_id());
+  active_live_ranges().push_back(range);
+}
+
+
+void LinearScanAllocator::AddToInactive(LiveRange* range) {
+  TRACE("Add live range %d:%d to inactive\n", range->TopLevel()->vreg(),
+        range->relative_id());
+  inactive_live_ranges().push_back(range);
+}
+
+
+void LinearScanAllocator::AddToUnhandledSorted(LiveRange* range) {
+  if (range == nullptr || range->IsEmpty()) return;
+  DCHECK(!range->HasRegisterAssigned() && !range->spilled());
+  DCHECK(allocation_finger_ <= range->Start());
+  for (int i = static_cast<int>(unhandled_live_ranges().size() - 1); i >= 0;
+       --i) {
+    LiveRange* cur_range = unhandled_live_ranges().at(i);
+    if (!range->ShouldBeAllocatedBefore(cur_range)) continue;
+    TRACE("Add live range %d:%d to unhandled at %d\n",
+          range->TopLevel()->vreg(), range->relative_id(), i + 1);
+    auto it = unhandled_live_ranges().begin() + (i + 1);
+    unhandled_live_ranges().insert(it, range);
+    DCHECK(UnhandledIsSorted());
+    return;
+  }
+  TRACE("Add live range %d:%d to unhandled at start\n",
+        range->TopLevel()->vreg(), range->relative_id());
+  unhandled_live_ranges().insert(unhandled_live_ranges().begin(), range);
+  DCHECK(UnhandledIsSorted());
+}
+
+
+void LinearScanAllocator::AddToUnhandledUnsorted(LiveRange* range) {
+  if (range == nullptr || range->IsEmpty()) return;
+  DCHECK(!range->HasRegisterAssigned() && !range->spilled());
+  TRACE("Add live range %d:%d to unhandled unsorted at end\n",
+        range->TopLevel()->vreg(), range->relative_id());
+  unhandled_live_ranges().push_back(range);
+}
+
+
+static bool UnhandledSortHelper(LiveRange* a, LiveRange* b) {
+  DCHECK(!a->ShouldBeAllocatedBefore(b) || !b->ShouldBeAllocatedBefore(a));
+  if (a->ShouldBeAllocatedBefore(b)) return false;
+  if (b->ShouldBeAllocatedBefore(a)) return true;
+  return a->TopLevel()->vreg() < b->TopLevel()->vreg();
+}
+
+
+// Sort the unhandled live ranges so that the ranges to be processed first are
+// at the end of the array list.  This is convenient for the register allocation
+// algorithm because it is efficient to remove elements from the end.
+void LinearScanAllocator::SortUnhandled() {
+  TRACE("Sort unhandled\n");
+  std::sort(unhandled_live_ranges().begin(), unhandled_live_ranges().end(),
+            &UnhandledSortHelper);
+}
+
+
+bool LinearScanAllocator::UnhandledIsSorted() {
+  size_t len = unhandled_live_ranges().size();
+  for (size_t i = 1; i < len; i++) {
+    LiveRange* a = unhandled_live_ranges().at(i - 1);
+    LiveRange* b = unhandled_live_ranges().at(i);
+    if (a->Start() < b->Start()) return false;
+  }
+  return true;
+}
+
+
+void LinearScanAllocator::ActiveToHandled(LiveRange* range) {
+  RemoveElement(&active_live_ranges(), range);
+  TRACE("Moving live range %d:%d from active to handled\n",
+        range->TopLevel()->vreg(), range->relative_id());
+}
+
+
+void LinearScanAllocator::ActiveToInactive(LiveRange* range) {
+  RemoveElement(&active_live_ranges(), range);
+  inactive_live_ranges().push_back(range);
+  TRACE("Moving live range %d:%d from active to inactive\n",
+        range->TopLevel()->vreg(), range->relative_id());
+}
+
+
+void LinearScanAllocator::InactiveToHandled(LiveRange* range) {
+  RemoveElement(&inactive_live_ranges(), range);
+  TRACE("Moving live range %d:%d from inactive to handled\n",
+        range->TopLevel()->vreg(), range->relative_id());
+}
+
+
+void LinearScanAllocator::InactiveToActive(LiveRange* range) {
+  RemoveElement(&inactive_live_ranges(), range);
+  active_live_ranges().push_back(range);
+  TRACE("Moving live range %d:%d from inactive to active\n",
+        range->TopLevel()->vreg(), range->relative_id());
+}
+
+
+bool LinearScanAllocator::TryAllocateFreeReg(LiveRange* current) {
+  LifetimePosition free_until_pos[RegisterConfiguration::kMaxDoubleRegisters];
+
+  for (int i = 0; i < num_registers(); i++) {
+    free_until_pos[i] = LifetimePosition::MaxPosition();
+  }
+
+  for (LiveRange* cur_active : active_live_ranges()) {
+    free_until_pos[cur_active->assigned_register()] =
+        LifetimePosition::GapFromInstructionIndex(0);
+    TRACE("Register %s is free until pos %d (1)\n",
+          RegisterName(cur_active->assigned_register()),
+          LifetimePosition::GapFromInstructionIndex(0).value());
+  }
+
+  for (LiveRange* cur_inactive : inactive_live_ranges()) {
+    DCHECK(cur_inactive->End() > current->Start());
+    LifetimePosition next_intersection =
+        cur_inactive->FirstIntersection(current);
+    if (!next_intersection.IsValid()) continue;
+    int cur_reg = cur_inactive->assigned_register();
+    free_until_pos[cur_reg] = Min(free_until_pos[cur_reg], next_intersection);
+    TRACE("Register %s is free until pos %d (2)\n", RegisterName(cur_reg),
+          Min(free_until_pos[cur_reg], next_intersection).value());
+  }
+
+  int hint_register;
+  if (current->FirstHintPosition(&hint_register) != nullptr) {
+    TRACE(
+        "Found reg hint %s (free until [%d) for live range %d:%d (end %d[).\n",
+        RegisterName(hint_register), free_until_pos[hint_register].value(),
+        current->TopLevel()->vreg(), current->relative_id(),
+        current->End().value());
+
+    // The desired register is free until the end of the current live range.
+    if (free_until_pos[hint_register] >= current->End()) {
+      TRACE("Assigning preferred reg %s to live range %d:%d\n",
+            RegisterName(hint_register), current->TopLevel()->vreg(),
+            current->relative_id());
+      SetLiveRangeAssignedRegister(current, hint_register);
+      return true;
+    }
+  }
+
+  // Find the register which stays free for the longest time.
+  int reg = allocatable_register_code(0);
+  for (int i = 1; i < num_allocatable_registers(); ++i) {
+    int code = allocatable_register_code(i);
+    if (free_until_pos[code] > free_until_pos[reg]) {
+      reg = code;
+    }
+  }
+
+  LifetimePosition pos = free_until_pos[reg];
+
+  if (pos <= current->Start()) {
+    // All registers are blocked.
+    return false;
+  }
+
+  if (pos < current->End()) {
+    // Register reg is available at the range start but becomes blocked before
+    // the range end. Split current at position where it becomes blocked.
+    LiveRange* tail = SplitRangeAt(current, pos);
+    AddToUnhandledSorted(tail);
+  }
+
+  // Register reg is available at the range start and is free until
+  // the range end.
+  DCHECK(pos >= current->End());
+  TRACE("Assigning free reg %s to live range %d:%d\n", RegisterName(reg),
+        current->TopLevel()->vreg(), current->relative_id());
+  SetLiveRangeAssignedRegister(current, reg);
+
+  return true;
+}
+
+
+void LinearScanAllocator::AllocateBlockedReg(LiveRange* current) {
+  UsePosition* register_use = current->NextRegisterPosition(current->Start());
+  if (register_use == nullptr) {
+    // There is no use in the current live range that requires a register.
+    // We can just spill it.
+    Spill(current);
+    return;
+  }
+
+  LifetimePosition use_pos[RegisterConfiguration::kMaxDoubleRegisters];
+  LifetimePosition block_pos[RegisterConfiguration::kMaxDoubleRegisters];
+
+  for (int i = 0; i < num_registers(); i++) {
+    use_pos[i] = block_pos[i] = LifetimePosition::MaxPosition();
+  }
+
+  for (LiveRange* range : active_live_ranges()) {
+    int cur_reg = range->assigned_register();
+    if (range->TopLevel()->IsFixed() ||
+        !range->CanBeSpilled(current->Start())) {
+      block_pos[cur_reg] = use_pos[cur_reg] =
+          LifetimePosition::GapFromInstructionIndex(0);
+    } else {
+      UsePosition* next_use =
+          range->NextUsePositionRegisterIsBeneficial(current->Start());
+      if (next_use == nullptr) {
+        use_pos[cur_reg] = range->End();
+      } else {
+        use_pos[cur_reg] = next_use->pos();
+      }
+    }
+  }
+
+  for (LiveRange* range : inactive_live_ranges()) {
+    DCHECK(range->End() > current->Start());
+    LifetimePosition next_intersection = range->FirstIntersection(current);
+    if (!next_intersection.IsValid()) continue;
+    int cur_reg = range->assigned_register();
+    if (range->TopLevel()->IsFixed()) {
+      block_pos[cur_reg] = Min(block_pos[cur_reg], next_intersection);
+      use_pos[cur_reg] = Min(block_pos[cur_reg], use_pos[cur_reg]);
+    } else {
+      use_pos[cur_reg] = Min(use_pos[cur_reg], next_intersection);
+    }
+  }
+
+  int reg = allocatable_register_code(0);
+  for (int i = 1; i < num_allocatable_registers(); ++i) {
+    int code = allocatable_register_code(i);
+    if (use_pos[code] > use_pos[reg]) {
+      reg = code;
+    }
+  }
+
+  LifetimePosition pos = use_pos[reg];
+
+  if (pos < register_use->pos()) {
+    // All registers are blocked before the first use that requires a register.
+    // Spill starting part of live range up to that use.
+    SpillBetween(current, current->Start(), register_use->pos());
+    return;
+  }
+
+  if (block_pos[reg] < current->End()) {
+    // Register becomes blocked before the current range end. Split before that
+    // position.
+    LiveRange* tail =
+        SplitBetween(current, current->Start(), block_pos[reg].Start());
+    AddToUnhandledSorted(tail);
+  }
+
+  // Register reg is not blocked for the whole range.
+  DCHECK(block_pos[reg] >= current->End());
+  TRACE("Assigning blocked reg %s to live range %d:%d\n", RegisterName(reg),
+        current->TopLevel()->vreg(), current->relative_id());
+  SetLiveRangeAssignedRegister(current, reg);
+
+  // This register was not free. Thus we need to find and spill
+  // parts of active and inactive live regions that use the same register
+  // at the same lifetime positions as current.
+  SplitAndSpillIntersecting(current);
+}
+
+
+void LinearScanAllocator::SplitAndSpillIntersecting(LiveRange* current) {
+  DCHECK(current->HasRegisterAssigned());
+  int reg = current->assigned_register();
+  LifetimePosition split_pos = current->Start();
+  for (size_t i = 0; i < active_live_ranges().size(); ++i) {
+    LiveRange* range = active_live_ranges()[i];
+    if (range->assigned_register() == reg) {
+      UsePosition* next_pos = range->NextRegisterPosition(current->Start());
+      LifetimePosition spill_pos = FindOptimalSpillingPos(range, split_pos);
+      if (next_pos == nullptr) {
+        SpillAfter(range, spill_pos);
+      } else {
+        // When spilling between spill_pos and next_pos ensure that the range
+        // remains spilled at least until the start of the current live range.
+        // This guarantees that we will not introduce new unhandled ranges that
+        // start before the current range as this violates allocation invariant
+        // and will lead to an inconsistent state of active and inactive
+        // live-ranges: ranges are allocated in order of their start positions,
+        // ranges are retired from active/inactive when the start of the
+        // current live-range is larger than their end.
+        SpillBetweenUntil(range, spill_pos, current->Start(), next_pos->pos());
+      }
+      ActiveToHandled(range);
+      --i;
+    }
+  }
+
+  for (size_t i = 0; i < inactive_live_ranges().size(); ++i) {
+    LiveRange* range = inactive_live_ranges()[i];
+    DCHECK(range->End() > current->Start());
+    if (range->assigned_register() == reg && !range->TopLevel()->IsFixed()) {
+      LifetimePosition next_intersection = range->FirstIntersection(current);
+      if (next_intersection.IsValid()) {
+        UsePosition* next_pos = range->NextRegisterPosition(current->Start());
+        if (next_pos == nullptr) {
+          SpillAfter(range, split_pos);
+        } else {
+          next_intersection = Min(next_intersection, next_pos->pos());
+          SpillBetween(range, split_pos, next_intersection);
+        }
+        InactiveToHandled(range);
+        --i;
+      }
+    }
+  }
+}
+
+
+bool LinearScanAllocator::TryReuseSpillForPhi(TopLevelLiveRange* range) {
+  if (!range->is_phi()) return false;
+
+  DCHECK(!range->HasSpillOperand());
+  RegisterAllocationData::PhiMapValue* phi_map_value =
+      data()->GetPhiMapValueFor(range);
+  const PhiInstruction* phi = phi_map_value->phi();
+  const InstructionBlock* block = phi_map_value->block();
   // Count the number of spilled operands.
   size_t spilled_count = 0;
   LiveRange* first_op = nullptr;
   for (size_t i = 0; i < phi->operands().size(); i++) {
     int op = phi->operands()[i];
-    LiveRange* op_range = LiveRangeFor(op);
-    if (op_range->GetSpillRange() == nullptr) continue;
-    auto pred = code()->InstructionBlockAt(block->predecessors()[i]);
-    auto pred_end =
-        LifetimePosition::FromInstructionIndex(pred->last_instruction_index());
+    LiveRange* op_range = data()->GetOrCreateLiveRangeFor(op);
+    if (!op_range->TopLevel()->HasSpillRange()) continue;
+    const InstructionBlock* pred =
+        code()->InstructionBlockAt(block->predecessors()[i]);
+    LifetimePosition pred_end =
+        LifetimePosition::InstructionFromInstructionIndex(
+            pred->last_instruction_index());
     while (op_range != nullptr && !op_range->CanCover(pred_end)) {
       op_range = op_range->next();
     }
-    if (op_range != nullptr && op_range->IsSpilled()) {
+    if (op_range != nullptr && op_range->spilled()) {
       spilled_count++;
       if (first_op == nullptr) {
         first_op = op_range->TopLevel();
@@ -988,14 +2855,14 @@
   // Try to merge the spilled operands and count the number of merged spilled
   // operands.
   DCHECK(first_op != nullptr);
-  auto first_op_spill = first_op->GetSpillRange();
+  SpillRange* first_op_spill = first_op->TopLevel()->GetSpillRange();
   size_t num_merged = 1;
   for (size_t i = 1; i < phi->operands().size(); i++) {
     int op = phi->operands()[i];
-    auto op_range = LiveRangeFor(op);
-    auto op_spill = op_range->GetSpillRange();
-    if (op_spill != nullptr &&
-        (op_spill == first_op_spill || first_op_spill->TryMerge(op_spill))) {
+    TopLevelLiveRange* op_range = data()->live_ranges()[op];
+    if (!op_range->HasSpillRange()) continue;
+    SpillRange* op_spill = op_range->GetSpillRange();
+    if (op_spill == first_op_spill || first_op_spill->TryMerge(op_spill)) {
       num_merged++;
     }
   }
@@ -1010,21 +2877,26 @@
 
   // If the range does not need register soon, spill it to the merged
   // spill range.
-  auto next_pos = range->Start();
-  if (code()->IsGapAt(next_pos.InstructionIndex())) {
-    next_pos = next_pos.NextInstruction();
-  }
-  auto pos = range->NextUsePositionRegisterIsBeneficial(next_pos);
+  LifetimePosition next_pos = range->Start();
+  if (next_pos.IsGapPosition()) next_pos = next_pos.NextStart();
+  UsePosition* pos = range->NextUsePositionRegisterIsBeneficial(next_pos);
   if (pos == nullptr) {
-    auto spill_range = AssignSpillRangeToLiveRange(range->TopLevel());
-    CHECK(first_op_spill->TryMerge(spill_range));
+    SpillRange* spill_range =
+        range->TopLevel()->HasSpillRange()
+            ? range->TopLevel()->GetSpillRange()
+            : data()->AssignSpillRangeToLiveRange(range->TopLevel());
+    bool merged = first_op_spill->TryMerge(spill_range);
+    CHECK(merged);
     Spill(range);
     return true;
-  } else if (pos->pos().Value() > range->Start().NextInstruction().Value()) {
-    auto spill_range = AssignSpillRangeToLiveRange(range->TopLevel());
-    CHECK(first_op_spill->TryMerge(spill_range));
+  } else if (pos->pos() > range->Start().NextStart()) {
+    SpillRange* spill_range =
+        range->TopLevel()->HasSpillRange()
+            ? range->TopLevel()->GetSpillRange()
+            : data()->AssignSpillRangeToLiveRange(range->TopLevel());
+    bool merged = first_op_spill->TryMerge(spill_range);
+    CHECK(merged);
     SpillBetween(range, range->Start(), pos->pos());
-    if (!AllocationOk()) return false;
     DCHECK(UnhandledIsSorted());
     return true;
   }
@@ -1032,446 +2904,307 @@
 }
 
 
-void RegisterAllocator::MeetRegisterConstraints(const InstructionBlock* block) {
-  int start = block->first_instruction_index();
-  int end = block->last_instruction_index();
-  DCHECK_NE(-1, start);
-  for (int i = start; i <= end; ++i) {
-    if (code()->IsGapAt(i)) {
-      Instruction* instr = nullptr;
-      Instruction* prev_instr = nullptr;
-      if (i < end) instr = InstructionAt(i + 1);
-      if (i > start) prev_instr = InstructionAt(i - 1);
-      MeetConstraintsBetween(prev_instr, instr, i);
-      if (!AllocationOk()) return;
-    }
-  }
+void LinearScanAllocator::SpillAfter(LiveRange* range, LifetimePosition pos) {
+  LiveRange* second_part = SplitRangeAt(range, pos);
+  Spill(second_part);
+}
 
-  // Meet register constraints for the instruction in the end.
-  if (!code()->IsGapAt(end)) {
-    MeetRegisterConstraintsForLastInstructionInBlock(block);
+
+void LinearScanAllocator::SpillBetween(LiveRange* range, LifetimePosition start,
+                                       LifetimePosition end) {
+  SpillBetweenUntil(range, start, start, end);
+}
+
+
+void LinearScanAllocator::SpillBetweenUntil(LiveRange* range,
+                                            LifetimePosition start,
+                                            LifetimePosition until,
+                                            LifetimePosition end) {
+  CHECK(start < end);
+  LiveRange* second_part = SplitRangeAt(range, start);
+
+  if (second_part->Start() < end) {
+    // The split result intersects with [start, end[.
+    // Split it at position between ]start+1, end[, spill the middle part
+    // and put the rest to unhandled.
+    LifetimePosition third_part_end = end.PrevStart().End();
+    if (data()->IsBlockBoundary(end.Start())) {
+      third_part_end = end.Start();
+    }
+    LiveRange* third_part = SplitBetween(
+        second_part, Max(second_part->Start().End(), until), third_part_end);
+
+    DCHECK(third_part != second_part);
+
+    Spill(second_part);
+    AddToUnhandledSorted(third_part);
+  } else {
+    // The split result does not intersect with [start, end[.
+    // Nothing to spill. Just put it to unhandled as whole.
+    AddToUnhandledSorted(second_part);
   }
 }
 
 
-void RegisterAllocator::MeetRegisterConstraintsForLastInstructionInBlock(
-    const InstructionBlock* block) {
-  int end = block->last_instruction_index();
-  auto last_instruction = InstructionAt(end);
-  for (size_t i = 0; i < last_instruction->OutputCount(); i++) {
-    auto output_operand = last_instruction->OutputAt(i);
-    DCHECK(!output_operand->IsConstant());
-    auto output = UnallocatedOperand::cast(output_operand);
-    int output_vreg = output->virtual_register();
-    auto range = LiveRangeFor(output_vreg);
-    bool assigned = false;
-    if (output->HasFixedPolicy()) {
-      AllocateFixed(output, -1, false);
-      // This value is produced on the stack, we never need to spill it.
-      if (output->IsStackSlot()) {
-        DCHECK(output->index() < 0);
-        range->SetSpillOperand(output);
-        range->SetSpillStartIndex(end);
-        assigned = true;
-      }
-
-      for (auto succ : block->successors()) {
-        const InstructionBlock* successor = code()->InstructionBlockAt(succ);
-        DCHECK(successor->PredecessorCount() == 1);
-        int gap_index = successor->first_instruction_index() + 1;
-        DCHECK(code()->IsGapAt(gap_index));
-
-        // Create an unconstrained operand for the same virtual register
-        // and insert a gap move from the fixed output to the operand.
-        UnallocatedOperand* output_copy =
-            new (code_zone()) UnallocatedOperand(UnallocatedOperand::ANY);
-        output_copy->set_virtual_register(output_vreg);
-
-        AddGapMove(gap_index, GapInstruction::START, output, output_copy);
-      }
-    }
-
-    if (!assigned) {
-      for (auto succ : block->successors()) {
-        const InstructionBlock* successor = code()->InstructionBlockAt(succ);
-        DCHECK(successor->PredecessorCount() == 1);
-        int gap_index = successor->first_instruction_index() + 1;
-        range->SpillAtDefinition(local_zone(), gap_index, output);
-        range->SetSpillStartIndex(gap_index);
-      }
-    }
-  }
-}
+SpillSlotLocator::SpillSlotLocator(RegisterAllocationData* data)
+    : data_(data) {}
 
 
-void RegisterAllocator::MeetConstraintsBetween(Instruction* first,
-                                               Instruction* second,
-                                               int gap_index) {
-  if (first != nullptr) {
-    // Handle fixed temporaries.
-    for (size_t i = 0; i < first->TempCount(); i++) {
-      auto temp = UnallocatedOperand::cast(first->TempAt(i));
-      if (temp->HasFixedPolicy()) {
-        AllocateFixed(temp, gap_index - 1, false);
-      }
-    }
-
-    // Handle constant/fixed output operands.
-    for (size_t i = 0; i < first->OutputCount(); i++) {
-      InstructionOperand* output = first->OutputAt(i);
-      if (output->IsConstant()) {
-        int output_vreg = output->index();
-        auto range = LiveRangeFor(output_vreg);
-        range->SetSpillStartIndex(gap_index - 1);
-        range->SetSpillOperand(output);
-      } else {
-        auto first_output = UnallocatedOperand::cast(output);
-        auto range = LiveRangeFor(first_output->virtual_register());
-        bool assigned = false;
-        if (first_output->HasFixedPolicy()) {
-          auto output_copy = first_output->CopyUnconstrained(code_zone());
-          bool is_tagged = HasTaggedValue(first_output->virtual_register());
-          AllocateFixed(first_output, gap_index, is_tagged);
-
-          // This value is produced on the stack, we never need to spill it.
-          if (first_output->IsStackSlot()) {
-            DCHECK(first_output->index() < 0);
-            range->SetSpillOperand(first_output);
-            range->SetSpillStartIndex(gap_index - 1);
-            assigned = true;
-          }
-          AddGapMove(gap_index, GapInstruction::START, first_output,
-                     output_copy);
-        }
-
-        // Make sure we add a gap move for spilling (if we have not done
-        // so already).
-        if (!assigned) {
-          range->SpillAtDefinition(local_zone(), gap_index, first_output);
-          range->SetSpillStartIndex(gap_index);
-        }
-      }
-    }
-  }
-
-  if (second != nullptr) {
-    // Handle fixed input operands of second instruction.
-    for (size_t i = 0; i < second->InputCount(); i++) {
-      auto input = second->InputAt(i);
-      if (input->IsImmediate()) continue;  // Ignore immediates.
-      auto cur_input = UnallocatedOperand::cast(input);
-      if (cur_input->HasFixedPolicy()) {
-        auto input_copy = cur_input->CopyUnconstrained(code_zone());
-        bool is_tagged = HasTaggedValue(cur_input->virtual_register());
-        AllocateFixed(cur_input, gap_index + 1, is_tagged);
-        AddGapMove(gap_index, GapInstruction::END, input_copy, cur_input);
-      }
-    }
-
-    // Handle "output same as input" for second instruction.
-    for (size_t i = 0; i < second->OutputCount(); i++) {
-      auto output = second->OutputAt(i);
-      if (!output->IsUnallocated()) continue;
-      auto second_output = UnallocatedOperand::cast(output);
-      if (second_output->HasSameAsInputPolicy()) {
-        DCHECK(i == 0);  // Only valid for first output.
-        UnallocatedOperand* cur_input =
-            UnallocatedOperand::cast(second->InputAt(0));
-        int output_vreg = second_output->virtual_register();
-        int input_vreg = cur_input->virtual_register();
-
-        auto input_copy = cur_input->CopyUnconstrained(code_zone());
-        cur_input->set_virtual_register(second_output->virtual_register());
-        AddGapMove(gap_index, GapInstruction::END, input_copy, cur_input);
-
-        if (HasTaggedValue(input_vreg) && !HasTaggedValue(output_vreg)) {
-          int index = gap_index + 1;
-          Instruction* instr = InstructionAt(index);
-          if (instr->HasPointerMap()) {
-            instr->pointer_map()->RecordPointer(input_copy, code_zone());
-          }
-        } else if (!HasTaggedValue(input_vreg) && HasTaggedValue(output_vreg)) {
-          // The input is assumed to immediately have a tagged representation,
-          // before the pointer map can be used. I.e. the pointer map at the
-          // instruction will include the output operand (whose value at the
-          // beginning of the instruction is equal to the input operand). If
-          // this is not desired, then the pointer map at this instruction needs
-          // to be adjusted manually.
-        }
-      }
-    }
-  }
-}
-
-
-bool RegisterAllocator::IsOutputRegisterOf(Instruction* instr, int index) {
-  for (size_t i = 0; i < instr->OutputCount(); i++) {
-    auto output = instr->OutputAt(i);
-    if (output->IsRegister() && output->index() == index) return true;
-  }
-  return false;
-}
-
-
-bool RegisterAllocator::IsOutputDoubleRegisterOf(Instruction* instr,
-                                                 int index) {
-  for (size_t i = 0; i < instr->OutputCount(); i++) {
-    auto output = instr->OutputAt(i);
-    if (output->IsDoubleRegister() && output->index() == index) return true;
-  }
-  return false;
-}
-
-
-void RegisterAllocator::ProcessInstructions(const InstructionBlock* block,
-                                            BitVector* live) {
-  int block_start = block->first_instruction_index();
-  auto block_start_position =
-      LifetimePosition::FromInstructionIndex(block_start);
-
-  for (int index = block->last_instruction_index(); index >= block_start;
-       index--) {
-    auto curr_position = LifetimePosition::FromInstructionIndex(index);
-    auto instr = InstructionAt(index);
-    DCHECK(instr != nullptr);
-    if (instr->IsGapMoves()) {
-      // Process the moves of the gap instruction, making their sources live.
-      auto gap = code()->GapAt(index);
-      const GapInstruction::InnerPosition kPositions[] = {
-          GapInstruction::END, GapInstruction::START};
-      for (auto position : kPositions) {
-        auto move = gap->GetParallelMove(position);
-        if (move == nullptr) continue;
-        if (position == GapInstruction::END) {
-          curr_position = curr_position.InstructionEnd();
-        } else {
-          curr_position = curr_position.InstructionStart();
-        }
-        auto move_ops = move->move_operands();
-        for (auto cur = move_ops->begin(); cur != move_ops->end(); ++cur) {
-          auto from = cur->source();
-          auto to = cur->destination();
-          auto hint = to;
-          if (to->IsUnallocated()) {
-            int to_vreg = UnallocatedOperand::cast(to)->virtual_register();
-            auto to_range = LiveRangeFor(to_vreg);
-            if (to_range->is_phi()) {
-              DCHECK(!FLAG_turbo_delay_ssa_decon);
-              if (to_range->is_non_loop_phi()) {
-                hint = to_range->current_hint_operand();
-              }
-            } else {
-              if (live->Contains(to_vreg)) {
-                Define(curr_position, to, from);
-                live->Remove(to_vreg);
-              } else {
-                cur->Eliminate();
-                continue;
-              }
-            }
-          } else {
-            Define(curr_position, to, from);
-          }
-          Use(block_start_position, curr_position, from, hint);
-          if (from->IsUnallocated()) {
-            live->Add(UnallocatedOperand::cast(from)->virtual_register());
-          }
+void SpillSlotLocator::LocateSpillSlots() {
+  const InstructionSequence* code = data()->code();
+  for (TopLevelLiveRange* range : data()->live_ranges()) {
+    if (range == nullptr || range->IsEmpty()) continue;
+    // We care only about ranges which spill in the frame.
+    if (!range->HasSpillRange()) continue;
+    if (range->IsSpilledOnlyInDeferredBlocks()) {
+      for (LiveRange* child = range; child != nullptr; child = child->next()) {
+        if (child->spilled()) {
+          code->GetInstructionBlock(child->Start().ToInstructionIndex())
+              ->mark_needs_frame();
         }
       }
     } else {
-      // Process output, inputs, and temps of this non-gap instruction.
-      for (size_t i = 0; i < instr->OutputCount(); i++) {
-        auto output = instr->OutputAt(i);
-        if (output->IsUnallocated()) {
-          int out_vreg = UnallocatedOperand::cast(output)->virtual_register();
-          live->Remove(out_vreg);
-        } else if (output->IsConstant()) {
-          int out_vreg = output->index();
-          live->Remove(out_vreg);
-        }
-        Define(curr_position, output, nullptr);
+      TopLevelLiveRange::SpillMoveInsertionList* spills =
+          range->spill_move_insertion_locations();
+      DCHECK_NOT_NULL(spills);
+      for (; spills != nullptr; spills = spills->next) {
+        code->GetInstructionBlock(spills->gap_index)->mark_needs_frame();
       }
+    }
+  }
+}
 
-      if (instr->ClobbersRegisters()) {
-        for (int i = 0; i < config()->num_general_registers(); ++i) {
-          if (!IsOutputRegisterOf(instr, i)) {
-            auto range = FixedLiveRangeFor(i);
-            range->AddUseInterval(curr_position, curr_position.InstructionEnd(),
-                                  local_zone());
-          }
-        }
+
+OperandAssigner::OperandAssigner(RegisterAllocationData* data) : data_(data) {}
+
+
+void OperandAssigner::AssignSpillSlots() {
+  ZoneVector<SpillRange*>& spill_ranges = data()->spill_ranges();
+  // Merge disjoint spill ranges
+  for (size_t i = 0; i < spill_ranges.size(); ++i) {
+    SpillRange* range = spill_ranges[i];
+    if (range == nullptr) continue;
+    if (range->IsEmpty()) continue;
+    for (size_t j = i + 1; j < spill_ranges.size(); ++j) {
+      SpillRange* other = spill_ranges[j];
+      if (other != nullptr && !other->IsEmpty()) {
+        range->TryMerge(other);
       }
+    }
+  }
+  // Allocate slots for the merged spill ranges.
+  for (SpillRange* range : spill_ranges) {
+    if (range == nullptr || range->IsEmpty()) continue;
+    // Allocate a new operand referring to the spill slot.
+    if (!range->HasSlot()) {
+      int byte_width = range->ByteWidth();
+      int index = data()->frame()->AllocateSpillSlot(byte_width);
+      range->set_assigned_slot(index);
+    }
+  }
+}
 
-      if (instr->ClobbersDoubleRegisters()) {
-        for (int i = 0; i < config()->num_aliased_double_registers(); ++i) {
-          if (!IsOutputDoubleRegisterOf(instr, i)) {
-            auto range = FixedDoubleLiveRangeFor(i);
-            range->AddUseInterval(curr_position, curr_position.InstructionEnd(),
-                                  local_zone());
-          }
-        }
+
+void OperandAssigner::CommitAssignment() {
+  for (TopLevelLiveRange* top_range : data()->live_ranges()) {
+    if (top_range == nullptr || top_range->IsEmpty()) continue;
+    InstructionOperand spill_operand;
+    if (top_range->HasSpillOperand()) {
+      spill_operand = *top_range->TopLevel()->GetSpillOperand();
+    } else if (top_range->TopLevel()->HasSpillRange()) {
+      spill_operand = top_range->TopLevel()->GetSpillRangeOperand();
+    }
+    if (top_range->is_phi()) {
+      data()->GetPhiMapValueFor(top_range)->CommitAssignment(
+          top_range->GetAssignedOperand());
+    }
+    for (LiveRange* range = top_range; range != nullptr;
+         range = range->next()) {
+      InstructionOperand assigned = range->GetAssignedOperand();
+      range->ConvertUsesToOperand(assigned, spill_operand);
+    }
+
+    if (!spill_operand.IsInvalid()) {
+      // If this top level range has a child spilled in a deferred block, we use
+      // the range and control flow connection mechanism instead of spilling at
+      // definition. Refer to the ConnectLiveRanges and ResolveControlFlow
+      // phases. Normally, when we spill at definition, we do not insert a
+      // connecting move when a successor child range is spilled - because the
+      // spilled range picks up its value from the slot which was assigned at
+      // definition. For ranges that are determined to spill only in deferred
+      // blocks, we let ConnectLiveRanges and ResolveControlFlow insert such
+      // moves between ranges. Because of how the ranges are split around
+      // deferred blocks, this amounts to spilling and filling inside such
+      // blocks.
+      if (!top_range->TryCommitSpillInDeferredBlock(data()->code(),
+                                                    spill_operand)) {
+        // Spill at definition if the range isn't spilled only in deferred
+        // blocks.
+        top_range->CommitSpillMoves(
+            data()->code(), spill_operand,
+            top_range->has_slot_use() || top_range->spilled());
       }
+    }
+  }
+}
 
-      for (size_t i = 0; i < instr->InputCount(); i++) {
-        auto input = instr->InputAt(i);
-        if (input->IsImmediate()) continue;  // Ignore immediates.
-        LifetimePosition use_pos;
-        if (input->IsUnallocated() &&
-            UnallocatedOperand::cast(input)->IsUsedAtStart()) {
-          use_pos = curr_position;
+
+ReferenceMapPopulator::ReferenceMapPopulator(RegisterAllocationData* data)
+    : data_(data) {}
+
+
+bool ReferenceMapPopulator::SafePointsAreInOrder() const {
+  int safe_point = 0;
+  for (ReferenceMap* map : *data()->code()->reference_maps()) {
+    if (safe_point > map->instruction_position()) return false;
+    safe_point = map->instruction_position();
+  }
+  return true;
+}
+
+
+void ReferenceMapPopulator::PopulateReferenceMaps() {
+  DCHECK(SafePointsAreInOrder());
+  // Map all delayed references.
+  for (RegisterAllocationData::DelayedReference& delayed_reference :
+       data()->delayed_references()) {
+    delayed_reference.map->RecordReference(
+        AllocatedOperand::cast(*delayed_reference.operand));
+  }
+  // Iterate over all safe point positions and record a pointer
+  // for all spilled live ranges at this point.
+  int last_range_start = 0;
+  const ReferenceMapDeque* reference_maps = data()->code()->reference_maps();
+  ReferenceMapDeque::const_iterator first_it = reference_maps->begin();
+  for (TopLevelLiveRange* range : data()->live_ranges()) {
+    if (range == nullptr) continue;
+    // Skip non-reference values.
+    if (!data()->IsReference(range)) continue;
+    // Skip empty live ranges.
+    if (range->IsEmpty()) continue;
+    if (range->has_preassigned_slot()) continue;
+
+    // Find the extent of the range and its children.
+    int start = range->Start().ToInstructionIndex();
+    int end = 0;
+    for (LiveRange* cur = range; cur != nullptr; cur = cur->next()) {
+      LifetimePosition this_end = cur->End();
+      if (this_end.ToInstructionIndex() > end)
+        end = this_end.ToInstructionIndex();
+      DCHECK(cur->Start().ToInstructionIndex() >= start);
+    }
+
+    // Most of the ranges are in order, but not all.  Keep an eye on when they
+    // step backwards and reset the first_it so we don't miss any safe points.
+    if (start < last_range_start) first_it = reference_maps->begin();
+    last_range_start = start;
+
+    // Step across all the safe points that are before the start of this range,
+    // recording how far we step in order to save doing this for the next range.
+    for (; first_it != reference_maps->end(); ++first_it) {
+      ReferenceMap* map = *first_it;
+      if (map->instruction_position() >= start) break;
+    }
+
+    InstructionOperand spill_operand;
+    if (((range->HasSpillOperand() &&
+          !range->GetSpillOperand()->IsConstant()) ||
+         range->HasSpillRange())) {
+      if (range->HasSpillOperand()) {
+        spill_operand = *range->GetSpillOperand();
+      } else {
+        spill_operand = range->GetSpillRangeOperand();
+      }
+      DCHECK(spill_operand.IsStackSlot());
+      DCHECK_EQ(MachineRepresentation::kTagged,
+                AllocatedOperand::cast(spill_operand).representation());
+    }
+
+    LiveRange* cur = range;
+    // Step through the safe points to see whether they are in the range.
+    for (auto it = first_it; it != reference_maps->end(); ++it) {
+      ReferenceMap* map = *it;
+      int safe_point = map->instruction_position();
+
+      // The safe points are sorted so we can stop searching here.
+      if (safe_point - 1 > end) break;
+
+      // Advance to the next active range that covers the current
+      // safe point position.
+      LifetimePosition safe_point_pos =
+          LifetimePosition::InstructionFromInstructionIndex(safe_point);
+
+      // Search for the child range (cur) that covers safe_point_pos. If we
+      // don't find it before the children pass safe_point_pos, keep cur at
+      // the last child, because the next safe_point_pos may be covered by cur.
+      // This may happen if cur has more than one interval, and the current
+      // safe_point_pos is in between intervals.
+      // For that reason, cur may be at most the last child.
+      DCHECK_NOT_NULL(cur);
+      DCHECK(safe_point_pos >= cur->Start() || range == cur);
+      bool found = false;
+      while (!found) {
+        if (cur->Covers(safe_point_pos)) {
+          found = true;
         } else {
-          use_pos = curr_position.InstructionEnd();
-        }
-
-        Use(block_start_position, use_pos, input, nullptr);
-        if (input->IsUnallocated()) {
-          live->Add(UnallocatedOperand::cast(input)->virtual_register());
-        }
-      }
-
-      for (size_t i = 0; i < instr->TempCount(); i++) {
-        auto temp = instr->TempAt(i);
-        if (instr->ClobbersTemps()) {
-          if (temp->IsRegister()) continue;
-          if (temp->IsUnallocated()) {
-            UnallocatedOperand* temp_unalloc = UnallocatedOperand::cast(temp);
-            if (temp_unalloc->HasFixedPolicy()) {
-              continue;
-            }
+          LiveRange* next = cur->next();
+          if (next == nullptr || next->Start() > safe_point_pos) {
+            break;
           }
-        }
-        Use(block_start_position, curr_position.InstructionEnd(), temp,
-            nullptr);
-        Define(curr_position, temp, nullptr);
-      }
-    }
-  }
-}
-
-
-void RegisterAllocator::ResolvePhis(const InstructionBlock* block) {
-  for (auto phi : block->phis()) {
-    if (FLAG_turbo_reuse_spill_slots) {
-      auto res = phi_map_.insert(
-          std::make_pair(phi->virtual_register(), PhiMapValue(phi, block)));
-      DCHECK(res.second);
-      USE(res);
-    }
-    auto output = phi->output();
-    int phi_vreg = phi->virtual_register();
-    if (!FLAG_turbo_delay_ssa_decon) {
-      for (size_t i = 0; i < phi->operands().size(); ++i) {
-        InstructionBlock* cur_block =
-            code()->InstructionBlockAt(block->predecessors()[i]);
-        AddGapMove(cur_block->last_instruction_index() - 1, GapInstruction::END,
-                   phi->inputs()[i], output);
-        DCHECK(!InstructionAt(cur_block->last_instruction_index())
-                    ->HasPointerMap());
-      }
-    }
-    auto live_range = LiveRangeFor(phi_vreg);
-    int gap_index = block->first_instruction_index();
-    live_range->SpillAtDefinition(local_zone(), gap_index, output);
-    live_range->SetSpillStartIndex(gap_index);
-    // We use the phi-ness of some nodes in some later heuristics.
-    live_range->set_is_phi(true);
-    live_range->set_is_non_loop_phi(!block->IsLoopHeader());
-  }
-}
-
-
-void RegisterAllocator::MeetRegisterConstraints() {
-  for (auto block : code()->instruction_blocks()) {
-    MeetRegisterConstraints(block);
-  }
-}
-
-
-void RegisterAllocator::ResolvePhis() {
-  // Process the blocks in reverse order.
-  for (auto i = code()->instruction_blocks().rbegin();
-       i != code()->instruction_blocks().rend(); ++i) {
-    ResolvePhis(*i);
-  }
-}
-
-
-ParallelMove* RegisterAllocator::GetConnectingParallelMove(
-    LifetimePosition pos) {
-  int index = pos.InstructionIndex();
-  if (code()->IsGapAt(index)) {
-    auto gap = code()->GapAt(index);
-    return gap->GetOrCreateParallelMove(
-        pos.IsInstructionStart() ? GapInstruction::START : GapInstruction::END,
-        code_zone());
-  }
-  int gap_pos = pos.IsInstructionStart() ? (index - 1) : (index + 1);
-  return code()->GapAt(gap_pos)->GetOrCreateParallelMove(
-      (gap_pos < index) ? GapInstruction::AFTER : GapInstruction::BEFORE,
-      code_zone());
-}
-
-
-const InstructionBlock* RegisterAllocator::GetInstructionBlock(
-    LifetimePosition pos) {
-  return code()->GetInstructionBlock(pos.InstructionIndex());
-}
-
-
-void RegisterAllocator::ConnectRanges() {
-  for (auto first_range : live_ranges()) {
-    if (first_range == nullptr || first_range->IsChild()) continue;
-    auto second_range = first_range->next();
-    while (second_range != nullptr) {
-      auto pos = second_range->Start();
-      if (!second_range->IsSpilled()) {
-        // Add gap move if the two live ranges touch and there is no block
-        // boundary.
-        if (first_range->End().Value() == pos.Value()) {
-          bool should_insert = true;
-          if (IsBlockBoundary(pos)) {
-            should_insert =
-                CanEagerlyResolveControlFlow(GetInstructionBlock(pos));
-          }
-          if (should_insert) {
-            auto move = GetConnectingParallelMove(pos);
-            auto prev_operand = first_range->CreateAssignedOperand(code_zone());
-            auto cur_operand = second_range->CreateAssignedOperand(code_zone());
-            move->AddMove(prev_operand, cur_operand, code_zone());
-          }
+          cur = next;
         }
       }
-      first_range = second_range;
-      second_range = second_range->next();
+
+      if (!found) {
+        continue;
+      }
+
+      // Check if the live range is spilled and the safe point is after
+      // the spill position.
+      int spill_index = range->IsSpilledOnlyInDeferredBlocks()
+                            ? cur->Start().ToInstructionIndex()
+                            : range->spill_start_index();
+
+      if (!spill_operand.IsInvalid() && safe_point >= spill_index) {
+        TRACE("Pointer for range %d (spilled at %d) at safe point %d\n",
+              range->vreg(), spill_index, safe_point);
+        map->RecordReference(AllocatedOperand::cast(spill_operand));
+      }
+
+      if (!cur->spilled()) {
+        TRACE(
+            "Pointer in register for range %d:%d (start at %d) "
+            "at safe point %d\n",
+            range->vreg(), cur->relative_id(), cur->Start().value(),
+            safe_point);
+        InstructionOperand operand = cur->GetAssignedOperand();
+        DCHECK(!operand.IsStackSlot());
+        DCHECK_EQ(MachineRepresentation::kTagged,
+                  AllocatedOperand::cast(operand).representation());
+        map->RecordReference(AllocatedOperand::cast(operand));
+      }
     }
   }
 }
 
 
-bool RegisterAllocator::CanEagerlyResolveControlFlow(
-    const InstructionBlock* block) const {
-  if (block->PredecessorCount() != 1) return false;
-  return block->predecessors()[0].IsNext(block->rpo_number());
-}
-
-
 namespace {
 
 class LiveRangeBound {
  public:
-  explicit LiveRangeBound(const LiveRange* range)
-      : range_(range), start_(range->Start()), end_(range->End()) {
+  explicit LiveRangeBound(const LiveRange* range, bool skip)
+      : range_(range), start_(range->Start()), end_(range->End()), skip_(skip) {
     DCHECK(!range->IsEmpty());
   }
 
   bool CanCover(LifetimePosition position) {
-    return start_.Value() <= position.Value() &&
-           position.Value() < end_.Value();
+    return start_ <= position && position < end_;
   }
 
   const LiveRange* const range_;
   const LifetimePosition start_;
   const LifetimePosition end_;
+  const bool skip_;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(LiveRangeBound);
@@ -1490,14 +3223,17 @@
 
   bool ShouldInitialize() { return start_ == nullptr; }
 
-  void Initialize(Zone* zone, const LiveRange* const range) {
-    size_t length = 0;
-    for (auto i = range; i != nullptr; i = i->next()) length++;
-    start_ = zone->NewArray<LiveRangeBound>(static_cast<int>(length));
-    length_ = length;
-    auto curr = start_;
-    for (auto i = range; i != nullptr; i = i->next(), ++curr) {
-      new (curr) LiveRangeBound(i);
+  void Initialize(Zone* zone, const TopLevelLiveRange* const range) {
+    length_ = range->GetChildCount();
+
+    start_ = zone->NewArray<LiveRangeBound>(length_);
+    LiveRangeBound* curr = start_;
+    // Normally, spilled ranges do not need connecting moves, because the spill
+    // location has been assigned at definition. For ranges spilled in deferred
+    // blocks, that is not the case, so we need to connect the spilled children.
+    bool spilled_in_blocks = range->IsSpilledOnlyInDeferredBlocks();
+    for (const LiveRange *i = range; i != nullptr; i = i->next(), ++curr) {
+      new (curr) LiveRangeBound(i, !spilled_in_blocks && i->spilled());
     }
   }
 
@@ -1507,9 +3243,9 @@
     while (true) {
       size_t current_index = left_index + (right_index - left_index) / 2;
       DCHECK(right_index > current_index);
-      auto bound = &start_[current_index];
-      if (bound->start_.Value() <= position.Value()) {
-        if (position.Value() < bound->end_.Value()) return bound;
+      LiveRangeBound* bound = &start_[current_index];
+      if (bound->start_ <= position) {
+        if (position < bound->end_) return bound;
         DCHECK(left_index < current_index);
         left_index = current_index;
       } else {
@@ -1519,32 +3255,41 @@
   }
 
   LiveRangeBound* FindPred(const InstructionBlock* pred) {
-    auto pred_end =
-        LifetimePosition::FromInstructionIndex(pred->last_instruction_index());
+    LifetimePosition pred_end =
+        LifetimePosition::InstructionFromInstructionIndex(
+            pred->last_instruction_index());
     return Find(pred_end);
   }
 
   LiveRangeBound* FindSucc(const InstructionBlock* succ) {
-    auto succ_start =
-        LifetimePosition::FromInstructionIndex(succ->first_instruction_index());
+    LifetimePosition succ_start = LifetimePosition::GapFromInstructionIndex(
+        succ->first_instruction_index());
     return Find(succ_start);
   }
 
-  void Find(const InstructionBlock* block, const InstructionBlock* pred,
-            FindResult* result) const {
-    auto pred_end =
-        LifetimePosition::FromInstructionIndex(pred->last_instruction_index());
-    auto bound = Find(pred_end);
+  bool FindConnectableSubranges(const InstructionBlock* block,
+                                const InstructionBlock* pred,
+                                FindResult* result) const {
+    LifetimePosition pred_end =
+        LifetimePosition::InstructionFromInstructionIndex(
+            pred->last_instruction_index());
+    LiveRangeBound* bound = Find(pred_end);
     result->pred_cover_ = bound->range_;
-    auto cur_start = LifetimePosition::FromInstructionIndex(
+    LifetimePosition cur_start = LifetimePosition::GapFromInstructionIndex(
         block->first_instruction_index());
-    // Common case.
+
     if (bound->CanCover(cur_start)) {
-      result->cur_cover_ = bound->range_;
-      return;
+      // Both blocks are covered by the same range, so there is nothing to
+      // connect.
+      return false;
     }
-    result->cur_cover_ = Find(cur_start)->range_;
+    bound = Find(cur_start);
+    if (bound->skip_) {
+      return false;
+    }
+    result->cur_cover_ = bound->range_;
     DCHECK(result->pred_cover_ != nullptr && result->cur_cover_ != nullptr);
+    return (result->cur_cover_ != result->pred_cover_);
   }
 
  private:
@@ -1557,11 +3302,11 @@
 
 class LiveRangeFinder {
  public:
-  explicit LiveRangeFinder(const RegisterAllocator& allocator)
-      : allocator_(allocator),
-        bounds_length_(static_cast<int>(allocator.live_ranges().size())),
-        bounds_(allocator.local_zone()->NewArray<LiveRangeBoundArray>(
-            bounds_length_)) {
+  explicit LiveRangeFinder(const RegisterAllocationData* data, Zone* zone)
+      : data_(data),
+        bounds_length_(static_cast<int>(data_->live_ranges().size())),
+        bounds_(zone->NewArray<LiveRangeBoundArray>(bounds_length_)),
+        zone_(zone) {
     for (int i = 0; i < bounds_length_; ++i) {
       new (&bounds_[i]) LiveRangeBoundArray();
     }
@@ -1569,65 +3314,81 @@
 
   LiveRangeBoundArray* ArrayFor(int operand_index) {
     DCHECK(operand_index < bounds_length_);
-    auto range = allocator_.live_ranges()[operand_index];
+    TopLevelLiveRange* range = data_->live_ranges()[operand_index];
     DCHECK(range != nullptr && !range->IsEmpty());
-    auto array = &bounds_[operand_index];
+    LiveRangeBoundArray* array = &bounds_[operand_index];
     if (array->ShouldInitialize()) {
-      array->Initialize(allocator_.local_zone(), range);
+      array->Initialize(zone_, range);
     }
     return array;
   }
 
  private:
-  const RegisterAllocator& allocator_;
+  const RegisterAllocationData* const data_;
   const int bounds_length_;
   LiveRangeBoundArray* const bounds_;
+  Zone* const zone_;
 
   DISALLOW_COPY_AND_ASSIGN(LiveRangeFinder);
 };
 
+
+typedef std::pair<ParallelMove*, InstructionOperand> DelayedInsertionMapKey;
+
+
+struct DelayedInsertionMapCompare {
+  bool operator()(const DelayedInsertionMapKey& a,
+                  const DelayedInsertionMapKey& b) const {
+    if (a.first == b.first) {
+      return a.second.Compare(b.second);
+    }
+    return a.first < b.first;
+  }
+};
+
+
+typedef ZoneMap<DelayedInsertionMapKey, InstructionOperand,
+                DelayedInsertionMapCompare> DelayedInsertionMap;
+
 }  // namespace
 
 
-void RegisterAllocator::ResolveControlFlow() {
+LiveRangeConnector::LiveRangeConnector(RegisterAllocationData* data)
+    : data_(data) {}
+
+
+bool LiveRangeConnector::CanEagerlyResolveControlFlow(
+    const InstructionBlock* block) const {
+  if (block->PredecessorCount() != 1) return false;
+  return block->predecessors()[0].IsNext(block->rpo_number());
+}
+
+
+void LiveRangeConnector::ResolveControlFlow(Zone* local_zone) {
   // Lazily linearize live ranges in memory for fast lookup.
-  LiveRangeFinder finder(*this);
-  for (auto block : code()->instruction_blocks()) {
+  LiveRangeFinder finder(data(), local_zone);
+  ZoneVector<BitVector*>& live_in_sets = data()->live_in_sets();
+  for (const InstructionBlock* block : code()->instruction_blocks()) {
     if (CanEagerlyResolveControlFlow(block)) continue;
-    if (FLAG_turbo_delay_ssa_decon) {
-      // resolve phis
-      for (auto phi : block->phis()) {
-        auto* block_bound =
-            finder.ArrayFor(phi->virtual_register())->FindSucc(block);
-        auto phi_output =
-            block_bound->range_->CreateAssignedOperand(code_zone());
-        phi->output()->ConvertTo(phi_output->kind(), phi_output->index());
-        size_t pred_index = 0;
-        for (auto pred : block->predecessors()) {
-          const InstructionBlock* pred_block = code()->InstructionBlockAt(pred);
-          auto* pred_bound = finder.ArrayFor(phi->operands()[pred_index])
-                                 ->FindPred(pred_block);
-          auto pred_op = pred_bound->range_->CreateAssignedOperand(code_zone());
-          phi->inputs()[pred_index] = pred_op;
-          ResolveControlFlow(block, phi_output, pred_block, pred_op);
-          pred_index++;
-        }
-      }
-    }
-    auto live = live_in_sets_[block->rpo_number().ToInt()];
+    BitVector* live = live_in_sets[block->rpo_number().ToInt()];
     BitVector::Iterator iterator(live);
     while (!iterator.Done()) {
-      auto* array = finder.ArrayFor(iterator.Current());
-      for (auto pred : block->predecessors()) {
+      LiveRangeBoundArray* array = finder.ArrayFor(iterator.Current());
+      for (const RpoNumber& pred : block->predecessors()) {
         FindResult result;
-        const auto* pred_block = code()->InstructionBlockAt(pred);
-        array->Find(block, pred_block, &result);
-        if (result.cur_cover_ == result.pred_cover_ ||
-            result.cur_cover_->IsSpilled())
+        const InstructionBlock* pred_block = code()->InstructionBlockAt(pred);
+        if (!array->FindConnectableSubranges(block, pred_block, &result)) {
           continue;
-        auto pred_op = result.pred_cover_->CreateAssignedOperand(code_zone());
-        auto cur_op = result.cur_cover_->CreateAssignedOperand(code_zone());
-        ResolveControlFlow(block, cur_op, pred_block, pred_op);
+        }
+        InstructionOperand pred_op = result.pred_cover_->GetAssignedOperand();
+        InstructionOperand cur_op = result.cur_cover_->GetAssignedOperand();
+        if (pred_op.Equals(cur_op)) continue;
+        int move_loc = ResolveControlFlow(block, cur_op, pred_block, pred_op);
+        USE(move_loc);
+        DCHECK_IMPLIES(
+            result.cur_cover_->TopLevel()->IsSpilledOnlyInDeferredBlocks() &&
+                !(pred_op.IsAnyRegister() && cur_op.IsAnyRegister()),
+            code()->GetInstructionBlock(move_loc)->IsDeferred());
       }
       iterator.Advance();
     }
@@ -1635,914 +3396,113 @@
 }
 
 
-void RegisterAllocator::ResolveControlFlow(const InstructionBlock* block,
-                                           InstructionOperand* cur_op,
+int LiveRangeConnector::ResolveControlFlow(const InstructionBlock* block,
+                                           const InstructionOperand& cur_op,
                                            const InstructionBlock* pred,
-                                           InstructionOperand* pred_op) {
-  if (pred_op->Equals(cur_op)) return;
+                                           const InstructionOperand& pred_op) {
+  DCHECK(!pred_op.Equals(cur_op));
   int gap_index;
-  GapInstruction::InnerPosition position;
+  Instruction::GapPosition position;
   if (block->PredecessorCount() == 1) {
     gap_index = block->first_instruction_index();
-    position = GapInstruction::START;
+    position = Instruction::START;
   } else {
     DCHECK(pred->SuccessorCount() == 1);
-    DCHECK(!InstructionAt(pred->last_instruction_index())->HasPointerMap());
-    gap_index = pred->last_instruction_index() - 1;
-    position = GapInstruction::END;
+    DCHECK(!code()
+                ->InstructionAt(pred->last_instruction_index())
+                ->HasReferenceMap());
+    gap_index = pred->last_instruction_index();
+    position = Instruction::END;
   }
-  AddGapMove(gap_index, position, pred_op, cur_op);
+  data()->AddGapMove(gap_index, position, pred_op, cur_op);
+  return gap_index;
 }
 
 
-void RegisterAllocator::BuildLiveRanges() {
-  // Process the blocks in reverse order.
-  for (int block_id = code()->InstructionBlockCount() - 1; block_id >= 0;
-       --block_id) {
-    auto block =
-        code()->InstructionBlockAt(BasicBlock::RpoNumber::FromInt(block_id));
-    auto live = ComputeLiveOut(block);
-    // Initially consider all live_out values live for the entire block. We
-    // will shorten these intervals if necessary.
-    AddInitialIntervals(block, live);
-
-    // Process the instructions in reverse order, generating and killing
-    // live values.
-    ProcessInstructions(block, live);
-    // All phi output operands are killed by this block.
-    for (auto phi : block->phis()) {
-      // The live range interval already ends at the first instruction of the
-      // block.
-      int phi_vreg = phi->virtual_register();
-      live->Remove(phi_vreg);
-      if (!FLAG_turbo_delay_ssa_decon) {
-        InstructionOperand* hint = nullptr;
-        InstructionOperand* phi_operand = nullptr;
-        auto gap =
-            GetLastGap(code()->InstructionBlockAt(block->predecessors()[0]));
-        auto move =
-            gap->GetOrCreateParallelMove(GapInstruction::END, code_zone());
-        for (int j = 0; j < move->move_operands()->length(); ++j) {
-          auto to = move->move_operands()->at(j).destination();
-          if (to->IsUnallocated() &&
-              UnallocatedOperand::cast(to)->virtual_register() == phi_vreg) {
-            hint = move->move_operands()->at(j).source();
-            phi_operand = to;
-            break;
-          }
-        }
-        DCHECK(hint != nullptr);
-        auto block_start = LifetimePosition::FromInstructionIndex(
-            block->first_instruction_index());
-        Define(block_start, phi_operand, hint);
-      }
-    }
-
-    // Now live is live_in for this block except not including values live
-    // out on backward successor edges.
-    live_in_sets_[block_id] = live;
-
-    if (block->IsLoopHeader()) {
-      // Add a live range stretching from the first loop instruction to the last
-      // for each value live on entry to the header.
-      BitVector::Iterator iterator(live);
-      auto start = LifetimePosition::FromInstructionIndex(
-          block->first_instruction_index());
-      auto end = LifetimePosition::FromInstructionIndex(
-                     code()->LastLoopInstructionIndex(block)).NextInstruction();
-      while (!iterator.Done()) {
-        int operand_index = iterator.Current();
-        auto range = LiveRangeFor(operand_index);
-        range->EnsureInterval(start, end, local_zone());
-        iterator.Advance();
-      }
-      // Insert all values into the live in sets of all blocks in the loop.
-      for (int i = block->rpo_number().ToInt() + 1;
-           i < block->loop_end().ToInt(); ++i) {
-        live_in_sets_[i]->Union(*live);
-      }
-    }
-  }
-
-  for (auto range : live_ranges()) {
-    if (range == nullptr) continue;
-    range->kind_ = RequiredRegisterKind(range->id());
-    // TODO(bmeurer): This is a horrible hack to make sure that for constant
-    // live ranges, every use requires the constant to be in a register.
-    // Without this hack, all uses with "any" policy would get the constant
-    // operand assigned.
-    if (range->HasSpillOperand() && range->GetSpillOperand()->IsConstant()) {
-      for (auto pos = range->first_pos(); pos != nullptr; pos = pos->next_) {
-        pos->register_beneficial_ = true;
-        // TODO(dcarney): should the else case assert requires_reg_ == false?
-        // Can't mark phis as needing a register.
-        if (!code()
-                 ->InstructionAt(pos->pos().InstructionIndex())
-                 ->IsGapMoves()) {
-          pos->requires_reg_ = true;
-        }
-      }
-    }
-  }
-}
-
-
-bool RegisterAllocator::ExistsUseWithoutDefinition() {
-  bool found = false;
-  BitVector::Iterator iterator(live_in_sets_[0]);
-  while (!iterator.Done()) {
-    found = true;
-    int operand_index = iterator.Current();
-    PrintF("Register allocator error: live v%d reached first block.\n",
-           operand_index);
-    LiveRange* range = LiveRangeFor(operand_index);
-    PrintF("  (first use is at %d)\n", range->first_pos()->pos().Value());
-    if (debug_name() == nullptr) {
-      PrintF("\n");
-    } else {
-      PrintF("  (function: %s)\n", debug_name());
-    }
-    iterator.Advance();
-  }
-  return found;
-}
-
-
-bool RegisterAllocator::SafePointsAreInOrder() const {
-  int safe_point = 0;
-  for (auto map : *code()->pointer_maps()) {
-    if (safe_point > map->instruction_position()) return false;
-    safe_point = map->instruction_position();
-  }
-  return true;
-}
-
-
-void RegisterAllocator::PopulatePointerMaps() {
-  DCHECK(SafePointsAreInOrder());
-
-  // Iterate over all safe point positions and record a pointer
-  // for all spilled live ranges at this point.
-  int last_range_start = 0;
-  auto pointer_maps = code()->pointer_maps();
-  PointerMapDeque::const_iterator first_it = pointer_maps->begin();
-  for (LiveRange* range : live_ranges()) {
-    if (range == nullptr) continue;
-    // Iterate over the first parts of multi-part live ranges.
-    if (range->IsChild()) continue;
-    // Skip non-reference values.
-    if (!HasTaggedValue(range->id())) continue;
-    // Skip empty live ranges.
-    if (range->IsEmpty()) continue;
-
-    // Find the extent of the range and its children.
-    int start = range->Start().InstructionIndex();
-    int end = 0;
-    for (auto cur = range; cur != nullptr; cur = cur->next()) {
-      auto this_end = cur->End();
-      if (this_end.InstructionIndex() > end) end = this_end.InstructionIndex();
-      DCHECK(cur->Start().InstructionIndex() >= start);
-    }
-
-    // Most of the ranges are in order, but not all.  Keep an eye on when they
-    // step backwards and reset the first_it so we don't miss any safe points.
-    if (start < last_range_start) first_it = pointer_maps->begin();
-    last_range_start = start;
-
-    // Step across all the safe points that are before the start of this range,
-    // recording how far we step in order to save doing this for the next range.
-    for (; first_it != pointer_maps->end(); ++first_it) {
-      auto map = *first_it;
-      if (map->instruction_position() >= start) break;
-    }
-
-    // Step through the safe points to see whether they are in the range.
-    for (auto it = first_it; it != pointer_maps->end(); ++it) {
-      auto map = *it;
-      int safe_point = map->instruction_position();
-
-      // The safe points are sorted so we can stop searching here.
-      if (safe_point - 1 > end) break;
-
-      // Advance to the next active range that covers the current
-      // safe point position.
-      auto safe_point_pos = LifetimePosition::FromInstructionIndex(safe_point);
-      auto cur = range;
-      while (cur != nullptr && !cur->Covers(safe_point_pos)) {
-        cur = cur->next();
-      }
-      if (cur == nullptr) continue;
-
-      // Check if the live range is spilled and the safe point is after
-      // the spill position.
-      if (range->HasSpillOperand() &&
-          safe_point >= range->spill_start_index() &&
-          !range->GetSpillOperand()->IsConstant()) {
-        TraceAlloc("Pointer for range %d (spilled at %d) at safe point %d\n",
-                   range->id(), range->spill_start_index(), safe_point);
-        map->RecordPointer(range->GetSpillOperand(), code_zone());
-      }
-
-      if (!cur->IsSpilled()) {
-        TraceAlloc(
-            "Pointer in register for range %d (start at %d) "
-            "at safe point %d\n",
-            cur->id(), cur->Start().Value(), safe_point);
-        InstructionOperand* operand = cur->CreateAssignedOperand(code_zone());
-        DCHECK(!operand->IsStackSlot());
-        map->RecordPointer(operand, code_zone());
-      }
-    }
-  }
-}
-
-
-void RegisterAllocator::AllocateGeneralRegisters() {
-  num_registers_ = config()->num_general_registers();
-  mode_ = GENERAL_REGISTERS;
-  AllocateRegisters();
-}
-
-
-void RegisterAllocator::AllocateDoubleRegisters() {
-  num_registers_ = config()->num_aliased_double_registers();
-  mode_ = DOUBLE_REGISTERS;
-  AllocateRegisters();
-}
-
-
-void RegisterAllocator::AllocateRegisters() {
-  DCHECK(unhandled_live_ranges().empty());
-
-  for (auto range : live_ranges()) {
-    if (range == nullptr) continue;
-    if (range->Kind() == mode_) {
-      AddToUnhandledUnsorted(range);
-    }
-  }
-  SortUnhandled();
-  DCHECK(UnhandledIsSorted());
-
-  DCHECK(reusable_slots().empty());
-  DCHECK(active_live_ranges().empty());
-  DCHECK(inactive_live_ranges().empty());
-
-  if (mode_ == DOUBLE_REGISTERS) {
-    for (int i = 0; i < config()->num_aliased_double_registers(); ++i) {
-      auto current = fixed_double_live_ranges()[i];
-      if (current != nullptr) {
-        AddToInactive(current);
-      }
-    }
-  } else {
-    DCHECK(mode_ == GENERAL_REGISTERS);
-    for (auto current : fixed_live_ranges()) {
-      if (current != nullptr) {
-        AddToInactive(current);
-      }
-    }
-  }
-
-  while (!unhandled_live_ranges().empty()) {
-    DCHECK(UnhandledIsSorted());
-    auto current = unhandled_live_ranges().back();
-    unhandled_live_ranges().pop_back();
-    DCHECK(UnhandledIsSorted());
-    auto position = current->Start();
-#ifdef DEBUG
-    allocation_finger_ = position;
-#endif
-    TraceAlloc("Processing interval %d start=%d\n", current->id(),
-               position.Value());
-
-    if (!current->HasNoSpillType()) {
-      TraceAlloc("Live range %d already has a spill operand\n", current->id());
-      auto next_pos = position;
-      if (code()->IsGapAt(next_pos.InstructionIndex())) {
-        next_pos = next_pos.NextInstruction();
-      }
-      auto pos = current->NextUsePositionRegisterIsBeneficial(next_pos);
-      // If the range already has a spill operand and it doesn't need a
-      // register immediately, split it and spill the first part of the range.
-      if (pos == nullptr) {
-        Spill(current);
-        continue;
-      } else if (pos->pos().Value() >
-                 current->Start().NextInstruction().Value()) {
-        // Do not spill live range eagerly if use position that can benefit from
-        // the register is too close to the start of live range.
-        SpillBetween(current, current->Start(), pos->pos());
-        if (!AllocationOk()) return;
-        DCHECK(UnhandledIsSorted());
+void LiveRangeConnector::ConnectRanges(Zone* local_zone) {
+  DelayedInsertionMap delayed_insertion_map(local_zone);
+  for (TopLevelLiveRange* top_range : data()->live_ranges()) {
+    if (top_range == nullptr) continue;
+    bool connect_spilled = top_range->IsSpilledOnlyInDeferredBlocks();
+    LiveRange* first_range = top_range;
+    for (LiveRange *second_range = first_range->next(); second_range != nullptr;
+         first_range = second_range, second_range = second_range->next()) {
+      LifetimePosition pos = second_range->Start();
+      // Add gap move if the two live ranges touch and there is no block
+      // boundary.
+      if (!connect_spilled && second_range->spilled()) continue;
+      if (first_range->End() != pos) continue;
+      if (data()->IsBlockBoundary(pos) &&
+          !CanEagerlyResolveControlFlow(GetInstructionBlock(code(), pos))) {
         continue;
       }
-    }
-
-    if (FLAG_turbo_reuse_spill_slots) {
-      if (TryReuseSpillForPhi(current)) {
-        continue;
-      }
-      if (!AllocationOk()) return;
-    }
-
-    for (size_t i = 0; i < active_live_ranges().size(); ++i) {
-      auto cur_active = active_live_ranges()[i];
-      if (cur_active->End().Value() <= position.Value()) {
-        ActiveToHandled(cur_active);
-        --i;  // The live range was removed from the list of active live ranges.
-      } else if (!cur_active->Covers(position)) {
-        ActiveToInactive(cur_active);
-        --i;  // The live range was removed from the list of active live ranges.
-      }
-    }
-
-    for (size_t i = 0; i < inactive_live_ranges().size(); ++i) {
-      auto cur_inactive = inactive_live_ranges()[i];
-      if (cur_inactive->End().Value() <= position.Value()) {
-        InactiveToHandled(cur_inactive);
-        --i;  // Live range was removed from the list of inactive live ranges.
-      } else if (cur_inactive->Covers(position)) {
-        InactiveToActive(cur_inactive);
-        --i;  // Live range was removed from the list of inactive live ranges.
-      }
-    }
-
-    DCHECK(!current->HasRegisterAssigned() && !current->IsSpilled());
-
-    bool result = TryAllocateFreeReg(current);
-    if (!AllocationOk()) return;
-
-    if (!result) AllocateBlockedReg(current);
-    if (!AllocationOk()) return;
-
-    if (current->HasRegisterAssigned()) {
-      AddToActive(current);
-    }
-  }
-
-  reusable_slots().clear();
-  active_live_ranges().clear();
-  inactive_live_ranges().clear();
-}
-
-
-const char* RegisterAllocator::RegisterName(int allocation_index) {
-  if (mode_ == GENERAL_REGISTERS) {
-    return config()->general_register_name(allocation_index);
-  } else {
-    return config()->double_register_name(allocation_index);
-  }
-}
-
-
-bool RegisterAllocator::HasTaggedValue(int virtual_register) const {
-  return code()->IsReference(virtual_register);
-}
-
-
-RegisterKind RegisterAllocator::RequiredRegisterKind(
-    int virtual_register) const {
-  return (code()->IsDouble(virtual_register)) ? DOUBLE_REGISTERS
-                                              : GENERAL_REGISTERS;
-}
-
-
-void RegisterAllocator::AddToActive(LiveRange* range) {
-  TraceAlloc("Add live range %d to active\n", range->id());
-  active_live_ranges().push_back(range);
-}
-
-
-void RegisterAllocator::AddToInactive(LiveRange* range) {
-  TraceAlloc("Add live range %d to inactive\n", range->id());
-  inactive_live_ranges().push_back(range);
-}
-
-
-void RegisterAllocator::AddToUnhandledSorted(LiveRange* range) {
-  if (range == nullptr || range->IsEmpty()) return;
-  DCHECK(!range->HasRegisterAssigned() && !range->IsSpilled());
-  DCHECK(allocation_finger_.Value() <= range->Start().Value());
-  for (int i = static_cast<int>(unhandled_live_ranges().size() - 1); i >= 0;
-       --i) {
-    auto cur_range = unhandled_live_ranges().at(i);
-    if (!range->ShouldBeAllocatedBefore(cur_range)) continue;
-    TraceAlloc("Add live range %d to unhandled at %d\n", range->id(), i + 1);
-    auto it = unhandled_live_ranges().begin() + (i + 1);
-    unhandled_live_ranges().insert(it, range);
-    DCHECK(UnhandledIsSorted());
-    return;
-  }
-  TraceAlloc("Add live range %d to unhandled at start\n", range->id());
-  unhandled_live_ranges().insert(unhandled_live_ranges().begin(), range);
-  DCHECK(UnhandledIsSorted());
-}
-
-
-void RegisterAllocator::AddToUnhandledUnsorted(LiveRange* range) {
-  if (range == nullptr || range->IsEmpty()) return;
-  DCHECK(!range->HasRegisterAssigned() && !range->IsSpilled());
-  TraceAlloc("Add live range %d to unhandled unsorted at end\n", range->id());
-  unhandled_live_ranges().push_back(range);
-}
-
-
-static bool UnhandledSortHelper(LiveRange* a, LiveRange* b) {
-  DCHECK(!a->ShouldBeAllocatedBefore(b) || !b->ShouldBeAllocatedBefore(a));
-  if (a->ShouldBeAllocatedBefore(b)) return false;
-  if (b->ShouldBeAllocatedBefore(a)) return true;
-  return a->id() < b->id();
-}
-
-
-// Sort the unhandled live ranges so that the ranges to be processed first are
-// at the end of the array list.  This is convenient for the register allocation
-// algorithm because it is efficient to remove elements from the end.
-void RegisterAllocator::SortUnhandled() {
-  TraceAlloc("Sort unhandled\n");
-  std::sort(unhandled_live_ranges().begin(), unhandled_live_ranges().end(),
-            &UnhandledSortHelper);
-}
-
-
-bool RegisterAllocator::UnhandledIsSorted() {
-  size_t len = unhandled_live_ranges().size();
-  for (size_t i = 1; i < len; i++) {
-    auto a = unhandled_live_ranges().at(i - 1);
-    auto b = unhandled_live_ranges().at(i);
-    if (a->Start().Value() < b->Start().Value()) return false;
-  }
-  return true;
-}
-
-
-void RegisterAllocator::FreeSpillSlot(LiveRange* range) {
-  DCHECK(!FLAG_turbo_reuse_spill_slots);
-  // Check that we are the last range.
-  if (range->next() != nullptr) return;
-  if (!range->TopLevel()->HasSpillOperand()) return;
-  auto spill_operand = range->TopLevel()->GetSpillOperand();
-  if (spill_operand->IsConstant()) return;
-  if (spill_operand->index() >= 0) {
-    reusable_slots().push_back(range);
-  }
-}
-
-
-InstructionOperand* RegisterAllocator::TryReuseSpillSlot(LiveRange* range) {
-  DCHECK(!FLAG_turbo_reuse_spill_slots);
-  if (reusable_slots().empty()) return nullptr;
-  if (reusable_slots().front()->End().Value() >
-      range->TopLevel()->Start().Value()) {
-    return nullptr;
-  }
-  auto result = reusable_slots().front()->TopLevel()->GetSpillOperand();
-  reusable_slots().erase(reusable_slots().begin());
-  return result;
-}
-
-
-void RegisterAllocator::ActiveToHandled(LiveRange* range) {
-  RemoveElement(&active_live_ranges(), range);
-  TraceAlloc("Moving live range %d from active to handled\n", range->id());
-  if (!FLAG_turbo_reuse_spill_slots) FreeSpillSlot(range);
-}
-
-
-void RegisterAllocator::ActiveToInactive(LiveRange* range) {
-  RemoveElement(&active_live_ranges(), range);
-  inactive_live_ranges().push_back(range);
-  TraceAlloc("Moving live range %d from active to inactive\n", range->id());
-}
-
-
-void RegisterAllocator::InactiveToHandled(LiveRange* range) {
-  RemoveElement(&inactive_live_ranges(), range);
-  TraceAlloc("Moving live range %d from inactive to handled\n", range->id());
-  if (!FLAG_turbo_reuse_spill_slots) FreeSpillSlot(range);
-}
-
-
-void RegisterAllocator::InactiveToActive(LiveRange* range) {
-  RemoveElement(&inactive_live_ranges(), range);
-  active_live_ranges().push_back(range);
-  TraceAlloc("Moving live range %d from inactive to active\n", range->id());
-}
-
-
-bool RegisterAllocator::TryAllocateFreeReg(LiveRange* current) {
-  LifetimePosition free_until_pos[RegisterConfiguration::kMaxDoubleRegisters];
-
-  for (int i = 0; i < num_registers_; i++) {
-    free_until_pos[i] = LifetimePosition::MaxPosition();
-  }
-
-  for (auto cur_active : active_live_ranges()) {
-    free_until_pos[cur_active->assigned_register()] =
-        LifetimePosition::FromInstructionIndex(0);
-  }
-
-  for (auto cur_inactive : inactive_live_ranges()) {
-    DCHECK(cur_inactive->End().Value() > current->Start().Value());
-    auto next_intersection = cur_inactive->FirstIntersection(current);
-    if (!next_intersection.IsValid()) continue;
-    int cur_reg = cur_inactive->assigned_register();
-    free_until_pos[cur_reg] = Min(free_until_pos[cur_reg], next_intersection);
-  }
-
-  auto hint = current->FirstHint();
-  if (hint != nullptr && (hint->IsRegister() || hint->IsDoubleRegister())) {
-    int register_index = hint->index();
-    TraceAlloc(
-        "Found reg hint %s (free until [%d) for live range %d (end %d[).\n",
-        RegisterName(register_index), free_until_pos[register_index].Value(),
-        current->id(), current->End().Value());
-
-    // The desired register is free until the end of the current live range.
-    if (free_until_pos[register_index].Value() >= current->End().Value()) {
-      TraceAlloc("Assigning preferred reg %s to live range %d\n",
-                 RegisterName(register_index), current->id());
-      SetLiveRangeAssignedRegister(current, register_index);
-      return true;
-    }
-  }
-
-  // Find the register which stays free for the longest time.
-  int reg = 0;
-  for (int i = 1; i < RegisterCount(); ++i) {
-    if (free_until_pos[i].Value() > free_until_pos[reg].Value()) {
-      reg = i;
-    }
-  }
-
-  auto pos = free_until_pos[reg];
-
-  if (pos.Value() <= current->Start().Value()) {
-    // All registers are blocked.
-    return false;
-  }
-
-  if (pos.Value() < current->End().Value()) {
-    // Register reg is available at the range start but becomes blocked before
-    // the range end. Split current at position where it becomes blocked.
-    auto tail = SplitRangeAt(current, pos);
-    if (!AllocationOk()) return false;
-    AddToUnhandledSorted(tail);
-  }
-
-  // Register reg is available at the range start and is free until
-  // the range end.
-  DCHECK(pos.Value() >= current->End().Value());
-  TraceAlloc("Assigning free reg %s to live range %d\n", RegisterName(reg),
-             current->id());
-  SetLiveRangeAssignedRegister(current, reg);
-
-  return true;
-}
-
-
-void RegisterAllocator::AllocateBlockedReg(LiveRange* current) {
-  auto register_use = current->NextRegisterPosition(current->Start());
-  if (register_use == nullptr) {
-    // There is no use in the current live range that requires a register.
-    // We can just spill it.
-    Spill(current);
-    return;
-  }
-
-  LifetimePosition use_pos[RegisterConfiguration::kMaxDoubleRegisters];
-  LifetimePosition block_pos[RegisterConfiguration::kMaxDoubleRegisters];
-
-  for (int i = 0; i < num_registers_; i++) {
-    use_pos[i] = block_pos[i] = LifetimePosition::MaxPosition();
-  }
-
-  for (auto range : active_live_ranges()) {
-    int cur_reg = range->assigned_register();
-    if (range->IsFixed() || !range->CanBeSpilled(current->Start())) {
-      block_pos[cur_reg] = use_pos[cur_reg] =
-          LifetimePosition::FromInstructionIndex(0);
-    } else {
-      auto next_use =
-          range->NextUsePositionRegisterIsBeneficial(current->Start());
-      if (next_use == nullptr) {
-        use_pos[cur_reg] = range->End();
+      InstructionOperand prev_operand = first_range->GetAssignedOperand();
+      InstructionOperand cur_operand = second_range->GetAssignedOperand();
+      if (prev_operand.Equals(cur_operand)) continue;
+      bool delay_insertion = false;
+      Instruction::GapPosition gap_pos;
+      int gap_index = pos.ToInstructionIndex();
+      if (pos.IsGapPosition()) {
+        gap_pos = pos.IsStart() ? Instruction::START : Instruction::END;
       } else {
-        use_pos[cur_reg] = next_use->pos();
-      }
-    }
-  }
-
-  for (auto range : inactive_live_ranges()) {
-    DCHECK(range->End().Value() > current->Start().Value());
-    auto next_intersection = range->FirstIntersection(current);
-    if (!next_intersection.IsValid()) continue;
-    int cur_reg = range->assigned_register();
-    if (range->IsFixed()) {
-      block_pos[cur_reg] = Min(block_pos[cur_reg], next_intersection);
-      use_pos[cur_reg] = Min(block_pos[cur_reg], use_pos[cur_reg]);
-    } else {
-      use_pos[cur_reg] = Min(use_pos[cur_reg], next_intersection);
-    }
-  }
-
-  int reg = 0;
-  for (int i = 1; i < RegisterCount(); ++i) {
-    if (use_pos[i].Value() > use_pos[reg].Value()) {
-      reg = i;
-    }
-  }
-
-  auto pos = use_pos[reg];
-
-  if (pos.Value() < register_use->pos().Value()) {
-    // All registers are blocked before the first use that requires a register.
-    // Spill starting part of live range up to that use.
-    SpillBetween(current, current->Start(), register_use->pos());
-    return;
-  }
-
-  if (block_pos[reg].Value() < current->End().Value()) {
-    // Register becomes blocked before the current range end. Split before that
-    // position.
-    LiveRange* tail = SplitBetween(current, current->Start(),
-                                   block_pos[reg].InstructionStart());
-    if (!AllocationOk()) return;
-    AddToUnhandledSorted(tail);
-  }
-
-  // Register reg is not blocked for the whole range.
-  DCHECK(block_pos[reg].Value() >= current->End().Value());
-  TraceAlloc("Assigning blocked reg %s to live range %d\n", RegisterName(reg),
-             current->id());
-  SetLiveRangeAssignedRegister(current, reg);
-
-  // This register was not free. Thus we need to find and spill
-  // parts of active and inactive live regions that use the same register
-  // at the same lifetime positions as current.
-  SplitAndSpillIntersecting(current);
-}
-
-
-static const InstructionBlock* GetContainingLoop(
-    const InstructionSequence* sequence, const InstructionBlock* block) {
-  auto index = block->loop_header();
-  if (!index.IsValid()) return nullptr;
-  return sequence->InstructionBlockAt(index);
-}
-
-
-LifetimePosition RegisterAllocator::FindOptimalSpillingPos(
-    LiveRange* range, LifetimePosition pos) {
-  auto block = GetInstructionBlock(pos.InstructionStart());
-  auto loop_header =
-      block->IsLoopHeader() ? block : GetContainingLoop(code(), block);
-
-  if (loop_header == nullptr) return pos;
-
-  auto prev_use = range->PreviousUsePositionRegisterIsBeneficial(pos);
-
-  while (loop_header != nullptr) {
-    // We are going to spill live range inside the loop.
-    // If possible try to move spilling position backwards to loop header.
-    // This will reduce number of memory moves on the back edge.
-    auto loop_start = LifetimePosition::FromInstructionIndex(
-        loop_header->first_instruction_index());
-
-    if (range->Covers(loop_start)) {
-      if (prev_use == nullptr || prev_use->pos().Value() < loop_start.Value()) {
-        // No register beneficial use inside the loop before the pos.
-        pos = loop_start;
-      }
-    }
-
-    // Try hoisting out to an outer loop.
-    loop_header = GetContainingLoop(code(), loop_header);
-  }
-
-  return pos;
-}
-
-
-void RegisterAllocator::SplitAndSpillIntersecting(LiveRange* current) {
-  DCHECK(current->HasRegisterAssigned());
-  int reg = current->assigned_register();
-  auto split_pos = current->Start();
-  for (size_t i = 0; i < active_live_ranges().size(); ++i) {
-    auto range = active_live_ranges()[i];
-    if (range->assigned_register() == reg) {
-      auto next_pos = range->NextRegisterPosition(current->Start());
-      auto spill_pos = FindOptimalSpillingPos(range, split_pos);
-      if (next_pos == nullptr) {
-        SpillAfter(range, spill_pos);
-      } else {
-        // When spilling between spill_pos and next_pos ensure that the range
-        // remains spilled at least until the start of the current live range.
-        // This guarantees that we will not introduce new unhandled ranges that
-        // start before the current range as this violates allocation invariant
-        // and will lead to an inconsistent state of active and inactive
-        // live-ranges: ranges are allocated in order of their start positions,
-        // ranges are retired from active/inactive when the start of the
-        // current live-range is larger than their end.
-        SpillBetweenUntil(range, spill_pos, current->Start(), next_pos->pos());
-      }
-      if (!AllocationOk()) return;
-      ActiveToHandled(range);
-      --i;
-    }
-  }
-
-  for (size_t i = 0; i < inactive_live_ranges().size(); ++i) {
-    auto range = inactive_live_ranges()[i];
-    DCHECK(range->End().Value() > current->Start().Value());
-    if (range->assigned_register() == reg && !range->IsFixed()) {
-      LifetimePosition next_intersection = range->FirstIntersection(current);
-      if (next_intersection.IsValid()) {
-        UsePosition* next_pos = range->NextRegisterPosition(current->Start());
-        if (next_pos == nullptr) {
-          SpillAfter(range, split_pos);
+        if (pos.IsStart()) {
+          delay_insertion = true;
         } else {
-          next_intersection = Min(next_intersection, next_pos->pos());
-          SpillBetween(range, split_pos, next_intersection);
+          gap_index++;
         }
-        if (!AllocationOk()) return;
-        InactiveToHandled(range);
-        --i;
+        gap_pos = delay_insertion ? Instruction::END : Instruction::START;
+      }
+      // Fills or spills for spilled in deferred blocks ranges must happen
+      // only in deferred blocks.
+      DCHECK_IMPLIES(
+          connect_spilled &&
+              !(prev_operand.IsAnyRegister() && cur_operand.IsAnyRegister()),
+          code()->GetInstructionBlock(gap_index)->IsDeferred());
+
+      ParallelMove* move =
+          code()->InstructionAt(gap_index)->GetOrCreateParallelMove(
+              gap_pos, code_zone());
+      if (!delay_insertion) {
+        move->AddMove(prev_operand, cur_operand);
+      } else {
+        delayed_insertion_map.insert(
+            std::make_pair(std::make_pair(move, prev_operand), cur_operand));
       }
     }
   }
-}
-
-
-bool RegisterAllocator::IsBlockBoundary(LifetimePosition pos) {
-  return pos.IsInstructionStart() &&
-         InstructionAt(pos.InstructionIndex())->IsBlockStart();
-}
-
-
-LiveRange* RegisterAllocator::SplitRangeAt(LiveRange* range,
-                                           LifetimePosition pos) {
-  DCHECK(!range->IsFixed());
-  TraceAlloc("Splitting live range %d at %d\n", range->id(), pos.Value());
-
-  if (pos.Value() <= range->Start().Value()) return range;
-
-  // We can't properly connect liveranges if split occured at the end
-  // of control instruction.
-  DCHECK(pos.IsInstructionStart() ||
-         !InstructionAt(pos.InstructionIndex())->IsControl());
-
-  int vreg = GetVirtualRegister();
-  if (!AllocationOk()) return nullptr;
-  auto result = LiveRangeFor(vreg);
-  range->SplitAt(pos, result, local_zone());
-  return result;
-}
-
-
-LiveRange* RegisterAllocator::SplitBetween(LiveRange* range,
-                                           LifetimePosition start,
-                                           LifetimePosition end) {
-  DCHECK(!range->IsFixed());
-  TraceAlloc("Splitting live range %d in position between [%d, %d]\n",
-             range->id(), start.Value(), end.Value());
-
-  auto split_pos = FindOptimalSplitPos(start, end);
-  DCHECK(split_pos.Value() >= start.Value());
-  return SplitRangeAt(range, split_pos);
-}
-
-
-LifetimePosition RegisterAllocator::FindOptimalSplitPos(LifetimePosition start,
-                                                        LifetimePosition end) {
-  int start_instr = start.InstructionIndex();
-  int end_instr = end.InstructionIndex();
-  DCHECK(start_instr <= end_instr);
-
-  // We have no choice
-  if (start_instr == end_instr) return end;
-
-  auto start_block = GetInstructionBlock(start);
-  auto end_block = GetInstructionBlock(end);
-
-  if (end_block == start_block) {
-    // The interval is split in the same basic block. Split at the latest
-    // possible position.
-    return end;
-  }
-
-  auto block = end_block;
-  // Find header of outermost loop.
-  // TODO(titzer): fix redundancy below.
-  while (GetContainingLoop(code(), block) != nullptr &&
-         GetContainingLoop(code(), block)->rpo_number().ToInt() >
-             start_block->rpo_number().ToInt()) {
-    block = GetContainingLoop(code(), block);
-  }
-
-  // We did not find any suitable outer loop. Split at the latest possible
-  // position unless end_block is a loop header itself.
-  if (block == end_block && !end_block->IsLoopHeader()) return end;
-
-  return LifetimePosition::FromInstructionIndex(
-      block->first_instruction_index());
-}
-
-
-void RegisterAllocator::SpillAfter(LiveRange* range, LifetimePosition pos) {
-  auto second_part = SplitRangeAt(range, pos);
-  if (!AllocationOk()) return;
-  Spill(second_part);
-}
-
-
-void RegisterAllocator::SpillBetween(LiveRange* range, LifetimePosition start,
-                                     LifetimePosition end) {
-  SpillBetweenUntil(range, start, start, end);
-}
-
-
-void RegisterAllocator::SpillBetweenUntil(LiveRange* range,
-                                          LifetimePosition start,
-                                          LifetimePosition until,
-                                          LifetimePosition end) {
-  CHECK(start.Value() < end.Value());
-  auto second_part = SplitRangeAt(range, start);
-  if (!AllocationOk()) return;
-
-  if (second_part->Start().Value() < end.Value()) {
-    // The split result intersects with [start, end[.
-    // Split it at position between ]start+1, end[, spill the middle part
-    // and put the rest to unhandled.
-    auto third_part = SplitBetween(
-        second_part, Max(second_part->Start().InstructionEnd(), until),
-        end.PrevInstruction().InstructionEnd());
-    if (!AllocationOk()) return;
-
-    DCHECK(third_part != second_part);
-
-    Spill(second_part);
-    AddToUnhandledSorted(third_part);
-  } else {
-    // The split result does not intersect with [start, end[.
-    // Nothing to spill. Just put it to unhandled as whole.
-    AddToUnhandledSorted(second_part);
-  }
-}
-
-
-void RegisterAllocator::Spill(LiveRange* range) {
-  DCHECK(!range->IsSpilled());
-  TraceAlloc("Spilling live range %d\n", range->id());
-  auto first = range->TopLevel();
-  if (first->HasNoSpillType()) {
-    if (FLAG_turbo_reuse_spill_slots) {
-      AssignSpillRangeToLiveRange(first);
-    } else {
-      auto op = TryReuseSpillSlot(range);
-      if (op == nullptr) {
-        // Allocate a new operand referring to the spill slot.
-        RegisterKind kind = range->Kind();
-        int index = frame()->AllocateSpillSlot(kind == DOUBLE_REGISTERS);
-        auto op_kind = kind == DOUBLE_REGISTERS
-                           ? InstructionOperand::DOUBLE_STACK_SLOT
-                           : InstructionOperand::STACK_SLOT;
-        op = new (code_zone()) InstructionOperand(op_kind, index);
+  if (delayed_insertion_map.empty()) return;
+  // Insert all the moves which should occur after the stored move.
+  ZoneVector<MoveOperands*> to_insert(local_zone);
+  ZoneVector<MoveOperands*> to_eliminate(local_zone);
+  to_insert.reserve(4);
+  to_eliminate.reserve(4);
+  ParallelMove* moves = delayed_insertion_map.begin()->first.first;
+  for (auto it = delayed_insertion_map.begin();; ++it) {
+    bool done = it == delayed_insertion_map.end();
+    if (done || it->first.first != moves) {
+      // Commit the MoveOperands for current ParallelMove.
+      for (MoveOperands* move : to_eliminate) {
+        move->Eliminate();
       }
-      first->SetSpillOperand(op);
+      for (MoveOperands* move : to_insert) {
+        moves->push_back(move);
+      }
+      if (done) break;
+      // Reset state.
+      to_eliminate.clear();
+      to_insert.clear();
+      moves = it->first.first;
     }
-  }
-  range->MakeSpilled();
-}
-
-
-int RegisterAllocator::RegisterCount() const { return num_registers_; }
-
-
-#ifdef DEBUG
-
-
-void RegisterAllocator::Verify() const {
-  for (auto current : live_ranges()) {
-    if (current != nullptr) current->Verify();
+    // Gather all MoveOperands for a single ParallelMove.
+    MoveOperands* move =
+        new (code_zone()) MoveOperands(it->first.second, it->second);
+    MoveOperands* eliminate = moves->PrepareInsertAfter(move);
+    to_insert.push_back(move);
+    if (eliminate != nullptr) to_eliminate.push_back(eliminate);
   }
 }
 
 
-#endif
-
-
-void RegisterAllocator::SetLiveRangeAssignedRegister(LiveRange* range,
-                                                     int reg) {
-  if (range->Kind() == DOUBLE_REGISTERS) {
-    assigned_double_registers_->Add(reg);
-  } else {
-    DCHECK(range->Kind() == GENERAL_REGISTERS);
-    assigned_registers_->Add(reg);
-  }
-  range->set_assigned_register(reg, code_zone());
-}
-
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/src/compiler/register-allocator.h b/src/compiler/register-allocator.h
index b17837b..b96a43c 100644
--- a/src/compiler/register-allocator.h
+++ b/src/compiler/register-allocator.h
@@ -6,6 +6,8 @@
 #define V8_REGISTER_ALLOCATOR_H_
 
 #include "src/compiler/instruction.h"
+#include "src/ostreams.h"
+#include "src/register-configuration.h"
 #include "src/zone-containers.h"
 
 namespace v8 {
@@ -13,64 +15,92 @@
 namespace compiler {
 
 enum RegisterKind {
-  UNALLOCATED_REGISTERS,
   GENERAL_REGISTERS,
   DOUBLE_REGISTERS
 };
 
 
 // This class represents a single point of a InstructionOperand's lifetime. For
-// each instruction there are exactly two lifetime positions: the beginning and
-// the end of the instruction. Lifetime positions for different instructions are
-// disjoint.
-class LifetimePosition FINAL {
+// each instruction there are four lifetime positions:
+//
+//   [[START, END], [START, END]]
+//
+// Where the first half position corresponds to
+//
+//  [GapPosition::START, GapPosition::END]
+//
+// and the second half position corresponds to
+//
+//  [Lifetime::USED_AT_START, Lifetime::USED_AT_END]
+//
+class LifetimePosition final {
  public:
   // Return the lifetime position that corresponds to the beginning of
-  // the instruction with the given index.
-  static LifetimePosition FromInstructionIndex(int index) {
+  // the gap with the given index.
+  static LifetimePosition GapFromInstructionIndex(int index) {
     return LifetimePosition(index * kStep);
   }
+  // Return the lifetime position that corresponds to the beginning of
+  // the instruction with the given index.
+  static LifetimePosition InstructionFromInstructionIndex(int index) {
+    return LifetimePosition(index * kStep + kHalfStep);
+  }
 
   // Returns a numeric representation of this lifetime position.
-  int Value() const { return value_; }
+  int value() const { return value_; }
 
   // Returns the index of the instruction to which this lifetime position
   // corresponds.
-  int InstructionIndex() const {
+  int ToInstructionIndex() const {
     DCHECK(IsValid());
     return value_ / kStep;
   }
 
-  // Returns true if this lifetime position corresponds to the instruction
-  // start.
-  bool IsInstructionStart() const { return (value_ & (kStep - 1)) == 0; }
+  // Returns true if this lifetime position corresponds to a START value
+  bool IsStart() const { return (value_ & (kHalfStep - 1)) == 0; }
+  // Returns true if this lifetime position corresponds to an END value
+  bool IsEnd() const { return (value_ & (kHalfStep - 1)) == 1; }
+  // Returns true if this lifetime position corresponds to a gap START value
+  bool IsFullStart() const { return (value_ & (kStep - 1)) == 0; }
 
-  // Returns the lifetime position for the start of the instruction which
-  // corresponds to this lifetime position.
-  LifetimePosition InstructionStart() const {
+  bool IsGapPosition() const { return (value_ & 0x2) == 0; }
+  bool IsInstructionPosition() const { return !IsGapPosition(); }
+
+  // Returns the lifetime position for the current START.
+  LifetimePosition Start() const {
+    DCHECK(IsValid());
+    return LifetimePosition(value_ & ~(kHalfStep - 1));
+  }
+
+  // Returns the lifetime position for the current gap START.
+  LifetimePosition FullStart() const {
     DCHECK(IsValid());
     return LifetimePosition(value_ & ~(kStep - 1));
   }
 
-  // Returns the lifetime position for the end of the instruction which
-  // corresponds to this lifetime position.
-  LifetimePosition InstructionEnd() const {
+  // Returns the lifetime position for the current END.
+  LifetimePosition End() const {
     DCHECK(IsValid());
-    return LifetimePosition(InstructionStart().Value() + kStep / 2);
+    return LifetimePosition(Start().value_ + kHalfStep / 2);
   }
 
-  // Returns the lifetime position for the beginning of the next instruction.
-  LifetimePosition NextInstruction() const {
+  // Returns the lifetime position for the beginning of the next START.
+  LifetimePosition NextStart() const {
     DCHECK(IsValid());
-    return LifetimePosition(InstructionStart().Value() + kStep);
+    return LifetimePosition(Start().value_ + kHalfStep);
   }
 
-  // Returns the lifetime position for the beginning of the previous
-  // instruction.
-  LifetimePosition PrevInstruction() const {
+  // Returns the lifetime position for the beginning of the next gap START.
+  LifetimePosition NextFullStart() const {
     DCHECK(IsValid());
-    DCHECK(value_ > 1);
-    return LifetimePosition(InstructionStart().Value() - kStep);
+    return LifetimePosition(FullStart().value_ + kStep);
+  }
+
+  // Returns the lifetime position for the beginning of the previous START.
+  LifetimePosition PrevStart() const {
+    DCHECK(IsValid());
+    DCHECK(value_ >= kHalfStep);
+    return LifetimePosition(Start().value_ - kHalfStep);
   }
 
   // Constructs the lifetime position which does not correspond to any
@@ -81,6 +111,32 @@
   // instruction.
   bool IsValid() const { return value_ != -1; }
 
+  bool operator<(const LifetimePosition& that) const {
+    return this->value_ < that.value_;
+  }
+
+  bool operator<=(const LifetimePosition& that) const {
+    return this->value_ <= that.value_;
+  }
+
+  bool operator==(const LifetimePosition& that) const {
+    return this->value_ == that.value_;
+  }
+
+  bool operator!=(const LifetimePosition& that) const {
+    return this->value_ != that.value_;
+  }
+
+  bool operator>(const LifetimePosition& that) const {
+    return this->value_ > that.value_;
+  }
+
+  bool operator>=(const LifetimePosition& that) const {
+    return this->value_ >= that.value_;
+  }
+
+  void Print() const;
+
   static inline LifetimePosition Invalid() { return LifetimePosition(); }
 
   static inline LifetimePosition MaxPosition() {
@@ -89,11 +145,16 @@
     return LifetimePosition(kMaxInt);
   }
 
- private:
-  static const int kStep = 2;
+  static inline LifetimePosition FromInt(int value) {
+    return LifetimePosition(value);
+  }
 
-  // Code relies on kStep being a power of two.
-  STATIC_ASSERT(IS_POWER_OF_TWO(kStep));
+ private:
+  static const int kHalfStep = 2;
+  static const int kStep = 2 * kHalfStep;
+
+  // Code relies on kStep and kHalfStep being a power of two.
+  STATIC_ASSERT(IS_POWER_OF_TWO(kHalfStep));
 
   explicit LifetimePosition(int value) : value_(value) {}
 
@@ -101,153 +162,227 @@
 };
 
 
+std::ostream& operator<<(std::ostream& os, const LifetimePosition pos);
+
+
 // Representation of the non-empty interval [start,end[.
-class UseInterval FINAL : public ZoneObject {
+class UseInterval final : public ZoneObject {
  public:
   UseInterval(LifetimePosition start, LifetimePosition end)
       : start_(start), end_(end), next_(nullptr) {
-    DCHECK(start.Value() < end.Value());
+    DCHECK(start < end);
   }
 
   LifetimePosition start() const { return start_; }
+  void set_start(LifetimePosition start) { start_ = start; }
   LifetimePosition end() const { return end_; }
+  void set_end(LifetimePosition end) { end_ = end; }
   UseInterval* next() const { return next_; }
+  void set_next(UseInterval* next) { next_ = next; }
 
   // Split this interval at the given position without effecting the
   // live range that owns it. The interval must contain the position.
-  void SplitAt(LifetimePosition pos, Zone* zone);
+  UseInterval* SplitAt(LifetimePosition pos, Zone* zone);
 
   // If this interval intersects with other return smallest position
   // that belongs to both of them.
   LifetimePosition Intersect(const UseInterval* other) const {
-    if (other->start().Value() < start_.Value()) return other->Intersect(this);
-    if (other->start().Value() < end_.Value()) return other->start();
+    if (other->start() < start_) return other->Intersect(this);
+    if (other->start() < end_) return other->start();
     return LifetimePosition::Invalid();
   }
 
   bool Contains(LifetimePosition point) const {
-    return start_.Value() <= point.Value() && point.Value() < end_.Value();
+    return start_ <= point && point < end_;
   }
 
-  void set_start(LifetimePosition start) { start_ = start; }
-  void set_next(UseInterval* next) { next_ = next; }
+  // Returns the index of the first gap covered by this interval.
+  int FirstGapIndex() const {
+    int ret = start_.ToInstructionIndex();
+    if (start_.IsInstructionPosition()) {
+      ++ret;
+    }
+    return ret;
+  }
 
+  // Returns the index of the last gap covered by this interval.
+  int LastGapIndex() const {
+    int ret = end_.ToInstructionIndex();
+    if (end_.IsGapPosition() && end_.IsStart()) {
+      --ret;
+    }
+    return ret;
+  }
+
+ private:
   LifetimePosition start_;
   LifetimePosition end_;
   UseInterval* next_;
 
- private:
   DISALLOW_COPY_AND_ASSIGN(UseInterval);
 };
 
 
+enum class UsePositionType : uint8_t { kAny, kRequiresRegister, kRequiresSlot };
+
+
+enum class UsePositionHintType : uint8_t {
+  kNone,
+  kOperand,
+  kUsePos,
+  kPhi,
+  kUnresolved
+};
+
+
+static const int32_t kUnassignedRegister =
+    RegisterConfiguration::kMaxGeneralRegisters;
+
+
+static_assert(kUnassignedRegister <= RegisterConfiguration::kMaxDoubleRegisters,
+              "kUnassignedRegister too small");
+
+
 // Representation of a use position.
-class UsePosition FINAL : public ZoneObject {
+class UsePosition final : public ZoneObject {
  public:
-  UsePosition(LifetimePosition pos, InstructionOperand* operand,
-              InstructionOperand* hint);
+  UsePosition(LifetimePosition pos, InstructionOperand* operand, void* hint,
+              UsePositionHintType hint_type);
 
   InstructionOperand* operand() const { return operand_; }
   bool HasOperand() const { return operand_ != nullptr; }
 
-  InstructionOperand* hint() const { return hint_; }
-  bool HasHint() const;
-  bool RequiresRegister() const;
-  bool RegisterIsBeneficial() const;
+  bool RegisterIsBeneficial() const {
+    return RegisterBeneficialField::decode(flags_);
+  }
+  UsePositionType type() const { return TypeField::decode(flags_); }
+  void set_type(UsePositionType type, bool register_beneficial);
 
   LifetimePosition pos() const { return pos_; }
-  UsePosition* next() const { return next_; }
 
+  UsePosition* next() const { return next_; }
   void set_next(UsePosition* next) { next_ = next; }
 
-  InstructionOperand* const operand_;
-  InstructionOperand* const hint_;
-  LifetimePosition const pos_;
-  UsePosition* next_;
-  bool requires_reg_ : 1;
-  bool register_beneficial_ : 1;
+  // For hinting only.
+  void set_assigned_register(int register_code) {
+    flags_ = AssignedRegisterField::update(flags_, register_code);
+  }
+
+  UsePositionHintType hint_type() const {
+    return HintTypeField::decode(flags_);
+  }
+  bool HasHint() const;
+  bool HintRegister(int* register_code) const;
+  void ResolveHint(UsePosition* use_pos);
+  bool IsResolved() const {
+    return hint_type() != UsePositionHintType::kUnresolved;
+  }
+  static UsePositionHintType HintTypeForOperand(const InstructionOperand& op);
 
  private:
+  typedef BitField<UsePositionType, 0, 2> TypeField;
+  typedef BitField<UsePositionHintType, 2, 3> HintTypeField;
+  typedef BitField<bool, 5, 1> RegisterBeneficialField;
+  typedef BitField<int32_t, 6, 6> AssignedRegisterField;
+
+  InstructionOperand* const operand_;
+  void* hint_;
+  UsePosition* next_;
+  LifetimePosition const pos_;
+  uint32_t flags_;
+
   DISALLOW_COPY_AND_ASSIGN(UsePosition);
 };
 
+
 class SpillRange;
+class RegisterAllocationData;
+class TopLevelLiveRange;
+class LiveRangeGroup;
 
 // Representation of SSA values' live ranges as a collection of (continuous)
 // intervals over the instruction ordering.
-class LiveRange FINAL : public ZoneObject {
+class LiveRange : public ZoneObject {
  public:
-  static const int kInvalidAssignment = 0x7fffffff;
-
-  LiveRange(int id, Zone* zone);
-
   UseInterval* first_interval() const { return first_interval_; }
   UsePosition* first_pos() const { return first_pos_; }
-  LiveRange* parent() const { return parent_; }
-  LiveRange* TopLevel() { return (parent_ == nullptr) ? this : parent_; }
-  const LiveRange* TopLevel() const {
-    return (parent_ == nullptr) ? this : parent_;
-  }
+  TopLevelLiveRange* TopLevel() { return top_level_; }
+  const TopLevelLiveRange* TopLevel() const { return top_level_; }
+
+  bool IsTopLevel() const;
+
   LiveRange* next() const { return next_; }
-  bool IsChild() const { return parent() != nullptr; }
-  int id() const { return id_; }
-  bool IsFixed() const { return id_ < 0; }
+
+  int relative_id() const { return relative_id_; }
+
   bool IsEmpty() const { return first_interval() == nullptr; }
-  InstructionOperand* CreateAssignedOperand(Zone* zone) const;
-  int assigned_register() const { return assigned_register_; }
-  int spill_start_index() const { return spill_start_index_; }
-  void set_assigned_register(int reg, Zone* zone);
-  void MakeSpilled();
-  bool is_phi() const { return is_phi_; }
-  void set_is_phi(bool is_phi) { is_phi_ = is_phi; }
-  bool is_non_loop_phi() const { return is_non_loop_phi_; }
-  void set_is_non_loop_phi(bool is_non_loop_phi) {
-    is_non_loop_phi_ = is_non_loop_phi;
+
+  InstructionOperand GetAssignedOperand() const;
+
+  MachineRepresentation representation() const {
+    return RepresentationField::decode(bits_);
   }
 
+  int assigned_register() const { return AssignedRegisterField::decode(bits_); }
+  bool HasRegisterAssigned() const {
+    return assigned_register() != kUnassignedRegister;
+  }
+  void set_assigned_register(int reg);
+  void UnsetAssignedRegister();
+
+  bool spilled() const { return SpilledField::decode(bits_); }
+  void Spill();
+
+  RegisterKind kind() const;
+
   // Returns use position in this live range that follows both start
   // and last processed use position.
-  // Modifies internal state of live range!
-  UsePosition* NextUsePosition(LifetimePosition start);
+  UsePosition* NextUsePosition(LifetimePosition start) const;
 
   // Returns use position for which register is required in this live
   // range and which follows both start and last processed use position
-  // Modifies internal state of live range!
-  UsePosition* NextRegisterPosition(LifetimePosition start);
+  UsePosition* NextRegisterPosition(LifetimePosition start) const;
+
+  // Returns the first use position requiring stack slot, or nullptr.
+  UsePosition* NextSlotPosition(LifetimePosition start) const;
 
   // Returns use position for which register is beneficial in this live
   // range and which follows both start and last processed use position
-  // Modifies internal state of live range!
-  UsePosition* NextUsePositionRegisterIsBeneficial(LifetimePosition start);
+  UsePosition* NextUsePositionRegisterIsBeneficial(
+      LifetimePosition start) const;
 
   // Returns use position for which register is beneficial in this live
   // range and which precedes start.
-  UsePosition* PreviousUsePositionRegisterIsBeneficial(LifetimePosition start);
+  UsePosition* PreviousUsePositionRegisterIsBeneficial(
+      LifetimePosition start) const;
 
   // Can this live range be spilled at this position.
-  bool CanBeSpilled(LifetimePosition pos);
+  bool CanBeSpilled(LifetimePosition pos) const;
 
-  // Split this live range at the given position which must follow the start of
-  // the range.
+  // Splitting primitive used by both splitting and splintering members.
+  // Performs the split, but does not link the resulting ranges.
+  // The given position must follow the start of the range.
   // All uses following the given position will be moved from this
   // live range to the result live range.
-  void SplitAt(LifetimePosition position, LiveRange* result, Zone* zone);
+  // The current range will terminate at position, while result will start from
+  // position.
+  UsePosition* DetachAt(LifetimePosition position, LiveRange* result,
+                        Zone* zone);
 
-  RegisterKind Kind() const { return kind_; }
-  bool HasRegisterAssigned() const {
-    return assigned_register_ != kInvalidAssignment;
-  }
-  bool IsSpilled() const { return spilled_; }
+  // Detaches at position, and then links the resulting ranges. Returns the
+  // child, which starts at position.
+  LiveRange* SplitAt(LifetimePosition position, Zone* zone);
 
-  InstructionOperand* current_hint_operand() const {
-    DCHECK(current_hint_operand_ == FirstHint());
-    return current_hint_operand_;
+  // Returns nullptr when no register is hinted, otherwise sets register_index.
+  UsePosition* FirstHintPosition(int* register_index) const;
+  UsePosition* FirstHintPosition() const {
+    int register_index;
+    return FirstHintPosition(&register_index);
   }
-  InstructionOperand* FirstHint() const {
-    UsePosition* pos = first_pos_;
-    while (pos != nullptr && !pos->HasHint()) pos = pos->next();
-    if (pos != nullptr) return pos->hint();
-    return nullptr;
+
+  UsePosition* current_hint_position() const {
+    DCHECK(current_hint_position_ == FirstHintPosition());
+    return current_hint_position_;
   }
 
   LifetimePosition Start() const {
@@ -260,135 +395,464 @@
     return last_interval_->end();
   }
 
-  enum class SpillType { kNoSpillType, kSpillOperand, kSpillRange };
-  SpillType spill_type() const { return spill_type_; }
-  InstructionOperand* GetSpillOperand() const {
-    return spill_type_ == SpillType::kSpillOperand ? spill_operand_ : nullptr;
-  }
-  SpillRange* GetSpillRange() const {
-    return spill_type_ == SpillType::kSpillRange ? spill_range_ : nullptr;
-  }
-  bool HasNoSpillType() const { return spill_type_ == SpillType::kNoSpillType; }
-  bool HasSpillOperand() const {
-    return spill_type_ == SpillType::kSpillOperand;
-  }
-  bool HasSpillRange() const { return spill_type_ == SpillType::kSpillRange; }
-
-  void SpillAtDefinition(Zone* zone, int gap_index,
-                         InstructionOperand* operand);
-  void SetSpillOperand(InstructionOperand* operand);
-  void SetSpillRange(SpillRange* spill_range);
-  void CommitSpillOperand(InstructionOperand* operand);
-  void CommitSpillsAtDefinition(InstructionSequence* sequence,
-                                InstructionOperand* operand);
-
-  void SetSpillStartIndex(int start) {
-    spill_start_index_ = Min(start, spill_start_index_);
-  }
-
   bool ShouldBeAllocatedBefore(const LiveRange* other) const;
   bool CanCover(LifetimePosition position) const;
-  bool Covers(LifetimePosition position);
-  LifetimePosition FirstIntersection(LiveRange* other);
+  bool Covers(LifetimePosition position) const;
+  LifetimePosition FirstIntersection(LiveRange* other) const;
 
-  // Add a new interval or a new use position to this live range.
-  void EnsureInterval(LifetimePosition start, LifetimePosition end, Zone* zone);
-  void AddUseInterval(LifetimePosition start, LifetimePosition end, Zone* zone);
-  void AddUsePosition(LifetimePosition pos, InstructionOperand* operand,
-                      InstructionOperand* hint, Zone* zone);
+  void VerifyChildStructure() const {
+    VerifyIntervals();
+    VerifyPositions();
+  }
 
-  // Shorten the most recently added interval by setting a new start.
-  void ShortenTo(LifetimePosition start);
+  void ConvertUsesToOperand(const InstructionOperand& op,
+                            const InstructionOperand& spill_op);
+  void SetUseHints(int register_index);
+  void UnsetUseHints() { SetUseHints(kUnassignedRegister); }
 
-#ifdef DEBUG
-  // True if target overlaps an existing interval.
-  bool HasOverlap(UseInterval* target) const;
-  void Verify() const;
-#endif
+  // Used solely by the Greedy Allocator:
+  unsigned GetSize();
+  float weight() const { return weight_; }
+  void set_weight(float weight) { weight_ = weight; }
+  LiveRangeGroup* group() const { return group_; }
+  void set_group(LiveRangeGroup* group) { group_ = group; }
+  void Print(const RegisterConfiguration* config, bool with_children) const;
+  void Print(bool with_children) const;
+
+  static const int kInvalidSize = -1;
+  static const float kInvalidWeight;
+  static const float kMaxWeight;
 
  private:
-  struct SpillAtDefinitionList;
+  friend class TopLevelLiveRange;
+  explicit LiveRange(int relative_id, MachineRepresentation rep,
+                     TopLevelLiveRange* top_level);
 
-  void ConvertUsesToOperand(InstructionOperand* op);
+  void UpdateParentForAllChildren(TopLevelLiveRange* new_top_level);
+
+  void set_spilled(bool value) { bits_ = SpilledField::update(bits_, value); }
+
   UseInterval* FirstSearchIntervalForPosition(LifetimePosition position) const;
   void AdvanceLastProcessedMarker(UseInterval* to_start_of,
                                   LifetimePosition but_not_past) const;
 
-  // TODO(dcarney): pack this structure better.
-  int id_;
-  bool spilled_;
-  bool is_phi_;
-  bool is_non_loop_phi_;
-  RegisterKind kind_;
-  int assigned_register_;
+  void VerifyPositions() const;
+  void VerifyIntervals() const;
+
+  typedef BitField<bool, 0, 1> SpilledField;
+  typedef BitField<int32_t, 6, 6> AssignedRegisterField;
+  typedef BitField<MachineRepresentation, 12, 8> RepresentationField;
+
+  // Unique among children and splinters of the same virtual register.
+  int relative_id_;
+  uint32_t bits_;
   UseInterval* last_interval_;
   UseInterval* first_interval_;
   UsePosition* first_pos_;
-  LiveRange* parent_;
+  TopLevelLiveRange* top_level_;
   LiveRange* next_;
   // This is used as a cache, it doesn't affect correctness.
   mutable UseInterval* current_interval_;
-  UsePosition* last_processed_use_;
+  // This is used as a cache, it doesn't affect correctness.
+  mutable UsePosition* last_processed_use_;
   // This is used as a cache, it's invalid outside of BuildLiveRanges.
-  InstructionOperand* current_hint_operand_;
-  int spill_start_index_;
-  SpillType spill_type_;
-  union {
-    InstructionOperand* spill_operand_;
-    SpillRange* spill_range_;
-  };
-  SpillAtDefinitionList* spills_at_definition_;
+  mutable UsePosition* current_hint_position_;
+  // Cache the last position splintering stopped at.
+  mutable UsePosition* splitting_pointer_;
+  // greedy: the number of LifetimePositions covered by this range. Used to
+  // prioritize selecting live ranges for register assignment, as well as
+  // in weight calculations.
+  int size_;
 
-  friend class RegisterAllocator;  // Assigns to kind_.
+  // greedy: a metric for resolving conflicts between ranges with an assigned
+  // register and ranges that intersect them and need a register.
+  float weight_;
+
+  // greedy: groupping
+  LiveRangeGroup* group_;
 
   DISALLOW_COPY_AND_ASSIGN(LiveRange);
 };
 
 
-class SpillRange FINAL : public ZoneObject {
+class LiveRangeGroup final : public ZoneObject {
  public:
-  SpillRange(LiveRange* range, Zone* zone);
+  explicit LiveRangeGroup(Zone* zone) : ranges_(zone) {}
+  ZoneVector<LiveRange*>& ranges() { return ranges_; }
+  const ZoneVector<LiveRange*>& ranges() const { return ranges_; }
+
+  // TODO(mtrofin): populate assigned register and use in weight calculation.
+  int assigned_register() const { return assigned_register_; }
+  void set_assigned_register(int reg) { assigned_register_ = reg; }
+
+ private:
+  ZoneVector<LiveRange*> ranges_;
+  int assigned_register_;
+  DISALLOW_COPY_AND_ASSIGN(LiveRangeGroup);
+};
+
+
+class TopLevelLiveRange final : public LiveRange {
+ public:
+  explicit TopLevelLiveRange(int vreg, MachineRepresentation rep);
+  int spill_start_index() const { return spill_start_index_; }
+
+  bool IsFixed() const { return vreg_ < 0; }
+
+  bool is_phi() const { return IsPhiField::decode(bits_); }
+  void set_is_phi(bool value) { bits_ = IsPhiField::update(bits_, value); }
+
+  bool is_non_loop_phi() const { return IsNonLoopPhiField::decode(bits_); }
+  void set_is_non_loop_phi(bool value) {
+    bits_ = IsNonLoopPhiField::update(bits_, value);
+  }
+
+  bool has_slot_use() const { return HasSlotUseField::decode(bits_); }
+  void set_has_slot_use(bool value) {
+    bits_ = HasSlotUseField::update(bits_, value);
+  }
+
+  // Add a new interval or a new use position to this live range.
+  void EnsureInterval(LifetimePosition start, LifetimePosition end, Zone* zone);
+  void AddUseInterval(LifetimePosition start, LifetimePosition end, Zone* zone);
+  void AddUsePosition(UsePosition* pos);
+
+  // Shorten the most recently added interval by setting a new start.
+  void ShortenTo(LifetimePosition start);
+
+  // Detaches between start and end, and attributes the resulting range to
+  // result.
+  // The current range is pointed to as "splintered_from". No parent/child
+  // relationship is established between this and result.
+  void Splinter(LifetimePosition start, LifetimePosition end, Zone* zone);
+
+  // Assuming other was splintered from this range, embeds other and its
+  // children as part of the children sequence of this range.
+  void Merge(TopLevelLiveRange* other, Zone* zone);
+
+  // Spill range management.
+  void SetSpillRange(SpillRange* spill_range);
+  enum class SpillType { kNoSpillType, kSpillOperand, kSpillRange };
+  void set_spill_type(SpillType value) {
+    bits_ = SpillTypeField::update(bits_, value);
+  }
+  SpillType spill_type() const { return SpillTypeField::decode(bits_); }
+  InstructionOperand* GetSpillOperand() const {
+    DCHECK(spill_type() == SpillType::kSpillOperand);
+    return spill_operand_;
+  }
+
+  SpillRange* GetAllocatedSpillRange() const {
+    DCHECK(spill_type() != SpillType::kSpillOperand);
+    return spill_range_;
+  }
+
+  SpillRange* GetSpillRange() const {
+    DCHECK(spill_type() == SpillType::kSpillRange);
+    return spill_range_;
+  }
+  bool HasNoSpillType() const {
+    return spill_type() == SpillType::kNoSpillType;
+  }
+  bool HasSpillOperand() const {
+    return spill_type() == SpillType::kSpillOperand;
+  }
+  bool HasSpillRange() const { return spill_type() == SpillType::kSpillRange; }
+
+  AllocatedOperand GetSpillRangeOperand() const;
+
+  void RecordSpillLocation(Zone* zone, int gap_index,
+                           InstructionOperand* operand);
+  void SetSpillOperand(InstructionOperand* operand);
+  void SetSpillStartIndex(int start) {
+    spill_start_index_ = Min(start, spill_start_index_);
+  }
+
+  void CommitSpillMoves(InstructionSequence* sequence,
+                        const InstructionOperand& operand,
+                        bool might_be_duplicated);
+
+  // If all the children of this range are spilled in deferred blocks, and if
+  // for any non-spilled child with a use position requiring a slot, that range
+  // is contained in a deferred block, mark the range as
+  // IsSpilledOnlyInDeferredBlocks, so that we avoid spilling at definition,
+  // and instead let the LiveRangeConnector perform the spills within the
+  // deferred blocks. If so, we insert here spills for non-spilled ranges
+  // with slot use positions.
+  void MarkSpilledInDeferredBlock() {
+    spill_start_index_ = -1;
+    spilled_in_deferred_blocks_ = true;
+    spill_move_insertion_locations_ = nullptr;
+  }
+
+  bool TryCommitSpillInDeferredBlock(InstructionSequence* code,
+                                     const InstructionOperand& spill_operand);
+
+  TopLevelLiveRange* splintered_from() const { return splintered_from_; }
+  bool IsSplinter() const { return splintered_from_ != nullptr; }
+  bool MayRequireSpillRange() const {
+    DCHECK(!IsSplinter());
+    return !HasSpillOperand() && spill_range_ == nullptr;
+  }
+  void UpdateSpillRangePostMerge(TopLevelLiveRange* merged);
+  int vreg() const { return vreg_; }
+
+#if DEBUG
+  int debug_virt_reg() const;
+#endif
+
+  void Verify() const;
+  void VerifyChildrenInOrder() const;
+
+  int GetNextChildId() {
+    return IsSplinter() ? splintered_from()->GetNextChildId()
+                        : ++last_child_id_;
+  }
+
+  int GetChildCount() const { return last_child_id_ + 1; }
+
+  bool IsSpilledOnlyInDeferredBlocks() const {
+    return spilled_in_deferred_blocks_;
+  }
+
+  struct SpillMoveInsertionList;
+
+  SpillMoveInsertionList* spill_move_insertion_locations() const {
+    return spill_move_insertion_locations_;
+  }
+  TopLevelLiveRange* splinter() const { return splinter_; }
+  void SetSplinter(TopLevelLiveRange* splinter) {
+    DCHECK_NULL(splinter_);
+    DCHECK_NOT_NULL(splinter);
+
+    splinter_ = splinter;
+    splinter->relative_id_ = GetNextChildId();
+    splinter->set_spill_type(spill_type());
+    splinter->SetSplinteredFrom(this);
+  }
+
+  void MarkHasPreassignedSlot() { has_preassigned_slot_ = true; }
+  bool has_preassigned_slot() const { return has_preassigned_slot_; }
+
+ private:
+  void SetSplinteredFrom(TopLevelLiveRange* splinter_parent);
+
+  typedef BitField<bool, 1, 1> HasSlotUseField;
+  typedef BitField<bool, 2, 1> IsPhiField;
+  typedef BitField<bool, 3, 1> IsNonLoopPhiField;
+  typedef BitField<SpillType, 4, 2> SpillTypeField;
+
+  int vreg_;
+  int last_child_id_;
+  TopLevelLiveRange* splintered_from_;
+  union {
+    // Correct value determined by spill_type()
+    InstructionOperand* spill_operand_;
+    SpillRange* spill_range_;
+  };
+  SpillMoveInsertionList* spill_move_insertion_locations_;
+  // TODO(mtrofin): generalize spilling after definition, currently specialized
+  // just for spill in a single deferred block.
+  bool spilled_in_deferred_blocks_;
+  int spill_start_index_;
+  UsePosition* last_pos_;
+  TopLevelLiveRange* splinter_;
+  bool has_preassigned_slot_;
+
+  DISALLOW_COPY_AND_ASSIGN(TopLevelLiveRange);
+};
+
+
+struct PrintableLiveRange {
+  const RegisterConfiguration* register_configuration_;
+  const LiveRange* range_;
+};
+
+
+std::ostream& operator<<(std::ostream& os,
+                         const PrintableLiveRange& printable_range);
+
+
+class SpillRange final : public ZoneObject {
+ public:
+  static const int kUnassignedSlot = -1;
+  SpillRange(TopLevelLiveRange* range, Zone* zone);
 
   UseInterval* interval() const { return use_interval_; }
-  RegisterKind Kind() const { return live_ranges_[0]->Kind(); }
+  // Currently, only 4 or 8 byte slots are supported.
+  int ByteWidth() const;
   bool IsEmpty() const { return live_ranges_.empty(); }
   bool TryMerge(SpillRange* other);
-  void SetOperand(InstructionOperand* op);
+  bool HasSlot() const { return assigned_slot_ != kUnassignedSlot; }
+
+  void set_assigned_slot(int index) {
+    DCHECK_EQ(kUnassignedSlot, assigned_slot_);
+    assigned_slot_ = index;
+  }
+  int assigned_slot() {
+    DCHECK_NE(kUnassignedSlot, assigned_slot_);
+    return assigned_slot_;
+  }
+  const ZoneVector<TopLevelLiveRange*>& live_ranges() const {
+    return live_ranges_;
+  }
+  ZoneVector<TopLevelLiveRange*>& live_ranges() { return live_ranges_; }
+  int byte_width() const { return byte_width_; }
+  RegisterKind kind() const { return kind_; }
+  void Print() const;
 
  private:
   LifetimePosition End() const { return end_position_; }
-  ZoneVector<LiveRange*>& live_ranges() { return live_ranges_; }
   bool IsIntersectingWith(SpillRange* other) const;
   // Merge intervals, making sure the use intervals are sorted
   void MergeDisjointIntervals(UseInterval* other);
 
-  ZoneVector<LiveRange*> live_ranges_;
+  ZoneVector<TopLevelLiveRange*> live_ranges_;
   UseInterval* use_interval_;
   LifetimePosition end_position_;
+  int assigned_slot_;
+  int byte_width_;
+  RegisterKind kind_;
 
   DISALLOW_COPY_AND_ASSIGN(SpillRange);
 };
 
 
-class RegisterAllocator FINAL : public ZoneObject {
+class RegisterAllocationData final : public ZoneObject {
  public:
-  explicit RegisterAllocator(const RegisterConfiguration* config,
-                             Zone* local_zone, Frame* frame,
-                             InstructionSequence* code,
-                             const char* debug_name = nullptr);
+  class PhiMapValue : public ZoneObject {
+   public:
+    PhiMapValue(PhiInstruction* phi, const InstructionBlock* block, Zone* zone);
 
-  bool AllocationOk() { return allocation_ok_; }
+    const PhiInstruction* phi() const { return phi_; }
+    const InstructionBlock* block() const { return block_; }
 
-  const ZoneVector<LiveRange*>& live_ranges() const { return live_ranges_; }
-  const ZoneVector<LiveRange*>& fixed_live_ranges() const {
+    // For hinting.
+    int assigned_register() const { return assigned_register_; }
+    void set_assigned_register(int register_code) {
+      DCHECK_EQ(assigned_register_, kUnassignedRegister);
+      assigned_register_ = register_code;
+    }
+    void UnsetAssignedRegister() { assigned_register_ = kUnassignedRegister; }
+
+    void AddOperand(InstructionOperand* operand);
+    void CommitAssignment(const InstructionOperand& operand);
+
+   private:
+    PhiInstruction* const phi_;
+    const InstructionBlock* const block_;
+    ZoneVector<InstructionOperand*> incoming_operands_;
+    int assigned_register_;
+  };
+  typedef ZoneMap<int, PhiMapValue*> PhiMap;
+
+  struct DelayedReference {
+    ReferenceMap* map;
+    InstructionOperand* operand;
+  };
+  typedef ZoneVector<DelayedReference> DelayedReferences;
+  typedef ZoneVector<std::pair<TopLevelLiveRange*, int>>
+      RangesWithPreassignedSlots;
+
+  RegisterAllocationData(const RegisterConfiguration* config,
+                         Zone* allocation_zone, Frame* frame,
+                         InstructionSequence* code,
+                         const char* debug_name = nullptr);
+
+  const ZoneVector<TopLevelLiveRange*>& live_ranges() const {
+    return live_ranges_;
+  }
+  ZoneVector<TopLevelLiveRange*>& live_ranges() { return live_ranges_; }
+  const ZoneVector<TopLevelLiveRange*>& fixed_live_ranges() const {
     return fixed_live_ranges_;
   }
-  const ZoneVector<LiveRange*>& fixed_double_live_ranges() const {
+  ZoneVector<TopLevelLiveRange*>& fixed_live_ranges() {
+    return fixed_live_ranges_;
+  }
+  ZoneVector<TopLevelLiveRange*>& fixed_double_live_ranges() {
     return fixed_double_live_ranges_;
   }
+  const ZoneVector<TopLevelLiveRange*>& fixed_double_live_ranges() const {
+    return fixed_double_live_ranges_;
+  }
+  ZoneVector<BitVector*>& live_in_sets() { return live_in_sets_; }
+  ZoneVector<BitVector*>& live_out_sets() { return live_out_sets_; }
+  ZoneVector<SpillRange*>& spill_ranges() { return spill_ranges_; }
+  DelayedReferences& delayed_references() { return delayed_references_; }
   InstructionSequence* code() const { return code_; }
-  // This zone is for datastructures only needed during register allocation.
-  Zone* local_zone() const { return local_zone_; }
+  // This zone is for datastructures only needed during register allocation
+  // phases.
+  Zone* allocation_zone() const { return allocation_zone_; }
+  // This zone is for InstructionOperands and moves that live beyond register
+  // allocation.
+  Zone* code_zone() const { return code()->zone(); }
+  Frame* frame() const { return frame_; }
+  const char* debug_name() const { return debug_name_; }
+  const RegisterConfiguration* config() const { return config_; }
+
+  MachineRepresentation RepresentationFor(int virtual_register);
+
+  TopLevelLiveRange* GetOrCreateLiveRangeFor(int index);
+  // Creates a new live range.
+  TopLevelLiveRange* NewLiveRange(int index, MachineRepresentation rep);
+  TopLevelLiveRange* NextLiveRange(MachineRepresentation rep);
+
+  SpillRange* AssignSpillRangeToLiveRange(TopLevelLiveRange* range);
+  SpillRange* CreateSpillRangeForLiveRange(TopLevelLiveRange* range);
+
+  MoveOperands* AddGapMove(int index, Instruction::GapPosition position,
+                           const InstructionOperand& from,
+                           const InstructionOperand& to);
+
+  bool IsReference(TopLevelLiveRange* top_range) const {
+    return code()->IsReference(top_range->vreg());
+  }
+
+  bool ExistsUseWithoutDefinition();
+  bool RangesDefinedInDeferredStayInDeferred();
+
+  void MarkAllocated(RegisterKind kind, int index);
+
+  PhiMapValue* InitializePhiMap(const InstructionBlock* block,
+                                PhiInstruction* phi);
+  PhiMapValue* GetPhiMapValueFor(TopLevelLiveRange* top_range);
+  PhiMapValue* GetPhiMapValueFor(int virtual_register);
+  bool IsBlockBoundary(LifetimePosition pos) const;
+
+  RangesWithPreassignedSlots& preassigned_slot_ranges() {
+    return preassigned_slot_ranges_;
+  }
+
+ private:
+  int GetNextLiveRangeId();
+
+  Zone* const allocation_zone_;
+  Frame* const frame_;
+  InstructionSequence* const code_;
+  const char* const debug_name_;
+  const RegisterConfiguration* const config_;
+  PhiMap phi_map_;
+  ZoneVector<int> allocatable_codes_;
+  ZoneVector<int> allocatable_double_codes_;
+  ZoneVector<BitVector*> live_in_sets_;
+  ZoneVector<BitVector*> live_out_sets_;
+  ZoneVector<TopLevelLiveRange*> live_ranges_;
+  ZoneVector<TopLevelLiveRange*> fixed_live_ranges_;
+  ZoneVector<TopLevelLiveRange*> fixed_double_live_ranges_;
+  ZoneVector<SpillRange*> spill_ranges_;
+  DelayedReferences delayed_references_;
+  BitVector* assigned_registers_;
+  BitVector* assigned_double_registers_;
+  int virtual_register_count_;
+  RangesWithPreassignedSlots preassigned_slot_ranges_;
+
+  DISALLOW_COPY_AND_ASSIGN(RegisterAllocationData);
+};
+
+
+class ConstraintBuilder final : public ZoneObject {
+ public:
+  explicit ConstraintBuilder(RegisterAllocationData* data);
 
   // Phase 1 : insert moves to account for fixed register operands.
   void MeetRegisterConstraints();
@@ -397,85 +861,174 @@
   // of blocks containing phis.
   void ResolvePhis();
 
-  // Phase 3: compute liveness of all virtual register.
-  void BuildLiveRanges();
-  bool ExistsUseWithoutDefinition();
-
-  // Phase 4: compute register assignments.
-  void AllocateGeneralRegisters();
-  void AllocateDoubleRegisters();
-
-  // Phase 5: reassign spill splots for maximal reuse.
-  void ReuseSpillSlots();
-
-  // Phase 6: commit assignment.
-  void CommitAssignment();
-
-  // Phase 7: compute values for pointer maps.
-  void PopulatePointerMaps();  // TODO(titzer): rename to PopulateReferenceMaps.
-
-  // Phase 8: reconnect split ranges with moves.
-  void ConnectRanges();
-
-  // Phase 9: insert moves to connect ranges across basic blocks.
-  void ResolveControlFlow();
-
  private:
-  int GetVirtualRegister() {
-    int vreg = code()->NextVirtualRegister();
-    if (vreg >= UnallocatedOperand::kMaxVirtualRegisters) {
-      allocation_ok_ = false;
-      // Maintain the invariant that we return something below the maximum.
-      return 0;
-    }
-    return vreg;
-  }
+  RegisterAllocationData* data() const { return data_; }
+  InstructionSequence* code() const { return data()->code(); }
+  Zone* allocation_zone() const { return data()->allocation_zone(); }
 
-  // Checks whether the value of a given virtual register is a reference.
-  // TODO(titzer): rename this to IsReference.
-  bool HasTaggedValue(int virtual_register) const;
-
-  // Returns the register kind required by the given virtual register.
-  RegisterKind RequiredRegisterKind(int virtual_register) const;
-
-  // This zone is for InstructionOperands and moves that live beyond register
-  // allocation.
-  Zone* code_zone() const { return code()->zone(); }
-
-  BitVector* assigned_registers() { return assigned_registers_; }
-  BitVector* assigned_double_registers() { return assigned_double_registers_; }
-
-#ifdef DEBUG
-  void Verify() const;
-#endif
-
-  void AllocateRegisters();
-  bool CanEagerlyResolveControlFlow(const InstructionBlock* block) const;
-  bool SafePointsAreInOrder() const;
-
-  // Liveness analysis support.
-  BitVector* ComputeLiveOut(const InstructionBlock* block);
-  void AddInitialIntervals(const InstructionBlock* block, BitVector* live_out);
-  bool IsOutputRegisterOf(Instruction* instr, int index);
-  bool IsOutputDoubleRegisterOf(Instruction* instr, int index);
-  void ProcessInstructions(const InstructionBlock* block, BitVector* live);
+  InstructionOperand* AllocateFixed(UnallocatedOperand* operand, int pos,
+                                    bool is_tagged);
   void MeetRegisterConstraints(const InstructionBlock* block);
-  void MeetConstraintsBetween(Instruction* first, Instruction* second,
-                              int gap_index);
+  void MeetConstraintsBefore(int index);
+  void MeetConstraintsAfter(int index);
   void MeetRegisterConstraintsForLastInstructionInBlock(
       const InstructionBlock* block);
   void ResolvePhis(const InstructionBlock* block);
 
+  RegisterAllocationData* const data_;
+
+  DISALLOW_COPY_AND_ASSIGN(ConstraintBuilder);
+};
+
+
+class LiveRangeBuilder final : public ZoneObject {
+ public:
+  explicit LiveRangeBuilder(RegisterAllocationData* data, Zone* local_zone);
+
+  // Phase 3: compute liveness of all virtual register.
+  void BuildLiveRanges();
+  static BitVector* ComputeLiveOut(const InstructionBlock* block,
+                                   RegisterAllocationData* data);
+
+ private:
+  RegisterAllocationData* data() const { return data_; }
+  InstructionSequence* code() const { return data()->code(); }
+  Zone* allocation_zone() const { return data()->allocation_zone(); }
+  Zone* code_zone() const { return code()->zone(); }
+  const RegisterConfiguration* config() const { return data()->config(); }
+  ZoneVector<BitVector*>& live_in_sets() const {
+    return data()->live_in_sets();
+  }
+
+  void Verify() const;
+
+  // Liveness analysis support.
+  void AddInitialIntervals(const InstructionBlock* block, BitVector* live_out);
+  void ProcessInstructions(const InstructionBlock* block, BitVector* live);
+  void ProcessPhis(const InstructionBlock* block, BitVector* live);
+  void ProcessLoopHeader(const InstructionBlock* block, BitVector* live);
+
+  static int FixedLiveRangeID(int index) { return -index - 1; }
+  int FixedDoubleLiveRangeID(int index);
+  TopLevelLiveRange* FixedLiveRangeFor(int index);
+  TopLevelLiveRange* FixedDoubleLiveRangeFor(int index);
+
+  void MapPhiHint(InstructionOperand* operand, UsePosition* use_pos);
+  void ResolvePhiHint(InstructionOperand* operand, UsePosition* use_pos);
+
+  UsePosition* NewUsePosition(LifetimePosition pos, InstructionOperand* operand,
+                              void* hint, UsePositionHintType hint_type);
+  UsePosition* NewUsePosition(LifetimePosition pos) {
+    return NewUsePosition(pos, nullptr, nullptr, UsePositionHintType::kNone);
+  }
+  TopLevelLiveRange* LiveRangeFor(InstructionOperand* operand);
   // Helper methods for building intervals.
-  InstructionOperand* AllocateFixed(UnallocatedOperand* operand, int pos,
-                                    bool is_tagged);
-  LiveRange* LiveRangeFor(InstructionOperand* operand);
-  void Define(LifetimePosition position, InstructionOperand* operand,
-              InstructionOperand* hint);
+  UsePosition* Define(LifetimePosition position, InstructionOperand* operand,
+                      void* hint, UsePositionHintType hint_type);
+  void Define(LifetimePosition position, InstructionOperand* operand) {
+    Define(position, operand, nullptr, UsePositionHintType::kNone);
+  }
+  UsePosition* Use(LifetimePosition block_start, LifetimePosition position,
+                   InstructionOperand* operand, void* hint,
+                   UsePositionHintType hint_type);
   void Use(LifetimePosition block_start, LifetimePosition position,
-           InstructionOperand* operand, InstructionOperand* hint);
-  void AddGapMove(int index, GapInstruction::InnerPosition position,
-                  InstructionOperand* from, InstructionOperand* to);
+           InstructionOperand* operand) {
+    Use(block_start, position, operand, nullptr, UsePositionHintType::kNone);
+  }
+
+  RegisterAllocationData* const data_;
+  ZoneMap<InstructionOperand*, UsePosition*> phi_hints_;
+
+  DISALLOW_COPY_AND_ASSIGN(LiveRangeBuilder);
+};
+
+
+class RegisterAllocator : public ZoneObject {
+ public:
+  explicit RegisterAllocator(RegisterAllocationData* data, RegisterKind kind);
+
+ protected:
+  RegisterAllocationData* data() const { return data_; }
+  InstructionSequence* code() const { return data()->code(); }
+  RegisterKind mode() const { return mode_; }
+  int num_registers() const { return num_registers_; }
+  int num_allocatable_registers() const { return num_allocatable_registers_; }
+  int allocatable_register_code(int allocatable_index) const {
+    return allocatable_register_codes_[allocatable_index];
+  }
+
+  // TODO(mtrofin): explain why splitting in gap START is always OK.
+  LifetimePosition GetSplitPositionForInstruction(const LiveRange* range,
+                                                  int instruction_index);
+
+  Zone* allocation_zone() const { return data()->allocation_zone(); }
+
+  // Find the optimal split for ranges defined by a memory operand, e.g.
+  // constants or function parameters passed on the stack.
+  void SplitAndSpillRangesDefinedByMemoryOperand(bool operands_only);
+
+  // Split the given range at the given position.
+  // If range starts at or after the given position then the
+  // original range is returned.
+  // Otherwise returns the live range that starts at pos and contains
+  // all uses from the original range that follow pos. Uses at pos will
+  // still be owned by the original range after splitting.
+  LiveRange* SplitRangeAt(LiveRange* range, LifetimePosition pos);
+
+  bool CanProcessRange(LiveRange* range) const {
+    return range != nullptr && !range->IsEmpty() && range->kind() == mode();
+  }
+
+
+  // Split the given range in a position from the interval [start, end].
+  LiveRange* SplitBetween(LiveRange* range, LifetimePosition start,
+                          LifetimePosition end);
+
+  // Find a lifetime position in the interval [start, end] which
+  // is optimal for splitting: it is either header of the outermost
+  // loop covered by this interval or the latest possible position.
+  LifetimePosition FindOptimalSplitPos(LifetimePosition start,
+                                       LifetimePosition end);
+
+  void Spill(LiveRange* range);
+
+  // If we are trying to spill a range inside the loop try to
+  // hoist spill position out to the point just before the loop.
+  LifetimePosition FindOptimalSpillingPos(LiveRange* range,
+                                          LifetimePosition pos);
+
+  const ZoneVector<TopLevelLiveRange*>& GetFixedRegisters() const;
+  const char* RegisterName(int allocation_index) const;
+
+ private:
+  RegisterAllocationData* const data_;
+  const RegisterKind mode_;
+  const int num_registers_;
+  int num_allocatable_registers_;
+  const int* allocatable_register_codes_;
+
+  DISALLOW_COPY_AND_ASSIGN(RegisterAllocator);
+};
+
+
+class LinearScanAllocator final : public RegisterAllocator {
+ public:
+  LinearScanAllocator(RegisterAllocationData* data, RegisterKind kind,
+                      Zone* local_zone);
+
+  // Phase 4: compute register assignments.
+  void AllocateRegisters();
+
+ private:
+  ZoneVector<LiveRange*>& unhandled_live_ranges() {
+    return unhandled_live_ranges_;
+  }
+  ZoneVector<LiveRange*>& active_live_ranges() { return active_live_ranges_; }
+  ZoneVector<LiveRange*>& inactive_live_ranges() {
+    return inactive_live_ranges_;
+  }
+
+  void SetLiveRangeAssignedRegister(LiveRange* range, int reg);
 
   // Helper methods for updating the life range lists.
   void AddToActive(LiveRange* range);
@@ -490,32 +1043,9 @@
   void InactiveToActive(LiveRange* range);
 
   // Helper methods for allocating registers.
-  bool TryReuseSpillForPhi(LiveRange* range);
+  bool TryReuseSpillForPhi(TopLevelLiveRange* range);
   bool TryAllocateFreeReg(LiveRange* range);
   void AllocateBlockedReg(LiveRange* range);
-  SpillRange* AssignSpillRangeToLiveRange(LiveRange* range);
-  void FreeSpillSlot(LiveRange* range);
-  InstructionOperand* TryReuseSpillSlot(LiveRange* range);
-
-  // Live range splitting helpers.
-
-  // Split the given range at the given position.
-  // If range starts at or after the given position then the
-  // original range is returned.
-  // Otherwise returns the live range that starts at pos and contains
-  // all uses from the original range that follow pos. Uses at pos will
-  // still be owned by the original range after splitting.
-  LiveRange* SplitRangeAt(LiveRange* range, LifetimePosition pos);
-
-  // Split the given range in a position from the interval [start, end].
-  LiveRange* SplitBetween(LiveRange* range, LifetimePosition start,
-                          LifetimePosition end);
-
-  // Find a lifetime position in the interval [start, end] which
-  // is optimal for splitting: it is either header of the outermost
-  // loop covered by this interval or the latest possible position.
-  LifetimePosition FindOptimalSplitPos(LifetimePosition start,
-                                       LifetimePosition end);
 
   // Spill the given life range after position pos.
   void SpillAfter(LiveRange* range, LifetimePosition pos);
@@ -531,108 +1061,105 @@
 
   void SplitAndSpillIntersecting(LiveRange* range);
 
-  // If we are trying to spill a range inside the loop try to
-  // hoist spill position out to the point just before the loop.
-  LifetimePosition FindOptimalSpillingPos(LiveRange* range,
-                                          LifetimePosition pos);
-
-  void Spill(LiveRange* range);
-  bool IsBlockBoundary(LifetimePosition pos);
-
-  // Helper methods for resolving control flow.
-  void ResolveControlFlow(const InstructionBlock* block,
-                          InstructionOperand* cur_op,
-                          const InstructionBlock* pred,
-                          InstructionOperand* pred_op);
-
-  void SetLiveRangeAssignedRegister(LiveRange* range, int reg);
-
-  // Return parallel move that should be used to connect ranges split at the
-  // given position.
-  ParallelMove* GetConnectingParallelMove(LifetimePosition pos);
-
-  // Return the block which contains give lifetime position.
-  const InstructionBlock* GetInstructionBlock(LifetimePosition pos);
-
-  // Helper methods for the fixed registers.
-  int RegisterCount() const;
-  static int FixedLiveRangeID(int index) { return -index - 1; }
-  int FixedDoubleLiveRangeID(int index);
-  LiveRange* FixedLiveRangeFor(int index);
-  LiveRange* FixedDoubleLiveRangeFor(int index);
-  LiveRange* LiveRangeFor(int index);
-  GapInstruction* GetLastGap(const InstructionBlock* block);
-
-  const char* RegisterName(int allocation_index);
-
-  Instruction* InstructionAt(int index) { return code()->InstructionAt(index); }
-
-  Frame* frame() const { return frame_; }
-  const char* debug_name() const { return debug_name_; }
-  const RegisterConfiguration* config() const { return config_; }
-  ZoneVector<LiveRange*>& live_ranges() { return live_ranges_; }
-  ZoneVector<LiveRange*>& fixed_live_ranges() { return fixed_live_ranges_; }
-  ZoneVector<LiveRange*>& fixed_double_live_ranges() {
-    return fixed_double_live_ranges_;
-  }
-  ZoneVector<LiveRange*>& unhandled_live_ranges() {
-    return unhandled_live_ranges_;
-  }
-  ZoneVector<LiveRange*>& active_live_ranges() { return active_live_ranges_; }
-  ZoneVector<LiveRange*>& inactive_live_ranges() {
-    return inactive_live_ranges_;
-  }
-  ZoneVector<LiveRange*>& reusable_slots() { return reusable_slots_; }
-  ZoneVector<SpillRange*>& spill_ranges() { return spill_ranges_; }
-
-  struct PhiMapValue {
-    PhiMapValue(PhiInstruction* phi, const InstructionBlock* block)
-        : phi(phi), block(block) {}
-    PhiInstruction* const phi;
-    const InstructionBlock* const block;
-  };
-  typedef std::map<int, PhiMapValue, std::less<int>,
-                   zone_allocator<std::pair<int, PhiMapValue>>> PhiMap;
-
-  Zone* const local_zone_;
-  Frame* const frame_;
-  InstructionSequence* const code_;
-  const char* const debug_name_;
-
-  const RegisterConfiguration* config_;
-
-  PhiMap phi_map_;
-
-  // During liveness analysis keep a mapping from block id to live_in sets
-  // for blocks already analyzed.
-  ZoneVector<BitVector*> live_in_sets_;
-
-  // Liveness analysis results.
-  ZoneVector<LiveRange*> live_ranges_;
-
-  // Lists of live ranges
-  ZoneVector<LiveRange*> fixed_live_ranges_;
-  ZoneVector<LiveRange*> fixed_double_live_ranges_;
   ZoneVector<LiveRange*> unhandled_live_ranges_;
   ZoneVector<LiveRange*> active_live_ranges_;
   ZoneVector<LiveRange*> inactive_live_ranges_;
-  ZoneVector<LiveRange*> reusable_slots_;
-  ZoneVector<SpillRange*> spill_ranges_;
-
-  RegisterKind mode_;
-  int num_registers_;
-
-  BitVector* assigned_registers_;
-  BitVector* assigned_double_registers_;
-
-  // Indicates success or failure during register allocation.
-  bool allocation_ok_;
 
 #ifdef DEBUG
   LifetimePosition allocation_finger_;
 #endif
 
-  DISALLOW_COPY_AND_ASSIGN(RegisterAllocator);
+  DISALLOW_COPY_AND_ASSIGN(LinearScanAllocator);
+};
+
+
+class SpillSlotLocator final : public ZoneObject {
+ public:
+  explicit SpillSlotLocator(RegisterAllocationData* data);
+
+  void LocateSpillSlots();
+
+ private:
+  RegisterAllocationData* data() const { return data_; }
+
+  RegisterAllocationData* const data_;
+
+  DISALLOW_COPY_AND_ASSIGN(SpillSlotLocator);
+};
+
+
+class OperandAssigner final : public ZoneObject {
+ public:
+  explicit OperandAssigner(RegisterAllocationData* data);
+
+  // Phase 5: assign spill splots.
+  void AssignSpillSlots();
+
+  // Phase 6: commit assignment.
+  void CommitAssignment();
+
+ private:
+  RegisterAllocationData* data() const { return data_; }
+
+  RegisterAllocationData* const data_;
+
+  DISALLOW_COPY_AND_ASSIGN(OperandAssigner);
+};
+
+
+class ReferenceMapPopulator final : public ZoneObject {
+ public:
+  explicit ReferenceMapPopulator(RegisterAllocationData* data);
+
+  // Phase 7: compute values for pointer maps.
+  void PopulateReferenceMaps();
+
+ private:
+  RegisterAllocationData* data() const { return data_; }
+
+  bool SafePointsAreInOrder() const;
+
+  RegisterAllocationData* const data_;
+
+  DISALLOW_COPY_AND_ASSIGN(ReferenceMapPopulator);
+};
+
+
+// Insert moves of the form
+//
+//          Operand(child_(k+1)) = Operand(child_k)
+//
+// where child_k and child_(k+1) are consecutive children of a range (so
+// child_k->next() == child_(k+1)), and Operand(...) refers to the
+// assigned operand, be it a register or a slot.
+class LiveRangeConnector final : public ZoneObject {
+ public:
+  explicit LiveRangeConnector(RegisterAllocationData* data);
+
+  // Phase 8: reconnect split ranges with moves, when the control flow
+  // between the ranges is trivial (no branches).
+  void ConnectRanges(Zone* local_zone);
+
+  // Phase 9: insert moves to connect ranges across basic blocks, when the
+  // control flow between them cannot be trivially resolved, such as joining
+  // branches.
+  void ResolveControlFlow(Zone* local_zone);
+
+ private:
+  RegisterAllocationData* data() const { return data_; }
+  InstructionSequence* code() const { return data()->code(); }
+  Zone* code_zone() const { return code()->zone(); }
+
+  bool CanEagerlyResolveControlFlow(const InstructionBlock* block) const;
+
+  int ResolveControlFlow(const InstructionBlock* block,
+                         const InstructionOperand& cur_op,
+                         const InstructionBlock* pred,
+                         const InstructionOperand& pred_op);
+
+  RegisterAllocationData* const data_;
+
+  DISALLOW_COPY_AND_ASSIGN(LiveRangeConnector);
 };
 
 }  // namespace compiler
diff --git a/src/compiler/register-configuration.cc b/src/compiler/register-configuration.cc
deleted file mode 100644
index e7d8bbd..0000000
--- a/src/compiler/register-configuration.cc
+++ /dev/null
@@ -1,68 +0,0 @@
-// 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/register-configuration.h"
-#include "src/macro-assembler.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-namespace {
-
-STATIC_ASSERT(RegisterConfiguration::kMaxGeneralRegisters >=
-              Register::kNumRegisters);
-STATIC_ASSERT(RegisterConfiguration::kMaxDoubleRegisters >=
-              DoubleRegister::kMaxNumRegisters);
-
-class ArchDefaultRegisterConfiguration : public RegisterConfiguration {
- public:
-  ArchDefaultRegisterConfiguration()
-      : RegisterConfiguration(Register::kMaxNumAllocatableRegisters,
-                              DoubleRegister::kMaxNumAllocatableRegisters,
-                              DoubleRegister::NumAllocatableAliasedRegisters(),
-                              general_register_name_table_,
-                              double_register_name_table_) {
-    DCHECK_EQ(Register::kMaxNumAllocatableRegisters,
-              Register::NumAllocatableRegisters());
-    for (int i = 0; i < Register::kMaxNumAllocatableRegisters; ++i) {
-      general_register_name_table_[i] = Register::AllocationIndexToString(i);
-    }
-    for (int i = 0; i < DoubleRegister::kMaxNumAllocatableRegisters; ++i) {
-      double_register_name_table_[i] =
-          DoubleRegister::AllocationIndexToString(i);
-    }
-  }
-
-  const char*
-      general_register_name_table_[Register::kMaxNumAllocatableRegisters];
-  const char*
-      double_register_name_table_[DoubleRegister::kMaxNumAllocatableRegisters];
-};
-
-
-static base::LazyInstance<ArchDefaultRegisterConfiguration>::type
-    kDefaultRegisterConfiguration = LAZY_INSTANCE_INITIALIZER;
-
-}  // namepace
-
-
-const RegisterConfiguration* RegisterConfiguration::ArchDefault() {
-  return &kDefaultRegisterConfiguration.Get();
-}
-
-RegisterConfiguration::RegisterConfiguration(
-    int num_general_registers, int num_double_registers,
-    int num_aliased_double_registers, const char* const* general_register_names,
-    const char* const* double_register_names)
-    : num_general_registers_(num_general_registers),
-      num_double_registers_(num_double_registers),
-      num_aliased_double_registers_(num_aliased_double_registers),
-      general_register_names_(general_register_names),
-      double_register_names_(double_register_names) {}
-
-
-}  // namespace compiler
-}  // namespace internal
-}  // namespace v8
diff --git a/src/compiler/register-configuration.h b/src/compiler/register-configuration.h
deleted file mode 100644
index 8178ba2..0000000
--- a/src/compiler/register-configuration.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// 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.
-
-#ifndef V8_COMPILER_REGISTER_CONFIGURATION_H_
-#define V8_COMPILER_REGISTER_CONFIGURATION_H_
-
-#include "src/v8.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-// An architecture independent representation of the sets of registers available
-// for instruction creation.
-class RegisterConfiguration {
- public:
-  // Architecture independent maxes.
-  static const int kMaxGeneralRegisters = 32;
-  static const int kMaxDoubleRegisters = 32;
-
-  static const RegisterConfiguration* ArchDefault();
-
-  RegisterConfiguration(int num_general_registers, int num_double_registers,
-                        int num_aliased_double_registers,
-                        const char* const* general_register_name,
-                        const char* const* double_register_name);
-
-  int num_general_registers() const { return num_general_registers_; }
-  int num_double_registers() const { return num_double_registers_; }
-  int num_aliased_double_registers() const {
-    return num_aliased_double_registers_;
-  }
-
-  const char* general_register_name(int offset) const {
-    DCHECK(offset >= 0 && offset < kMaxGeneralRegisters);
-    return general_register_names_[offset];
-  }
-  const char* double_register_name(int offset) const {
-    DCHECK(offset >= 0 && offset < kMaxDoubleRegisters);
-    return double_register_names_[offset];
-  }
-
- private:
-  const int num_general_registers_;
-  const int num_double_registers_;
-  const int num_aliased_double_registers_;
-  const char* const* general_register_names_;
-  const char* const* double_register_names_;
-};
-
-}  // namespace compiler
-}  // namespace internal
-}  // namespace v8
-
-#endif  // V8_COMPILER_REGISTER_CONFIGURATION_H_
diff --git a/src/compiler/representation-change.cc b/src/compiler/representation-change.cc
new file mode 100644
index 0000000..5dab60f
--- /dev/null
+++ b/src/compiler/representation-change.cc
@@ -0,0 +1,537 @@
+// Copyright 2015 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/representation-change.h"
+
+#include <sstream>
+
+#include "src/base/bits.h"
+#include "src/code-factory.h"
+#include "src/compiler/machine-operator.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+const char* Truncation::description() const {
+  switch (kind()) {
+    case TruncationKind::kNone:
+      return "no-value-use";
+    case TruncationKind::kBool:
+      return "truncate-to-bool";
+    case TruncationKind::kWord32:
+      return "truncate-to-word32";
+    case TruncationKind::kWord64:
+      return "truncate-to-word64";
+    case TruncationKind::kFloat32:
+      return "truncate-to-float32";
+    case TruncationKind::kFloat64:
+      return "truncate-to-float64";
+    case TruncationKind::kAny:
+      return "no-truncation";
+  }
+  UNREACHABLE();
+  return nullptr;
+}
+
+
+// Partial order for truncations:
+//
+//  kWord64       kAny
+//     ^            ^
+//     \            |
+//      \         kFloat64  <--+
+//       \        ^    ^       |
+//        \       /    |       |
+//         kWord32  kFloat32  kBool
+//               ^     ^      ^
+//               \     |      /
+//                \    |     /
+//                 \   |    /
+//                  \  |   /
+//                   \ |  /
+//                   kNone
+
+// static
+Truncation::TruncationKind Truncation::Generalize(TruncationKind rep1,
+                                                  TruncationKind rep2) {
+  if (LessGeneral(rep1, rep2)) return rep2;
+  if (LessGeneral(rep2, rep1)) return rep1;
+  // Handle the generalization of float64-representable values.
+  if (LessGeneral(rep1, TruncationKind::kFloat64) &&
+      LessGeneral(rep2, TruncationKind::kFloat64)) {
+    return TruncationKind::kFloat64;
+  }
+  // All other combinations are illegal.
+  FATAL("Tried to combine incompatible truncations");
+  return TruncationKind::kNone;
+}
+
+
+// static
+bool Truncation::LessGeneral(TruncationKind rep1, TruncationKind rep2) {
+  switch (rep1) {
+    case TruncationKind::kNone:
+      return true;
+    case TruncationKind::kBool:
+      return rep2 == TruncationKind::kBool || rep2 == TruncationKind::kAny;
+    case TruncationKind::kWord32:
+      return rep2 == TruncationKind::kWord32 ||
+             rep2 == TruncationKind::kWord64 ||
+             rep2 == TruncationKind::kFloat64 || rep2 == TruncationKind::kAny;
+    case TruncationKind::kWord64:
+      return rep2 == TruncationKind::kWord64;
+    case TruncationKind::kFloat32:
+      return rep2 == TruncationKind::kFloat32 ||
+             rep2 == TruncationKind::kFloat64 || rep2 == TruncationKind::kAny;
+    case TruncationKind::kFloat64:
+      return rep2 == TruncationKind::kFloat64 || rep2 == TruncationKind::kAny;
+    case TruncationKind::kAny:
+      return rep2 == TruncationKind::kAny;
+  }
+  UNREACHABLE();
+  return false;
+}
+
+
+namespace {
+
+// TODO(titzer): should Word64 also be implicitly convertable to others?
+bool IsWord(MachineRepresentation rep) {
+  return rep == MachineRepresentation::kWord8 ||
+         rep == MachineRepresentation::kWord16 ||
+         rep == MachineRepresentation::kWord32;
+}
+
+}  // namespace
+
+
+// Changes representation from {output_rep} to {use_rep}. The {truncation}
+// parameter is only used for sanity checking - if the changer cannot figure
+// out signedness for the word32->float64 conversion, then we check that the
+// uses truncate to word32 (so they do not care about signedness).
+Node* RepresentationChanger::GetRepresentationFor(
+    Node* node, MachineRepresentation output_rep, Type* output_type,
+    MachineRepresentation use_rep, Truncation truncation) {
+  if (output_rep == MachineRepresentation::kNone) {
+    // The output representation should be set.
+    return TypeError(node, output_rep, output_type, use_rep);
+  }
+  if (use_rep == output_rep) {
+    // Representations are the same. That's a no-op.
+    return node;
+  }
+  if (IsWord(use_rep) && IsWord(output_rep)) {
+    // Both are words less than or equal to 32-bits.
+    // Since loads of integers from memory implicitly sign or zero extend the
+    // value to the full machine word size and stores implicitly truncate,
+    // no representation change is necessary.
+    return node;
+  }
+  switch (use_rep) {
+    case MachineRepresentation::kTagged:
+      return GetTaggedRepresentationFor(node, output_rep, output_type);
+    case MachineRepresentation::kFloat32:
+      return GetFloat32RepresentationFor(node, output_rep, output_type,
+                                         truncation);
+    case MachineRepresentation::kFloat64:
+      return GetFloat64RepresentationFor(node, output_rep, output_type,
+                                         truncation);
+    case MachineRepresentation::kBit:
+      return GetBitRepresentationFor(node, output_rep, output_type);
+    case MachineRepresentation::kWord8:
+    case MachineRepresentation::kWord16:
+    case MachineRepresentation::kWord32:
+      return GetWord32RepresentationFor(node, output_rep, output_type);
+    case MachineRepresentation::kWord64:
+      return GetWord64RepresentationFor(node, output_rep, output_type);
+    case MachineRepresentation::kNone:
+      return node;
+  }
+  UNREACHABLE();
+  return nullptr;
+}
+
+
+Node* RepresentationChanger::GetTaggedRepresentationFor(
+    Node* node, MachineRepresentation output_rep, Type* output_type) {
+  // Eagerly fold representation changes for constants.
+  switch (node->opcode()) {
+    case IrOpcode::kNumberConstant:
+    case IrOpcode::kHeapConstant:
+      return node;  // No change necessary.
+    case IrOpcode::kInt32Constant:
+      if (output_type->Is(Type::Signed32())) {
+        int32_t value = OpParameter<int32_t>(node);
+        return jsgraph()->Constant(value);
+      } else if (output_type->Is(Type::Unsigned32())) {
+        uint32_t value = static_cast<uint32_t>(OpParameter<int32_t>(node));
+        return jsgraph()->Constant(static_cast<double>(value));
+      } else if (output_rep == MachineRepresentation::kBit) {
+        return OpParameter<int32_t>(node) == 0 ? jsgraph()->FalseConstant()
+                                               : jsgraph()->TrueConstant();
+      } else {
+        return TypeError(node, output_rep, output_type,
+                         MachineRepresentation::kTagged);
+      }
+    case IrOpcode::kFloat64Constant:
+      return jsgraph()->Constant(OpParameter<double>(node));
+    case IrOpcode::kFloat32Constant:
+      return jsgraph()->Constant(OpParameter<float>(node));
+    default:
+      break;
+  }
+  // Select the correct X -> Tagged operator.
+  const Operator* op;
+  if (output_rep == MachineRepresentation::kBit) {
+    op = simplified()->ChangeBitToBool();
+  } else if (IsWord(output_rep)) {
+    if (output_type->Is(Type::Unsigned32())) {
+      op = simplified()->ChangeUint32ToTagged();
+    } else if (output_type->Is(Type::Signed32())) {
+      op = simplified()->ChangeInt32ToTagged();
+    } else {
+      return TypeError(node, output_rep, output_type,
+                       MachineRepresentation::kTagged);
+    }
+  } else if (output_rep ==
+             MachineRepresentation::kFloat32) {  // float32 -> float64 -> tagged
+    node = InsertChangeFloat32ToFloat64(node);
+    op = simplified()->ChangeFloat64ToTagged();
+  } else if (output_rep == MachineRepresentation::kFloat64) {
+    op = simplified()->ChangeFloat64ToTagged();
+  } else {
+    return TypeError(node, output_rep, output_type,
+                     MachineRepresentation::kTagged);
+  }
+  return jsgraph()->graph()->NewNode(op, node);
+}
+
+
+Node* RepresentationChanger::GetFloat32RepresentationFor(
+    Node* node, MachineRepresentation output_rep, Type* output_type,
+    Truncation truncation) {
+  // Eagerly fold representation changes for constants.
+  switch (node->opcode()) {
+    case IrOpcode::kFloat64Constant:
+    case IrOpcode::kNumberConstant:
+      return jsgraph()->Float32Constant(
+          DoubleToFloat32(OpParameter<double>(node)));
+    case IrOpcode::kInt32Constant:
+      if (output_type->Is(Type::Unsigned32())) {
+        uint32_t value = static_cast<uint32_t>(OpParameter<int32_t>(node));
+        return jsgraph()->Float32Constant(static_cast<float>(value));
+      } else {
+        int32_t value = OpParameter<int32_t>(node);
+        return jsgraph()->Float32Constant(static_cast<float>(value));
+      }
+    case IrOpcode::kFloat32Constant:
+      return node;  // No change necessary.
+    default:
+      break;
+  }
+  // Select the correct X -> Float32 operator.
+  const Operator* op;
+  if (output_rep == MachineRepresentation::kBit) {
+    return TypeError(node, output_rep, output_type,
+                     MachineRepresentation::kFloat32);
+  } else if (IsWord(output_rep)) {
+    if (output_type->Is(Type::Signed32())) {
+      op = machine()->ChangeInt32ToFloat64();
+    } else {
+      // Either the output is int32 or the uses only care about the
+      // low 32 bits (so we can pick int32 safely).
+      DCHECK(output_type->Is(Type::Unsigned32()) ||
+             truncation.TruncatesToWord32());
+      op = machine()->ChangeUint32ToFloat64();
+    }
+    // int32 -> float64 -> float32
+    node = jsgraph()->graph()->NewNode(op, node);
+    op = machine()->TruncateFloat64ToFloat32();
+  } else if (output_rep == MachineRepresentation::kTagged) {
+    op = simplified()->ChangeTaggedToFloat64();  // tagged -> float64 -> float32
+    node = jsgraph()->graph()->NewNode(op, node);
+    op = machine()->TruncateFloat64ToFloat32();
+  } else if (output_rep == MachineRepresentation::kFloat64) {
+    op = machine()->TruncateFloat64ToFloat32();
+  } else {
+    return TypeError(node, output_rep, output_type,
+                     MachineRepresentation::kFloat32);
+  }
+  return jsgraph()->graph()->NewNode(op, node);
+}
+
+
+Node* RepresentationChanger::GetFloat64RepresentationFor(
+    Node* node, MachineRepresentation output_rep, Type* output_type,
+    Truncation truncation) {
+  // Eagerly fold representation changes for constants.
+  switch (node->opcode()) {
+    case IrOpcode::kNumberConstant:
+      return jsgraph()->Float64Constant(OpParameter<double>(node));
+    case IrOpcode::kInt32Constant:
+      if (output_type->Is(Type::Signed32())) {
+        int32_t value = OpParameter<int32_t>(node);
+        return jsgraph()->Float64Constant(value);
+      } else {
+        DCHECK(output_type->Is(Type::Unsigned32()));
+        uint32_t value = static_cast<uint32_t>(OpParameter<int32_t>(node));
+        return jsgraph()->Float64Constant(static_cast<double>(value));
+      }
+    case IrOpcode::kFloat64Constant:
+      return node;  // No change necessary.
+    case IrOpcode::kFloat32Constant:
+      return jsgraph()->Float64Constant(OpParameter<float>(node));
+    default:
+      break;
+  }
+  // Select the correct X -> Float64 operator.
+  const Operator* op;
+  if (output_rep == MachineRepresentation::kBit) {
+    return TypeError(node, output_rep, output_type,
+                     MachineRepresentation::kFloat64);
+  } else if (IsWord(output_rep)) {
+    if (output_type->Is(Type::Signed32())) {
+      op = machine()->ChangeInt32ToFloat64();
+    } else {
+      // Either the output is int32 or the uses only care about the
+      // low 32 bits (so we can pick int32 safely).
+      DCHECK(output_type->Is(Type::Unsigned32()) ||
+             truncation.TruncatesToWord32());
+      op = machine()->ChangeUint32ToFloat64();
+    }
+  } else if (output_rep == MachineRepresentation::kTagged) {
+    op = simplified()->ChangeTaggedToFloat64();
+  } else if (output_rep == MachineRepresentation::kFloat32) {
+    op = machine()->ChangeFloat32ToFloat64();
+  } else {
+    return TypeError(node, output_rep, output_type,
+                     MachineRepresentation::kFloat64);
+  }
+  return jsgraph()->graph()->NewNode(op, node);
+}
+
+
+Node* RepresentationChanger::MakeTruncatedInt32Constant(double value) {
+  return jsgraph()->Int32Constant(DoubleToInt32(value));
+}
+
+
+Node* RepresentationChanger::GetWord32RepresentationFor(
+    Node* node, MachineRepresentation output_rep, Type* output_type) {
+  // Eagerly fold representation changes for constants.
+  switch (node->opcode()) {
+    case IrOpcode::kInt32Constant:
+      return node;  // No change necessary.
+    case IrOpcode::kFloat32Constant:
+      return MakeTruncatedInt32Constant(OpParameter<float>(node));
+    case IrOpcode::kNumberConstant:
+    case IrOpcode::kFloat64Constant:
+      return MakeTruncatedInt32Constant(OpParameter<double>(node));
+    default:
+      break;
+  }
+  // Select the correct X -> Word32 operator.
+  const Operator* op;
+  Type* type = NodeProperties::GetType(node);
+
+  if (output_rep == MachineRepresentation::kBit) {
+    return node;  // Sloppy comparison -> word32
+  } else if (output_rep == MachineRepresentation::kFloat64) {
+    // TODO(jarin) Use only output_type here, once we intersect it with the
+    // type inferred by the typer.
+    if (output_type->Is(Type::Unsigned32()) || type->Is(Type::Unsigned32())) {
+      op = machine()->ChangeFloat64ToUint32();
+    } else if (output_type->Is(Type::Signed32()) ||
+               type->Is(Type::Signed32())) {
+      op = machine()->ChangeFloat64ToInt32();
+    } else {
+      op = machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript);
+    }
+  } else if (output_rep == MachineRepresentation::kFloat32) {
+    node = InsertChangeFloat32ToFloat64(node);  // float32 -> float64 -> int32
+    if (output_type->Is(Type::Unsigned32()) || type->Is(Type::Unsigned32())) {
+      op = machine()->ChangeFloat64ToUint32();
+    } else if (output_type->Is(Type::Signed32()) ||
+               type->Is(Type::Signed32())) {
+      op = machine()->ChangeFloat64ToInt32();
+    } else {
+      op = machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript);
+    }
+  } else if (output_rep == MachineRepresentation::kTagged) {
+    if (output_type->Is(Type::Unsigned32()) || type->Is(Type::Unsigned32())) {
+      op = simplified()->ChangeTaggedToUint32();
+    } else if (output_type->Is(Type::Signed32()) ||
+               type->Is(Type::Signed32())) {
+      op = simplified()->ChangeTaggedToInt32();
+    } else {
+      node = InsertChangeTaggedToFloat64(node);
+      op = machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript);
+    }
+  } else {
+    return TypeError(node, output_rep, output_type,
+                     MachineRepresentation::kWord32);
+  }
+  return jsgraph()->graph()->NewNode(op, node);
+}
+
+
+Node* RepresentationChanger::GetBitRepresentationFor(
+    Node* node, MachineRepresentation output_rep, Type* output_type) {
+  // Eagerly fold representation changes for constants.
+  switch (node->opcode()) {
+    case IrOpcode::kHeapConstant: {
+      Handle<HeapObject> value = OpParameter<Handle<HeapObject>>(node);
+      DCHECK(value.is_identical_to(factory()->true_value()) ||
+             value.is_identical_to(factory()->false_value()));
+      return jsgraph()->Int32Constant(
+          value.is_identical_to(factory()->true_value()) ? 1 : 0);
+    }
+    default:
+      break;
+  }
+  // Select the correct X -> Bit operator.
+  const Operator* op;
+  if (output_rep == MachineRepresentation::kTagged) {
+    op = simplified()->ChangeBoolToBit();
+  } else {
+    return TypeError(node, output_rep, output_type,
+                     MachineRepresentation::kBit);
+  }
+  return jsgraph()->graph()->NewNode(op, node);
+}
+
+
+Node* RepresentationChanger::GetWord64RepresentationFor(
+    Node* node, MachineRepresentation output_rep, Type* output_type) {
+  if (output_rep == MachineRepresentation::kBit) {
+    return node;  // Sloppy comparison -> word64
+  }
+  // Can't really convert Word64 to anything else. Purported to be internal.
+  return TypeError(node, output_rep, output_type,
+                   MachineRepresentation::kWord64);
+}
+
+
+const Operator* RepresentationChanger::Int32OperatorFor(
+    IrOpcode::Value opcode) {
+  switch (opcode) {
+    case IrOpcode::kNumberAdd:
+      return machine()->Int32Add();
+    case IrOpcode::kNumberSubtract:
+      return machine()->Int32Sub();
+    case IrOpcode::kNumberMultiply:
+      return machine()->Int32Mul();
+    case IrOpcode::kNumberDivide:
+      return machine()->Int32Div();
+    case IrOpcode::kNumberModulus:
+      return machine()->Int32Mod();
+    case IrOpcode::kNumberBitwiseOr:
+      return machine()->Word32Or();
+    case IrOpcode::kNumberBitwiseXor:
+      return machine()->Word32Xor();
+    case IrOpcode::kNumberBitwiseAnd:
+      return machine()->Word32And();
+    case IrOpcode::kNumberEqual:
+      return machine()->Word32Equal();
+    case IrOpcode::kNumberLessThan:
+      return machine()->Int32LessThan();
+    case IrOpcode::kNumberLessThanOrEqual:
+      return machine()->Int32LessThanOrEqual();
+    default:
+      UNREACHABLE();
+      return nullptr;
+  }
+}
+
+
+const Operator* RepresentationChanger::Uint32OperatorFor(
+    IrOpcode::Value opcode) {
+  switch (opcode) {
+    case IrOpcode::kNumberAdd:
+      return machine()->Int32Add();
+    case IrOpcode::kNumberSubtract:
+      return machine()->Int32Sub();
+    case IrOpcode::kNumberMultiply:
+      return machine()->Int32Mul();
+    case IrOpcode::kNumberDivide:
+      return machine()->Uint32Div();
+    case IrOpcode::kNumberModulus:
+      return machine()->Uint32Mod();
+    case IrOpcode::kNumberEqual:
+      return machine()->Word32Equal();
+    case IrOpcode::kNumberLessThan:
+      return machine()->Uint32LessThan();
+    case IrOpcode::kNumberLessThanOrEqual:
+      return machine()->Uint32LessThanOrEqual();
+    default:
+      UNREACHABLE();
+      return nullptr;
+  }
+}
+
+
+const Operator* RepresentationChanger::Float64OperatorFor(
+    IrOpcode::Value opcode) {
+  switch (opcode) {
+    case IrOpcode::kNumberAdd:
+      return machine()->Float64Add();
+    case IrOpcode::kNumberSubtract:
+      return machine()->Float64Sub();
+    case IrOpcode::kNumberMultiply:
+      return machine()->Float64Mul();
+    case IrOpcode::kNumberDivide:
+      return machine()->Float64Div();
+    case IrOpcode::kNumberModulus:
+      return machine()->Float64Mod();
+    case IrOpcode::kNumberEqual:
+      return machine()->Float64Equal();
+    case IrOpcode::kNumberLessThan:
+      return machine()->Float64LessThan();
+    case IrOpcode::kNumberLessThanOrEqual:
+      return machine()->Float64LessThanOrEqual();
+    default:
+      UNREACHABLE();
+      return nullptr;
+  }
+}
+
+
+Node* RepresentationChanger::TypeError(Node* node,
+                                       MachineRepresentation output_rep,
+                                       Type* output_type,
+                                       MachineRepresentation use) {
+  type_error_ = true;
+  if (!testing_type_errors_) {
+    std::ostringstream out_str;
+    out_str << output_rep << " (";
+    output_type->PrintTo(out_str, Type::SEMANTIC_DIM);
+    out_str << ")";
+
+    std::ostringstream use_str;
+    use_str << use;
+
+    V8_Fatal(__FILE__, __LINE__,
+             "RepresentationChangerError: node #%d:%s of "
+             "%s cannot be changed to %s",
+             node->id(), node->op()->mnemonic(), out_str.str().c_str(),
+             use_str.str().c_str());
+  }
+  return node;
+}
+
+
+Node* RepresentationChanger::InsertChangeFloat32ToFloat64(Node* node) {
+  return jsgraph()->graph()->NewNode(machine()->ChangeFloat32ToFloat64(), node);
+}
+
+
+Node* RepresentationChanger::InsertChangeTaggedToFloat64(Node* node) {
+  return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedToFloat64(),
+                                     node);
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/representation-change.h b/src/compiler/representation-change.h
index 8720afd..62ea3b4 100644
--- a/src/compiler/representation-change.h
+++ b/src/compiler/representation-change.h
@@ -5,429 +5,106 @@
 #ifndef V8_COMPILER_REPRESENTATION_CHANGE_H_
 #define V8_COMPILER_REPRESENTATION_CHANGE_H_
 
-#include <sstream>
-
-#include "src/base/bits.h"
 #include "src/compiler/js-graph.h"
-#include "src/compiler/machine-operator.h"
-#include "src/compiler/node-properties-inl.h"
 #include "src/compiler/simplified-operator.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
+class Truncation final {
+ public:
+  // Constructors.
+  static Truncation None() { return Truncation(TruncationKind::kNone); }
+  static Truncation Bool() { return Truncation(TruncationKind::kBool); }
+  static Truncation Word32() { return Truncation(TruncationKind::kWord32); }
+  static Truncation Word64() { return Truncation(TruncationKind::kWord64); }
+  static Truncation Float32() { return Truncation(TruncationKind::kFloat32); }
+  static Truncation Float64() { return Truncation(TruncationKind::kFloat64); }
+  static Truncation Any() { return Truncation(TruncationKind::kAny); }
+
+  static Truncation Generalize(Truncation t1, Truncation t2) {
+    return Truncation(Generalize(t1.kind(), t2.kind()));
+  }
+
+  // Queries.
+  bool TruncatesToWord32() const {
+    return LessGeneral(kind_, TruncationKind::kWord32);
+  }
+  bool TruncatesNaNToZero() {
+    return LessGeneral(kind_, TruncationKind::kWord32) ||
+           LessGeneral(kind_, TruncationKind::kBool);
+  }
+  bool TruncatesUndefinedToZeroOrNaN() {
+    return LessGeneral(kind_, TruncationKind::kFloat64) ||
+           LessGeneral(kind_, TruncationKind::kWord64);
+  }
+
+  // Operators.
+  bool operator==(Truncation other) const { return kind() == other.kind(); }
+  bool operator!=(Truncation other) const { return !(*this == other); }
+
+  // Debug utilities.
+  const char* description() const;
+  bool IsLessGeneralThan(Truncation other) {
+    return LessGeneral(kind(), other.kind());
+  }
+
+ private:
+  enum class TruncationKind : uint8_t {
+    kNone,
+    kBool,
+    kWord32,
+    kWord64,
+    kFloat32,
+    kFloat64,
+    kAny
+  };
+
+  explicit Truncation(TruncationKind kind) : kind_(kind) {}
+  TruncationKind kind() const { return kind_; }
+
+  TruncationKind kind_;
+
+  static TruncationKind Generalize(TruncationKind rep1, TruncationKind rep2);
+  static bool LessGeneral(TruncationKind rep1, TruncationKind rep2);
+};
+
+
 // Contains logic related to changing the representation of values for constants
 // and other nodes, as well as lowering Simplified->Machine operators.
 // Eagerly folds any representation changes for constants.
-class RepresentationChanger {
+class RepresentationChanger final {
  public:
-  RepresentationChanger(JSGraph* jsgraph, SimplifiedOperatorBuilder* simplified,
-                        Isolate* isolate)
+  RepresentationChanger(JSGraph* jsgraph, Isolate* isolate)
       : jsgraph_(jsgraph),
-        simplified_(simplified),
         isolate_(isolate),
         testing_type_errors_(false),
         type_error_(false) {}
 
-  // TODO(titzer): should Word64 also be implicitly convertable to others?
-  static const MachineTypeUnion rWord =
-      kRepBit | kRepWord8 | kRepWord16 | kRepWord32;
-
-  Node* GetRepresentationFor(Node* node, MachineTypeUnion output_type,
-                             MachineTypeUnion use_type) {
-    if (!base::bits::IsPowerOfTwo32(output_type & kRepMask)) {
-      // There should be only one output representation.
-      return TypeError(node, output_type, use_type);
-    }
-    if ((use_type & kRepMask) == (output_type & kRepMask)) {
-      // Representations are the same. That's a no-op.
-      return node;
-    }
-    if ((use_type & rWord) && (output_type & rWord)) {
-      // Both are words less than or equal to 32-bits.
-      // Since loads of integers from memory implicitly sign or zero extend the
-      // value to the full machine word size and stores implicitly truncate,
-      // no representation change is necessary.
-      return node;
-    }
-    if (use_type & kRepTagged) {
-      return GetTaggedRepresentationFor(node, output_type);
-    } else if (use_type & kRepFloat32) {
-      return GetFloat32RepresentationFor(node, output_type);
-    } else if (use_type & kRepFloat64) {
-      return GetFloat64RepresentationFor(node, output_type);
-    } else if (use_type & kRepBit) {
-      return GetBitRepresentationFor(node, output_type);
-    } else if (use_type & rWord) {
-      return GetWord32RepresentationFor(node, output_type,
-                                        use_type & kTypeUint32);
-    } else if (use_type & kRepWord64) {
-      return GetWord64RepresentationFor(node, output_type);
-    } else {
-      return node;
-    }
-  }
-
-  Node* GetTaggedRepresentationFor(Node* node, MachineTypeUnion output_type) {
-    // Eagerly fold representation changes for constants.
-    switch (node->opcode()) {
-      case IrOpcode::kNumberConstant:
-      case IrOpcode::kHeapConstant:
-        return node;  // No change necessary.
-      case IrOpcode::kInt32Constant:
-        if (output_type & kTypeUint32) {
-          uint32_t value = OpParameter<uint32_t>(node);
-          return jsgraph()->Constant(static_cast<double>(value));
-        } else if (output_type & kTypeInt32) {
-          int32_t value = OpParameter<int32_t>(node);
-          return jsgraph()->Constant(value);
-        } else if (output_type & kRepBit) {
-          return OpParameter<int32_t>(node) == 0 ? jsgraph()->FalseConstant()
-                                                 : jsgraph()->TrueConstant();
-        } else {
-          return TypeError(node, output_type, kRepTagged);
-        }
-      case IrOpcode::kFloat64Constant:
-        return jsgraph()->Constant(OpParameter<double>(node));
-      case IrOpcode::kFloat32Constant:
-        return jsgraph()->Constant(OpParameter<float>(node));
-      default:
-        break;
-    }
-    // Select the correct X -> Tagged operator.
-    const Operator* op;
-    if (output_type & kRepBit) {
-      op = simplified()->ChangeBitToBool();
-    } else if (output_type & rWord) {
-      if (output_type & kTypeUint32) {
-        op = simplified()->ChangeUint32ToTagged();
-      } else if (output_type & kTypeInt32) {
-        op = simplified()->ChangeInt32ToTagged();
-      } else {
-        return TypeError(node, output_type, kRepTagged);
-      }
-    } else if (output_type & kRepFloat32) {  // float32 -> float64 -> tagged
-      node = InsertChangeFloat32ToFloat64(node);
-      op = simplified()->ChangeFloat64ToTagged();
-    } else if (output_type & kRepFloat64) {
-      op = simplified()->ChangeFloat64ToTagged();
-    } else {
-      return TypeError(node, output_type, kRepTagged);
-    }
-    return jsgraph()->graph()->NewNode(op, node);
-  }
-
-  Node* GetFloat32RepresentationFor(Node* node, MachineTypeUnion output_type) {
-    // Eagerly fold representation changes for constants.
-    switch (node->opcode()) {
-      case IrOpcode::kFloat64Constant:
-      case IrOpcode::kNumberConstant:
-        return jsgraph()->Float32Constant(
-            DoubleToFloat32(OpParameter<double>(node)));
-      case IrOpcode::kInt32Constant:
-        if (output_type & kTypeUint32) {
-          uint32_t value = OpParameter<uint32_t>(node);
-          return jsgraph()->Float32Constant(static_cast<float>(value));
-        } else {
-          int32_t value = OpParameter<int32_t>(node);
-          return jsgraph()->Float32Constant(static_cast<float>(value));
-        }
-      case IrOpcode::kFloat32Constant:
-        return node;  // No change necessary.
-      default:
-        break;
-    }
-    // Select the correct X -> Float32 operator.
-    const Operator* op;
-    if (output_type & kRepBit) {
-      return TypeError(node, output_type, kRepFloat32);
-    } else if (output_type & rWord) {
-      if (output_type & kTypeUint32) {
-        op = machine()->ChangeUint32ToFloat64();
-      } else {
-        op = machine()->ChangeInt32ToFloat64();
-      }
-      // int32 -> float64 -> float32
-      node = jsgraph()->graph()->NewNode(op, node);
-      op = machine()->TruncateFloat64ToFloat32();
-    } else if (output_type & kRepTagged) {
-      op = simplified()
-               ->ChangeTaggedToFloat64();  // tagged -> float64 -> float32
-      node = jsgraph()->graph()->NewNode(op, node);
-      op = machine()->TruncateFloat64ToFloat32();
-    } else if (output_type & kRepFloat64) {
-      op = machine()->TruncateFloat64ToFloat32();
-    } else {
-      return TypeError(node, output_type, kRepFloat32);
-    }
-    return jsgraph()->graph()->NewNode(op, node);
-  }
-
-  Node* GetFloat64RepresentationFor(Node* node, MachineTypeUnion output_type) {
-    // Eagerly fold representation changes for constants.
-    switch (node->opcode()) {
-      case IrOpcode::kNumberConstant:
-        return jsgraph()->Float64Constant(OpParameter<double>(node));
-      case IrOpcode::kInt32Constant:
-        if (output_type & kTypeUint32) {
-          uint32_t value = OpParameter<uint32_t>(node);
-          return jsgraph()->Float64Constant(static_cast<double>(value));
-        } else {
-          int32_t value = OpParameter<int32_t>(node);
-          return jsgraph()->Float64Constant(value);
-        }
-      case IrOpcode::kFloat64Constant:
-        return node;  // No change necessary.
-      case IrOpcode::kFloat32Constant:
-        return jsgraph()->Float64Constant(OpParameter<float>(node));
-      default:
-        break;
-    }
-    // Select the correct X -> Float64 operator.
-    const Operator* op;
-    if (output_type & kRepBit) {
-      return TypeError(node, output_type, kRepFloat64);
-    } else if (output_type & rWord) {
-      if (output_type & kTypeUint32) {
-        op = machine()->ChangeUint32ToFloat64();
-      } else {
-        op = machine()->ChangeInt32ToFloat64();
-      }
-    } else if (output_type & kRepTagged) {
-      op = simplified()->ChangeTaggedToFloat64();
-    } else if (output_type & kRepFloat32) {
-      op = machine()->ChangeFloat32ToFloat64();
-    } else {
-      return TypeError(node, output_type, kRepFloat64);
-    }
-    return jsgraph()->graph()->NewNode(op, node);
-  }
-
-  Node* MakeInt32Constant(double value) {
-    if (value < 0) {
-      DCHECK(IsInt32Double(value));
-      int32_t iv = static_cast<int32_t>(value);
-      return jsgraph()->Int32Constant(iv);
-    } else {
-      DCHECK(IsUint32Double(value));
-      int32_t iv = static_cast<int32_t>(static_cast<uint32_t>(value));
-      return jsgraph()->Int32Constant(iv);
-    }
-  }
-
-  Node* GetTruncatedWord32For(Node* node, MachineTypeUnion output_type) {
-    // Eagerly fold truncations for constants.
-    switch (node->opcode()) {
-      case IrOpcode::kInt32Constant:
-        return node;  // No change necessary.
-      case IrOpcode::kFloat32Constant:
-        return jsgraph()->Int32Constant(
-            DoubleToInt32(OpParameter<float>(node)));
-      case IrOpcode::kNumberConstant:
-      case IrOpcode::kFloat64Constant:
-        return jsgraph()->Int32Constant(
-            DoubleToInt32(OpParameter<double>(node)));
-      default:
-        break;
-    }
-    // Select the correct X -> Word32 truncation operator.
-    const Operator* op = NULL;
-    if (output_type & kRepFloat64) {
-      op = machine()->TruncateFloat64ToInt32();
-    } else if (output_type & kRepFloat32) {
-      node = InsertChangeFloat32ToFloat64(node);
-      op = machine()->TruncateFloat64ToInt32();
-    } else if (output_type & kRepTagged) {
-      node = InsertChangeTaggedToFloat64(node);
-      op = machine()->TruncateFloat64ToInt32();
-    } else {
-      return TypeError(node, output_type, kRepWord32);
-    }
-    return jsgraph()->graph()->NewNode(op, node);
-  }
-
-  Node* GetWord32RepresentationFor(Node* node, MachineTypeUnion output_type,
-                                   bool use_unsigned) {
-    // Eagerly fold representation changes for constants.
-    switch (node->opcode()) {
-      case IrOpcode::kInt32Constant:
-        return node;  // No change necessary.
-      case IrOpcode::kFloat32Constant:
-        return MakeInt32Constant(OpParameter<float>(node));
-      case IrOpcode::kNumberConstant:
-      case IrOpcode::kFloat64Constant:
-        return MakeInt32Constant(OpParameter<double>(node));
-      default:
-        break;
-    }
-    // Select the correct X -> Word32 operator.
-    const Operator* op = NULL;
-    if (output_type & kRepFloat64) {
-      if (output_type & kTypeUint32 || use_unsigned) {
-        op = machine()->ChangeFloat64ToUint32();
-      } else {
-        op = machine()->ChangeFloat64ToInt32();
-      }
-    } else if (output_type & kRepFloat32) {
-      node = InsertChangeFloat32ToFloat64(node);  // float32 -> float64 -> int32
-      if (output_type & kTypeUint32 || use_unsigned) {
-        op = machine()->ChangeFloat64ToUint32();
-      } else {
-        op = machine()->ChangeFloat64ToInt32();
-      }
-    } else if (output_type & kRepTagged) {
-      if (output_type & kTypeUint32 || use_unsigned) {
-        op = simplified()->ChangeTaggedToUint32();
-      } else {
-        op = simplified()->ChangeTaggedToInt32();
-      }
-    } else {
-      return TypeError(node, output_type, kRepWord32);
-    }
-    return jsgraph()->graph()->NewNode(op, node);
-  }
-
-  Node* GetBitRepresentationFor(Node* node, MachineTypeUnion output_type) {
-    // Eagerly fold representation changes for constants.
-    switch (node->opcode()) {
-      case IrOpcode::kInt32Constant: {
-        int32_t value = OpParameter<int32_t>(node);
-        if (value == 0 || value == 1) return node;
-        return jsgraph()->Int32Constant(1);  // value != 0
-      }
-      case IrOpcode::kNumberConstant: {
-        double value = OpParameter<double>(node);
-        if (std::isnan(value) || value == 0.0) {
-          return jsgraph()->Int32Constant(0);
-        }
-        return jsgraph()->Int32Constant(1);
-      }
-      case IrOpcode::kHeapConstant: {
-        Handle<Object> handle = OpParameter<Unique<Object> >(node).handle();
-        DCHECK(*handle == isolate()->heap()->true_value() ||
-               *handle == isolate()->heap()->false_value());
-        return jsgraph()->Int32Constant(
-            *handle == isolate()->heap()->true_value() ? 1 : 0);
-      }
-      default:
-        break;
-    }
-    // Select the correct X -> Bit operator.
-    const Operator* op;
-    if (output_type & rWord) {
-      return node;  // No change necessary.
-    } else if (output_type & kRepWord64) {
-      return node;  // TODO(titzer): No change necessary, on 64-bit.
-    } else if (output_type & kRepTagged) {
-      op = simplified()->ChangeBoolToBit();
-    } else {
-      return TypeError(node, output_type, kRepBit);
-    }
-    return jsgraph()->graph()->NewNode(op, node);
-  }
-
-  Node* GetWord64RepresentationFor(Node* node, MachineTypeUnion output_type) {
-    if (output_type & kRepBit) {
-      return node;  // Sloppy comparison -> word64
-    }
-    // Can't really convert Word64 to anything else. Purported to be internal.
-    return TypeError(node, output_type, kRepWord64);
-  }
-
-  const Operator* Int32OperatorFor(IrOpcode::Value opcode) {
-    switch (opcode) {
-      case IrOpcode::kNumberAdd:
-        return machine()->Int32Add();
-      case IrOpcode::kNumberSubtract:
-        return machine()->Int32Sub();
-      case IrOpcode::kNumberMultiply:
-        return machine()->Int32Mul();
-      case IrOpcode::kNumberDivide:
-        return machine()->Int32Div();
-      case IrOpcode::kNumberModulus:
-        return machine()->Int32Mod();
-      case IrOpcode::kNumberEqual:
-        return machine()->Word32Equal();
-      case IrOpcode::kNumberLessThan:
-        return machine()->Int32LessThan();
-      case IrOpcode::kNumberLessThanOrEqual:
-        return machine()->Int32LessThanOrEqual();
-      default:
-        UNREACHABLE();
-        return NULL;
-    }
-  }
-
-  const Operator* Uint32OperatorFor(IrOpcode::Value opcode) {
-    switch (opcode) {
-      case IrOpcode::kNumberAdd:
-        return machine()->Int32Add();
-      case IrOpcode::kNumberSubtract:
-        return machine()->Int32Sub();
-      case IrOpcode::kNumberMultiply:
-        return machine()->Int32Mul();
-      case IrOpcode::kNumberDivide:
-        return machine()->Uint32Div();
-      case IrOpcode::kNumberModulus:
-        return machine()->Uint32Mod();
-      case IrOpcode::kNumberEqual:
-        return machine()->Word32Equal();
-      case IrOpcode::kNumberLessThan:
-        return machine()->Uint32LessThan();
-      case IrOpcode::kNumberLessThanOrEqual:
-        return machine()->Uint32LessThanOrEqual();
-      default:
-        UNREACHABLE();
-        return NULL;
-    }
-  }
-
-  const Operator* Float64OperatorFor(IrOpcode::Value opcode) {
-    switch (opcode) {
-      case IrOpcode::kNumberAdd:
-        return machine()->Float64Add();
-      case IrOpcode::kNumberSubtract:
-        return machine()->Float64Sub();
-      case IrOpcode::kNumberMultiply:
-        return machine()->Float64Mul();
-      case IrOpcode::kNumberDivide:
-        return machine()->Float64Div();
-      case IrOpcode::kNumberModulus:
-        return machine()->Float64Mod();
-      case IrOpcode::kNumberEqual:
-        return machine()->Float64Equal();
-      case IrOpcode::kNumberLessThan:
-        return machine()->Float64LessThan();
-      case IrOpcode::kNumberLessThanOrEqual:
-        return machine()->Float64LessThanOrEqual();
-      default:
-        UNREACHABLE();
-        return NULL;
-    }
-  }
+  // Changes representation from {output_type} to {use_rep}. The {truncation}
+  // parameter is only used for sanity checking - if the changer cannot figure
+  // out signedness for the word32->float64 conversion, then we check that the
+  // uses truncate to word32 (so they do not care about signedness).
+  Node* GetRepresentationFor(Node* node, MachineRepresentation output_rep,
+                             Type* output_type, MachineRepresentation use_rep,
+                             Truncation truncation = Truncation::None());
+  const Operator* Int32OperatorFor(IrOpcode::Value opcode);
+  const Operator* Uint32OperatorFor(IrOpcode::Value opcode);
+  const Operator* Float64OperatorFor(IrOpcode::Value opcode);
 
   MachineType TypeForBasePointer(const FieldAccess& access) {
-    return access.tag() != 0 ? kMachAnyTagged : kMachPtr;
+    return access.tag() != 0 ? MachineType::AnyTagged()
+                             : MachineType::Pointer();
   }
 
   MachineType TypeForBasePointer(const ElementAccess& access) {
-    return access.tag() != 0 ? kMachAnyTagged : kMachPtr;
-  }
-
-  MachineType TypeFromUpperBound(Type* type) {
-    if (type->Is(Type::None()))
-      return kTypeAny;  // TODO(titzer): should be an error
-    if (type->Is(Type::Signed32())) return kTypeInt32;
-    if (type->Is(Type::Unsigned32())) return kTypeUint32;
-    if (type->Is(Type::Number())) return kTypeNumber;
-    if (type->Is(Type::Boolean())) return kTypeBool;
-    return kTypeAny;
+    return access.tag() != 0 ? MachineType::AnyTagged()
+                             : MachineType::Pointer();
   }
 
  private:
   JSGraph* jsgraph_;
-  SimplifiedOperatorBuilder* simplified_;
   Isolate* isolate_;
 
   friend class RepresentationChangerTester;  // accesses the below fields.
@@ -435,38 +112,30 @@
   bool testing_type_errors_;  // If {true}, don't abort on a type error.
   bool type_error_;           // Set when a type error is detected.
 
-  Node* TypeError(Node* node, MachineTypeUnion output_type,
-                  MachineTypeUnion use) {
-    type_error_ = true;
-    if (!testing_type_errors_) {
-      std::ostringstream out_str;
-      out_str << static_cast<MachineType>(output_type);
+  Node* GetTaggedRepresentationFor(Node* node, MachineRepresentation output_rep,
+                                   Type* output_type);
+  Node* GetFloat32RepresentationFor(Node* node,
+                                    MachineRepresentation output_rep,
+                                    Type* output_type, Truncation truncation);
+  Node* GetFloat64RepresentationFor(Node* node,
+                                    MachineRepresentation output_rep,
+                                    Type* output_type, Truncation truncation);
+  Node* GetWord32RepresentationFor(Node* node, MachineRepresentation output_rep,
+                                   Type* output_type);
+  Node* GetBitRepresentationFor(Node* node, MachineRepresentation output_rep,
+                                Type* output_type);
+  Node* GetWord64RepresentationFor(Node* node, MachineRepresentation output_rep,
+                                   Type* output_type);
+  Node* TypeError(Node* node, MachineRepresentation output_rep,
+                  Type* output_type, MachineRepresentation use);
+  Node* MakeTruncatedInt32Constant(double value);
+  Node* InsertChangeFloat32ToFloat64(Node* node);
+  Node* InsertChangeTaggedToFloat64(Node* node);
 
-      std::ostringstream use_str;
-      use_str << static_cast<MachineType>(use);
-
-      V8_Fatal(__FILE__, __LINE__,
-               "RepresentationChangerError: node #%d:%s of "
-               "%s cannot be changed to %s",
-               node->id(), node->op()->mnemonic(), out_str.str().c_str(),
-               use_str.str().c_str());
-    }
-    return node;
-  }
-
-  Node* InsertChangeFloat32ToFloat64(Node* node) {
-    return jsgraph()->graph()->NewNode(machine()->ChangeFloat32ToFloat64(),
-                                       node);
-  }
-
-  Node* InsertChangeTaggedToFloat64(Node* node) {
-    return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedToFloat64(),
-                                       node);
-  }
-
-  JSGraph* jsgraph() { return jsgraph_; }
-  Isolate* isolate() { return isolate_; }
-  SimplifiedOperatorBuilder* simplified() { return simplified_; }
+  JSGraph* jsgraph() const { return jsgraph_; }
+  Isolate* isolate() const { return isolate_; }
+  Factory* factory() const { return isolate()->factory(); }
+  SimplifiedOperatorBuilder* simplified() { return jsgraph()->simplified(); }
   MachineOperatorBuilder* machine() { return jsgraph()->machine(); }
 };
 
diff --git a/src/compiler/schedule.cc b/src/compiler/schedule.cc
index 30bfbc8..455fcd1 100644
--- a/src/compiler/schedule.cc
+++ b/src/compiler/schedule.cc
@@ -2,10 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "src/compiler/schedule.h"
+
 #include "src/compiler/node.h"
 #include "src/compiler/node-properties.h"
-#include "src/compiler/node-properties-inl.h"
-#include "src/compiler/schedule.h"
 #include "src/ostreams.h"
 
 namespace v8 {
@@ -17,13 +17,13 @@
       rpo_number_(-1),
       deferred_(false),
       dominator_depth_(-1),
-      dominator_(NULL),
-      rpo_next_(NULL),
-      loop_header_(NULL),
-      loop_end_(NULL),
+      dominator_(nullptr),
+      rpo_next_(nullptr),
+      loop_header_(nullptr),
+      loop_end_(nullptr),
       loop_depth_(0),
       control_(kNone),
-      control_input_(NULL),
+      control_input_(nullptr),
       nodes_(zone),
       successors_(zone),
       predecessors_(zone),
@@ -34,7 +34,7 @@
   // RPO numbers must be initialized.
   DCHECK(rpo_number_ >= 0);
   DCHECK(block->rpo_number_ >= 0);
-  if (loop_end_ == NULL) return false;  // This is not a loop.
+  if (loop_end_ == nullptr) return false;  // This is not a loop.
   return block->rpo_number_ >= rpo_number_ &&
          block->rpo_number_ < loop_end_->rpo_number_;
 }
@@ -81,14 +81,35 @@
 }
 
 
+// static
+BasicBlock* BasicBlock::GetCommonDominator(BasicBlock* b1, BasicBlock* b2) {
+  while (b1 != b2) {
+    if (b1->dominator_depth() < b2->dominator_depth()) {
+      b2 = b2->dominator();
+    } else {
+      b1 = b1->dominator();
+    }
+  }
+  return b1;
+}
+
+
 std::ostream& operator<<(std::ostream& os, const BasicBlock::Control& c) {
   switch (c) {
     case BasicBlock::kNone:
       return os << "none";
     case BasicBlock::kGoto:
       return os << "goto";
+    case BasicBlock::kCall:
+      return os << "call";
     case BasicBlock::kBranch:
       return os << "branch";
+    case BasicBlock::kSwitch:
+      return os << "switch";
+    case BasicBlock::kDeoptimize:
+      return os << "deoptimize";
+    case BasicBlock::kTailCall:
+      return os << "tailcall";
     case BasicBlock::kReturn:
       return os << "return";
     case BasicBlock::kThrow:
@@ -104,11 +125,6 @@
 }
 
 
-std::ostream& operator<<(std::ostream& os, const BasicBlock::RpoNumber& rpo) {
-  return os << rpo.ToSize();
-}
-
-
 Schedule::Schedule(Zone* zone, size_t node_count_hint)
     : zone_(zone),
       all_blocks_(zone),
@@ -124,14 +140,13 @@
   if (node->id() < static_cast<NodeId>(nodeid_to_block_.size())) {
     return nodeid_to_block_[node->id()];
   }
-  return NULL;
+  return nullptr;
 }
 
 
 bool Schedule::IsScheduled(Node* node) {
-  int length = static_cast<int>(nodeid_to_block_.size());
-  if (node->id() >= length) return false;
-  return nodeid_to_block_[node->id()] != NULL;
+  if (node->id() >= nodeid_to_block_.size()) return false;
+  return nodeid_to_block_[node->id()] != nullptr;
 }
 
 
@@ -143,7 +158,7 @@
 
 bool Schedule::SameBasicBlock(Node* a, Node* b) const {
   BasicBlock* block = this->block(a);
-  return block != NULL && block == this->block(b);
+  return block != nullptr && block == this->block(b);
 }
 
 
@@ -161,7 +176,7 @@
     os << "Planning #" << node->id() << ":" << node->op()->mnemonic()
        << " for future add to B" << block->id() << "\n";
   }
-  DCHECK(this->block(node) == NULL);
+  DCHECK(this->block(node) == nullptr);
   SetBlockForNode(block, node);
 }
 
@@ -172,23 +187,34 @@
     os << "Adding #" << node->id() << ":" << node->op()->mnemonic() << " to B"
        << block->id() << "\n";
   }
-  DCHECK(this->block(node) == NULL || this->block(node) == block);
+  DCHECK(this->block(node) == nullptr || this->block(node) == block);
   block->AddNode(node);
   SetBlockForNode(block, node);
 }
 
 
 void Schedule::AddGoto(BasicBlock* block, BasicBlock* succ) {
-  DCHECK(block->control() == BasicBlock::kNone);
+  DCHECK_EQ(BasicBlock::kNone, block->control());
   block->set_control(BasicBlock::kGoto);
   AddSuccessor(block, succ);
 }
 
 
+void Schedule::AddCall(BasicBlock* block, Node* call, BasicBlock* success_block,
+                       BasicBlock* exception_block) {
+  DCHECK_EQ(BasicBlock::kNone, block->control());
+  DCHECK_EQ(IrOpcode::kCall, call->opcode());
+  block->set_control(BasicBlock::kCall);
+  AddSuccessor(block, success_block);
+  AddSuccessor(block, exception_block);
+  SetControlInput(block, call);
+}
+
+
 void Schedule::AddBranch(BasicBlock* block, Node* branch, BasicBlock* tblock,
                          BasicBlock* fblock) {
-  DCHECK(block->control() == BasicBlock::kNone);
-  DCHECK(branch->opcode() == IrOpcode::kBranch);
+  DCHECK_EQ(BasicBlock::kNone, block->control());
+  DCHECK_EQ(IrOpcode::kBranch, branch->opcode());
   block->set_control(BasicBlock::kBranch);
   AddSuccessor(block, tblock);
   AddSuccessor(block, fblock);
@@ -196,16 +222,44 @@
 }
 
 
+void Schedule::AddSwitch(BasicBlock* block, Node* sw, BasicBlock** succ_blocks,
+                         size_t succ_count) {
+  DCHECK_EQ(BasicBlock::kNone, block->control());
+  DCHECK_EQ(IrOpcode::kSwitch, sw->opcode());
+  block->set_control(BasicBlock::kSwitch);
+  for (size_t index = 0; index < succ_count; ++index) {
+    AddSuccessor(block, succ_blocks[index]);
+  }
+  SetControlInput(block, sw);
+}
+
+
+void Schedule::AddTailCall(BasicBlock* block, Node* input) {
+  DCHECK_EQ(BasicBlock::kNone, block->control());
+  block->set_control(BasicBlock::kTailCall);
+  SetControlInput(block, input);
+  if (block != end()) AddSuccessor(block, end());
+}
+
+
 void Schedule::AddReturn(BasicBlock* block, Node* input) {
-  DCHECK(block->control() == BasicBlock::kNone);
+  DCHECK_EQ(BasicBlock::kNone, block->control());
   block->set_control(BasicBlock::kReturn);
   SetControlInput(block, input);
   if (block != end()) AddSuccessor(block, end());
 }
 
 
+void Schedule::AddDeoptimize(BasicBlock* block, Node* input) {
+  DCHECK_EQ(BasicBlock::kNone, block->control());
+  block->set_control(BasicBlock::kDeoptimize);
+  SetControlInput(block, input);
+  if (block != end()) AddSuccessor(block, end());
+}
+
+
 void Schedule::AddThrow(BasicBlock* block, Node* input) {
-  DCHECK(block->control() == BasicBlock::kNone);
+  DCHECK_EQ(BasicBlock::kNone, block->control());
   block->set_control(BasicBlock::kThrow);
   SetControlInput(block, input);
   if (block != end()) AddSuccessor(block, end());
@@ -214,20 +268,37 @@
 
 void Schedule::InsertBranch(BasicBlock* block, BasicBlock* end, Node* branch,
                             BasicBlock* tblock, BasicBlock* fblock) {
-  DCHECK(block->control() != BasicBlock::kNone);
-  DCHECK(end->control() == BasicBlock::kNone);
+  DCHECK_NE(BasicBlock::kNone, block->control());
+  DCHECK_EQ(BasicBlock::kNone, end->control());
   end->set_control(block->control());
   block->set_control(BasicBlock::kBranch);
   MoveSuccessors(block, end);
   AddSuccessor(block, tblock);
   AddSuccessor(block, fblock);
-  if (block->control_input() != NULL) {
+  if (block->control_input() != nullptr) {
     SetControlInput(end, block->control_input());
   }
   SetControlInput(block, branch);
 }
 
 
+void Schedule::InsertSwitch(BasicBlock* block, BasicBlock* end, Node* sw,
+                            BasicBlock** succ_blocks, size_t succ_count) {
+  DCHECK_NE(BasicBlock::kNone, block->control());
+  DCHECK_EQ(BasicBlock::kNone, end->control());
+  end->set_control(block->control());
+  block->set_control(BasicBlock::kSwitch);
+  MoveSuccessors(block, end);
+  for (size_t index = 0; index < succ_count; ++index) {
+    AddSuccessor(block, succ_blocks[index]);
+  }
+  if (block->control_input() != nullptr) {
+    SetControlInput(end, block->control_input());
+  }
+  SetControlInput(block, sw);
+}
+
+
 void Schedule::AddSuccessor(BasicBlock* block, BasicBlock* succ) {
   block->AddSuccessor(succ);
   succ->AddPredecessor(block);
@@ -235,13 +306,10 @@
 
 
 void Schedule::MoveSuccessors(BasicBlock* from, BasicBlock* to) {
-  for (BasicBlock::Predecessors::iterator i = from->successors_begin();
-       i != from->successors_end(); ++i) {
-    BasicBlock* succ = *i;
-    to->AddSuccessor(succ);
-    for (BasicBlock::Predecessors::iterator j = succ->predecessors_begin();
-         j != succ->predecessors_end(); ++j) {
-      if (*j == from) *j = to;
+  for (BasicBlock* const successor : from->successors()) {
+    to->AddSuccessor(successor);
+    for (BasicBlock*& predecessor : successor->predecessors()) {
+      if (predecessor == from) predecessor = to;
     }
   }
   from->ClearSuccessors();
@@ -255,8 +323,7 @@
 
 
 void Schedule::SetBlockForNode(BasicBlock* block, Node* node) {
-  int length = static_cast<int>(nodeid_to_block_.size());
-  if (node->id() >= length) {
+  if (node->id() >= nodeid_to_block_.size()) {
     nodeid_to_block_.resize(node->id() + 1);
   }
   nodeid_to_block_[node->id()] = block;
@@ -264,51 +331,40 @@
 
 
 std::ostream& operator<<(std::ostream& os, const Schedule& s) {
-  // TODO(svenpanne) Const-correct the RPO stuff/iterators.
-  BasicBlockVector* rpo = const_cast<Schedule*>(&s)->rpo_order();
-  for (BasicBlockVectorIter i = rpo->begin(); i != rpo->end(); ++i) {
-    BasicBlock* block = *i;
-    os << "--- BLOCK B" << block->id();
+  for (BasicBlock* block : *s.rpo_order()) {
+    os << "--- BLOCK B" << block->rpo_number();
     if (block->deferred()) os << " (deferred)";
     if (block->PredecessorCount() != 0) os << " <- ";
     bool comma = false;
-    for (BasicBlock::Predecessors::iterator j = block->predecessors_begin();
-         j != block->predecessors_end(); ++j) {
+    for (BasicBlock const* predecessor : block->predecessors()) {
       if (comma) os << ", ";
       comma = true;
-      os << "B" << (*j)->id();
+      os << "B" << predecessor->rpo_number();
     }
     os << " ---\n";
-    for (BasicBlock::const_iterator j = block->begin(); j != block->end();
-         ++j) {
-      Node* node = *j;
+    for (Node* node : *block) {
       os << "  " << *node;
       if (NodeProperties::IsTyped(node)) {
-        Bounds bounds = NodeProperties::GetBounds(node);
+        Type* type = NodeProperties::GetType(node);
         os << " : ";
-        bounds.lower->PrintTo(os);
-        if (!bounds.upper->Is(bounds.lower)) {
-          os << "..";
-          bounds.upper->PrintTo(os);
-        }
+        type->PrintTo(os);
       }
       os << "\n";
     }
     BasicBlock::Control control = block->control();
     if (control != BasicBlock::kNone) {
       os << "  ";
-      if (block->control_input() != NULL) {
+      if (block->control_input() != nullptr) {
         os << *block->control_input();
       } else {
         os << "Goto";
       }
       os << " -> ";
       comma = false;
-      for (BasicBlock::Successors::iterator j = block->successors_begin();
-           j != block->successors_end(); ++j) {
+      for (BasicBlock const* successor : block->successors()) {
         if (comma) os << ", ";
         comma = true;
-        os << "B" << (*j)->id();
+        os << "B" << successor->rpo_number();
       }
       os << "\n";
     }
diff --git a/src/compiler/schedule.h b/src/compiler/schedule.h
index 0bba689..9624ff5 100644
--- a/src/compiler/schedule.h
+++ b/src/compiler/schedule.h
@@ -6,36 +6,40 @@
 #define V8_COMPILER_SCHEDULE_H_
 
 #include <iosfwd>
-#include <vector>
 
-#include "src/v8.h"
-
-#include "src/compiler/node.h"
-#include "src/compiler/opcodes.h"
-#include "src/zone.h"
+#include "src/zone-containers.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
+// Forward declarations.
 class BasicBlock;
 class BasicBlockInstrumentor;
-class Graph;
-class ConstructScheduleData;
-class CodeGenerator;  // Because of a namespace bug in clang.
+class Node;
+
+
+typedef ZoneVector<BasicBlock*> BasicBlockVector;
+typedef ZoneVector<Node*> NodeVector;
+
 
 // A basic block contains an ordered list of nodes and ends with a control
 // node. Note that if a basic block has phis, then all phis must appear as the
 // first nodes in the block.
-class BasicBlock FINAL : public ZoneObject {
+class BasicBlock final : public ZoneObject {
  public:
   // Possible control nodes that can end a block.
   enum Control {
-    kNone,    // Control not initialized yet.
-    kGoto,    // Goto a single successor block.
-    kBranch,  // Branch if true to first successor, otherwise second.
-    kReturn,  // Return a value from this method.
-    kThrow    // Throw an exception.
+    kNone,        // Control not initialized yet.
+    kGoto,        // Goto a single successor block.
+    kCall,        // Call with continuation as first successor, exception
+                  // second.
+    kBranch,      // Branch if true to first successor, otherwise second.
+    kSwitch,      // Table dispatch to one of the successor blocks.
+    kDeoptimize,  // Return a value from this method.
+    kTailCall,    // Tail call another method from this method.
+    kReturn,      // Return a value from this method.
+    kThrow        // Throw an exception.
   };
 
   class Id {
@@ -50,72 +54,36 @@
     size_t index_;
   };
 
-  static const int kInvalidRpoNumber = -1;
-  class RpoNumber FINAL {
-   public:
-    int ToInt() const {
-      DCHECK(IsValid());
-      return index_;
-    }
-    size_t ToSize() const {
-      DCHECK(IsValid());
-      return static_cast<size_t>(index_);
-    }
-    bool IsValid() const { return index_ >= 0; }
-    static RpoNumber FromInt(int index) { return RpoNumber(index); }
-    static RpoNumber Invalid() { return RpoNumber(kInvalidRpoNumber); }
-
-    bool IsNext(const RpoNumber other) const {
-      DCHECK(IsValid());
-      return other.index_ == this->index_ + 1;
-    }
-
-    bool operator==(RpoNumber other) const {
-      return this->index_ == other.index_;
-    }
-
-   private:
-    explicit RpoNumber(int32_t index) : index_(index) {}
-    int32_t index_;
-  };
-
   BasicBlock(Zone* zone, Id id);
 
   Id id() const { return id_; }
 
-  // Predecessors and successors.
-  typedef ZoneVector<BasicBlock*> Predecessors;
-  Predecessors::iterator predecessors_begin() { return predecessors_.begin(); }
-  Predecessors::iterator predecessors_end() { return predecessors_.end(); }
-  Predecessors::const_iterator predecessors_begin() const {
-    return predecessors_.begin();
-  }
-  Predecessors::const_iterator predecessors_end() const {
-    return predecessors_.end();
-  }
+  // Predecessors.
+  BasicBlockVector& predecessors() { return predecessors_; }
+  const BasicBlockVector& predecessors() const { return predecessors_; }
   size_t PredecessorCount() const { return predecessors_.size(); }
   BasicBlock* PredecessorAt(size_t index) { return predecessors_[index]; }
   void ClearPredecessors() { predecessors_.clear(); }
   void AddPredecessor(BasicBlock* predecessor);
 
-  typedef ZoneVector<BasicBlock*> Successors;
-  Successors::iterator successors_begin() { return successors_.begin(); }
-  Successors::iterator successors_end() { return successors_.end(); }
-  Successors::const_iterator successors_begin() const {
-    return successors_.begin();
-  }
-  Successors::const_iterator successors_end() const {
-    return successors_.end();
-  }
+  // Successors.
+  BasicBlockVector& successors() { return successors_; }
+  const BasicBlockVector& successors() const { return successors_; }
   size_t SuccessorCount() const { return successors_.size(); }
   BasicBlock* SuccessorAt(size_t index) { return successors_[index]; }
   void ClearSuccessors() { successors_.clear(); }
   void AddSuccessor(BasicBlock* successor);
 
   // Nodes in the basic block.
+  typedef Node* value_type;
+  bool empty() const { return nodes_.empty(); }
+  size_t size() const { return nodes_.size(); }
   Node* NodeAt(size_t index) { return nodes_[index]; }
   size_t NodeCount() const { return nodes_.size(); }
 
+  value_type& front() { return nodes_.front(); }
+  value_type const& front() const { return nodes_.front(); }
+
   typedef NodeVector::iterator iterator;
   iterator begin() { return nodes_.begin(); }
   iterator end() { return nodes_.end(); }
@@ -166,14 +134,17 @@
   int32_t loop_number() const { return loop_number_; }
   void set_loop_number(int32_t loop_number) { loop_number_ = loop_number; }
 
-  RpoNumber GetRpoNumber() const { return RpoNumber::FromInt(rpo_number_); }
   int32_t rpo_number() const { return rpo_number_; }
   void set_rpo_number(int32_t rpo_number);
 
   // Loop membership helpers.
-  inline bool IsLoopHeader() const { return loop_end_ != NULL; }
+  inline bool IsLoopHeader() const { return loop_end_ != nullptr; }
   bool LoopContains(BasicBlock* block) const;
 
+  // Computes the immediate common dominator of {b1} and {b2}. The worst time
+  // complexity is O(N) where N is the height of the dominator tree.
+  static BasicBlock* GetCommonDominator(BasicBlock* b1, BasicBlock* b2);
+
  private:
   int32_t loop_number_;      // loop number of the block.
   int32_t rpo_number_;       // special RPO number of the block.
@@ -182,8 +153,8 @@
   BasicBlock* dominator_;    // Immediate dominator of the block.
   BasicBlock* rpo_next_;     // Link to next block in special RPO order.
   BasicBlock* loop_header_;  // Pointer to dominating loop header basic block,
-                             // NULL if none. For loop headers, this points to
-                             // enclosing loop header.
+  // nullptr if none. For loop headers, this points to
+  // enclosing loop header.
   BasicBlock* loop_end_;     // end of the loop, if this block is a loop header.
   int32_t loop_depth_;       // loop nesting, 0 is top-level
 
@@ -191,26 +162,22 @@
   Node* control_input_;      // Input value for control.
   NodeVector nodes_;         // nodes of this block in forward order.
 
-  Successors successors_;
-  Predecessors predecessors_;
+  BasicBlockVector successors_;
+  BasicBlockVector predecessors_;
   Id id_;
 
   DISALLOW_COPY_AND_ASSIGN(BasicBlock);
 };
 
-std::ostream& operator<<(std::ostream& os, const BasicBlock::Control& c);
-std::ostream& operator<<(std::ostream& os, const BasicBlock::Id& id);
-std::ostream& operator<<(std::ostream& os, const BasicBlock::RpoNumber& rpo);
+std::ostream& operator<<(std::ostream&, const BasicBlock::Control&);
+std::ostream& operator<<(std::ostream&, const BasicBlock::Id&);
 
-typedef ZoneVector<BasicBlock*> BasicBlockVector;
-typedef BasicBlockVector::iterator BasicBlockVectorIter;
-typedef BasicBlockVector::reverse_iterator BasicBlockVectorRIter;
 
 // A schedule represents the result of assigning nodes to basic blocks
 // and ordering them within basic blocks. Prior to computing a schedule,
 // a graph has no notion of control flow ordering other than that induced
 // by the graph's dependencies. A schedule is required to generate code.
-class Schedule FINAL : public ZoneObject {
+class Schedule final : public ZoneObject {
  public:
   explicit Schedule(Zone* zone, size_t node_count_hint = 0);
 
@@ -239,10 +206,24 @@
   // BasicBlock building: add a goto to the end of {block}.
   void AddGoto(BasicBlock* block, BasicBlock* succ);
 
+  // BasicBlock building: add a call at the end of {block}.
+  void AddCall(BasicBlock* block, Node* call, BasicBlock* success_block,
+               BasicBlock* exception_block);
+
   // BasicBlock building: add a branch at the end of {block}.
   void AddBranch(BasicBlock* block, Node* branch, BasicBlock* tblock,
                  BasicBlock* fblock);
 
+  // BasicBlock building: add a switch at the end of {block}.
+  void AddSwitch(BasicBlock* block, Node* sw, BasicBlock** succ_blocks,
+                 size_t succ_count);
+
+  // BasicBlock building: add a deoptimize at the end of {block}.
+  void AddDeoptimize(BasicBlock* block, Node* input);
+
+  // BasicBlock building: add a tailcall at the end of {block}.
+  void AddTailCall(BasicBlock* block, Node* input);
+
   // BasicBlock building: add a return at the end of {block}.
   void AddReturn(BasicBlock* block, Node* input);
 
@@ -253,6 +234,10 @@
   void InsertBranch(BasicBlock* block, BasicBlock* end, Node* branch,
                     BasicBlock* tblock, BasicBlock* fblock);
 
+  // BasicBlock mutation: insert a switch into the end of {block}.
+  void InsertSwitch(BasicBlock* block, BasicBlock* end, Node* sw,
+                    BasicBlock** succ_blocks, size_t succ_count);
+
   // Exposed publicly for testing only.
   void AddSuccessorForTesting(BasicBlock* block, BasicBlock* succ) {
     return AddSuccessor(block, succ);
@@ -286,7 +271,7 @@
   DISALLOW_COPY_AND_ASSIGN(Schedule);
 };
 
-std::ostream& operator<<(std::ostream& os, const Schedule& s);
+std::ostream& operator<<(std::ostream&, const Schedule&);
 
 }  // namespace compiler
 }  // namespace internal
diff --git a/src/compiler/scheduler.cc b/src/compiler/scheduler.cc
index f12c631..80ce8b1 100644
--- a/src/compiler/scheduler.cc
+++ b/src/compiler/scheduler.cc
@@ -2,47 +2,44 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include <deque>
-#include <queue>
-
 #include "src/compiler/scheduler.h"
 
+#include <iomanip>
+
+#include "src/base/adapters.h"
 #include "src/bit-vector.h"
+#include "src/compiler/common-operator.h"
 #include "src/compiler/control-equivalence.h"
 #include "src/compiler/graph.h"
-#include "src/compiler/graph-inl.h"
 #include "src/compiler/node.h"
+#include "src/compiler/node-marker.h"
 #include "src/compiler/node-properties.h"
-#include "src/compiler/node-properties-inl.h"
+#include "src/zone-containers.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
-static inline void Trace(const char* msg, ...) {
-  if (FLAG_trace_turbo_scheduler) {
-    va_list arguments;
-    va_start(arguments, msg);
-    base::OS::VPrint(msg, arguments);
-    va_end(arguments);
-  }
-}
+#define TRACE(...)                                       \
+  do {                                                   \
+    if (FLAG_trace_turbo_scheduler) PrintF(__VA_ARGS__); \
+  } while (false)
 
-
-Scheduler::Scheduler(Zone* zone, Graph* graph, Schedule* schedule)
+Scheduler::Scheduler(Zone* zone, Graph* graph, Schedule* schedule, Flags flags)
     : zone_(zone),
       graph_(graph),
       schedule_(schedule),
+      flags_(flags),
       scheduled_nodes_(zone),
       schedule_root_nodes_(zone),
       schedule_queue_(zone),
       node_data_(graph_->NodeCount(), DefaultSchedulerData(), zone) {}
 
 
-Schedule* Scheduler::ComputeSchedule(Zone* zone, Graph* graph) {
+Schedule* Scheduler::ComputeSchedule(Zone* zone, Graph* graph, Flags flags) {
   Schedule* schedule = new (graph->zone())
       Schedule(graph->zone(), static_cast<size_t>(graph->NodeCount()));
-  Scheduler scheduler(zone, graph, schedule);
+  Scheduler scheduler(zone, graph, schedule, flags);
 
   scheduler.BuildCFG();
   scheduler.ComputeSpecialRPONumbering();
@@ -65,7 +62,6 @@
 
 
 Scheduler::SchedulerData* Scheduler::GetData(Node* node) {
-  DCHECK(node->id() < static_cast<int>(node_data_.size()));
   return &node_data_[node->id()];
 }
 
@@ -75,7 +71,8 @@
   if (data->placement_ == kUnknown) {  // Compute placement, once, on demand.
     switch (node->opcode()) {
       case IrOpcode::kParameter:
-        // Parameters are always fixed to the start node.
+      case IrOpcode::kOsrValue:
+        // Parameters and OSR values are always fixed to the start block.
         data->placement_ = kFixed;
         break;
       case IrOpcode::kPhi:
@@ -126,11 +123,10 @@
 #undef DEFINE_CONTROL_CASE
       {
         // Control nodes force coupled uses to be placed.
-        Node::Uses uses = node->uses();
-        for (Node::Uses::iterator i = uses.begin(); i != uses.end(); ++i) {
-          if (GetPlacement(*i) == Scheduler::kCoupled) {
-            DCHECK_EQ(node, NodeProperties::GetControlInput(*i));
-            UpdatePlacement(*i, placement);
+        for (auto use : node->uses()) {
+          if (GetPlacement(use) == Scheduler::kCoupled) {
+            DCHECK_EQ(node, NodeProperties::GetControlInput(use));
+            UpdatePlacement(use, placement);
           }
         }
         break;
@@ -173,7 +169,7 @@
 
   ++(GetData(node)->unscheduled_count_);
   if (FLAG_trace_turbo_scheduler) {
-    Trace("  Use count of #%d:%s (used by #%d:%s)++ = %d\n", node->id(),
+    TRACE("  Use count of #%d:%s (used by #%d:%s)++ = %d\n", node->id(),
           node->op()->mnemonic(), from->id(), from->op()->mnemonic(),
           GetData(node)->unscheduled_count_);
   }
@@ -197,31 +193,17 @@
   DCHECK(GetData(node)->unscheduled_count_ > 0);
   --(GetData(node)->unscheduled_count_);
   if (FLAG_trace_turbo_scheduler) {
-    Trace("  Use count of #%d:%s (used by #%d:%s)-- = %d\n", node->id(),
+    TRACE("  Use count of #%d:%s (used by #%d:%s)-- = %d\n", node->id(),
           node->op()->mnemonic(), from->id(), from->op()->mnemonic(),
           GetData(node)->unscheduled_count_);
   }
   if (GetData(node)->unscheduled_count_ == 0) {
-    Trace("    newly eligible #%d:%s\n", node->id(), node->op()->mnemonic());
+    TRACE("    newly eligible #%d:%s\n", node->id(), node->op()->mnemonic());
     schedule_queue_.push(node);
   }
 }
 
 
-BasicBlock* Scheduler::GetCommonDominator(BasicBlock* b1, BasicBlock* b2) {
-  while (b1 != b2) {
-    int32_t b1_depth = b1->dominator_depth();
-    int32_t b2_depth = b2->dominator_depth();
-    if (b1_depth < b2_depth) {
-      b2 = b2->dominator();
-    } else {
-      b1 = b1->dominator();
-    }
-  }
-  return b1;
-}
-
-
 // -----------------------------------------------------------------------------
 // Phase 1: Build control-flow graph.
 
@@ -233,14 +215,15 @@
 class CFGBuilder : public ZoneObject {
  public:
   CFGBuilder(Zone* zone, Scheduler* scheduler)
-      : scheduler_(scheduler),
+      : zone_(zone),
+        scheduler_(scheduler),
         schedule_(scheduler->schedule_),
         queued_(scheduler->graph_, 2),
         queue_(zone),
         control_(zone),
-        component_entry_(NULL),
-        component_start_(NULL),
-        component_end_(NULL) {}
+        component_entry_(nullptr),
+        component_start_(nullptr),
+        component_end_(nullptr) {}
 
   // Run the control flow graph construction algorithm by walking the graph
   // backwards from end through control edges, building and connecting the
@@ -270,7 +253,7 @@
     ResetDataStructures();
     Queue(exit);
 
-    component_entry_ = NULL;
+    component_entry_ = nullptr;
     component_start_ = block;
     component_end_ = schedule_->block(exit);
     scheduler_->equivalence_->Run(exit);
@@ -281,8 +264,8 @@
       // Use control dependence equivalence to find a canonical single-entry
       // single-exit region that makes up a minimal component to be scheduled.
       if (IsSingleEntrySingleExitRegion(node, exit)) {
-        Trace("Found SESE at #%d:%s\n", node->id(), node->op()->mnemonic());
-        DCHECK_EQ(NULL, component_entry_);
+        TRACE("Found SESE at #%d:%s\n", node->id(), node->op()->mnemonic());
+        DCHECK(!component_entry_);
         component_entry_ = node;
         continue;
       }
@@ -292,7 +275,7 @@
         Queue(node->InputAt(i));
       }
     }
-    DCHECK_NE(NULL, component_entry_);
+    DCHECK(component_entry_);
 
     for (NodeVector::iterator i = control_.begin(); i != control_.end(); ++i) {
       ConnectBlocks(*i);  // Connect block to its predecessor/successors.
@@ -300,7 +283,7 @@
   }
 
  private:
-  // TODO(mstarzinger): Only for Scheduler::FuseFloatingControl.
+  friend class ScheduleLateNodeVisitor;
   friend class Scheduler;
 
   void FixNode(BasicBlock* block, Node* node) {
@@ -338,7 +321,13 @@
         break;
       }
       case IrOpcode::kBranch:
-        BuildBlocksForSuccessors(node, IrOpcode::kIfTrue, IrOpcode::kIfFalse);
+      case IrOpcode::kSwitch:
+        BuildBlocksForSuccessors(node);
+        break;
+      case IrOpcode::kCall:
+        if (NodeProperties::IsExceptionalCall(node)) {
+          BuildBlocksForSuccessors(node);
+        }
         break;
       default:
         break;
@@ -355,10 +344,32 @@
         scheduler_->UpdatePlacement(node, Scheduler::kFixed);
         ConnectBranch(node);
         break;
+      case IrOpcode::kSwitch:
+        scheduler_->UpdatePlacement(node, Scheduler::kFixed);
+        ConnectSwitch(node);
+        break;
+      case IrOpcode::kDeoptimize:
+        scheduler_->UpdatePlacement(node, Scheduler::kFixed);
+        ConnectDeoptimize(node);
+        break;
+      case IrOpcode::kTailCall:
+        scheduler_->UpdatePlacement(node, Scheduler::kFixed);
+        ConnectTailCall(node);
+        break;
       case IrOpcode::kReturn:
         scheduler_->UpdatePlacement(node, Scheduler::kFixed);
         ConnectReturn(node);
         break;
+      case IrOpcode::kThrow:
+        scheduler_->UpdatePlacement(node, Scheduler::kFixed);
+        ConnectThrow(node);
+        break;
+      case IrOpcode::kCall:
+        if (NodeProperties::IsExceptionalCall(node)) {
+          scheduler_->UpdatePlacement(node, Scheduler::kFixed);
+          ConnectCall(node);
+        }
+        break;
       default:
         break;
     }
@@ -366,58 +377,62 @@
 
   BasicBlock* BuildBlockForNode(Node* node) {
     BasicBlock* block = schedule_->block(node);
-    if (block == NULL) {
+    if (block == nullptr) {
       block = schedule_->NewBasicBlock();
-      Trace("Create block B%d for #%d:%s\n", block->id().ToInt(), node->id(),
+      TRACE("Create block id:%d for #%d:%s\n", block->id().ToInt(), node->id(),
             node->op()->mnemonic());
       FixNode(block, node);
     }
     return block;
   }
 
-  void BuildBlocksForSuccessors(Node* node, IrOpcode::Value a,
-                                IrOpcode::Value b) {
-    Node* successors[2];
-    CollectSuccessorProjections(node, successors, a, b);
-    BuildBlockForNode(successors[0]);
-    BuildBlockForNode(successors[1]);
-  }
-
-  // Collect the branch-related projections from a node, such as IfTrue,
-  // IfFalse.
-  // TODO(titzer): consider moving this to node.h
-  void CollectSuccessorProjections(Node* node, Node** buffer,
-                                   IrOpcode::Value true_opcode,
-                                   IrOpcode::Value false_opcode) {
-    buffer[0] = NULL;
-    buffer[1] = NULL;
-    for (Node* use : node->uses()) {
-      if (use->opcode() == true_opcode) {
-        DCHECK_EQ(NULL, buffer[0]);
-        buffer[0] = use;
-      }
-      if (use->opcode() == false_opcode) {
-        DCHECK_EQ(NULL, buffer[1]);
-        buffer[1] = use;
-      }
+  void BuildBlocksForSuccessors(Node* node) {
+    size_t const successor_cnt = node->op()->ControlOutputCount();
+    Node** successors = zone_->NewArray<Node*>(successor_cnt);
+    NodeProperties::CollectControlProjections(node, successors, successor_cnt);
+    for (size_t index = 0; index < successor_cnt; ++index) {
+      BuildBlockForNode(successors[index]);
     }
-    DCHECK_NE(NULL, buffer[0]);
-    DCHECK_NE(NULL, buffer[1]);
   }
 
-  void CollectSuccessorBlocks(Node* node, BasicBlock** buffer,
-                              IrOpcode::Value true_opcode,
-                              IrOpcode::Value false_opcode) {
-    Node* successors[2];
-    CollectSuccessorProjections(node, successors, true_opcode, false_opcode);
-    buffer[0] = schedule_->block(successors[0]);
-    buffer[1] = schedule_->block(successors[1]);
+  void CollectSuccessorBlocks(Node* node, BasicBlock** successor_blocks,
+                              size_t successor_cnt) {
+    Node** successors = reinterpret_cast<Node**>(successor_blocks);
+    NodeProperties::CollectControlProjections(node, successors, successor_cnt);
+    for (size_t index = 0; index < successor_cnt; ++index) {
+      successor_blocks[index] = schedule_->block(successors[index]);
+    }
+  }
+
+  BasicBlock* FindPredecessorBlock(Node* node) {
+    BasicBlock* predecessor_block = nullptr;
+    while (true) {
+      predecessor_block = schedule_->block(node);
+      if (predecessor_block != nullptr) break;
+      node = NodeProperties::GetControlInput(node);
+    }
+    return predecessor_block;
+  }
+
+  void ConnectCall(Node* call) {
+    BasicBlock* successor_blocks[2];
+    CollectSuccessorBlocks(call, successor_blocks, arraysize(successor_blocks));
+
+    // Consider the exception continuation to be deferred.
+    successor_blocks[1]->set_deferred(true);
+
+    Node* call_control = NodeProperties::GetControlInput(call);
+    BasicBlock* call_block = FindPredecessorBlock(call_control);
+    TraceConnect(call, call_block, successor_blocks[0]);
+    TraceConnect(call, call_block, successor_blocks[1]);
+    schedule_->AddCall(call_block, call, successor_blocks[0],
+                       successor_blocks[1]);
   }
 
   void ConnectBranch(Node* branch) {
     BasicBlock* successor_blocks[2];
-    CollectSuccessorBlocks(branch, successor_blocks, IrOpcode::kIfTrue,
-                           IrOpcode::kIfFalse);
+    CollectSuccessorBlocks(branch, successor_blocks,
+                           arraysize(successor_blocks));
 
     // Consider branch hints.
     switch (BranchHintOf(branch->op())) {
@@ -437,10 +452,8 @@
       schedule_->InsertBranch(component_start_, component_end_, branch,
                               successor_blocks[0], successor_blocks[1]);
     } else {
-      Node* branch_block_node = NodeProperties::GetControlInput(branch);
-      BasicBlock* branch_block = schedule_->block(branch_block_node);
-      DCHECK(branch_block != NULL);
-
+      Node* branch_control = NodeProperties::GetControlInput(branch);
+      BasicBlock* branch_block = FindPredecessorBlock(branch_control);
       TraceConnect(branch, branch_block, successor_blocks[0]);
       TraceConnect(branch, branch_block, successor_blocks[1]);
       schedule_->AddBranch(branch_block, branch, successor_blocks[0],
@@ -448,36 +461,79 @@
     }
   }
 
+  void ConnectSwitch(Node* sw) {
+    size_t const successor_count = sw->op()->ControlOutputCount();
+    BasicBlock** successor_blocks =
+        zone_->NewArray<BasicBlock*>(successor_count);
+    CollectSuccessorBlocks(sw, successor_blocks, successor_count);
+
+    if (sw == component_entry_) {
+      for (size_t index = 0; index < successor_count; ++index) {
+        TraceConnect(sw, component_start_, successor_blocks[index]);
+      }
+      schedule_->InsertSwitch(component_start_, component_end_, sw,
+                              successor_blocks, successor_count);
+    } else {
+      Node* switch_control = NodeProperties::GetControlInput(sw);
+      BasicBlock* switch_block = FindPredecessorBlock(switch_control);
+      for (size_t index = 0; index < successor_count; ++index) {
+        TraceConnect(sw, switch_block, successor_blocks[index]);
+      }
+      schedule_->AddSwitch(switch_block, sw, successor_blocks, successor_count);
+    }
+  }
+
   void ConnectMerge(Node* merge) {
     // Don't connect the special merge at the end to its predecessors.
     if (IsFinalMerge(merge)) return;
 
     BasicBlock* block = schedule_->block(merge);
-    DCHECK(block != NULL);
+    DCHECK_NOT_NULL(block);
     // For all of the merge's control inputs, add a goto at the end to the
     // merge's basic block.
     for (Node* const input : merge->inputs()) {
-      BasicBlock* predecessor_block = schedule_->block(input);
+      BasicBlock* predecessor_block = FindPredecessorBlock(input);
       TraceConnect(merge, predecessor_block, block);
       schedule_->AddGoto(predecessor_block, block);
     }
   }
 
+  void ConnectTailCall(Node* call) {
+    Node* call_control = NodeProperties::GetControlInput(call);
+    BasicBlock* call_block = FindPredecessorBlock(call_control);
+    TraceConnect(call, call_block, nullptr);
+    schedule_->AddTailCall(call_block, call);
+  }
+
   void ConnectReturn(Node* ret) {
-    Node* return_block_node = NodeProperties::GetControlInput(ret);
-    BasicBlock* return_block = schedule_->block(return_block_node);
-    TraceConnect(ret, return_block, NULL);
+    Node* return_control = NodeProperties::GetControlInput(ret);
+    BasicBlock* return_block = FindPredecessorBlock(return_control);
+    TraceConnect(ret, return_block, nullptr);
     schedule_->AddReturn(return_block, ret);
   }
 
+  void ConnectDeoptimize(Node* deopt) {
+    Node* deoptimize_control = NodeProperties::GetControlInput(deopt);
+    BasicBlock* deoptimize_block = FindPredecessorBlock(deoptimize_control);
+    TraceConnect(deopt, deoptimize_block, nullptr);
+    schedule_->AddDeoptimize(deoptimize_block, deopt);
+  }
+
+  void ConnectThrow(Node* thr) {
+    Node* throw_control = NodeProperties::GetControlInput(thr);
+    BasicBlock* throw_block = FindPredecessorBlock(throw_control);
+    TraceConnect(thr, throw_block, nullptr);
+    schedule_->AddThrow(throw_block, thr);
+  }
+
   void TraceConnect(Node* node, BasicBlock* block, BasicBlock* succ) {
-    DCHECK_NE(NULL, block);
-    if (succ == NULL) {
-      Trace("Connect #%d:%s, B%d -> end\n", node->id(), node->op()->mnemonic(),
-            block->id().ToInt());
+    DCHECK_NOT_NULL(block);
+    if (succ == nullptr) {
+      TRACE("Connect #%d:%s, id:%d -> end\n", node->id(),
+            node->op()->mnemonic(), block->id().ToInt());
     } else {
-      Trace("Connect #%d:%s, B%d -> B%d\n", node->id(), node->op()->mnemonic(),
-            block->id().ToInt(), succ->id().ToInt());
+      TRACE("Connect #%d:%s, id:%d -> id:%d\n", node->id(),
+            node->op()->mnemonic(), block->id().ToInt(), succ->id().ToInt());
     }
   }
 
@@ -498,6 +554,7 @@
     DCHECK(control_.empty());
   }
 
+  Zone* zone_;
   Scheduler* scheduler_;
   Schedule* schedule_;
   NodeMarker<bool> queued_;      // Mark indicating whether node is queued.
@@ -510,7 +567,7 @@
 
 
 void Scheduler::BuildCFG() {
-  Trace("--- CREATING CFG -------------------------------------------\n");
+  TRACE("--- CREATING CFG -------------------------------------------\n");
 
   // Instantiate a new control equivalence algorithm for the graph.
   equivalence_ = new (zone_) ControlEquivalence(zone_, graph_);
@@ -545,18 +602,19 @@
   SpecialRPONumberer(Zone* zone, Schedule* schedule)
       : zone_(zone),
         schedule_(schedule),
-        order_(NULL),
-        beyond_end_(NULL),
+        order_(nullptr),
+        beyond_end_(nullptr),
         loops_(zone),
         backedges_(zone),
         stack_(zone),
-        previous_block_count_(0) {}
+        previous_block_count_(0),
+        empty_(0, zone) {}
 
   // Computes the special reverse-post-order for the main control flow graph,
   // that is for the graph spanned between the schedule's start and end blocks.
   void ComputeSpecialRPO() {
     DCHECK(schedule_->end()->SuccessorCount() == 0);
-    DCHECK_EQ(NULL, order_);  // Main order does not exist yet.
+    DCHECK(!order_);  // Main order does not exist yet.
     ComputeAndInsertSpecialRPO(schedule_->start(), schedule_->end());
   }
 
@@ -564,7 +622,7 @@
   // that is for the graph spanned between the given {entry} and {end} blocks,
   // then updates the existing ordering with this new information.
   void UpdateSpecialRPO(BasicBlock* entry, BasicBlock* end) {
-    DCHECK_NE(NULL, order_);  // Main order to be updated is present.
+    DCHECK(order_);  // Main order to be updated is present.
     ComputeAndInsertSpecialRPO(entry, end);
   }
 
@@ -572,7 +630,7 @@
   // numbering for basic blocks into the final schedule.
   void SerializeRPOIntoSchedule() {
     int32_t number = 0;
-    for (BasicBlock* b = order_; b != NULL; b = b->rpo_next()) {
+    for (BasicBlock* b = order_; b != nullptr; b = b->rpo_next()) {
       b->set_rpo_number(number++);
       schedule_->rpo_order()->push_back(b);
     }
@@ -587,6 +645,14 @@
 #endif
   }
 
+  const ZoneVector<BasicBlock*>& GetOutgoingBlocks(BasicBlock* block) {
+    if (HasLoopNumber(block)) {
+      LoopInfo const& loop = loops_[GetLoopNumber(block)];
+      if (loop.outgoing) return *loop.outgoing;
+    }
+    return empty_;
+  }
+
  private:
   typedef std::pair<BasicBlock*, size_t> Backedge;
 
@@ -604,17 +670,18 @@
 
   struct LoopInfo {
     BasicBlock* header;
-    ZoneList<BasicBlock*>* outgoing;
+    ZoneVector<BasicBlock*>* outgoing;
     BitVector* members;
     LoopInfo* prev;
     BasicBlock* end;
     BasicBlock* start;
 
     void AddOutgoing(Zone* zone, BasicBlock* block) {
-      if (outgoing == NULL) {
-        outgoing = new (zone) ZoneList<BasicBlock*>(2, zone);
+      if (outgoing == nullptr) {
+        outgoing = new (zone->New(sizeof(ZoneVector<BasicBlock*>)))
+            ZoneVector<BasicBlock*>(zone);
       }
-      outgoing->Add(block, zone);
+      outgoing->push_back(block);
     }
   };
 
@@ -646,7 +713,7 @@
   // use the schedule's end block in actual control flow (e.g. with end having
   // successors). Once this has been cleaned up we can use the end block here.
   BasicBlock* BeyondEndSentinel() {
-    if (beyond_end_ == NULL) {
+    if (beyond_end_ == nullptr) {
       BasicBlock::Id id = BasicBlock::Id::FromInt(-1);
       beyond_end_ = new (schedule_->zone()) BasicBlock(schedule_->zone(), id);
     }
@@ -710,7 +777,7 @@
 
       // Initialize the "loop stack". Note the entry could be a loop header.
       LoopInfo* loop =
-          HasLoopNumber(entry) ? &loops_[GetLoopNumber(entry)] : NULL;
+          HasLoopNumber(entry) ? &loops_[GetLoopNumber(entry)] : nullptr;
       order = insertion_point;
 
       // Perform an iterative post-order traversal, visiting loop bodies before
@@ -721,7 +788,7 @@
       while (stack_depth > 0) {
         SpecialRPOStackFrame* frame = &stack_[stack_depth - 1];
         BasicBlock* block = frame->block;
-        BasicBlock* succ = NULL;
+        BasicBlock* succ = nullptr;
 
         if (block != end && frame->index < block->SuccessorCount()) {
           // Process the next normal successor.
@@ -731,7 +798,7 @@
           if (block->rpo_number() == kBlockOnStack) {
             // Finish the loop body the first time the header is left on the
             // stack.
-            DCHECK(loop != NULL && loop->header == block);
+            DCHECK(loop != nullptr && loop->header == block);
             loop->start = PushFront(order, block);
             order = loop->end;
             block->set_rpo_number(kBlockVisited2);
@@ -743,23 +810,22 @@
           }
 
           // Use the next outgoing edge if there are any.
-          int outgoing_index =
-              static_cast<int>(frame->index - block->SuccessorCount());
+          size_t outgoing_index = frame->index - block->SuccessorCount();
           LoopInfo* info = &loops_[GetLoopNumber(block)];
           DCHECK(loop != info);
-          if (block != entry && info->outgoing != NULL &&
-              outgoing_index < info->outgoing->length()) {
+          if (block != entry && info->outgoing != nullptr &&
+              outgoing_index < info->outgoing->size()) {
             succ = info->outgoing->at(outgoing_index);
             frame->index++;
           }
         }
 
-        if (succ != NULL) {
+        if (succ != nullptr) {
           // Process the next successor.
           if (succ->rpo_number() == kBlockOnStack) continue;
           if (succ->rpo_number() == kBlockVisited2) continue;
           DCHECK(succ->rpo_number() == kBlockUnvisited2);
-          if (loop != NULL && !loop->members->Contains(succ->id().ToInt())) {
+          if (loop != nullptr && !loop->members->Contains(succ->id().ToInt())) {
             // The successor is not in the current loop or any nested loop.
             // Add it to the outgoing edges of this loop and visit it later.
             loop->AddOutgoing(zone_, succ);
@@ -799,10 +865,10 @@
     }
 
     // Publish new order the first time.
-    if (order_ == NULL) order_ = order;
+    if (order_ == nullptr) order_ = order;
 
     // Compute the correct loop headers and set the correct loop ends.
-    LoopInfo* current_loop = NULL;
+    LoopInfo* current_loop = nullptr;
     BasicBlock* current_header = entry->loop_header();
     int32_t loop_depth = entry->loop_depth();
     if (entry->IsLoopHeader()) --loop_depth;  // Entry might be a loop header.
@@ -813,11 +879,13 @@
       current->set_rpo_number(kBlockUnvisited1);
 
       // Finish the previous loop(s) if we just exited them.
-      while (current_header != NULL && current == current_header->loop_end()) {
+      while (current_header != nullptr &&
+             current == current_header->loop_end()) {
         DCHECK(current_header->IsLoopHeader());
-        DCHECK(current_loop != NULL);
+        DCHECK_NOT_NULL(current_loop);
         current_loop = current_loop->prev;
-        current_header = current_loop == NULL ? NULL : current_loop->header;
+        current_header =
+            current_loop == nullptr ? nullptr : current_loop->header;
         --loop_depth;
       }
       current->set_loop_header(current_header);
@@ -827,20 +895,21 @@
         ++loop_depth;
         current_loop = &loops_[GetLoopNumber(current)];
         BasicBlock* end = current_loop->end;
-        current->set_loop_end(end == NULL ? BeyondEndSentinel() : end);
+        current->set_loop_end(end == nullptr ? BeyondEndSentinel() : end);
         current_header = current_loop->header;
-        Trace("B%d is a loop header, increment loop depth to %d\n",
+        TRACE("id:%d is a loop header, increment loop depth to %d\n",
               current->id().ToInt(), loop_depth);
       }
 
       current->set_loop_depth(loop_depth);
 
-      if (current->loop_header() == NULL) {
-        Trace("B%d is not in a loop (depth == %d)\n", current->id().ToInt(),
+      if (current->loop_header() == nullptr) {
+        TRACE("id:%d is not in a loop (depth == %d)\n", current->id().ToInt(),
               current->loop_depth());
       } else {
-        Trace("B%d has loop header B%d, (depth == %d)\n", current->id().ToInt(),
-              current->loop_header()->id().ToInt(), current->loop_depth());
+        TRACE("id:%d has loop header id:%d, (depth == %d)\n",
+              current->id().ToInt(), current->loop_header()->id().ToInt(),
+              current->loop_depth());
       }
     }
   }
@@ -865,7 +934,7 @@
       BasicBlock* member = backedges->at(i).first;
       BasicBlock* header = member->SuccessorAt(backedges->at(i).second);
       size_t loop_num = GetLoopNumber(header);
-      if (loops_[loop_num].header == NULL) {
+      if (loops_[loop_num].header == nullptr) {
         loops_[loop_num].header = header;
         loops_[loop_num].members = new (zone_)
             BitVector(static_cast<int>(schedule_->BasicBlockCount()), zone_);
@@ -906,30 +975,28 @@
       os << " (";
       for (size_t i = 0; i < loops_.size(); i++) {
         if (i > 0) os << " ";
-        os << "B" << loops_[i].header->id();
+        os << "id:" << loops_[i].header->id();
       }
       os << ")";
     }
     os << ":\n";
 
-    for (BasicBlock* block = order_; block != NULL; block = block->rpo_next()) {
-      BasicBlock::Id bid = block->id();
-      // TODO(jarin,svenpanne): Add formatting here once we have support for
-      // that in streams (we want an equivalent of PrintF("%5d:", x) here).
-      os << "  " << block->rpo_number() << ":";
+    for (BasicBlock* block = order_; block != nullptr;
+         block = block->rpo_next()) {
+      os << std::setw(5) << "B" << block->rpo_number() << ":";
       for (size_t i = 0; i < loops_.size(); i++) {
         bool range = loops_[i].header->LoopContains(block);
         bool membership = loops_[i].header != block && range;
         os << (membership ? " |" : "  ");
         os << (range ? "x" : " ");
       }
-      os << "  B" << bid << ": ";
-      if (block->loop_end() != NULL) {
-        os << " range: [" << block->rpo_number() << ", "
+      os << "  id:" << block->id() << ": ";
+      if (block->loop_end() != nullptr) {
+        os << " range: [B" << block->rpo_number() << ", B"
            << block->loop_end()->rpo_number() << ")";
       }
-      if (block->loop_header() != NULL) {
-        os << " header: B" << block->loop_header()->id();
+      if (block->loop_header() != nullptr) {
+        os << " header: id:" << block->loop_header()->id();
       }
       if (block->loop_depth() > 0) {
         os << " depth: " << block->loop_depth();
@@ -948,10 +1015,10 @@
       BasicBlock* header = loop->header;
       BasicBlock* end = header->loop_end();
 
-      DCHECK(header != NULL);
+      DCHECK_NOT_NULL(header);
       DCHECK(header->rpo_number() >= 0);
       DCHECK(header->rpo_number() < static_cast<int>(order->size()));
-      DCHECK(end != NULL);
+      DCHECK_NOT_NULL(end);
       DCHECK(end->rpo_number() <= static_cast<int>(order->size()));
       DCHECK(end->rpo_number() > header->rpo_number());
       DCHECK(header->loop_header() != header);
@@ -962,7 +1029,7 @@
       DCHECK_EQ(header, block);
       bool end_found;
       while (true) {
-        if (block == NULL || block == loop->end) {
+        if (block == nullptr || block == loop->end) {
           end_found = (loop->end == block);
           break;
         }
@@ -970,7 +1037,7 @@
         DCHECK(block->rpo_number() == links + header->rpo_number());
         links++;
         block = block->rpo_next();
-        DCHECK(links < static_cast<int>(2 * order->size()));  // cycle?
+        DCHECK_LT(links, static_cast<int>(2 * order->size()));  // cycle?
       }
       DCHECK(links > 0);
       DCHECK(links == end->rpo_number() - header->rpo_number());
@@ -978,7 +1045,7 @@
 
       // Check loop depth of the header.
       int loop_depth = 0;
-      for (LoopInfo* outer = loop; outer != NULL; outer = outer->prev) {
+      for (LoopInfo* outer = loop; outer != nullptr; outer = outer->prev) {
         loop_depth++;
       }
       DCHECK_EQ(loop_depth, header->loop_depth());
@@ -1009,6 +1076,7 @@
   ZoneVector<Backedge> backedges_;
   ZoneVector<SpecialRPOStackFrame> stack_;
   size_t previous_block_count_;
+  ZoneVector<BasicBlock*> const empty_;
 };
 
 
@@ -1022,7 +1090,7 @@
 
 
 void Scheduler::ComputeSpecialRPONumbering() {
-  Trace("--- COMPUTING SPECIAL RPO ----------------------------------\n");
+  TRACE("--- COMPUTING SPECIAL RPO ----------------------------------\n");
 
   // Compute the special reverse-post-order for basic blocks.
   special_rpo_ = new (zone_) SpecialRPONumberer(zone_, schedule_);
@@ -1031,31 +1099,32 @@
 
 
 void Scheduler::PropagateImmediateDominators(BasicBlock* block) {
-  for (/*nop*/; block != NULL; block = block->rpo_next()) {
-    BasicBlock::Predecessors::iterator pred = block->predecessors_begin();
-    BasicBlock::Predecessors::iterator end = block->predecessors_end();
+  for (/*nop*/; block != nullptr; block = block->rpo_next()) {
+    auto pred = block->predecessors().begin();
+    auto end = block->predecessors().end();
     DCHECK(pred != end);  // All blocks except start have predecessors.
     BasicBlock* dominator = *pred;
+    bool deferred = dominator->deferred();
     // For multiple predecessors, walk up the dominator tree until a common
     // dominator is found. Visitation order guarantees that all predecessors
     // except for backwards edges have been visited.
     for (++pred; pred != end; ++pred) {
       // Don't examine backwards edges.
       if ((*pred)->dominator_depth() < 0) continue;
-      dominator = GetCommonDominator(dominator, *pred);
+      dominator = BasicBlock::GetCommonDominator(dominator, *pred);
+      deferred = deferred & (*pred)->deferred();
     }
     block->set_dominator(dominator);
     block->set_dominator_depth(dominator->dominator_depth() + 1);
-    // Propagate "deferredness" of the dominator.
-    if (dominator->deferred()) block->set_deferred(true);
-    Trace("Block B%d's idom is B%d, depth = %d\n", block->id().ToInt(),
+    block->set_deferred(deferred | block->deferred());
+    TRACE("Block id:%d's idom is id:%d, depth = %d\n", block->id().ToInt(),
           dominator->id().ToInt(), block->dominator_depth());
   }
 }
 
 
 void Scheduler::GenerateImmediateDominatorTree() {
-  Trace("--- IMMEDIATE BLOCK DOMINATORS -----------------------------\n");
+  TRACE("--- IMMEDIATE BLOCK DOMINATORS -----------------------------\n");
 
   // Seed start block to be the first dominator.
   schedule_->start()->set_dominator_depth(0);
@@ -1069,7 +1138,7 @@
 // Phase 3: Prepare use counts for nodes.
 
 
-class PrepareUsesVisitor : public NullNodeVisitor {
+class PrepareUsesVisitor {
  public:
   explicit PrepareUsesVisitor(Scheduler* scheduler)
       : scheduler_(scheduler), schedule_(scheduler->schedule_) {}
@@ -1080,14 +1149,14 @@
       scheduler_->schedule_root_nodes_.push_back(node);
       if (!schedule_->IsScheduled(node)) {
         // Make sure root nodes are scheduled in their respective blocks.
-        Trace("Scheduling fixed position node #%d:%s\n", node->id(),
+        TRACE("Scheduling fixed position node #%d:%s\n", node->id(),
               node->op()->mnemonic());
         IrOpcode::Value opcode = node->opcode();
         BasicBlock* block =
             opcode == IrOpcode::kParameter
                 ? schedule_->start()
                 : schedule_->block(NodeProperties::GetControlInput(node));
-        DCHECK(block != NULL);
+        DCHECK_NOT_NULL(block);
         schedule_->AddNode(block, node);
       }
     }
@@ -1110,12 +1179,31 @@
 
 
 void Scheduler::PrepareUses() {
-  Trace("--- PREPARE USES -------------------------------------------\n");
+  TRACE("--- PREPARE USES -------------------------------------------\n");
 
-  // Count the uses of every node, it will be used to ensure that all of a
+  // Count the uses of every node, which is used to ensure that all of a
   // node's uses are scheduled before the node itself.
   PrepareUsesVisitor prepare_uses(this);
-  graph_->VisitNodeInputsFromEnd(&prepare_uses);
+
+  // TODO(turbofan): simplify the careful pre/post ordering here.
+  BoolVector visited(graph_->NodeCount(), false, zone_);
+  ZoneStack<Node::InputEdges::iterator> stack(zone_);
+  Node* node = graph_->end();
+  prepare_uses.Pre(node);
+  visited[node->id()] = true;
+  stack.push(node->input_edges().begin());
+  while (!stack.empty()) {
+    Edge edge = *stack.top();
+    Node* node = edge.to();
+    if (visited[node->id()]) {
+      prepare_uses.PostEdge(edge.from(), edge.index(), edge.to());
+      if (++stack.top() == edge.from()->input_edges().end()) stack.pop();
+    } else {
+      prepare_uses.Pre(node);
+      visited[node->id()] = true;
+      if (node->InputCount() > 0) stack.push(node->input_edges().begin());
+    }
+  }
 }
 
 
@@ -1130,8 +1218,8 @@
 
   // Run the schedule early algorithm on a set of fixed root nodes.
   void Run(NodeVector* roots) {
-    for (NodeVectorIter i = roots->begin(); i != roots->end(); ++i) {
-      queue_.push(*i);
+    for (Node* const root : *roots) {
+      queue_.push(root);
       while (!queue_.empty()) {
         VisitNode(queue_.front());
         queue_.pop();
@@ -1148,7 +1236,7 @@
     // Fixed nodes already know their schedule early position.
     if (scheduler_->GetPlacement(node) == Scheduler::kFixed) {
       data->minimum_block_ = schedule_->block(node);
-      Trace("Fixing #%d:%s minimum_block = B%d, dominator_depth = %d\n",
+      TRACE("Fixing #%d:%s minimum_block = id:%d, dominator_depth = %d\n",
             node->id(), node->op()->mnemonic(),
             data->minimum_block_->id().ToInt(),
             data->minimum_block_->dominator_depth());
@@ -1158,10 +1246,9 @@
     if (data->minimum_block_ == schedule_->start()) return;
 
     // Propagate schedule early position.
-    DCHECK(data->minimum_block_ != NULL);
-    Node::Uses uses = node->uses();
-    for (Node::Uses::iterator i = uses.begin(); i != uses.end(); ++i) {
-      PropagateMinimumPositionToNode(data->minimum_block_, *i);
+    DCHECK_NOT_NULL(data->minimum_block_);
+    for (auto use : node->uses()) {
+      PropagateMinimumPositionToNode(data->minimum_block_, use);
     }
   }
 
@@ -1187,7 +1274,7 @@
     if (block->dominator_depth() > data->minimum_block_->dominator_depth()) {
       data->minimum_block_ = block;
       queue_.push(node);
-      Trace("Propagating #%d:%s minimum_block = B%d, dominator_depth = %d\n",
+      TRACE("Propagating #%d:%s minimum_block = id:%d, dominator_depth = %d\n",
             node->id(), node->op()->mnemonic(),
             data->minimum_block_->id().ToInt(),
             data->minimum_block_->dominator_depth());
@@ -1196,7 +1283,7 @@
 
 #if DEBUG
   bool InsideSameDominatorChain(BasicBlock* b1, BasicBlock* b2) {
-    BasicBlock* dominator = scheduler_->GetCommonDominator(b1, b2);
+    BasicBlock* dominator = BasicBlock::GetCommonDominator(b1, b2);
     return dominator == b1 || dominator == b2;
   }
 #endif
@@ -1208,13 +1295,13 @@
 
 
 void Scheduler::ScheduleEarly() {
-  Trace("--- SCHEDULE EARLY -----------------------------------------\n");
+  TRACE("--- SCHEDULE EARLY -----------------------------------------\n");
   if (FLAG_trace_turbo_scheduler) {
-    Trace("roots: ");
+    TRACE("roots: ");
     for (Node* node : schedule_root_nodes_) {
-      Trace("#%d:%s ", node->id(), node->op()->mnemonic());
+      TRACE("#%d:%s ", node->id(), node->op()->mnemonic());
     }
-    Trace("\n");
+    TRACE("\n");
   }
 
   // Compute the minimum block for each node thereby determining the earliest
@@ -1231,12 +1318,15 @@
 class ScheduleLateNodeVisitor {
  public:
   ScheduleLateNodeVisitor(Zone* zone, Scheduler* scheduler)
-      : scheduler_(scheduler), schedule_(scheduler_->schedule_) {}
+      : scheduler_(scheduler),
+        schedule_(scheduler_->schedule_),
+        marked_(scheduler->zone_),
+        marking_queue_(scheduler->zone_) {}
 
   // Run the schedule late algorithm on a set of fixed root nodes.
   void Run(NodeVector* roots) {
-    for (NodeVectorIter i = roots->begin(); i != roots->end(); ++i) {
-      ProcessQueue(*i);
+    for (Node* const root : *roots) {
+      ProcessQueue(root);
     }
   }
 
@@ -1253,10 +1343,11 @@
       if (scheduler_->GetData(node)->unscheduled_count_ != 0) continue;
 
       queue->push(node);
-      while (!queue->empty()) {
-        VisitNode(queue->front());
+      do {
+        Node* const node = queue->front();
         queue->pop();
-      }
+        VisitNode(node);
+      } while (!queue->empty());
     }
   }
 
@@ -1272,86 +1363,213 @@
 
     // Determine the dominating block for all of the uses of this node. It is
     // the latest block that this node can be scheduled in.
-    Trace("Scheduling #%d:%s\n", node->id(), node->op()->mnemonic());
+    TRACE("Scheduling #%d:%s\n", node->id(), node->op()->mnemonic());
     BasicBlock* block = GetCommonDominatorOfUses(node);
     DCHECK_NOT_NULL(block);
 
     // The schedule early block dominates the schedule late block.
     BasicBlock* min_block = scheduler_->GetData(node)->minimum_block_;
-    DCHECK_EQ(min_block, scheduler_->GetCommonDominator(block, min_block));
-    Trace("Schedule late of #%d:%s is B%d at loop depth %d, minimum = B%d\n",
-          node->id(), node->op()->mnemonic(), block->id().ToInt(),
-          block->loop_depth(), min_block->id().ToInt());
+    DCHECK_EQ(min_block, BasicBlock::GetCommonDominator(block, min_block));
+    TRACE(
+        "Schedule late of #%d:%s is id:%d at loop depth %d, minimum = id:%d\n",
+        node->id(), node->op()->mnemonic(), block->id().ToInt(),
+        block->loop_depth(), min_block->id().ToInt());
 
     // Hoist nodes out of loops if possible. Nodes can be hoisted iteratively
     // into enclosing loop pre-headers until they would preceed their schedule
     // early position.
-    BasicBlock* hoist_block = GetPreHeader(block);
-    while (hoist_block != NULL &&
-           hoist_block->dominator_depth() >= min_block->dominator_depth()) {
-      Trace("  hoisting #%d:%s to block B%d\n", node->id(),
-            node->op()->mnemonic(), hoist_block->id().ToInt());
-      DCHECK_LT(hoist_block->loop_depth(), block->loop_depth());
-      block = hoist_block;
-      hoist_block = GetPreHeader(hoist_block);
+    BasicBlock* hoist_block = GetHoistBlock(block);
+    if (hoist_block &&
+        hoist_block->dominator_depth() >= min_block->dominator_depth()) {
+      do {
+        TRACE("  hoisting #%d:%s to block id:%d\n", node->id(),
+              node->op()->mnemonic(), hoist_block->id().ToInt());
+        DCHECK_LT(hoist_block->loop_depth(), block->loop_depth());
+        block = hoist_block;
+        hoist_block = GetHoistBlock(hoist_block);
+      } while (hoist_block &&
+               hoist_block->dominator_depth() >= min_block->dominator_depth());
+    } else if (scheduler_->flags_ & Scheduler::kSplitNodes) {
+      // Split the {node} if beneficial and return the new {block} for it.
+      block = SplitNode(block, node);
     }
 
     // Schedule the node or a floating control structure.
-    if (NodeProperties::IsControl(node)) {
+    if (IrOpcode::IsMergeOpcode(node->opcode())) {
       ScheduleFloatingControl(block, node);
+    } else if (node->opcode() == IrOpcode::kFinishRegion) {
+      ScheduleRegion(block, node);
     } else {
       ScheduleNode(block, node);
     }
   }
 
-  BasicBlock* GetPreHeader(BasicBlock* block) {
-    if (block->IsLoopHeader()) {
-      return block->dominator();
-    } else if (block->loop_header() != NULL) {
-      return block->loop_header()->dominator();
-    } else {
-      return NULL;
+  // Mark {block} and push its non-marked predecessor on the marking queue.
+  void MarkBlock(BasicBlock* block) {
+    DCHECK_LT(block->id().ToSize(), marked_.size());
+    marked_[block->id().ToSize()] = true;
+    for (BasicBlock* pred_block : block->predecessors()) {
+      DCHECK_LT(pred_block->id().ToSize(), marked_.size());
+      if (marked_[pred_block->id().ToSize()]) continue;
+      marking_queue_.push_back(pred_block);
     }
   }
 
-  BasicBlock* GetCommonDominatorOfUses(Node* node) {
-    BasicBlock* block = NULL;
+  BasicBlock* SplitNode(BasicBlock* block, Node* node) {
+    // For now, we limit splitting to pure nodes.
+    if (!node->op()->HasProperty(Operator::kPure)) return block;
+    // TODO(titzer): fix the special case of splitting of projections.
+    if (node->opcode() == IrOpcode::kProjection) return block;
+
+    // The {block} is common dominator of all uses of {node}, so we cannot
+    // split anything unless the {block} has at least two successors.
+    DCHECK_EQ(block, GetCommonDominatorOfUses(node));
+    if (block->SuccessorCount() < 2) return block;
+
+    // Clear marking bits.
+    DCHECK(marking_queue_.empty());
+    std::fill(marked_.begin(), marked_.end(), false);
+    marked_.resize(schedule_->BasicBlockCount() + 1, false);
+
+    // Check if the {node} has uses in {block}.
     for (Edge edge : node->use_edges()) {
       BasicBlock* use_block = GetBlockForUse(edge);
-      block = block == NULL ? use_block : use_block == NULL
-                                              ? block
-                                              : scheduler_->GetCommonDominator(
-                                                    block, use_block);
+      if (use_block == nullptr || marked_[use_block->id().ToSize()]) continue;
+      if (use_block == block) {
+        TRACE("  not splitting #%d:%s, it is used in id:%d\n", node->id(),
+              node->op()->mnemonic(), block->id().ToInt());
+        marking_queue_.clear();
+        return block;
+      }
+      MarkBlock(use_block);
+    }
+
+    // Compute transitive marking closure; a block is marked if all its
+    // successors are marked.
+    do {
+      BasicBlock* top_block = marking_queue_.front();
+      marking_queue_.pop_front();
+      if (marked_[top_block->id().ToSize()]) continue;
+      bool marked = true;
+      for (BasicBlock* successor : top_block->successors()) {
+        if (!marked_[successor->id().ToSize()]) {
+          marked = false;
+          break;
+        }
+      }
+      if (marked) MarkBlock(top_block);
+    } while (!marking_queue_.empty());
+
+    // If the (common dominator) {block} is marked, we know that all paths from
+    // {block} to the end contain at least one use of {node}, and hence there's
+    // no point in splitting the {node} in this case.
+    if (marked_[block->id().ToSize()]) {
+      TRACE("  not splitting #%d:%s, its common dominator id:%d is perfect\n",
+            node->id(), node->op()->mnemonic(), block->id().ToInt());
+      return block;
+    }
+
+    // Split {node} for uses according to the previously computed marking
+    // closure. Every marking partition has a unique dominator, which get's a
+    // copy of the {node} with the exception of the first partition, which get's
+    // the {node} itself.
+    ZoneMap<BasicBlock*, Node*> dominators(scheduler_->zone_);
+    for (Edge edge : node->use_edges()) {
+      BasicBlock* use_block = GetBlockForUse(edge);
+      if (use_block == nullptr) continue;
+      while (marked_[use_block->dominator()->id().ToSize()]) {
+        use_block = use_block->dominator();
+      }
+      auto& use_node = dominators[use_block];
+      if (use_node == nullptr) {
+        if (dominators.size() == 1u) {
+          // Place the {node} at {use_block}.
+          block = use_block;
+          use_node = node;
+          TRACE("  pushing #%d:%s down to id:%d\n", node->id(),
+                node->op()->mnemonic(), block->id().ToInt());
+        } else {
+          // Place a copy of {node} at {use_block}.
+          use_node = CloneNode(node);
+          TRACE("  cloning #%d:%s for id:%d\n", use_node->id(),
+                use_node->op()->mnemonic(), use_block->id().ToInt());
+          scheduler_->schedule_queue_.push(use_node);
+        }
+      }
+      edge.UpdateTo(use_node);
     }
     return block;
   }
 
+  BasicBlock* GetHoistBlock(BasicBlock* block) {
+    if (block->IsLoopHeader()) return block->dominator();
+    // We have to check to make sure that the {block} dominates all
+    // of the outgoing blocks.  If it doesn't, then there is a path
+    // out of the loop which does not execute this {block}, so we
+    // can't hoist operations from this {block} out of the loop, as
+    // that would introduce additional computations.
+    if (BasicBlock* header_block = block->loop_header()) {
+      for (BasicBlock* outgoing_block :
+           scheduler_->special_rpo_->GetOutgoingBlocks(header_block)) {
+        if (BasicBlock::GetCommonDominator(block, outgoing_block) != block) {
+          return nullptr;
+        }
+      }
+      return header_block->dominator();
+    }
+    return nullptr;
+  }
+
+  BasicBlock* GetCommonDominatorOfUses(Node* node) {
+    BasicBlock* block = nullptr;
+    for (Edge edge : node->use_edges()) {
+      BasicBlock* use_block = GetBlockForUse(edge);
+      block = block == nullptr
+                  ? use_block
+                  : use_block == nullptr
+                        ? block
+                        : BasicBlock::GetCommonDominator(block, use_block);
+    }
+    return block;
+  }
+
+  BasicBlock* FindPredecessorBlock(Node* node) {
+    return scheduler_->control_flow_builder_->FindPredecessorBlock(node);
+  }
+
   BasicBlock* GetBlockForUse(Edge edge) {
     Node* use = edge.from();
-    IrOpcode::Value opcode = use->opcode();
-    if (opcode == IrOpcode::kPhi || opcode == IrOpcode::kEffectPhi) {
+    if (IrOpcode::IsPhiOpcode(use->opcode())) {
       // If the use is from a coupled (i.e. floating) phi, compute the common
       // dominator of its uses. This will not recurse more than one level.
       if (scheduler_->GetPlacement(use) == Scheduler::kCoupled) {
-        Trace("  inspecting uses of coupled #%d:%s\n", use->id(),
+        TRACE("  inspecting uses of coupled #%d:%s\n", use->id(),
               use->op()->mnemonic());
         DCHECK_EQ(edge.to(), NodeProperties::GetControlInput(use));
         return GetCommonDominatorOfUses(use);
       }
-      // If the use is from a fixed (i.e. non-floating) phi, use the block
-      // of the corresponding control input to the merge.
+      // If the use is from a fixed (i.e. non-floating) phi, we use the
+      // predecessor block of the corresponding control input to the merge.
       if (scheduler_->GetPlacement(use) == Scheduler::kFixed) {
-        Trace("  input@%d into a fixed phi #%d:%s\n", edge.index(), use->id(),
+        TRACE("  input@%d into a fixed phi #%d:%s\n", edge.index(), use->id(),
               use->op()->mnemonic());
         Node* merge = NodeProperties::GetControlInput(use, 0);
-        opcode = merge->opcode();
-        DCHECK(opcode == IrOpcode::kMerge || opcode == IrOpcode::kLoop);
-        use = NodeProperties::GetControlInput(merge, edge.index());
+        DCHECK(IrOpcode::IsMergeOpcode(merge->opcode()));
+        Node* input = NodeProperties::GetControlInput(merge, edge.index());
+        return FindPredecessorBlock(input);
+      }
+    } else if (IrOpcode::IsMergeOpcode(use->opcode())) {
+      // If the use is from a fixed (i.e. non-floating) merge, we use the
+      // predecessor block of the current input to the merge.
+      if (scheduler_->GetPlacement(use) == Scheduler::kFixed) {
+        TRACE("  input@%d into a fixed merge #%d:%s\n", edge.index(), use->id(),
+              use->op()->mnemonic());
+        return FindPredecessorBlock(edge.to());
       }
     }
     BasicBlock* result = schedule_->block(use);
-    if (result == NULL) return NULL;
-    Trace("  must dominate use #%d:%s in B%d\n", use->id(),
+    if (result == nullptr) return nullptr;
+    TRACE("  must dominate use #%d:%s in id:%d\n", use->id(),
           use->op()->mnemonic(), result->id().ToInt());
     return result;
   }
@@ -1360,25 +1578,70 @@
     scheduler_->FuseFloatingControl(block, node);
   }
 
+  void ScheduleRegion(BasicBlock* block, Node* region_end) {
+    // We only allow regions of instructions connected into a linear
+    // effect chain. The only value allowed to be produced by a node
+    // in the chain must be the value consumed by the FinishRegion node.
+
+    // We schedule back to front; we first schedule FinishRegion.
+    CHECK_EQ(IrOpcode::kFinishRegion, region_end->opcode());
+    ScheduleNode(block, region_end);
+
+    // Schedule the chain.
+    Node* node = NodeProperties::GetEffectInput(region_end);
+    while (node->opcode() != IrOpcode::kBeginRegion) {
+      DCHECK_EQ(0, scheduler_->GetData(node)->unscheduled_count_);
+      DCHECK_EQ(1, node->op()->EffectInputCount());
+      DCHECK_EQ(1, node->op()->EffectOutputCount());
+      DCHECK_EQ(0, node->op()->ControlOutputCount());
+      // The value output (if there is any) must be consumed
+      // by the EndRegion node.
+      DCHECK(node->op()->ValueOutputCount() == 0 ||
+             node == region_end->InputAt(0));
+      ScheduleNode(block, node);
+      node = NodeProperties::GetEffectInput(node);
+    }
+    // Schedule the BeginRegion node.
+    DCHECK_EQ(0, scheduler_->GetData(node)->unscheduled_count_);
+    ScheduleNode(block, node);
+  }
+
   void ScheduleNode(BasicBlock* block, Node* node) {
     schedule_->PlanNode(block, node);
     scheduler_->scheduled_nodes_[block->id().ToSize()].push_back(node);
     scheduler_->UpdatePlacement(node, Scheduler::kScheduled);
   }
 
+  Node* CloneNode(Node* node) {
+    int const input_count = node->InputCount();
+    for (int index = 0; index < input_count; ++index) {
+      Node* const input = node->InputAt(index);
+      scheduler_->IncrementUnscheduledUseCount(input, index, node);
+    }
+    Node* const copy = scheduler_->graph_->CloneNode(node);
+    TRACE(("clone #%d:%s -> #%d\n"), node->id(), node->op()->mnemonic(),
+          copy->id());
+    scheduler_->node_data_.resize(copy->id() + 1,
+                                  scheduler_->DefaultSchedulerData());
+    scheduler_->node_data_[copy->id()] = scheduler_->node_data_[node->id()];
+    return copy;
+  }
+
   Scheduler* scheduler_;
   Schedule* schedule_;
+  BoolVector marked_;
+  ZoneDeque<BasicBlock*> marking_queue_;
 };
 
 
 void Scheduler::ScheduleLate() {
-  Trace("--- SCHEDULE LATE ------------------------------------------\n");
+  TRACE("--- SCHEDULE LATE ------------------------------------------\n");
   if (FLAG_trace_turbo_scheduler) {
-    Trace("roots: ");
+    TRACE("roots: ");
     for (Node* node : schedule_root_nodes_) {
-      Trace("#%d:%s ", node->id(), node->op()->mnemonic());
+      TRACE("#%d:%s ", node->id(), node->op()->mnemonic());
     }
-    Trace("\n");
+    TRACE("\n");
   }
 
   // Schedule: Places nodes in dominator block of all their uses.
@@ -1392,7 +1655,7 @@
 
 
 void Scheduler::SealFinalSchedule() {
-  Trace("--- SEAL FINAL SCHEDULE ------------------------------------\n");
+  TRACE("--- SEAL FINAL SCHEDULE ------------------------------------\n");
 
   // Serialize the assembly order and reverse-post-order numbering.
   special_rpo_->SerializeRPOIntoSchedule();
@@ -1403,8 +1666,8 @@
   for (NodeVector& nodes : scheduled_nodes_) {
     BasicBlock::Id id = BasicBlock::Id::FromInt(block_num++);
     BasicBlock* block = schedule_->GetBlockById(id);
-    for (NodeVectorRIter i = nodes.rbegin(); i != nodes.rend(); ++i) {
-      schedule_->AddNode(block, *i);
+    for (Node* node : base::Reversed(nodes)) {
+      schedule_->AddNode(block, node);
     }
   }
 }
@@ -1414,7 +1677,7 @@
 
 
 void Scheduler::FuseFloatingControl(BasicBlock* block, Node* node) {
-  Trace("--- FUSE FLOATING CONTROL ----------------------------------\n");
+  TRACE("--- FUSE FLOATING CONTROL ----------------------------------\n");
   if (FLAG_trace_turbo_scheduler) {
     OFStream os(stdout);
     os << "Schedule before control flow fusion:\n" << *schedule_;
@@ -1426,9 +1689,9 @@
   // Iterate on phase 2: Compute special RPO and dominator tree.
   special_rpo_->UpdateSpecialRPO(block, schedule_->block(node));
   // TODO(mstarzinger): Currently "iterate on" means "re-run". Fix that.
-  for (BasicBlock* b = block->rpo_next(); b != NULL; b = b->rpo_next()) {
+  for (BasicBlock* b = block->rpo_next(); b != nullptr; b = b->rpo_next()) {
     b->set_dominator_depth(-1);
-    b->set_dominator(NULL);
+    b->set_dominator(nullptr);
   }
   PropagateImmediateDominators(block->rpo_next());
 
@@ -1439,18 +1702,15 @@
   NodeVector propagation_roots(control_flow_builder_->control_);
   for (Node* node : control_flow_builder_->control_) {
     for (Node* use : node->uses()) {
-      if (use->opcode() == IrOpcode::kPhi ||
-          use->opcode() == IrOpcode::kEffectPhi) {
-        propagation_roots.push_back(use);
-      }
+      if (NodeProperties::IsPhi(use)) propagation_roots.push_back(use);
     }
   }
   if (FLAG_trace_turbo_scheduler) {
-    Trace("propagation roots: ");
+    TRACE("propagation roots: ");
     for (Node* node : propagation_roots) {
-      Trace("#%d:%s ", node->id(), node->op()->mnemonic());
+      TRACE("#%d:%s ", node->id(), node->op()->mnemonic());
     }
-    Trace("\n");
+    TRACE("\n");
   }
   ScheduleEarlyNodeVisitor schedule_early_visitor(zone_, this);
   schedule_early_visitor.Run(&propagation_roots);
@@ -1468,12 +1728,12 @@
 
 
 void Scheduler::MovePlannedNodes(BasicBlock* from, BasicBlock* to) {
-  Trace("Move planned nodes from B%d to B%d\n", from->id().ToInt(),
+  TRACE("Move planned nodes from id:%d to id:%d\n", from->id().ToInt(),
         to->id().ToInt());
   NodeVector* nodes = &(scheduled_nodes_[from->id().ToSize()]);
-  for (NodeVectorIter i = nodes->begin(); i != nodes->end(); ++i) {
-    schedule_->SetBlockForNode(to, *i);
-    scheduled_nodes_[to->id().ToSize()].push_back(*i);
+  for (Node* const node : *nodes) {
+    schedule_->SetBlockForNode(to, node);
+    scheduled_nodes_[to->id().ToSize()].push_back(node);
   }
   nodes->clear();
 }
diff --git a/src/compiler/scheduler.h b/src/compiler/scheduler.h
index 9da0b6d..269c271 100644
--- a/src/compiler/scheduler.h
+++ b/src/compiler/scheduler.h
@@ -5,8 +5,8 @@
 #ifndef V8_COMPILER_SCHEDULER_H_
 #define V8_COMPILER_SCHEDULER_H_
 
-#include "src/v8.h"
-
+#include "src/base/flags.h"
+#include "src/compiler/node.h"
 #include "src/compiler/opcodes.h"
 #include "src/compiler/schedule.h"
 #include "src/compiler/zone-pool.h"
@@ -16,17 +16,24 @@
 namespace internal {
 namespace compiler {
 
+// Forward declarations.
 class CFGBuilder;
 class ControlEquivalence;
+class Graph;
 class SpecialRPONumberer;
 
+
 // Computes a schedule from a graph, placing nodes into basic blocks and
 // ordering the basic blocks in the special RPO order.
 class Scheduler {
  public:
+  // Flags that control the mode of operation.
+  enum Flag { kNoFlags = 0u, kSplitNodes = 1u << 1 };
+  typedef base::Flags<Flag> Flags;
+
   // The complete scheduling algorithm. Creates a new schedule and places all
   // nodes from the graph into it.
-  static Schedule* ComputeSchedule(Zone* zone, Graph* graph);
+  static Schedule* ComputeSchedule(Zone* zone, Graph* graph, Flags flags);
 
   // Compute the RPO of blocks in an existing schedule.
   static BasicBlockVector* ComputeSpecialRPO(Zone* zone, Schedule* schedule);
@@ -56,6 +63,7 @@
   Zone* zone_;
   Graph* graph_;
   Schedule* schedule_;
+  Flags flags_;
   NodeVectorVector scheduled_nodes_;     // Per-block list of nodes in reverse.
   NodeVector schedule_root_nodes_;       // Fixed root nodes seed the worklist.
   ZoneQueue<Node*> schedule_queue_;      // Worklist of schedulable nodes.
@@ -64,7 +72,7 @@
   SpecialRPONumberer* special_rpo_;      // Special RPO numbering of blocks.
   ControlEquivalence* equivalence_;      // Control dependence equivalence.
 
-  Scheduler(Zone* zone, Graph* graph, Schedule* schedule);
+  Scheduler(Zone* zone, Graph* graph, Schedule* schedule, Flags flags);
 
   inline SchedulerData DefaultSchedulerData();
   inline SchedulerData* GetData(Node* node);
@@ -76,7 +84,6 @@
   void IncrementUnscheduledUseCount(Node* node, int index, Node* from);
   void DecrementUnscheduledUseCount(Node* node, int index, Node* from);
 
-  BasicBlock* GetCommonDominator(BasicBlock* b1, BasicBlock* b2);
   void PropagateImmediateDominators(BasicBlock* block);
 
   // Phase 1: Build control-flow graph.
@@ -107,6 +114,9 @@
   void MovePlannedNodes(BasicBlock* from, BasicBlock* to);
 };
 
+
+DEFINE_OPERATORS_FOR_FLAGS(Scheduler::Flags)
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/src/compiler/select-lowering.cc b/src/compiler/select-lowering.cc
index edecf58..0e8b36f 100644
--- a/src/compiler/select-lowering.cc
+++ b/src/compiler/select-lowering.cc
@@ -8,6 +8,7 @@
 #include "src/compiler/diamond.h"
 #include "src/compiler/graph.h"
 #include "src/compiler/node.h"
+#include "src/compiler/node-properties.h"
 
 namespace v8 {
 namespace internal {
@@ -51,10 +52,10 @@
   }
 
   // Create a Phi hanging off the previously determined merge.
-  node->set_op(common()->Phi(p.type(), 2));
   node->ReplaceInput(0, vthen);
   node->ReplaceInput(1, velse);
   node->ReplaceInput(2, merge);
+  NodeProperties::ChangeOp(node, common()->Phi(p.representation(), 2));
   return Changed(node);
 }
 
@@ -62,7 +63,7 @@
 bool SelectLowering::ReachableFrom(Node* const sink, Node* const source) {
   // TODO(turbofan): This is probably horribly expensive, and it should be moved
   // into node.h or somewhere else?!
-  Zone zone(graph()->zone()->isolate());
+  Zone zone;
   std::queue<Node*, NodeDeque> queue((NodeDeque(&zone)));
   BoolVector visited(graph()->NodeCount(), false, &zone);
   queue.push(source);
diff --git a/src/compiler/select-lowering.h b/src/compiler/select-lowering.h
index 05ea0e0..5894d35 100644
--- a/src/compiler/select-lowering.h
+++ b/src/compiler/select-lowering.h
@@ -20,12 +20,12 @@
 
 
 // Lowers Select nodes to diamonds.
-class SelectLowering FINAL : public Reducer {
+class SelectLowering final : public Reducer {
  public:
   SelectLowering(Graph* graph, CommonOperatorBuilder* common);
   ~SelectLowering();
 
-  Reduction Reduce(Node* node) OVERRIDE;
+  Reduction Reduce(Node* node) override;
 
  private:
   typedef std::multimap<Node*, Node*, std::less<Node*>,
diff --git a/src/compiler/simplified-lowering.cc b/src/compiler/simplified-lowering.cc
index 1461709..653fea8 100644
--- a/src/compiler/simplified-lowering.cc
+++ b/src/compiler/simplified-lowering.cc
@@ -10,22 +10,25 @@
 #include "src/code-factory.h"
 #include "src/compiler/common-operator.h"
 #include "src/compiler/diamond.h"
-#include "src/compiler/graph-inl.h"
 #include "src/compiler/linkage.h"
 #include "src/compiler/node-matchers.h"
-#include "src/compiler/node-properties-inl.h"
+#include "src/compiler/node-properties.h"
+#include "src/compiler/operator-properties.h"
 #include "src/compiler/representation-change.h"
-#include "src/compiler/simplified-lowering.h"
 #include "src/compiler/simplified-operator.h"
+#include "src/compiler/source-position.h"
 #include "src/objects.h"
+#include "src/type-cache.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
 // Macro for outputting trace information from representation inference.
-#define TRACE(x) \
-  if (FLAG_trace_representation) PrintF x
+#define TRACE(...)                                      \
+  do {                                                  \
+    if (FLAG_trace_representation) PrintF(__VA_ARGS__); \
+  } while (false)
 
 // Representation selection and lowering of {Simplified} operators to machine
 // operators are interwined. We use a fixpoint calculation to compute both the
@@ -54,64 +57,329 @@
 };
 
 
+namespace {
+
+// The {UseInfo} class is used to describe a use of an input of a node.
+//
+// This information is used in two different ways, based on the phase:
+//
+// 1. During propagation, the use info is used to inform the input node
+//    about what part of the input is used (we call this truncation) and what
+//    is the preferred representation.
+//
+// 2. During lowering, the use info is used to properly convert the input
+//    to the preferred representation. The preferred representation might be
+//    insufficient to do the conversion (e.g. word32->float64 conv), so we also
+//    need the signedness information to produce the correct value.
+class UseInfo {
+ public:
+  UseInfo(MachineRepresentation preferred, Truncation truncation)
+      : preferred_(preferred), truncation_(truncation) {}
+  static UseInfo TruncatingWord32() {
+    return UseInfo(MachineRepresentation::kWord32, Truncation::Word32());
+  }
+  static UseInfo TruncatingWord64() {
+    return UseInfo(MachineRepresentation::kWord64, Truncation::Word64());
+  }
+  static UseInfo Bool() {
+    return UseInfo(MachineRepresentation::kBit, Truncation::Bool());
+  }
+  static UseInfo Float32() {
+    return UseInfo(MachineRepresentation::kFloat32, Truncation::Float32());
+  }
+  static UseInfo Float64() {
+    return UseInfo(MachineRepresentation::kFloat64, Truncation::Float64());
+  }
+  static UseInfo PointerInt() {
+    return kPointerSize == 4 ? TruncatingWord32() : TruncatingWord64();
+  }
+  static UseInfo AnyTagged() {
+    return UseInfo(MachineRepresentation::kTagged, Truncation::Any());
+  }
+
+  // Undetermined representation.
+  static UseInfo Any() {
+    return UseInfo(MachineRepresentation::kNone, Truncation::Any());
+  }
+  static UseInfo None() {
+    return UseInfo(MachineRepresentation::kNone, Truncation::None());
+  }
+
+  // Truncation to a representation that is smaller than the preferred
+  // one.
+  static UseInfo Float64TruncatingToWord32() {
+    return UseInfo(MachineRepresentation::kFloat64, Truncation::Word32());
+  }
+  static UseInfo Word64TruncatingToWord32() {
+    return UseInfo(MachineRepresentation::kWord64, Truncation::Word32());
+  }
+  static UseInfo AnyTruncatingToBool() {
+    return UseInfo(MachineRepresentation::kNone, Truncation::Bool());
+  }
+
+  MachineRepresentation preferred() const { return preferred_; }
+  Truncation truncation() const { return truncation_; }
+
+ private:
+  MachineRepresentation preferred_;
+  Truncation truncation_;
+};
+
+
+UseInfo TruncatingUseInfoFromRepresentation(MachineRepresentation rep) {
+  switch (rep) {
+    case MachineRepresentation::kTagged:
+      return UseInfo::AnyTagged();
+    case MachineRepresentation::kFloat64:
+    return UseInfo::Float64();
+    case MachineRepresentation::kFloat32:
+      return UseInfo::Float32();
+    case MachineRepresentation::kWord64:
+    return UseInfo::TruncatingWord64();
+    case MachineRepresentation::kWord8:
+    case MachineRepresentation::kWord16:
+    case MachineRepresentation::kWord32:
+    return UseInfo::TruncatingWord32();
+    case MachineRepresentation::kBit:
+      return UseInfo::Bool();
+    case MachineRepresentation::kNone:
+      break;
+  }
+  UNREACHABLE();
+  return UseInfo::None();
+}
+
+
+UseInfo UseInfoForBasePointer(const FieldAccess& access) {
+  return access.tag() != 0 ? UseInfo::AnyTagged() : UseInfo::PointerInt();
+}
+
+
+UseInfo UseInfoForBasePointer(const ElementAccess& access) {
+  return access.tag() != 0 ? UseInfo::AnyTagged() : UseInfo::PointerInt();
+}
+
+
+#ifdef DEBUG
+// Helpers for monotonicity checking.
+bool MachineRepresentationIsSubtype(MachineRepresentation r1,
+                                    MachineRepresentation r2) {
+  switch (r1) {
+    case MachineRepresentation::kNone:
+      return true;
+    case MachineRepresentation::kBit:
+      return r2 == MachineRepresentation::kBit ||
+             r2 == MachineRepresentation::kTagged;
+    case MachineRepresentation::kWord8:
+      return r2 == MachineRepresentation::kWord8 ||
+             r2 == MachineRepresentation::kWord16 ||
+             r2 == MachineRepresentation::kWord32 ||
+             r2 == MachineRepresentation::kWord64 ||
+             r2 == MachineRepresentation::kFloat32 ||
+             r2 == MachineRepresentation::kFloat64 ||
+             r2 == MachineRepresentation::kTagged;
+    case MachineRepresentation::kWord16:
+      return r2 == MachineRepresentation::kWord16 ||
+             r2 == MachineRepresentation::kWord32 ||
+             r2 == MachineRepresentation::kWord64 ||
+             r2 == MachineRepresentation::kFloat32 ||
+             r2 == MachineRepresentation::kFloat64 ||
+             r2 == MachineRepresentation::kTagged;
+    case MachineRepresentation::kWord32:
+      return r2 == MachineRepresentation::kWord32 ||
+             r2 == MachineRepresentation::kWord64 ||
+             r2 == MachineRepresentation::kFloat64 ||
+             r2 == MachineRepresentation::kTagged;
+    case MachineRepresentation::kWord64:
+      return r2 == MachineRepresentation::kWord64;
+    case MachineRepresentation::kFloat32:
+      return r2 == MachineRepresentation::kFloat32 ||
+             r2 == MachineRepresentation::kFloat64 ||
+             r2 == MachineRepresentation::kTagged;
+    case MachineRepresentation::kFloat64:
+      return r2 == MachineRepresentation::kFloat64 ||
+             r2 == MachineRepresentation::kTagged;
+    case MachineRepresentation::kTagged:
+      return r2 == MachineRepresentation::kTagged;
+  }
+  UNREACHABLE();
+  return false;
+}
+
+
+class InputUseInfos {
+ public:
+  explicit InputUseInfos(Zone* zone) : input_use_infos_(zone) {}
+
+  void SetAndCheckInput(Node* node, int index, UseInfo use_info) {
+    if (input_use_infos_.empty()) {
+      input_use_infos_.resize(node->InputCount(), UseInfo::None());
+    }
+    // Check that the new use informatin is a super-type of the old
+    // one.
+    CHECK(IsUseLessGeneral(input_use_infos_[index], use_info));
+    input_use_infos_[index] = use_info;
+  }
+
+ private:
+  ZoneVector<UseInfo> input_use_infos_;
+
+  static bool IsUseLessGeneral(UseInfo use1, UseInfo use2) {
+    return MachineRepresentationIsSubtype(use1.preferred(), use2.preferred()) &&
+           use1.truncation().IsLessGeneralThan(use2.truncation());
+  }
+};
+
+#endif  // DEBUG
+
+}  // namespace
+
+
 class RepresentationSelector {
  public:
   // Information for each node tracked during the fixpoint.
-  struct NodeInfo {
-    MachineTypeUnion use : 15;     // Union of all usages for the node.
-    bool queued : 1;           // Bookkeeping for the traversal.
-    bool visited : 1;          // Bookkeeping for the traversal.
-    MachineTypeUnion output : 15;  // Output type of the node.
+  class NodeOutputInfo {
+   public:
+    NodeOutputInfo(MachineRepresentation representation, Type* type)
+        : type_(type), representation_(representation) {}
+    NodeOutputInfo()
+        : type_(Type::None()), representation_(MachineRepresentation::kNone) {}
+
+    MachineRepresentation representation() const { return representation_; }
+    Type* type() const { return type_; }
+
+    static NodeOutputInfo None() {
+      return NodeOutputInfo(MachineRepresentation::kNone, Type::None());
+    }
+
+    static NodeOutputInfo Float32() {
+      return NodeOutputInfo(MachineRepresentation::kFloat32, Type::Number());
+    }
+
+    static NodeOutputInfo Float64() {
+      return NodeOutputInfo(MachineRepresentation::kFloat64, Type::Number());
+    }
+
+    static NodeOutputInfo NumberTruncatedToWord32() {
+      return NodeOutputInfo(MachineRepresentation::kWord32, Type::Number());
+    }
+
+    static NodeOutputInfo Int32() {
+      return NodeOutputInfo(MachineRepresentation::kWord32, Type::Signed32());
+    }
+
+    static NodeOutputInfo Uint32() {
+      return NodeOutputInfo(MachineRepresentation::kWord32, Type::Unsigned32());
+    }
+
+    static NodeOutputInfo Bool() {
+      return NodeOutputInfo(MachineRepresentation::kBit, Type::Boolean());
+    }
+
+    static NodeOutputInfo Int64() {
+      // TODO(jarin) Fix once we have a real int64 type.
+      return NodeOutputInfo(MachineRepresentation::kWord64, Type::Internal());
+    }
+
+    static NodeOutputInfo Uint64() {
+      // TODO(jarin) Fix once we have a real uint64 type.
+      return NodeOutputInfo(MachineRepresentation::kWord64, Type::Internal());
+    }
+
+    static NodeOutputInfo AnyTagged() {
+      return NodeOutputInfo(MachineRepresentation::kTagged, Type::Any());
+    }
+
+    static NodeOutputInfo NumberTagged() {
+      return NodeOutputInfo(MachineRepresentation::kTagged, Type::Number());
+    }
+
+    static NodeOutputInfo Pointer() {
+      return NodeOutputInfo(MachineType::PointerRepresentation(), Type::Any());
+    }
+
+   private:
+    Type* type_;
+    MachineRepresentation representation_;
+  };
+
+  class NodeInfo {
+   public:
+    // Adds new use to the node. Returns true if something has changed
+    // and the node has to be requeued.
+    bool AddUse(UseInfo info) {
+      Truncation old_truncation = truncation_;
+      truncation_ = Truncation::Generalize(truncation_, info.truncation());
+      return truncation_ != old_truncation;
+    }
+
+    void set_queued(bool value) { queued_ = value; }
+    bool queued() const { return queued_; }
+    void set_visited() { visited_ = true; }
+    bool visited() const { return visited_; }
+    Truncation truncation() const { return truncation_; }
+    void set_output_type(NodeOutputInfo output) { output_ = output; }
+
+    Type* output_type() const { return output_.type(); }
+    MachineRepresentation representation() const {
+      return output_.representation();
+    }
+
+   private:
+    bool queued_ = false;                  // Bookkeeping for the traversal.
+    bool visited_ = false;                 // Bookkeeping for the traversal.
+    NodeOutputInfo output_;                // Output type and representation.
+    Truncation truncation_ = Truncation::None();  // Information about uses.
   };
 
   RepresentationSelector(JSGraph* jsgraph, Zone* zone,
-                         RepresentationChanger* changer)
+                         RepresentationChanger* changer,
+                         SourcePositionTable* source_positions)
       : jsgraph_(jsgraph),
         count_(jsgraph->graph()->NodeCount()),
-        info_(zone->NewArray<NodeInfo>(count_)),
+        info_(count_, zone),
+#ifdef DEBUG
+        node_input_use_infos_(count_, InputUseInfos(zone), zone),
+#endif
         nodes_(zone),
         replacements_(zone),
         phase_(PROPAGATE),
         changer_(changer),
-        queue_(zone) {
-    memset(info_, 0, sizeof(NodeInfo) * count_);
-
-    Factory* f = zone->isolate()->factory();
-    safe_bit_range_ =
-        Type::Union(Type::Boolean(),
-                    Type::Range(f->NewNumber(0), f->NewNumber(1), zone), zone);
-    safe_int_additive_range_ =
-        Type::Range(f->NewNumber(-std::pow(2.0, 52.0)),
-                    f->NewNumber(std::pow(2.0, 52.0)), zone);
+        queue_(zone),
+        source_positions_(source_positions),
+        type_cache_(TypeCache::Get()) {
   }
 
   void Run(SimplifiedLowering* lowering) {
     // Run propagation phase to a fixpoint.
-    TRACE(("--{Propagation phase}--\n"));
+    TRACE("--{Propagation phase}--\n");
     phase_ = PROPAGATE;
-    Enqueue(jsgraph_->graph()->end());
+    EnqueueInitial(jsgraph_->graph()->end());
     // Process nodes from the queue until it is empty.
     while (!queue_.empty()) {
       Node* node = queue_.front();
       NodeInfo* info = GetInfo(node);
       queue_.pop();
-      info->queued = false;
-      TRACE((" visit #%d: %s\n", node->id(), node->op()->mnemonic()));
-      VisitNode(node, info->use, NULL);
-      TRACE(("  ==> output "));
-      PrintInfo(info->output);
-      TRACE(("\n"));
+      info->set_queued(false);
+      TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic());
+      VisitNode(node, info->truncation(), nullptr);
+      TRACE("  ==> output ");
+      PrintOutputInfo(info);
+      TRACE("\n");
     }
 
     // Run lowering and change insertion phase.
-    TRACE(("--{Simplified lowering phase}--\n"));
+    TRACE("--{Simplified lowering phase}--\n");
     phase_ = LOWER;
     // Process nodes from the collected {nodes_} vector.
     for (NodeVector::iterator i = nodes_.begin(); i != nodes_.end(); ++i) {
       Node* node = *i;
-      TRACE((" visit #%d: %s\n", node->id(), node->op()->mnemonic()));
+      NodeInfo* info = GetInfo(node);
+      TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic());
       // Reuse {VisitNode()} so the representation rules are in one place.
-      VisitNode(node, GetUseInfo(node), lowering);
+      SourcePositionTable::Scope scope(
+          source_positions_, source_positions_->GetSourcePosition(node));
+      VisitNode(node, info->truncation(), lowering);
     }
 
     // Perform the final replacements.
@@ -120,108 +388,181 @@
       Node* node = *i;
       Node* replacement = *(++i);
       node->ReplaceUses(replacement);
+      // We also need to replace the node in the rest of the vector.
+      for (NodeVector::iterator j = i + 1; j != replacements_.end(); ++j) {
+        ++j;
+        if (*j == node) *j = replacement;
+      }
     }
   }
 
-  // Enqueue {node} if the {use} contains new information for that node.
-  // Add {node} to {nodes_} if this is the first time it's been visited.
-  void Enqueue(Node* node, MachineTypeUnion use = 0) {
+  void EnqueueInitial(Node* node) {
+    NodeInfo* info = GetInfo(node);
+    info->set_visited();
+    info->set_queued(true);
+    nodes_.push_back(node);
+    queue_.push(node);
+  }
+
+  // Enqueue {use_node}'s {index} input if the {use} contains new information
+  // for that input node. Add the input to {nodes_} if this is the first time
+  // it's been visited.
+  void EnqueueInput(Node* use_node, int index,
+                    UseInfo use_info = UseInfo::None()) {
+    Node* node = use_node->InputAt(index);
     if (phase_ != PROPAGATE) return;
     NodeInfo* info = GetInfo(node);
-    if (!info->visited) {
+#ifdef DEBUG
+    // Check monotonicity of input requirements.
+    node_input_use_infos_[use_node->id()].SetAndCheckInput(use_node, index,
+                                                           use_info);
+#endif  // DEBUG
+    if (!info->visited()) {
       // First visit of this node.
-      info->visited = true;
-      info->queued = true;
+      info->set_visited();
+      info->set_queued(true);
       nodes_.push_back(node);
       queue_.push(node);
-      TRACE(("  initial: "));
-      info->use |= use;
-      PrintUseInfo(node);
+      TRACE("  initial: ");
+      info->AddUse(use_info);
+      PrintTruncation(info->truncation());
       return;
     }
-    TRACE(("   queue?: "));
-    PrintUseInfo(node);
-    if ((info->use & use) != use) {
+    TRACE("   queue?: ");
+    PrintTruncation(info->truncation());
+    if (info->AddUse(use_info)) {
       // New usage information for the node is available.
-      if (!info->queued) {
+      if (!info->queued()) {
         queue_.push(node);
-        info->queued = true;
-        TRACE(("   added: "));
+        info->set_queued(true);
+        TRACE("   added: ");
       } else {
-        TRACE((" inqueue: "));
+        TRACE(" inqueue: ");
       }
-      info->use |= use;
-      PrintUseInfo(node);
+      PrintTruncation(info->truncation());
     }
   }
 
   bool lower() { return phase_ == LOWER; }
 
-  void Enqueue(Node* node, MachineType use) {
-    Enqueue(node, static_cast<MachineTypeUnion>(use));
-  }
-
-  void SetOutput(Node* node, MachineTypeUnion output) {
-    // Every node should have at most one output representation. Note that
-    // phis can have 0, if they have not been used in a representation-inducing
-    // instruction.
-    DCHECK((output & kRepMask) == 0 ||
-           base::bits::IsPowerOfTwo32(output & kRepMask));
-    GetInfo(node)->output = output;
-  }
-
-  bool BothInputsAre(Node* node, Type* type) {
-    DCHECK_EQ(2, node->InputCount());
-    return NodeProperties::GetBounds(node->InputAt(0)).upper->Is(type) &&
-           NodeProperties::GetBounds(node->InputAt(1)).upper->Is(type);
-  }
-
-  void ProcessTruncateWord32Input(Node* node, int index, MachineTypeUnion use) {
-    Node* input = node->InputAt(index);
-    if (phase_ == PROPAGATE) {
-      // In the propagate phase, propagate the usage information backward.
-      Enqueue(input, use);
-    } else {
-      // In the change phase, insert a change before the use if necessary.
-      MachineTypeUnion output = GetInfo(input)->output;
-      if ((output & (kRepBit | kRepWord8 | kRepWord16 | kRepWord32)) == 0) {
-        // Output representation doesn't match usage.
-        TRACE(("  truncate-to-int32: #%d:%s(@%d #%d:%s) ", node->id(),
-               node->op()->mnemonic(), index, input->id(),
-               input->op()->mnemonic()));
-        TRACE((" from "));
-        PrintInfo(output);
-        TRACE((" to "));
-        PrintInfo(use);
-        TRACE(("\n"));
-        Node* n = changer_->GetTruncatedWord32For(input, output);
-        node->ReplaceInput(index, n);
+  void EnqueueUses(Node* node) {
+    for (Edge edge : node->use_edges()) {
+      if (NodeProperties::IsValueEdge(edge)) {
+        Node* const user = edge.from();
+        if (user->id() < count_) {
+          // New type information for the node is available.
+          NodeInfo* info = GetInfo(user);
+          // Enqueue the node only if we are sure it is reachable from
+          // the end and it has not been queued yet.
+          if (info->visited() && !info->queued()) {
+            queue_.push(user);
+            info->set_queued(true);
+          }
+        }
       }
     }
   }
 
-  void ProcessInput(Node* node, int index, MachineTypeUnion use) {
+  void SetOutputFromMachineType(Node* node, MachineType machine_type) {
+    Type* type = Type::None();
+    switch (machine_type.semantic()) {
+      case MachineSemantic::kNone:
+        type = Type::None();
+        break;
+      case MachineSemantic::kBool:
+        type = Type::Boolean();
+        break;
+      case MachineSemantic::kInt32:
+        type = Type::Signed32();
+        break;
+      case MachineSemantic::kUint32:
+        type = Type::Unsigned32();
+        break;
+      case MachineSemantic::kInt64:
+        // TODO(jarin) Fix once we have proper int64.
+        type = Type::Internal();
+        break;
+      case MachineSemantic::kUint64:
+        // TODO(jarin) Fix once we have proper uint64.
+        type = Type::Internal();
+        break;
+      case MachineSemantic::kNumber:
+        type = Type::Number();
+        break;
+      case MachineSemantic::kAny:
+        type = Type::Any();
+        break;
+    }
+    return SetOutput(node, NodeOutputInfo(machine_type.representation(), type));
+  }
+
+  void SetOutput(Node* node, NodeOutputInfo output_info) {
+    // Every node should have at most one output representation. Note that
+    // phis can have 0, if they have not been used in a representation-inducing
+    // instruction.
+    Type* output_type = output_info.type();
+    if (NodeProperties::IsTyped(node)) {
+      output_type = Type::Intersect(NodeProperties::GetType(node),
+                                    output_info.type(), jsgraph_->zone());
+    }
+    NodeInfo* info = GetInfo(node);
+    DCHECK(info->output_type()->Is(output_type));
+    DCHECK(MachineRepresentationIsSubtype(info->representation(),
+                                          output_info.representation()));
+    if (!output_type->Is(info->output_type()) ||
+        output_info.representation() != info->representation()) {
+      EnqueueUses(node);
+    }
+    info->set_output_type(
+        NodeOutputInfo(output_info.representation(), output_type));
+  }
+
+  bool BothInputsAreSigned32(Node* node) {
+    DCHECK_EQ(2, node->InputCount());
+    return GetInfo(node->InputAt(0))->output_type()->Is(Type::Signed32()) &&
+           GetInfo(node->InputAt(1))->output_type()->Is(Type::Signed32());
+  }
+
+  bool BothInputsAreUnsigned32(Node* node) {
+    DCHECK_EQ(2, node->InputCount());
+    return GetInfo(node->InputAt(0))->output_type()->Is(Type::Unsigned32()) &&
+           GetInfo(node->InputAt(1))->output_type()->Is(Type::Unsigned32());
+  }
+
+  bool BothInputsAre(Node* node, Type* type) {
+    DCHECK_EQ(2, node->InputCount());
+    return GetInfo(node->InputAt(0))->output_type()->Is(type) &&
+           GetInfo(node->InputAt(1))->output_type()->Is(type);
+  }
+
+  void ConvertInput(Node* node, int index, UseInfo use) {
     Node* input = node->InputAt(index);
+    // In the change phase, insert a change before the use if necessary.
+    if (use.preferred() == MachineRepresentation::kNone)
+      return;  // No input requirement on the use.
+    NodeInfo* input_info = GetInfo(input);
+    MachineRepresentation input_rep = input_info->representation();
+    if (input_rep != use.preferred()) {
+      // Output representation doesn't match usage.
+      TRACE("  change: #%d:%s(@%d #%d:%s) ", node->id(), node->op()->mnemonic(),
+            index, input->id(), input->op()->mnemonic());
+      TRACE(" from ");
+      PrintOutputInfo(input_info);
+      TRACE(" to ");
+      PrintUseInfo(use);
+      TRACE("\n");
+      Node* n = changer_->GetRepresentationFor(
+          input, input_info->representation(), input_info->output_type(),
+          use.preferred(), use.truncation());
+      node->ReplaceInput(index, n);
+    }
+  }
+
+  void ProcessInput(Node* node, int index, UseInfo use) {
     if (phase_ == PROPAGATE) {
-      // In the propagate phase, propagate the usage information backward.
-      Enqueue(input, use);
+      EnqueueInput(node, index, use);
     } else {
-      // In the change phase, insert a change before the use if necessary.
-      if ((use & kRepMask) == 0) return;  // No input requirement on the use.
-      MachineTypeUnion output = GetInfo(input)->output;
-      if ((output & kRepMask & use) == 0) {
-        // Output representation doesn't match usage.
-        TRACE(("  change: #%d:%s(@%d #%d:%s) ", node->id(),
-               node->op()->mnemonic(), index, input->id(),
-               input->op()->mnemonic()));
-        TRACE((" from "));
-        PrintInfo(output);
-        TRACE((" to "));
-        PrintInfo(use);
-        TRACE(("\n"));
-        Node* n = changer_->GetRepresentationFor(input, output, use);
-        node->ReplaceInput(index, n);
-      }
+      ConvertInput(node, index, use);
     }
   }
 
@@ -230,175 +571,246 @@
     DCHECK_GE(index, NodeProperties::PastContextIndex(node));
     for (int i = std::max(index, NodeProperties::FirstEffectIndex(node));
          i < NodeProperties::PastEffectIndex(node); ++i) {
-      Enqueue(node->InputAt(i));  // Effect inputs: just visit
+      EnqueueInput(node, i);  // Effect inputs: just visit
     }
     for (int i = std::max(index, NodeProperties::FirstControlIndex(node));
          i < NodeProperties::PastControlIndex(node); ++i) {
-      Enqueue(node->InputAt(i));  // Control inputs: just visit
+      EnqueueInput(node, i);  // Control inputs: just visit
     }
   }
 
   // The default, most general visitation case. For {node}, process all value,
-  // context, effect, and control inputs, assuming that value inputs should have
-  // {kRepTagged} representation and can observe all output values {kTypeAny}.
+  // context, frame state, effect, and control inputs, assuming that value
+  // inputs should have {kRepTagged} representation and can observe all output
+  // values {kTypeAny}.
   void VisitInputs(Node* node) {
-    auto i = node->input_edges().begin();
-    for (int j = node->op()->ValueInputCount(); j > 0; ++i, j--) {
-      ProcessInput(node, (*i).index(), kMachAnyTagged);  // Value inputs
+    int tagged_count = node->op()->ValueInputCount() +
+                       OperatorProperties::GetContextInputCount(node->op());
+    // Visit value and context inputs as tagged.
+    for (int i = 0; i < tagged_count; i++) {
+      ProcessInput(node, i, UseInfo::AnyTagged());
     }
-    for (int j = OperatorProperties::GetContextInputCount(node->op()); j > 0;
-         ++i, j--) {
-      ProcessInput(node, (*i).index(), kMachAnyTagged);  // Context inputs
+    // Only enqueue other inputs (framestates, effects, control).
+    for (int i = tagged_count; i < node->InputCount(); i++) {
+      EnqueueInput(node, i);
     }
-    for (int j = node->op()->EffectInputCount(); j > 0; ++i, j--) {
-      Enqueue((*i).to());  // Effect inputs: just visit
-    }
-    for (int j = node->op()->ControlInputCount(); j > 0; ++i, j--) {
-      Enqueue((*i).to());  // Control inputs: just visit
-    }
-    SetOutput(node, kMachAnyTagged);
   }
 
-  // Helper for binops of the I x I -> O variety.
-  void VisitBinop(Node* node, MachineTypeUnion input_use,
-                  MachineTypeUnion output) {
-    DCHECK_EQ(2, node->InputCount());
-    ProcessInput(node, 0, input_use);
-    ProcessInput(node, 1, input_use);
+  // Helper for binops of the R x L -> O variety.
+  void VisitBinop(Node* node, UseInfo left_use, UseInfo right_use,
+                  NodeOutputInfo output) {
+    DCHECK_EQ(2, node->op()->ValueInputCount());
+    ProcessInput(node, 0, left_use);
+    ProcessInput(node, 1, right_use);
+    for (int i = 2; i < node->InputCount(); i++) {
+      EnqueueInput(node, i);
+    }
     SetOutput(node, output);
   }
 
+  // Helper for binops of the I x I -> O variety.
+  void VisitBinop(Node* node, UseInfo input_use, NodeOutputInfo output) {
+    VisitBinop(node, input_use, input_use, output);
+  }
+
   // Helper for unops of the I -> O variety.
-  void VisitUnop(Node* node, MachineTypeUnion input_use,
-                 MachineTypeUnion output) {
+  void VisitUnop(Node* node, UseInfo input_use, NodeOutputInfo output) {
     DCHECK_EQ(1, node->InputCount());
     ProcessInput(node, 0, input_use);
     SetOutput(node, output);
   }
 
   // Helper for leaf nodes.
-  void VisitLeaf(Node* node, MachineTypeUnion output) {
+  void VisitLeaf(Node* node, NodeOutputInfo output) {
     DCHECK_EQ(0, node->InputCount());
     SetOutput(node, output);
   }
 
   // Helpers for specific types of binops.
   void VisitFloat64Binop(Node* node) {
-    VisitBinop(node, kMachFloat64, kMachFloat64);
+    VisitBinop(node, UseInfo::Float64(), NodeOutputInfo::Float64());
   }
-  void VisitInt32Binop(Node* node) { VisitBinop(node, kMachInt32, kMachInt32); }
+  void VisitInt32Binop(Node* node) {
+    VisitBinop(node, UseInfo::TruncatingWord32(), NodeOutputInfo::Int32());
+  }
+  void VisitWord32TruncatingBinop(Node* node) {
+    VisitBinop(node, UseInfo::TruncatingWord32(),
+               NodeOutputInfo::NumberTruncatedToWord32());
+  }
   void VisitUint32Binop(Node* node) {
-    VisitBinop(node, kMachUint32, kMachUint32);
+    VisitBinop(node, UseInfo::TruncatingWord32(), NodeOutputInfo::Uint32());
   }
-  void VisitInt64Binop(Node* node) { VisitBinop(node, kMachInt64, kMachInt64); }
+  void VisitInt64Binop(Node* node) {
+    VisitBinop(node, UseInfo::TruncatingWord64(), NodeOutputInfo::Int64());
+  }
   void VisitUint64Binop(Node* node) {
-    VisitBinop(node, kMachUint64, kMachUint64);
+    VisitBinop(node, UseInfo::TruncatingWord64(), NodeOutputInfo::Uint64());
   }
-  void VisitFloat64Cmp(Node* node) { VisitBinop(node, kMachFloat64, kRepBit); }
-  void VisitInt32Cmp(Node* node) { VisitBinop(node, kMachInt32, kRepBit); }
-  void VisitUint32Cmp(Node* node) { VisitBinop(node, kMachUint32, kRepBit); }
-  void VisitInt64Cmp(Node* node) { VisitBinop(node, kMachInt64, kRepBit); }
-  void VisitUint64Cmp(Node* node) { VisitBinop(node, kMachUint64, kRepBit); }
+  void VisitFloat64Cmp(Node* node) {
+    VisitBinop(node, UseInfo::Float64(), NodeOutputInfo::Bool());
+  }
+  void VisitInt32Cmp(Node* node) {
+    VisitBinop(node, UseInfo::TruncatingWord32(), NodeOutputInfo::Bool());
+  }
+  void VisitUint32Cmp(Node* node) {
+    VisitBinop(node, UseInfo::TruncatingWord32(), NodeOutputInfo::Bool());
+  }
+  void VisitInt64Cmp(Node* node) {
+    VisitBinop(node, UseInfo::TruncatingWord64(), NodeOutputInfo::Bool());
+  }
+  void VisitUint64Cmp(Node* node) {
+    VisitBinop(node, UseInfo::TruncatingWord64(), NodeOutputInfo::Bool());
+  }
 
   // Infer representation for phi-like nodes.
-  MachineType GetRepresentationForPhi(Node* node, MachineTypeUnion use) {
-    // Phis adapt to the output representation their uses demand.
-    Type* upper = NodeProperties::GetBounds(node).upper;
-    if ((use & kRepMask) == kRepTagged) {
-      // only tagged uses.
-      return kRepTagged;
-    } else if (upper->Is(Type::Integral32())) {
-      // Integer within [-2^31, 2^32[ range.
-      if ((use & kRepMask) == kRepFloat64) {
-        // only float64 uses.
-        return kRepFloat64;
-      } else if (upper->Is(Type::Signed32()) || upper->Is(Type::Unsigned32())) {
-        // multiple uses, but we are within 32 bits range => pick kRepWord32.
-        return kRepWord32;
-      } else if ((use & kRepMask) == kRepWord32 ||
-                 (use & kTypeMask) == kTypeInt32 ||
-                 (use & kTypeMask) == kTypeUint32) {
-        // We only use 32 bits or we use the result consistently.
-        return kRepWord32;
-      } else {
-        return kRepFloat64;
-      }
-    } else if (IsSafeBitOperand(node)) {
-      // multiple uses => pick kRepBit.
-      return kRepBit;
-    } else if (upper->Is(Type::Number())) {
-      // multiple uses => pick kRepFloat64.
-      return kRepFloat64;
+  NodeOutputInfo GetOutputInfoForPhi(Node* node, Truncation use) {
+    // Compute the type.
+    Type* type = GetInfo(node->InputAt(0))->output_type();
+    for (int i = 1; i < node->op()->ValueInputCount(); ++i) {
+      type = Type::Union(type, GetInfo(node->InputAt(i))->output_type(),
+                         jsgraph_->zone());
     }
-    return kRepTagged;
+
+    // Compute the representation.
+    MachineRepresentation rep = MachineRepresentation::kTagged;
+    if (type->Is(Type::None())) {
+      rep = MachineRepresentation::kNone;
+    } else if (type->Is(Type::Signed32()) || type->Is(Type::Unsigned32())) {
+      rep = MachineRepresentation::kWord32;
+    } else if (use.TruncatesToWord32()) {
+      rep = MachineRepresentation::kWord32;
+    } else if (type->Is(Type::Boolean())) {
+      rep = MachineRepresentation::kBit;
+    } else if (type->Is(Type::Number())) {
+      rep = MachineRepresentation::kFloat64;
+    } else if (type->Is(Type::Internal())) {
+      // We mark (u)int64 as Type::Internal.
+      // TODO(jarin) This is a workaround for our lack of (u)int64
+      // types. This can be removed once we can represent (u)int64
+      // unambiguously. (At the moment internal objects, such as the hole,
+      // are also Type::Internal()).
+      bool is_word64 = GetInfo(node->InputAt(0))->representation() ==
+                       MachineRepresentation::kWord64;
+#ifdef DEBUG
+      // Check that all the inputs agree on being Word64.
+      for (int i = 1; i < node->op()->ValueInputCount(); i++) {
+        DCHECK_EQ(is_word64, GetInfo(node->InputAt(i))->representation() ==
+                                 MachineRepresentation::kWord64);
+      }
+#endif
+      rep = is_word64 ? MachineRepresentation::kWord64
+                      : MachineRepresentation::kTagged;
+    }
+    return NodeOutputInfo(rep, type);
   }
 
   // Helper for handling selects.
-  void VisitSelect(Node* node, MachineTypeUnion use,
+  void VisitSelect(Node* node, Truncation truncation,
                    SimplifiedLowering* lowering) {
-    ProcessInput(node, 0, kRepBit);
-    MachineType output = GetRepresentationForPhi(node, use);
+    ProcessInput(node, 0, UseInfo::Bool());
 
-    Type* upper = NodeProperties::GetBounds(node).upper;
-    MachineType output_type =
-        static_cast<MachineType>(changer_->TypeFromUpperBound(upper) | output);
-    SetOutput(node, output_type);
+    NodeOutputInfo output = GetOutputInfoForPhi(node, truncation);
+    SetOutput(node, output);
 
     if (lower()) {
       // Update the select operator.
       SelectParameters p = SelectParametersOf(node->op());
-      MachineType type = static_cast<MachineType>(output_type);
-      if (type != p.type()) {
-        node->set_op(lowering->common()->Select(type, p.hint()));
+      if (output.representation() != p.representation()) {
+        NodeProperties::ChangeOp(node, lowering->common()->Select(
+                                           output.representation(), p.hint()));
       }
-
-      // Convert inputs to the output representation of this select.
-      ProcessInput(node, 1, output_type);
-      ProcessInput(node, 2, output_type);
-    } else {
-      // Propagate {use} of the select to value inputs.
-      MachineType use_type =
-          static_cast<MachineType>((use & kTypeMask) | output);
-      ProcessInput(node, 1, use_type);
-      ProcessInput(node, 2, use_type);
     }
+    // Convert inputs to the output representation of this phi, pass the
+    // truncation truncation along.
+    UseInfo input_use(output.representation(), truncation);
+    ProcessInput(node, 1, input_use);
+    ProcessInput(node, 2, input_use);
   }
 
   // Helper for handling phis.
-  void VisitPhi(Node* node, MachineTypeUnion use,
+  void VisitPhi(Node* node, Truncation truncation,
                 SimplifiedLowering* lowering) {
-    MachineType output = GetRepresentationForPhi(node, use);
-
-    Type* upper = NodeProperties::GetBounds(node).upper;
-    MachineType output_type =
-        static_cast<MachineType>(changer_->TypeFromUpperBound(upper) | output);
-    SetOutput(node, output_type);
+    NodeOutputInfo output = GetOutputInfoForPhi(node, truncation);
+    SetOutput(node, output);
 
     int values = node->op()->ValueInputCount();
-
     if (lower()) {
       // Update the phi operator.
-      MachineType type = static_cast<MachineType>(output_type);
-      if (type != OpParameter<MachineType>(node)) {
-        node->set_op(lowering->common()->Phi(type, values));
-      }
-
-      // Convert inputs to the output representation of this phi.
-      for (Edge const edge : node->input_edges()) {
-        // TODO(titzer): it'd be nice to have distinguished edge kinds here.
-        ProcessInput(node, edge.index(), values > 0 ? output_type : 0);
-        values--;
-      }
-    } else {
-      // Propagate {use} of the phi to value inputs, and 0 to control.
-      MachineType use_type =
-          static_cast<MachineType>((use & kTypeMask) | output);
-      for (Edge const edge : node->input_edges()) {
-        // TODO(titzer): it'd be nice to have distinguished edge kinds here.
-        ProcessInput(node, edge.index(), values > 0 ? use_type : 0);
-        values--;
+      if (output.representation() != PhiRepresentationOf(node->op())) {
+        NodeProperties::ChangeOp(
+            node, lowering->common()->Phi(output.representation(), values));
       }
     }
+
+    // Convert inputs to the output representation of this phi, pass the
+    // truncation truncation along.
+    UseInfo input_use(output.representation(), truncation);
+    for (int i = 0; i < node->InputCount(); i++) {
+      ProcessInput(node, i, i < values ? input_use : UseInfo::None());
+    }
+  }
+
+  void VisitCall(Node* node, SimplifiedLowering* lowering) {
+    const CallDescriptor* desc = OpParameter<const CallDescriptor*>(node->op());
+    const MachineSignature* sig = desc->GetMachineSignature();
+    int params = static_cast<int>(sig->parameter_count());
+    // Propagate representation information from call descriptor.
+    for (int i = 0; i < node->InputCount(); i++) {
+      if (i == 0) {
+        // The target of the call.
+        ProcessInput(node, i, UseInfo::None());
+      } else if ((i - 1) < params) {
+        ProcessInput(node, i, TruncatingUseInfoFromRepresentation(
+                                  sig->GetParam(i - 1).representation()));
+      } else {
+        ProcessInput(node, i, UseInfo::None());
+      }
+    }
+
+    if (sig->return_count() > 0) {
+      SetOutputFromMachineType(node, desc->GetMachineSignature()->GetReturn());
+    } else {
+      SetOutput(node, NodeOutputInfo::AnyTagged());
+    }
+  }
+
+  MachineSemantic DeoptValueSemanticOf(Type* type) {
+    CHECK(!type->Is(Type::None()));
+    // We only need signedness to do deopt correctly.
+    if (type->Is(Type::Signed32())) {
+      return MachineSemantic::kInt32;
+    } else if (type->Is(Type::Unsigned32())) {
+      return MachineSemantic::kUint32;
+    } else {
+      return MachineSemantic::kAny;
+    }
+  }
+
+  void VisitStateValues(Node* node) {
+    if (phase_ == PROPAGATE) {
+      for (int i = 0; i < node->InputCount(); i++) {
+        EnqueueInput(node, i, UseInfo::Any());
+      }
+    } else {
+      Zone* zone = jsgraph_->zone();
+      ZoneVector<MachineType>* types =
+          new (zone->New(sizeof(ZoneVector<MachineType>)))
+              ZoneVector<MachineType>(node->InputCount(), zone);
+      for (int i = 0; i < node->InputCount(); i++) {
+        NodeInfo* input_info = GetInfo(node->InputAt(i));
+        MachineType machine_type(
+            input_info->representation(),
+            DeoptValueSemanticOf(input_info->output_type()));
+        DCHECK(machine_type.representation() !=
+                   MachineRepresentation::kWord32 ||
+               machine_type.semantic() == MachineSemantic::kInt32 ||
+               machine_type.semantic() == MachineSemantic::kUint32);
+        (*types)[i] = machine_type;
+      }
+      NodeProperties::ChangeOp(node,
+                               jsgraph_->common()->TypedStateValues(types));
+    }
+    SetOutput(node, NodeOutputInfo::AnyTagged());
   }
 
   const Operator* Int32Op(Node* node) {
@@ -413,60 +825,9 @@
     return changer_->Float64OperatorFor(node->opcode());
   }
 
-  bool CanLowerToInt32Binop(Node* node, MachineTypeUnion use) {
-    return BothInputsAre(node, Type::Signed32()) && !CanObserveNonInt32(use);
-  }
-
-  bool IsSafeBitOperand(Node* node) {
-    Type* type = NodeProperties::GetBounds(node).upper;
-    return type->Is(safe_bit_range_);
-  }
-
-  bool IsSafeIntAdditiveOperand(Node* node) {
-    Type* type = NodeProperties::GetBounds(node).upper;
-    // TODO(jarin): Unfortunately, bitset types are not subtypes of larger
-    // range types, so we have to explicitly check for Integral32 here
-    // (in addition to the safe integer range). Once we fix subtyping for
-    // ranges, we should simplify this.
-    return type->Is(safe_int_additive_range_) || type->Is(Type::Integral32());
-  }
-
-  bool CanLowerToInt32AdditiveBinop(Node* node, MachineTypeUnion use) {
-    return IsSafeIntAdditiveOperand(node->InputAt(0)) &&
-           IsSafeIntAdditiveOperand(node->InputAt(1)) &&
-           !CanObserveNonInt32(use);
-  }
-
-  bool CanLowerToUint32Binop(Node* node, MachineTypeUnion use) {
-    return BothInputsAre(node, Type::Unsigned32()) && !CanObserveNonUint32(use);
-  }
-
-  bool CanLowerToUint32AdditiveBinop(Node* node, MachineTypeUnion use) {
-    return IsSafeIntAdditiveOperand(node->InputAt(0)) &&
-           IsSafeIntAdditiveOperand(node->InputAt(1)) &&
-           !CanObserveNonUint32(use);
-  }
-
-  bool CanObserveNonInt32(MachineTypeUnion use) {
-    return (use & (kTypeUint32 | kTypeNumber | kTypeAny)) != 0;
-  }
-
-  bool CanObserveMinusZero(MachineTypeUnion use) {
-    // TODO(turbofan): technically Uint32 cannot observe minus zero either.
-    return (use & (kTypeUint32 | kTypeNumber | kTypeAny)) != 0;
-  }
-
-  bool CanObserveNaN(MachineTypeUnion use) {
-    return (use & (kTypeNumber | kTypeAny)) != 0;
-  }
-
-  bool CanObserveNonUint32(MachineTypeUnion use) {
-    return (use & (kTypeInt32 | kTypeNumber | kTypeAny)) != 0;
-  }
-
   // Dispatching routine for visiting the node {node} with the usage {use}.
   // Depending on the operator, propagate new usage info to the inputs.
-  void VisitNode(Node* node, MachineTypeUnion use,
+  void VisitNode(Node* node, Truncation truncation,
                  SimplifiedLowering* lowering) {
     switch (node->opcode()) {
       //------------------------------------------------------------------
@@ -474,43 +835,43 @@
       //------------------------------------------------------------------
       case IrOpcode::kStart:
       case IrOpcode::kDead:
-        return VisitLeaf(node, 0);
+        return VisitLeaf(node, NodeOutputInfo::None());
       case IrOpcode::kParameter: {
         // TODO(titzer): use representation from linkage.
-        Type* upper = NodeProperties::GetBounds(node).upper;
-        ProcessInput(node, 0, 0);
-        SetOutput(node, kRepTagged | changer_->TypeFromUpperBound(upper));
+        Type* type = NodeProperties::GetType(node);
+        ProcessInput(node, 0, UseInfo::None());
+        SetOutput(node, NodeOutputInfo(MachineRepresentation::kTagged, type));
         return;
       }
       case IrOpcode::kInt32Constant:
-        return VisitLeaf(node, kRepWord32);
+        return VisitLeaf(node, NodeOutputInfo::Int32());
       case IrOpcode::kInt64Constant:
-        return VisitLeaf(node, kRepWord64);
+        return VisitLeaf(node, NodeOutputInfo::Int64());
+      case IrOpcode::kFloat32Constant:
+        return VisitLeaf(node, NodeOutputInfo::Float32());
       case IrOpcode::kFloat64Constant:
-        return VisitLeaf(node, kRepFloat64);
+        return VisitLeaf(node, NodeOutputInfo::Float64());
       case IrOpcode::kExternalConstant:
-        return VisitLeaf(node, kMachPtr);
+        return VisitLeaf(node, NodeOutputInfo::Pointer());
       case IrOpcode::kNumberConstant:
-        return VisitLeaf(node, kRepTagged);
+        return VisitLeaf(node, NodeOutputInfo::NumberTagged());
       case IrOpcode::kHeapConstant:
-        return VisitLeaf(node, kRepTagged);
-
-      case IrOpcode::kEnd:
-      case IrOpcode::kIfTrue:
-      case IrOpcode::kIfFalse:
-      case IrOpcode::kReturn:
-      case IrOpcode::kMerge:
-      case IrOpcode::kThrow:
-        return VisitInputs(node);  // default visit for all node inputs.
+        return VisitLeaf(node, NodeOutputInfo::AnyTagged());
 
       case IrOpcode::kBranch:
-        ProcessInput(node, 0, kRepBit);
-        Enqueue(NodeProperties::GetControlInput(node, 0));
+        ProcessInput(node, 0, UseInfo::Bool());
+        EnqueueInput(node, NodeProperties::FirstControlIndex(node));
+        break;
+      case IrOpcode::kSwitch:
+        ProcessInput(node, 0, UseInfo::TruncatingWord32());
+        EnqueueInput(node, NodeProperties::FirstControlIndex(node));
         break;
       case IrOpcode::kSelect:
-        return VisitSelect(node, use, lowering);
+        return VisitSelect(node, truncation, lowering);
       case IrOpcode::kPhi:
-        return VisitPhi(node, use, lowering);
+        return VisitPhi(node, truncation, lowering);
+      case IrOpcode::kCall:
+        return VisitCall(node, lowering);
 
 //------------------------------------------------------------------
 // JavaScript operators.
@@ -524,67 +885,45 @@
         JS_OP_LIST(DEFINE_JS_CASE)
 #undef DEFINE_JS_CASE
         VisitInputs(node);
-        return SetOutput(node, kRepTagged);
+        return SetOutput(node, NodeOutputInfo::AnyTagged());
 
       //------------------------------------------------------------------
       // Simplified operators.
       //------------------------------------------------------------------
-      case IrOpcode::kAnyToBoolean: {
-        if (IsSafeBitOperand(node->InputAt(0))) {
-          VisitUnop(node, kRepBit, kRepBit);
-          if (lower()) DeferReplacement(node, node->InputAt(0));
-        } else {
-          VisitUnop(node, kMachAnyTagged, kTypeBool | kRepTagged);
-          if (lower()) {
-            // AnyToBoolean(x) => Call(ToBooleanStub, x, no-context)
-            Operator::Properties properties = node->op()->properties();
-            Callable callable = CodeFactory::ToBoolean(
-                jsgraph_->isolate(), ToBooleanStub::RESULT_AS_ODDBALL);
-            CallDescriptor::Flags flags = CallDescriptor::kPatchableCallSite;
-            CallDescriptor* desc = Linkage::GetStubCallDescriptor(
-                callable.descriptor(), 0, flags, properties, jsgraph_->zone());
-            node->set_op(jsgraph_->common()->Call(desc));
-            node->InsertInput(jsgraph_->zone(), 0,
-                              jsgraph_->HeapConstant(callable.code()));
-            node->AppendInput(jsgraph_->zone(), jsgraph_->NoContextConstant());
-          }
-        }
-        break;
-      }
       case IrOpcode::kBooleanNot: {
         if (lower()) {
-          MachineTypeUnion input = GetInfo(node->InputAt(0))->output;
-          if (input & kRepBit) {
+          NodeInfo* input_info = GetInfo(node->InputAt(0));
+          if (input_info->representation() == MachineRepresentation::kBit) {
             // BooleanNot(x: kRepBit) => Word32Equal(x, #0)
-            node->set_op(lowering->machine()->Word32Equal());
             node->AppendInput(jsgraph_->zone(), jsgraph_->Int32Constant(0));
+            NodeProperties::ChangeOp(node, lowering->machine()->Word32Equal());
           } else {
             // BooleanNot(x: kRepTagged) => WordEqual(x, #false)
-            node->set_op(lowering->machine()->WordEqual());
             node->AppendInput(jsgraph_->zone(), jsgraph_->FalseConstant());
+            NodeProperties::ChangeOp(node, lowering->machine()->WordEqual());
           }
         } else {
           // No input representation requirement; adapt during lowering.
-          ProcessInput(node, 0, kTypeBool);
-          SetOutput(node, kRepBit);
+          ProcessInput(node, 0, UseInfo::AnyTruncatingToBool());
+          SetOutput(node, NodeOutputInfo::Bool());
         }
         break;
       }
       case IrOpcode::kBooleanToNumber: {
         if (lower()) {
-          MachineTypeUnion input = GetInfo(node->InputAt(0))->output;
-          if (input & kRepBit) {
+          NodeInfo* input_info = GetInfo(node->InputAt(0));
+          if (input_info->representation() == MachineRepresentation::kBit) {
             // BooleanToNumber(x: kRepBit) => x
             DeferReplacement(node, node->InputAt(0));
           } else {
             // BooleanToNumber(x: kRepTagged) => WordEqual(x, #true)
-            node->set_op(lowering->machine()->WordEqual());
             node->AppendInput(jsgraph_->zone(), jsgraph_->TrueConstant());
+            NodeProperties::ChangeOp(node, lowering->machine()->WordEqual());
           }
         } else {
           // No input representation requirement; adapt during lowering.
-          ProcessInput(node, 0, kTypeBool);
-          SetOutput(node, kMachInt32);
+          ProcessInput(node, 0, UseInfo::AnyTruncatingToBool());
+          SetOutput(node, NodeOutputInfo::Int32());
         }
         break;
       }
@@ -592,288 +931,319 @@
       case IrOpcode::kNumberLessThan:
       case IrOpcode::kNumberLessThanOrEqual: {
         // Number comparisons reduce to integer comparisons for integer inputs.
-        if (BothInputsAre(node, Type::Signed32())) {
+        if (BothInputsAreSigned32(node)) {
           // => signed Int32Cmp
           VisitInt32Cmp(node);
-          if (lower()) node->set_op(Int32Op(node));
-        } else if (BothInputsAre(node, Type::Unsigned32())) {
+          if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
+        } else if (BothInputsAreUnsigned32(node)) {
           // => unsigned Int32Cmp
           VisitUint32Cmp(node);
-          if (lower()) node->set_op(Uint32Op(node));
+          if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node));
         } else {
           // => Float64Cmp
           VisitFloat64Cmp(node);
-          if (lower()) node->set_op(Float64Op(node));
+          if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
         }
         break;
       }
       case IrOpcode::kNumberAdd:
       case IrOpcode::kNumberSubtract: {
-        // Add and subtract reduce to Int32Add/Sub if the inputs
-        // are already integers and all uses are truncating.
-        if (CanLowerToInt32Binop(node, use)) {
+        if (BothInputsAre(node, Type::Signed32()) &&
+            NodeProperties::GetType(node)->Is(Type::Signed32())) {
+          // int32 + int32 = int32
           // => signed Int32Add/Sub
           VisitInt32Binop(node);
-          if (lower()) node->set_op(Int32Op(node));
-        } else if (CanLowerToInt32AdditiveBinop(node, use)) {
-          // => signed Int32Add/Sub, truncating inputs
-          ProcessTruncateWord32Input(node, 0, kTypeInt32);
-          ProcessTruncateWord32Input(node, 1, kTypeInt32);
-          SetOutput(node, kMachInt32);
-          if (lower()) node->set_op(Int32Op(node));
-        } else if (CanLowerToUint32Binop(node, use)) {
-          // => unsigned Int32Add/Sub
-          VisitUint32Binop(node);
-          if (lower()) node->set_op(Uint32Op(node));
-        } else if (CanLowerToUint32AdditiveBinop(node, use)) {
-          // => signed Int32Add/Sub, truncating inputs
-          ProcessTruncateWord32Input(node, 0, kTypeUint32);
-          ProcessTruncateWord32Input(node, 1, kTypeUint32);
-          SetOutput(node, kMachUint32);
-          if (lower()) node->set_op(Uint32Op(node));
+          if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
+        } else if (BothInputsAre(node, type_cache_.kAdditiveSafeInteger) &&
+                   truncation.TruncatesToWord32()) {
+          // safe-int + safe-int = x (truncated to int32)
+          // => signed Int32Add/Sub (truncated)
+          VisitWord32TruncatingBinop(node);
+          if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
         } else {
           // => Float64Add/Sub
           VisitFloat64Binop(node);
-          if (lower()) node->set_op(Float64Op(node));
+          if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
         }
         break;
       }
       case IrOpcode::kNumberMultiply: {
-        NumberMatcher right(node->InputAt(1));
-        if (right.IsInRange(-1048576, 1048576)) {  // must fit double mantissa.
-          if (CanLowerToInt32Binop(node, use)) {
-            // => signed Int32Mul
+        if (BothInputsAreSigned32(node)) {
+          if (NodeProperties::GetType(node)->Is(Type::Signed32())) {
+            // Multiply reduces to Int32Mul if the inputs and the output
+            // are integers.
             VisitInt32Binop(node);
-            if (lower()) node->set_op(Int32Op(node));
+            if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
+            break;
+          }
+          if (truncation.TruncatesToWord32() &&
+              NodeProperties::GetType(node)->Is(type_cache_.kSafeInteger)) {
+            // Multiply reduces to Int32Mul if the inputs are integers,
+            // the uses are truncating and the result is in the safe
+            // integer range.
+            VisitWord32TruncatingBinop(node);
+            if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
             break;
           }
         }
         // => Float64Mul
         VisitFloat64Binop(node);
-        if (lower()) node->set_op(Float64Op(node));
+        if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
         break;
       }
       case IrOpcode::kNumberDivide: {
-        if (CanLowerToInt32Binop(node, use)) {
+        if (BothInputsAreSigned32(node)) {
+          if (NodeProperties::GetType(node)->Is(Type::Signed32())) {
           // => signed Int32Div
           VisitInt32Binop(node);
           if (lower()) DeferReplacement(node, lowering->Int32Div(node));
           break;
+          }
+          if (truncation.TruncatesToWord32()) {
+            // => signed Int32Div
+            VisitWord32TruncatingBinop(node);
+            if (lower()) DeferReplacement(node, lowering->Int32Div(node));
+            break;
+          }
         }
-        if (BothInputsAre(node, Type::Unsigned32()) && !CanObserveNaN(use)) {
+        if (BothInputsAreUnsigned32(node) && truncation.TruncatesToWord32()) {
           // => unsigned Uint32Div
-          VisitUint32Binop(node);
+          VisitWord32TruncatingBinop(node);
           if (lower()) DeferReplacement(node, lowering->Uint32Div(node));
           break;
         }
         // => Float64Div
         VisitFloat64Binop(node);
-        if (lower()) node->set_op(Float64Op(node));
+        if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
         break;
       }
       case IrOpcode::kNumberModulus: {
-        if (CanLowerToInt32Binop(node, use)) {
-          // => signed Int32Mod
-          VisitInt32Binop(node);
-          if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
-          break;
+        if (BothInputsAreSigned32(node)) {
+          if (NodeProperties::GetType(node)->Is(Type::Signed32())) {
+            // => signed Int32Mod
+            VisitInt32Binop(node);
+            if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
+            break;
+          }
+          if (truncation.TruncatesToWord32()) {
+            // => signed Int32Mod
+            VisitWord32TruncatingBinop(node);
+            if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
+            break;
+          }
         }
-        if (BothInputsAre(node, Type::Unsigned32()) && !CanObserveNaN(use)) {
+        if (BothInputsAreUnsigned32(node) && truncation.TruncatesToWord32()) {
           // => unsigned Uint32Mod
-          VisitUint32Binop(node);
+          VisitWord32TruncatingBinop(node);
           if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
           break;
         }
         // => Float64Mod
         VisitFloat64Binop(node);
-        if (lower()) node->set_op(Float64Op(node));
+        if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
         break;
       }
-      case IrOpcode::kNumberToInt32: {
-        MachineTypeUnion use_rep = use & kRepMask;
-        Node* input = node->InputAt(0);
-        Type* in_upper = NodeProperties::GetBounds(input).upper;
-        MachineTypeUnion in = GetInfo(input)->output;
-        if (in_upper->Is(Type::Signed32())) {
-          // If the input has type int32, pass through representation.
-          VisitUnop(node, kTypeInt32 | use_rep, kTypeInt32 | use_rep);
-          if (lower()) DeferReplacement(node, node->InputAt(0));
-        } else if ((in & kTypeMask) == kTypeUint32 ||
-                   in_upper->Is(Type::Unsigned32())) {
-          // Just change representation if necessary.
-          VisitUnop(node, kTypeUint32 | kRepWord32, kTypeInt32 | kRepWord32);
-          if (lower()) DeferReplacement(node, node->InputAt(0));
-        } else if ((in & kTypeMask) == kTypeInt32 ||
-                   (in & kRepMask) == kRepWord32) {
-          // Just change representation if necessary.
-          VisitUnop(node, kTypeInt32 | kRepWord32, kTypeInt32 | kRepWord32);
-          if (lower()) DeferReplacement(node, node->InputAt(0));
-        } else {
-          // Require the input in float64 format and perform truncation.
-          // TODO(turbofan): avoid a truncation with a smi check.
-          VisitUnop(node, kTypeInt32 | kRepFloat64, kTypeInt32 | kRepWord32);
-          if (lower())
-            node->set_op(lowering->machine()->TruncateFloat64ToInt32());
+      case IrOpcode::kNumberBitwiseOr:
+      case IrOpcode::kNumberBitwiseXor:
+      case IrOpcode::kNumberBitwiseAnd: {
+        VisitInt32Binop(node);
+        if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
+        break;
+      }
+      case IrOpcode::kNumberShiftLeft: {
+        Type* rhs_type = GetInfo(node->InputAt(1))->output_type();
+        VisitBinop(node, UseInfo::TruncatingWord32(),
+                   UseInfo::TruncatingWord32(), NodeOutputInfo::Int32());
+        if (lower()) {
+          lowering->DoShift(node, lowering->machine()->Word32Shl(), rhs_type);
         }
         break;
       }
+      case IrOpcode::kNumberShiftRight: {
+        Type* rhs_type = GetInfo(node->InputAt(1))->output_type();
+        VisitBinop(node, UseInfo::TruncatingWord32(),
+                   UseInfo::TruncatingWord32(), NodeOutputInfo::Int32());
+        if (lower()) {
+          lowering->DoShift(node, lowering->machine()->Word32Sar(), rhs_type);
+        }
+        break;
+      }
+      case IrOpcode::kNumberShiftRightLogical: {
+        Type* rhs_type = GetInfo(node->InputAt(1))->output_type();
+        VisitBinop(node, UseInfo::TruncatingWord32(),
+                   UseInfo::TruncatingWord32(), NodeOutputInfo::Uint32());
+        if (lower()) {
+          lowering->DoShift(node, lowering->machine()->Word32Shr(), rhs_type);
+        }
+        break;
+      }
+      case IrOpcode::kNumberToInt32: {
+        // Just change representation if necessary.
+        VisitUnop(node, UseInfo::TruncatingWord32(), NodeOutputInfo::Int32());
+        if (lower()) DeferReplacement(node, node->InputAt(0));
+        break;
+      }
       case IrOpcode::kNumberToUint32: {
-        MachineTypeUnion use_rep = use & kRepMask;
-        Node* input = node->InputAt(0);
-        Type* in_upper = NodeProperties::GetBounds(input).upper;
-        MachineTypeUnion in = GetInfo(input)->output;
-        if (in_upper->Is(Type::Unsigned32())) {
-          // If the input has type uint32, pass through representation.
-          VisitUnop(node, kTypeUint32 | use_rep, kTypeUint32 | use_rep);
-          if (lower()) DeferReplacement(node, node->InputAt(0));
-        } else if ((in & kTypeMask) == kTypeUint32 ||
-                   in_upper->Is(Type::Unsigned32())) {
-          // Just change representation if necessary.
-          VisitUnop(node, kTypeUint32 | kRepWord32, kTypeUint32 | kRepWord32);
-          if (lower()) DeferReplacement(node, node->InputAt(0));
-        } else if ((in & kTypeMask) == kTypeInt32 ||
-                   (in & kRepMask) == kRepWord32) {
-          // Just change representation if necessary.
-          VisitUnop(node, kTypeInt32 | kRepWord32, kTypeUint32 | kRepWord32);
-          if (lower()) DeferReplacement(node, node->InputAt(0));
-        } else {
-          // Require the input in float64 format and perform truncation.
-          // TODO(turbofan): avoid a truncation with a smi check.
-          VisitUnop(node, kTypeUint32 | kRepFloat64, kTypeUint32 | kRepWord32);
-          if (lower())
-            node->set_op(lowering->machine()->TruncateFloat64ToInt32());
+        // Just change representation if necessary.
+        VisitUnop(node, UseInfo::TruncatingWord32(), NodeOutputInfo::Uint32());
+        if (lower()) DeferReplacement(node, node->InputAt(0));
+        break;
+      }
+      case IrOpcode::kNumberIsHoleNaN: {
+        VisitUnop(node, UseInfo::Float64(), NodeOutputInfo::Bool());
+        if (lower()) {
+          // NumberIsHoleNaN(x) => Word32Equal(Float64ExtractLowWord32(x),
+          //                                   #HoleNaNLower32)
+          node->ReplaceInput(0,
+                             jsgraph_->graph()->NewNode(
+                                 lowering->machine()->Float64ExtractLowWord32(),
+                                 node->InputAt(0)));
+          node->AppendInput(jsgraph_->zone(),
+                            jsgraph_->Int32Constant(kHoleNanLower32));
+          NodeProperties::ChangeOp(node, jsgraph_->machine()->Word32Equal());
+        }
+        break;
+      }
+      case IrOpcode::kPlainPrimitiveToNumber: {
+        VisitUnop(node, UseInfo::AnyTagged(), NodeOutputInfo::NumberTagged());
+        if (lower()) {
+          // PlainPrimitiveToNumber(x) => Call(ToNumberStub, x, no-context)
+          Operator::Properties properties = node->op()->properties();
+          Callable callable = CodeFactory::ToNumber(jsgraph_->isolate());
+          CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
+          CallDescriptor* desc = Linkage::GetStubCallDescriptor(
+              jsgraph_->isolate(), jsgraph_->zone(), callable.descriptor(), 0,
+              flags, properties);
+          node->InsertInput(jsgraph_->zone(), 0,
+                            jsgraph_->HeapConstant(callable.code()));
+          node->AppendInput(jsgraph_->zone(), jsgraph_->NoContextConstant());
+          NodeProperties::ChangeOp(node, jsgraph_->common()->Call(desc));
         }
         break;
       }
       case IrOpcode::kReferenceEqual: {
-        VisitBinop(node, kMachAnyTagged, kRepBit);
-        if (lower()) node->set_op(lowering->machine()->WordEqual());
+        VisitBinop(node, UseInfo::AnyTagged(), NodeOutputInfo::Bool());
+        if (lower()) {
+          NodeProperties::ChangeOp(node, lowering->machine()->WordEqual());
+        }
         break;
       }
       case IrOpcode::kStringEqual: {
-        VisitBinop(node, kMachAnyTagged, kRepBit);
+        VisitBinop(node, UseInfo::AnyTagged(), NodeOutputInfo::Bool());
         if (lower()) lowering->DoStringEqual(node);
         break;
       }
       case IrOpcode::kStringLessThan: {
-        VisitBinop(node, kMachAnyTagged, kRepBit);
+        VisitBinop(node, UseInfo::AnyTagged(), NodeOutputInfo::Bool());
         if (lower()) lowering->DoStringLessThan(node);
         break;
       }
       case IrOpcode::kStringLessThanOrEqual: {
-        VisitBinop(node, kMachAnyTagged, kRepBit);
+        VisitBinop(node, UseInfo::AnyTagged(), NodeOutputInfo::Bool());
         if (lower()) lowering->DoStringLessThanOrEqual(node);
         break;
       }
-      case IrOpcode::kStringAdd: {
-        VisitBinop(node, kMachAnyTagged, kMachAnyTagged);
-        if (lower()) lowering->DoStringAdd(node);
+      case IrOpcode::kAllocate: {
+        ProcessInput(node, 0, UseInfo::AnyTagged());
+        ProcessRemainingInputs(node, 1);
+        SetOutput(node, NodeOutputInfo::AnyTagged());
         break;
       }
       case IrOpcode::kLoadField: {
         FieldAccess access = FieldAccessOf(node->op());
-        ProcessInput(node, 0, changer_->TypeForBasePointer(access));
+        ProcessInput(node, 0, UseInfoForBasePointer(access));
         ProcessRemainingInputs(node, 1);
-        SetOutput(node, access.machine_type);
-        if (lower()) lowering->DoLoadField(node);
+        SetOutputFromMachineType(node, access.machine_type);
         break;
       }
       case IrOpcode::kStoreField: {
         FieldAccess access = FieldAccessOf(node->op());
-        ProcessInput(node, 0, changer_->TypeForBasePointer(access));
-        ProcessInput(node, 1, access.machine_type);
+        ProcessInput(node, 0, UseInfoForBasePointer(access));
+        ProcessInput(node, 1, TruncatingUseInfoFromRepresentation(
+                                  access.machine_type.representation()));
         ProcessRemainingInputs(node, 2);
-        SetOutput(node, 0);
-        if (lower()) lowering->DoStoreField(node);
+        SetOutput(node, NodeOutputInfo::None());
         break;
       }
       case IrOpcode::kLoadBuffer: {
         BufferAccess access = BufferAccessOf(node->op());
-        ProcessInput(node, 0, kMachPtr);    // buffer
-        ProcessInput(node, 1, kMachInt32);  // offset
-        ProcessInput(node, 2, kMachInt32);  // length
+        ProcessInput(node, 0, UseInfo::PointerInt());        // buffer
+        ProcessInput(node, 1, UseInfo::TruncatingWord32());  // offset
+        ProcessInput(node, 2, UseInfo::TruncatingWord32());  // length
         ProcessRemainingInputs(node, 3);
-        // Tagged overrides everything if we have to do a typed array bounds
-        // check, because we may need to return undefined then.
-        MachineType output_type;
-        if (use & kRepTagged) {
-          output_type = kMachAnyTagged;
-        } else if (use & kRepFloat64) {
-          if (access.machine_type() & kRepFloat32) {
-            output_type = access.machine_type();
+
+        NodeOutputInfo output_info;
+        if (truncation.TruncatesUndefinedToZeroOrNaN()) {
+          if (truncation.TruncatesNaNToZero()) {
+            // If undefined is truncated to a non-NaN number, we can use
+            // the load's representation.
+            output_info = NodeOutputInfo(access.machine_type().representation(),
+                                         NodeProperties::GetType(node));
           } else {
-            output_type = kMachFloat64;
+            // If undefined is truncated to a number, but the use can
+            // observe NaN, we need to output at least the float32
+            // representation.
+            if (access.machine_type().representation() ==
+                MachineRepresentation::kFloat32) {
+              output_info =
+                  NodeOutputInfo(access.machine_type().representation(),
+                                 NodeProperties::GetType(node));
+            } else {
+              output_info = NodeOutputInfo::Float64();
+            }
           }
-        } else if (use & kRepFloat32) {
-          output_type = kMachFloat32;
         } else {
-          output_type = access.machine_type();
+          // If undefined is not truncated away, we need to have the tagged
+          // representation.
+          output_info = NodeOutputInfo::AnyTagged();
         }
-        SetOutput(node, output_type);
-        if (lower()) lowering->DoLoadBuffer(node, output_type, changer_);
+        SetOutput(node, output_info);
+        if (lower())
+          lowering->DoLoadBuffer(node, output_info.representation(), changer_);
         break;
       }
       case IrOpcode::kStoreBuffer: {
         BufferAccess access = BufferAccessOf(node->op());
-        ProcessInput(node, 0, kMachPtr);               // buffer
-        ProcessInput(node, 1, kMachInt32);             // offset
-        ProcessInput(node, 2, kMachInt32);             // length
-        ProcessInput(node, 3, access.machine_type());  // value
+        ProcessInput(node, 0, UseInfo::PointerInt());        // buffer
+        ProcessInput(node, 1, UseInfo::TruncatingWord32());  // offset
+        ProcessInput(node, 2, UseInfo::TruncatingWord32());  // length
+        ProcessInput(node, 3,
+                     TruncatingUseInfoFromRepresentation(
+                         access.machine_type().representation()));  // value
         ProcessRemainingInputs(node, 4);
-        SetOutput(node, 0);
+        SetOutput(node, NodeOutputInfo::None());
         if (lower()) lowering->DoStoreBuffer(node);
         break;
       }
       case IrOpcode::kLoadElement: {
         ElementAccess access = ElementAccessOf(node->op());
-        ProcessInput(node, 0, changer_->TypeForBasePointer(access));  // base
-        ProcessInput(node, 1, kMachInt32);                            // index
+        ProcessInput(node, 0, UseInfoForBasePointer(access));  // base
+        ProcessInput(node, 1, UseInfo::TruncatingWord32());    // index
         ProcessRemainingInputs(node, 2);
-        SetOutput(node, access.machine_type);
-        if (lower()) lowering->DoLoadElement(node);
+        SetOutputFromMachineType(node, access.machine_type);
         break;
       }
       case IrOpcode::kStoreElement: {
         ElementAccess access = ElementAccessOf(node->op());
-        ProcessInput(node, 0, changer_->TypeForBasePointer(access));  // base
-        ProcessInput(node, 1, kMachInt32);                            // index
-        ProcessInput(node, 2, access.machine_type);                   // value
+        ProcessInput(node, 0, UseInfoForBasePointer(access));  // base
+        ProcessInput(node, 1, UseInfo::TruncatingWord32());    // index
+        ProcessInput(node, 2,
+                     TruncatingUseInfoFromRepresentation(
+                         access.machine_type.representation()));  // value
         ProcessRemainingInputs(node, 3);
-        SetOutput(node, 0);
-        if (lower()) lowering->DoStoreElement(node);
+        SetOutput(node, NodeOutputInfo::None());
+        break;
+      }
+      case IrOpcode::kObjectIsNumber: {
+        ProcessInput(node, 0, UseInfo::AnyTagged());
+        SetOutput(node, NodeOutputInfo::Bool());
+        if (lower()) lowering->DoObjectIsNumber(node);
         break;
       }
       case IrOpcode::kObjectIsSmi: {
-        ProcessInput(node, 0, kMachAnyTagged);
-        SetOutput(node, kRepBit | kTypeBool);
-        if (lower()) {
-          Node* is_tagged = jsgraph_->graph()->NewNode(
-              jsgraph_->machine()->WordAnd(), node->InputAt(0),
-              jsgraph_->Int32Constant(static_cast<int>(kSmiTagMask)));
-          Node* is_smi = jsgraph_->graph()->NewNode(
-              jsgraph_->machine()->WordEqual(), is_tagged,
-              jsgraph_->Int32Constant(kSmiTag));
-          DeferReplacement(node, is_smi);
-        }
-        break;
-      }
-      case IrOpcode::kObjectIsNonNegativeSmi: {
-        ProcessInput(node, 0, kMachAnyTagged);
-        SetOutput(node, kRepBit | kTypeBool);
-        if (lower()) {
-          Node* is_tagged = jsgraph_->graph()->NewNode(
-              jsgraph_->machine()->WordAnd(), node->InputAt(0),
-              jsgraph_->Int32Constant(static_cast<int>(kSmiTagMask)));
-          Node* is_smi = jsgraph_->graph()->NewNode(
-              jsgraph_->machine()->WordEqual(), is_tagged,
-              jsgraph_->Int32Constant(kSmiTag));
-          Node* is_non_neg = jsgraph_->graph()->NewNode(
-              jsgraph_->machine()->IntLessThanOrEqual(),
-              jsgraph_->Int32Constant(0), node->InputAt(0));
-          Node* is_non_neg_smi = jsgraph_->graph()->NewNode(
-              jsgraph_->machine()->Word32And(), is_smi, is_non_neg);
-          DeferReplacement(node, is_non_neg_smi);
-        }
+        ProcessInput(node, 0, UseInfo::AnyTagged());
+        SetOutput(node, NodeOutputInfo::Bool());
+        if (lower()) lowering->DoObjectIsSmi(node);
         break;
       }
 
@@ -881,29 +1251,31 @@
       // Machine-level operators.
       //------------------------------------------------------------------
       case IrOpcode::kLoad: {
-        // TODO(titzer): machine loads/stores need to know BaseTaggedness!?
-        MachineTypeUnion tBase = kRepTagged | kMachPtr;
-        LoadRepresentation rep = OpParameter<LoadRepresentation>(node);
-        ProcessInput(node, 0, tBase);   // pointer or object
-        ProcessInput(node, 1, kMachInt32);  // index
+        // TODO(jarin) Eventually, we should get rid of all machine stores
+        // from the high-level phases, then this becomes UNREACHABLE.
+        LoadRepresentation rep = LoadRepresentationOf(node->op());
+        ProcessInput(node, 0, UseInfo::AnyTagged());   // tagged pointer
+        ProcessInput(node, 1, UseInfo::PointerInt());  // index
         ProcessRemainingInputs(node, 2);
-        SetOutput(node, rep);
+        SetOutputFromMachineType(node, rep);
         break;
       }
       case IrOpcode::kStore: {
-        // TODO(titzer): machine loads/stores need to know BaseTaggedness!?
-        MachineTypeUnion tBase = kRepTagged | kMachPtr;
-        StoreRepresentation rep = OpParameter<StoreRepresentation>(node);
-        ProcessInput(node, 0, tBase);   // pointer or object
-        ProcessInput(node, 1, kMachInt32);  // index
-        ProcessInput(node, 2, rep.machine_type());
+        // TODO(jarin) Eventually, we should get rid of all machine stores
+        // from the high-level phases, then this becomes UNREACHABLE.
+        StoreRepresentation rep = StoreRepresentationOf(node->op());
+        ProcessInput(node, 0, UseInfo::AnyTagged());   // tagged pointer
+        ProcessInput(node, 1, UseInfo::PointerInt());  // index
+        ProcessInput(node, 2,
+                     TruncatingUseInfoFromRepresentation(rep.representation()));
         ProcessRemainingInputs(node, 3);
-        SetOutput(node, 0);
+        SetOutput(node, NodeOutputInfo::None());
         break;
       }
       case IrOpcode::kWord32Shr:
         // We output unsigned int32 for shift right because JavaScript.
-        return VisitBinop(node, kMachUint32, kMachUint32);
+        return VisitBinop(node, UseInfo::TruncatingWord32(),
+                          NodeOutputInfo::Uint32());
       case IrOpcode::kWord32And:
       case IrOpcode::kWord32Or:
       case IrOpcode::kWord32Xor:
@@ -912,9 +1284,15 @@
         // We use signed int32 as the output type for these word32 operations,
         // though the machine bits are the same for either signed or unsigned,
         // because JavaScript considers the result from these operations signed.
-        return VisitBinop(node, kRepWord32, kRepWord32 | kTypeInt32);
+        return VisitBinop(node, UseInfo::TruncatingWord32(),
+                          NodeOutputInfo::Int32());
       case IrOpcode::kWord32Equal:
-        return VisitBinop(node, kRepWord32, kRepBit);
+        return VisitBinop(node, UseInfo::TruncatingWord32(),
+                          NodeOutputInfo::Bool());
+
+      case IrOpcode::kWord32Clz:
+        return VisitUnop(node, UseInfo::TruncatingWord32(),
+                         NodeOutputInfo::Uint32());
 
       case IrOpcode::kInt32Add:
       case IrOpcode::kInt32Sub:
@@ -958,222 +1336,187 @@
       case IrOpcode::kWord64Shl:
       case IrOpcode::kWord64Shr:
       case IrOpcode::kWord64Sar:
-        return VisitBinop(node, kRepWord64, kRepWord64);
+        return VisitBinop(node, UseInfo::TruncatingWord64(),
+                          NodeOutputInfo::Int64());
       case IrOpcode::kWord64Equal:
-        return VisitBinop(node, kRepWord64, kRepBit);
+        return VisitBinop(node, UseInfo::TruncatingWord64(),
+                          NodeOutputInfo::Bool());
 
       case IrOpcode::kChangeInt32ToInt64:
-        return VisitUnop(node, kTypeInt32 | kRepWord32,
-                         kTypeInt32 | kRepWord64);
+        return VisitUnop(
+            node, UseInfo::TruncatingWord32(),
+            NodeOutputInfo(MachineRepresentation::kWord64, Type::Signed32()));
       case IrOpcode::kChangeUint32ToUint64:
-        return VisitUnop(node, kTypeUint32 | kRepWord32,
-                         kTypeUint32 | kRepWord64);
+        return VisitUnop(
+            node, UseInfo::TruncatingWord32(),
+            NodeOutputInfo(MachineRepresentation::kWord64, Type::Unsigned32()));
       case IrOpcode::kTruncateFloat64ToFloat32:
-        return VisitUnop(node, kTypeNumber | kRepFloat64,
-                         kTypeNumber | kRepFloat32);
+        return VisitUnop(node, UseInfo::Float64(), NodeOutputInfo::Float32());
+      case IrOpcode::kTruncateFloat64ToInt32:
+        return VisitUnop(node, UseInfo::Float64(), NodeOutputInfo::Int32());
       case IrOpcode::kTruncateInt64ToInt32:
         // TODO(titzer): Is kTypeInt32 correct here?
-        return VisitUnop(node, kTypeInt32 | kRepWord64,
-                         kTypeInt32 | kRepWord32);
+        return VisitUnop(node, UseInfo::Word64TruncatingToWord32(),
+                         NodeOutputInfo::Int32());
 
       case IrOpcode::kChangeFloat32ToFloat64:
-        return VisitUnop(node, kTypeNumber | kRepFloat32,
-                         kTypeNumber | kRepFloat64);
+        return VisitUnop(node, UseInfo::Float32(), NodeOutputInfo::Float64());
       case IrOpcode::kChangeInt32ToFloat64:
-        return VisitUnop(node, kTypeInt32 | kRepWord32,
-                         kTypeInt32 | kRepFloat64);
+        return VisitUnop(
+            node, UseInfo::TruncatingWord32(),
+            NodeOutputInfo(MachineRepresentation::kFloat64, Type::Signed32()));
       case IrOpcode::kChangeUint32ToFloat64:
-        return VisitUnop(node, kTypeUint32 | kRepWord32,
-                         kTypeUint32 | kRepFloat64);
+        return VisitUnop(node, UseInfo::TruncatingWord32(),
+                         NodeOutputInfo(MachineRepresentation::kFloat64,
+                                        Type::Unsigned32()));
       case IrOpcode::kChangeFloat64ToInt32:
-        return VisitUnop(node, kTypeInt32 | kRepFloat64,
-                         kTypeInt32 | kRepWord32);
+        return VisitUnop(node, UseInfo::Float64TruncatingToWord32(),
+                         NodeOutputInfo::Int32());
       case IrOpcode::kChangeFloat64ToUint32:
-        return VisitUnop(node, kTypeUint32 | kRepFloat64,
-                         kTypeUint32 | kRepWord32);
+        return VisitUnop(node, UseInfo::Float64TruncatingToWord32(),
+                         NodeOutputInfo::Uint32());
 
       case IrOpcode::kFloat64Add:
       case IrOpcode::kFloat64Sub:
       case IrOpcode::kFloat64Mul:
       case IrOpcode::kFloat64Div:
       case IrOpcode::kFloat64Mod:
+      case IrOpcode::kFloat64Min:
         return VisitFloat64Binop(node);
+      case IrOpcode::kFloat64Abs:
       case IrOpcode::kFloat64Sqrt:
-      case IrOpcode::kFloat64Floor:
-      case IrOpcode::kFloat64Ceil:
+      case IrOpcode::kFloat64RoundDown:
       case IrOpcode::kFloat64RoundTruncate:
       case IrOpcode::kFloat64RoundTiesAway:
-        return VisitUnop(node, kMachFloat64, kMachFloat64);
+        return VisitUnop(node, UseInfo::Float64(), NodeOutputInfo::Float64());
       case IrOpcode::kFloat64Equal:
       case IrOpcode::kFloat64LessThan:
       case IrOpcode::kFloat64LessThanOrEqual:
         return VisitFloat64Cmp(node);
+      case IrOpcode::kFloat64ExtractLowWord32:
+      case IrOpcode::kFloat64ExtractHighWord32:
+        return VisitUnop(node, UseInfo::Float64(), NodeOutputInfo::Int32());
+      case IrOpcode::kFloat64InsertLowWord32:
+      case IrOpcode::kFloat64InsertHighWord32:
+        return VisitBinop(node, UseInfo::Float64(), UseInfo::TruncatingWord32(),
+                          NodeOutputInfo::Float64());
       case IrOpcode::kLoadStackPointer:
-        return VisitLeaf(node, kMachPtr);
+      case IrOpcode::kLoadFramePointer:
+        return VisitLeaf(node, NodeOutputInfo::Pointer());
       case IrOpcode::kStateValues:
-        for (int i = 0; i < node->InputCount(); i++) {
-          ProcessInput(node, i, kTypeAny);
-        }
-        SetOutput(node, kMachAnyTagged);
+        VisitStateValues(node);
         break;
       default:
         VisitInputs(node);
+        // Assume the output is tagged.
+        SetOutput(node, NodeOutputInfo::AnyTagged());
         break;
     }
   }
 
   void DeferReplacement(Node* node, Node* replacement) {
-    if (FLAG_trace_representation) {
-      TRACE(("defer replacement #%d:%s with #%d:%s\n", node->id(),
-             node->op()->mnemonic(), replacement->id(),
-             replacement->op()->mnemonic()));
-    }
-    if (replacement->id() < count_) {
-      // Replace with a previously existing node eagerly.
+    TRACE("defer replacement #%d:%s with #%d:%s\n", node->id(),
+          node->op()->mnemonic(), replacement->id(),
+          replacement->op()->mnemonic());
+
+    if (replacement->id() < count_ &&
+        GetInfo(node)->output_type()->Is(GetInfo(replacement)->output_type())) {
+      // Replace with a previously existing node eagerly only if the type is the
+      // same.
       node->ReplaceUses(replacement);
     } else {
       // Otherwise, we are replacing a node with a representation change.
       // Such a substitution must be done after all lowering is done, because
-      // new nodes do not have {NodeInfo} entries, and that would confuse
-      // the representation change insertion for uses of it.
+      // changing the type could confuse the representation change
+      // insertion for uses of the node.
       replacements_.push_back(node);
       replacements_.push_back(replacement);
     }
-    // TODO(titzer) node->RemoveAllInputs();  // Node is now dead.
+    node->NullAllInputs();  // Node is now dead.
   }
 
-  void PrintUseInfo(Node* node) {
-    TRACE(("#%d:%-20s ", node->id(), node->op()->mnemonic()));
-    PrintInfo(GetUseInfo(node));
-    TRACE(("\n"));
-  }
-
-  void PrintInfo(MachineTypeUnion info) {
+  void PrintOutputInfo(NodeInfo* info) {
     if (FLAG_trace_representation) {
       OFStream os(stdout);
-      os << static_cast<MachineType>(info);
+      os << info->representation() << " (";
+      info->output_type()->PrintTo(os, Type::SEMANTIC_DIM);
+      os << ")";
+    }
+  }
+
+  void PrintRepresentation(MachineRepresentation rep) {
+    if (FLAG_trace_representation) {
+      OFStream os(stdout);
+      os << rep;
+    }
+  }
+
+  void PrintTruncation(Truncation truncation) {
+    if (FLAG_trace_representation) {
+      OFStream os(stdout);
+      os << truncation.description();
+    }
+  }
+
+  void PrintUseInfo(UseInfo info) {
+    if (FLAG_trace_representation) {
+      OFStream os(stdout);
+      os << info.preferred() << ":" << info.truncation().description();
     }
   }
 
  private:
   JSGraph* jsgraph_;
-  int count_;                       // number of nodes in the graph
-  NodeInfo* info_;                  // node id -> usage information
+  size_t const count_;              // number of nodes in the graph
+  ZoneVector<NodeInfo> info_;       // node id -> usage information
+#ifdef DEBUG
+  ZoneVector<InputUseInfos> node_input_use_infos_;  // Debug information about
+                                                    // requirements on inputs.
+#endif                                              // DEBUG
   NodeVector nodes_;                // collected nodes
   NodeVector replacements_;         // replacements to be done after lowering
   Phase phase_;                     // current phase of algorithm
   RepresentationChanger* changer_;  // for inserting representation changes
   ZoneQueue<Node*> queue_;          // queue for traversing the graph
-  Type* safe_bit_range_;
-  Type* safe_int_additive_range_;
+  // TODO(danno): RepresentationSelector shouldn't know anything about the
+  // source positions table, but must for now since there currently is no other
+  // way to pass down source position information to nodes created during
+  // lowering. Once this phase becomes a vanilla reducer, it should get source
+  // position information via the SourcePositionWrapper like all other reducers.
+  SourcePositionTable* source_positions_;
+  TypeCache const& type_cache_;
 
   NodeInfo* GetInfo(Node* node) {
     DCHECK(node->id() >= 0);
     DCHECK(node->id() < count_);
     return &info_[node->id()];
   }
-
-  MachineTypeUnion GetUseInfo(Node* node) { return GetInfo(node)->use; }
 };
 
 
-Node* SimplifiedLowering::IsTagged(Node* node) {
-  // TODO(titzer): factor this out to a TaggingScheme abstraction.
-  STATIC_ASSERT(kSmiTagMask == 1);  // Only works if tag is the low bit.
-  return graph()->NewNode(machine()->WordAnd(), node,
-                          jsgraph()->Int32Constant(kSmiTagMask));
-}
+SimplifiedLowering::SimplifiedLowering(JSGraph* jsgraph, Zone* zone,
+                                       SourcePositionTable* source_positions)
+    : jsgraph_(jsgraph),
+      zone_(zone),
+      type_cache_(TypeCache::Get()),
+      source_positions_(source_positions) {}
 
 
 void SimplifiedLowering::LowerAllNodes() {
-  SimplifiedOperatorBuilder simplified(graph()->zone());
-  RepresentationChanger changer(jsgraph(), &simplified,
-                                graph()->zone()->isolate());
-  RepresentationSelector selector(jsgraph(), zone_, &changer);
+  RepresentationChanger changer(jsgraph(), jsgraph()->isolate());
+  RepresentationSelector selector(jsgraph(), zone_, &changer,
+                                  source_positions_);
   selector.Run(this);
 }
 
 
-Node* SimplifiedLowering::Untag(Node* node) {
-  // TODO(titzer): factor this out to a TaggingScheme abstraction.
-  Node* shift_amount = jsgraph()->Int32Constant(kSmiTagSize + kSmiShiftSize);
-  return graph()->NewNode(machine()->WordSar(), node, shift_amount);
-}
-
-
-Node* SimplifiedLowering::SmiTag(Node* node) {
-  // TODO(titzer): factor this out to a TaggingScheme abstraction.
-  Node* shift_amount = jsgraph()->Int32Constant(kSmiTagSize + kSmiShiftSize);
-  return graph()->NewNode(machine()->WordShl(), node, shift_amount);
-}
-
-
-Node* SimplifiedLowering::OffsetMinusTagConstant(int32_t offset) {
-  return jsgraph()->Int32Constant(offset - kHeapObjectTag);
-}
-
-
-static WriteBarrierKind ComputeWriteBarrierKind(BaseTaggedness base_is_tagged,
-                                                MachineType representation,
-                                                Type* type) {
-  // TODO(turbofan): skip write barriers for Smis, etc.
-  if (base_is_tagged == kTaggedBase &&
-      RepresentationOf(representation) == kRepTagged) {
-    // Write barriers are only for writes into heap objects (i.e. tagged base).
-    return kFullWriteBarrier;
-  }
-  return kNoWriteBarrier;
-}
-
-
-void SimplifiedLowering::DoLoadField(Node* node) {
-  const FieldAccess& access = FieldAccessOf(node->op());
-  node->set_op(machine()->Load(access.machine_type));
-  Node* offset = jsgraph()->IntPtrConstant(access.offset - access.tag());
-  node->InsertInput(graph()->zone(), 1, offset);
-}
-
-
-void SimplifiedLowering::DoStoreField(Node* node) {
-  const FieldAccess& access = FieldAccessOf(node->op());
-  WriteBarrierKind kind = ComputeWriteBarrierKind(
-      access.base_is_tagged, access.machine_type, access.type);
-  node->set_op(
-      machine()->Store(StoreRepresentation(access.machine_type, kind)));
-  Node* offset = jsgraph()->IntPtrConstant(access.offset - access.tag());
-  node->InsertInput(graph()->zone(), 1, offset);
-}
-
-
-Node* SimplifiedLowering::ComputeIndex(const ElementAccess& access,
-                                       Node* const key) {
-  Node* index = key;
-  const int element_size_shift = ElementSizeLog2Of(access.machine_type);
-  if (element_size_shift) {
-    index = graph()->NewNode(machine()->Word32Shl(), index,
-                             jsgraph()->Int32Constant(element_size_shift));
-  }
-  const int fixed_offset = access.header_size - access.tag();
-  if (fixed_offset) {
-    index = graph()->NewNode(machine()->Int32Add(), index,
-                             jsgraph()->Int32Constant(fixed_offset));
-  }
-  if (machine()->Is64()) {
-    // TODO(turbofan): This is probably only correct for typed arrays, and only
-    // if the typed arrays are at most 2GiB in size, which happens to match
-    // exactly our current situation.
-    index = graph()->NewNode(machine()->ChangeUint32ToUint64(), index);
-  }
-  return index;
-}
-
-
-void SimplifiedLowering::DoLoadBuffer(Node* node, MachineType output_type,
+void SimplifiedLowering::DoLoadBuffer(Node* node,
+                                      MachineRepresentation output_rep,
                                       RepresentationChanger* changer) {
   DCHECK_EQ(IrOpcode::kLoadBuffer, node->opcode());
-  DCHECK_NE(kMachNone, RepresentationOf(output_type));
-  MachineType const type = BufferAccessOf(node->op()).machine_type();
-  if (output_type != type) {
+  DCHECK_NE(MachineRepresentation::kNone, output_rep);
+  MachineType const access_type = BufferAccessOf(node->op()).machine_type();
+  if (output_rep != access_type.representation()) {
     Node* const buffer = node->InputAt(0);
     Node* const offset = node->InputAt(1);
     Node* const length = node->InputAt(2);
@@ -1189,19 +1532,21 @@
         graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
 
     Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
-    Node* etrue =
-        graph()->NewNode(machine()->Load(type), buffer, index, effect, if_true);
-    Node* vtrue = changer->GetRepresentationFor(etrue, type, output_type);
+    Node* etrue = graph()->NewNode(machine()->Load(access_type), buffer, index,
+                                   effect, if_true);
+    Node* vtrue = changer->GetRepresentationFor(
+        etrue, access_type.representation(), NodeProperties::GetType(node),
+        output_rep, Truncation::None());
 
     Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
     Node* efalse = effect;
     Node* vfalse;
-    if (output_type & kRepTagged) {
+    if (output_rep == MachineRepresentation::kTagged) {
       vfalse = jsgraph()->UndefinedConstant();
-    } else if (output_type & kRepFloat64) {
+    } else if (output_rep == MachineRepresentation::kFloat64) {
       vfalse =
           jsgraph()->Float64Constant(std::numeric_limits<double>::quiet_NaN());
-    } else if (output_type & kRepFloat32) {
+    } else if (output_rep == MachineRepresentation::kFloat32) {
       vfalse =
           jsgraph()->Float32Constant(std::numeric_limits<float>::quiet_NaN());
     } else {
@@ -1212,82 +1557,83 @@
     Node* ephi = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, merge);
 
     // Replace effect uses of {node} with the {ephi}.
-    NodeProperties::ReplaceWithValue(node, node, ephi);
+    NodeProperties::ReplaceUses(node, node, ephi);
 
     // Turn the {node} into a Phi.
-    node->set_op(common()->Phi(output_type, 2));
     node->ReplaceInput(0, vtrue);
     node->ReplaceInput(1, vfalse);
     node->ReplaceInput(2, merge);
     node->TrimInputCount(3);
+    NodeProperties::ChangeOp(node, common()->Phi(output_rep, 2));
   } else {
-    node->set_op(machine()->CheckedLoad(type));
+    NodeProperties::ChangeOp(node, machine()->CheckedLoad(access_type));
   }
 }
 
 
 void SimplifiedLowering::DoStoreBuffer(Node* node) {
   DCHECK_EQ(IrOpcode::kStoreBuffer, node->opcode());
-  MachineType const type = BufferAccessOf(node->op()).machine_type();
-  node->set_op(machine()->CheckedStore(type));
+  MachineRepresentation const rep =
+      BufferAccessOf(node->op()).machine_type().representation();
+  NodeProperties::ChangeOp(node, machine()->CheckedStore(rep));
 }
 
 
-void SimplifiedLowering::DoLoadElement(Node* node) {
-  const ElementAccess& access = ElementAccessOf(node->op());
-  node->set_op(machine()->Load(access.machine_type));
-  node->ReplaceInput(1, ComputeIndex(access, node->InputAt(1)));
+void SimplifiedLowering::DoObjectIsNumber(Node* node) {
+  Node* input = NodeProperties::GetValueInput(node, 0);
+  // TODO(bmeurer): Optimize somewhat based on input type.
+  Node* check =
+      graph()->NewNode(machine()->WordEqual(),
+                       graph()->NewNode(machine()->WordAnd(), input,
+                                        jsgraph()->IntPtrConstant(kSmiTagMask)),
+                       jsgraph()->IntPtrConstant(kSmiTag));
+  Node* branch = graph()->NewNode(common()->Branch(), check, graph()->start());
+  Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
+  Node* vtrue = jsgraph()->Int32Constant(1);
+  Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+  Node* vfalse = graph()->NewNode(
+      machine()->WordEqual(),
+      graph()->NewNode(
+          machine()->Load(MachineType::AnyTagged()), input,
+          jsgraph()->IntPtrConstant(HeapObject::kMapOffset - kHeapObjectTag),
+          graph()->start(), if_false),
+      jsgraph()->HeapConstant(isolate()->factory()->heap_number_map()));
+  Node* control = graph()->NewNode(common()->Merge(2), if_true, if_false);
+  node->ReplaceInput(0, vtrue);
+  node->AppendInput(graph()->zone(), vfalse);
+  node->AppendInput(graph()->zone(), control);
+  NodeProperties::ChangeOp(node, common()->Phi(MachineRepresentation::kBit, 2));
 }
 
 
-void SimplifiedLowering::DoStoreElement(Node* node) {
-  const ElementAccess& access = ElementAccessOf(node->op());
-  node->set_op(machine()->Store(StoreRepresentation(
-      access.machine_type,
-      ComputeWriteBarrierKind(access.base_is_tagged, access.machine_type,
-                              access.type))));
-  node->ReplaceInput(1, ComputeIndex(access, node->InputAt(1)));
+void SimplifiedLowering::DoObjectIsSmi(Node* node) {
+  node->ReplaceInput(0,
+                     graph()->NewNode(machine()->WordAnd(), node->InputAt(0),
+                                      jsgraph()->IntPtrConstant(kSmiTagMask)));
+  node->AppendInput(graph()->zone(), jsgraph()->IntPtrConstant(kSmiTag));
+  NodeProperties::ChangeOp(node, machine()->WordEqual());
 }
 
 
-void SimplifiedLowering::DoStringAdd(Node* node) {
+Node* SimplifiedLowering::StringComparison(Node* node) {
   Operator::Properties properties = node->op()->properties();
-  Callable callable = CodeFactory::StringAdd(
-      zone()->isolate(), STRING_ADD_CHECK_NONE, NOT_TENURED);
+  Callable callable = CodeFactory::StringCompare(isolate());
   CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
   CallDescriptor* desc = Linkage::GetStubCallDescriptor(
-      callable.descriptor(), 0, flags, properties, zone());
-  node->set_op(common()->Call(desc));
-  node->InsertInput(graph()->zone(), 0,
-                    jsgraph()->HeapConstant(callable.code()));
-  node->AppendInput(graph()->zone(), jsgraph()->UndefinedConstant());
-  node->AppendInput(graph()->zone(), graph()->start());
-  node->AppendInput(graph()->zone(), graph()->start());
-}
-
-
-Node* SimplifiedLowering::StringComparison(Node* node, bool requires_ordering) {
-  CEntryStub stub(zone()->isolate(), 1);
-  Runtime::FunctionId f =
-      requires_ordering ? Runtime::kStringCompare : Runtime::kStringEquals;
-  ExternalReference ref(f, zone()->isolate());
-  Operator::Properties props = node->op()->properties();
-  // TODO(mstarzinger): We should call StringCompareStub here instead, once an
-  // interface descriptor is available for it.
-  CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor(f, 2, props, zone());
-  return graph()->NewNode(common()->Call(desc),
-                          jsgraph()->HeapConstant(stub.GetCode()),
-                          NodeProperties::GetValueInput(node, 0),
-                          NodeProperties::GetValueInput(node, 1),
-                          jsgraph()->ExternalConstant(ref),
-                          jsgraph()->Int32Constant(2),
-                          jsgraph()->UndefinedConstant());
+      isolate(), zone(), callable.descriptor(), 0, flags, properties);
+  return graph()->NewNode(
+      common()->Call(desc), jsgraph()->HeapConstant(callable.code()),
+      NodeProperties::GetValueInput(node, 0),
+      NodeProperties::GetValueInput(node, 1), jsgraph()->NoContextConstant(),
+      NodeProperties::GetEffectInput(node),
+      NodeProperties::GetControlInput(node));
 }
 
 
 Node* SimplifiedLowering::Int32Div(Node* const node) {
   Int32BinopMatcher m(node);
   Node* const zero = jsgraph()->Int32Constant(0);
+  Node* const minus_one = jsgraph()->Int32Constant(-1);
   Node* const lhs = m.left().node();
   Node* const rhs = m.right().node();
 
@@ -1299,20 +1645,62 @@
     return graph()->NewNode(machine()->Int32Div(), lhs, rhs, graph()->start());
   }
 
-  Diamond if_zero(graph(), common(),
-                  graph()->NewNode(machine()->Word32Equal(), rhs, zero),
-                  BranchHint::kFalse);
+  // General case for signed integer division.
+  //
+  //    if 0 < rhs then
+  //      lhs / rhs
+  //    else
+  //      if rhs < -1 then
+  //        lhs / rhs
+  //      else if rhs == 0 then
+  //        0
+  //      else
+  //        0 - lhs
+  //
+  // Note: We do not use the Diamond helper class here, because it really hurts
+  // readability with nested diamonds.
+  const Operator* const merge_op = common()->Merge(2);
+  const Operator* const phi_op =
+      common()->Phi(MachineRepresentation::kWord32, 2);
 
-  Diamond if_minus_one(graph(), common(),
-                       graph()->NewNode(machine()->Word32Equal(), rhs,
-                                        jsgraph()->Int32Constant(-1)),
-                       BranchHint::kFalse);
-  if_minus_one.Nest(if_zero, false);
-  Node* sub = graph()->NewNode(machine()->Int32Sub(), zero, lhs);
-  Node* div =
-      graph()->NewNode(machine()->Int32Div(), lhs, rhs, if_minus_one.if_false);
+  Node* check0 = graph()->NewNode(machine()->Int32LessThan(), zero, rhs);
+  Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kTrue), check0,
+                                   graph()->start());
 
-  return if_zero.Phi(kMachInt32, zero, if_minus_one.Phi(kMachInt32, sub, div));
+  Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
+  Node* true0 = graph()->NewNode(machine()->Int32Div(), lhs, rhs, if_true0);
+
+  Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
+  Node* false0;
+  {
+    Node* check1 = graph()->NewNode(machine()->Int32LessThan(), rhs, minus_one);
+    Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0);
+
+    Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
+    Node* true1 = graph()->NewNode(machine()->Int32Div(), lhs, rhs, if_true1);
+
+    Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
+    Node* false1;
+    {
+      Node* check2 = graph()->NewNode(machine()->Word32Equal(), rhs, zero);
+      Node* branch2 = graph()->NewNode(common()->Branch(), check2, if_false1);
+
+      Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
+      Node* true2 = zero;
+
+      Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
+      Node* false2 = graph()->NewNode(machine()->Int32Sub(), zero, lhs);
+
+      if_false1 = graph()->NewNode(merge_op, if_true2, if_false2);
+      false1 = graph()->NewNode(phi_op, true2, false2, if_false1);
+    }
+
+    if_false0 = graph()->NewNode(merge_op, if_true1, if_false1);
+    false0 = graph()->NewNode(phi_op, true1, false1, if_false0);
+  }
+
+  Node* merge0 = graph()->NewNode(merge_op, if_true0, if_false0);
+  return graph()->NewNode(phi_op, true0, false0, merge0);
 }
 
 
@@ -1350,7 +1738,8 @@
   // Note: We do not use the Diamond helper class here, because it really hurts
   // readability with nested diamonds.
   const Operator* const merge_op = common()->Merge(2);
-  const Operator* const phi_op = common()->Phi(kMachInt32, 2);
+  const Operator* const phi_op =
+      common()->Phi(MachineRepresentation::kWord32, 2);
 
   Node* check0 = graph()->NewNode(machine()->Int32LessThan(), zero, rhs);
   Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kTrue), check0,
@@ -1429,7 +1818,7 @@
   Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, zero);
   Diamond d(graph(), common(), check, BranchHint::kFalse);
   Node* div = graph()->NewNode(machine()->Uint32Div(), lhs, rhs, d.if_false);
-  return d.Phi(kMachUint32, zero, div);
+  return d.Phi(MachineRepresentation::kWord32, zero, div);
 }
 
 
@@ -1461,7 +1850,8 @@
   // Note: We do not use the Diamond helper class here, because it really hurts
   // readability with nested diamonds.
   const Operator* const merge_op = common()->Merge(2);
-  const Operator* const phi_op = common()->Phi(kMachInt32, 2);
+  const Operator* const phi_op =
+      common()->Phi(MachineRepresentation::kWord32, 2);
 
   Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kTrue), rhs,
                                    graph()->start());
@@ -1492,24 +1882,61 @@
 }
 
 
+void SimplifiedLowering::DoShift(Node* node, Operator const* op,
+                                 Type* rhs_type) {
+  Node* const rhs = NodeProperties::GetValueInput(node, 1);
+  if (!rhs_type->Is(type_cache_.kZeroToThirtyOne)) {
+    node->ReplaceInput(1, graph()->NewNode(machine()->Word32And(), rhs,
+                                           jsgraph()->Int32Constant(0x1f)));
+  }
+  NodeProperties::ChangeOp(node, op);
+}
+
+
+namespace {
+
+void ReplaceEffectUses(Node* node, Node* replacement) {
+  // Requires distinguishing between value and effect edges.
+  DCHECK(replacement->op()->EffectOutputCount() > 0);
+  for (Edge edge : node->use_edges()) {
+    if (NodeProperties::IsEffectEdge(edge)) {
+      edge.UpdateTo(replacement);
+    } else {
+      DCHECK(NodeProperties::IsValueEdge(edge));
+    }
+  }
+}
+
+}  // namespace
+
+
 void SimplifiedLowering::DoStringEqual(Node* node) {
-  node->set_op(machine()->WordEqual());
-  node->ReplaceInput(0, StringComparison(node, false));
+  Node* comparison = StringComparison(node);
+  ReplaceEffectUses(node, comparison);
+  node->ReplaceInput(0, comparison);
   node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL));
+  node->TrimInputCount(2);
+  NodeProperties::ChangeOp(node, machine()->WordEqual());
 }
 
 
 void SimplifiedLowering::DoStringLessThan(Node* node) {
-  node->set_op(machine()->IntLessThan());
-  node->ReplaceInput(0, StringComparison(node, true));
+  Node* comparison = StringComparison(node);
+  ReplaceEffectUses(node, comparison);
+  node->ReplaceInput(0, comparison);
   node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL));
+  node->TrimInputCount(2);
+  NodeProperties::ChangeOp(node, machine()->IntLessThan());
 }
 
 
 void SimplifiedLowering::DoStringLessThanOrEqual(Node* node) {
-  node->set_op(machine()->IntLessThanOrEqual());
-  node->ReplaceInput(0, StringComparison(node, true));
+  Node* comparison = StringComparison(node);
+  ReplaceEffectUses(node, comparison);
+  node->ReplaceInput(0, comparison);
   node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL));
+  node->TrimInputCount(2);
+  NodeProperties::ChangeOp(node, machine()->IntLessThanOrEqual());
 }
 
 }  // namespace compiler
diff --git a/src/compiler/simplified-lowering.h b/src/compiler/simplified-lowering.h
index b21cf21..f9410f8 100644
--- a/src/compiler/simplified-lowering.h
+++ b/src/compiler/simplified-lowering.h
@@ -12,31 +12,33 @@
 
 namespace v8 {
 namespace internal {
+
+// Forward declarations.
+class TypeCache;
+
+
 namespace compiler {
 
 // Forward declarations.
 class RepresentationChanger;
+class SourcePositionTable;
 
-
-class SimplifiedLowering FINAL {
+class SimplifiedLowering final {
  public:
-  SimplifiedLowering(JSGraph* jsgraph, Zone* zone)
-      : jsgraph_(jsgraph), zone_(zone) {}
+  SimplifiedLowering(JSGraph* jsgraph, Zone* zone,
+                     SourcePositionTable* source_positions);
   ~SimplifiedLowering() {}
 
   void LowerAllNodes();
 
-  // TODO(titzer): These are exposed for direct testing. Use a friend class.
-  void DoLoadField(Node* node);
-  void DoStoreField(Node* node);
-  // TODO(turbofan): The output_type can be removed once the result of the
+  // TODO(turbofan): The representation can be removed once the result of the
   // representation analysis is stored in the node bounds.
-  void DoLoadBuffer(Node* node, MachineType output_type,
+  void DoLoadBuffer(Node* node, MachineRepresentation rep,
                     RepresentationChanger* changer);
   void DoStoreBuffer(Node* node);
-  void DoLoadElement(Node* node);
-  void DoStoreElement(Node* node);
-  void DoStringAdd(Node* node);
+  void DoObjectIsNumber(Node* node);
+  void DoObjectIsSmi(Node* node);
+  void DoShift(Node* node, Operator const* op, Type* rhs_type);
   void DoStringEqual(Node* node);
   void DoStringLessThan(Node* node);
   void DoStringLessThanOrEqual(Node* node);
@@ -44,13 +46,16 @@
  private:
   JSGraph* const jsgraph_;
   Zone* const zone_;
+  TypeCache const& type_cache_;
 
-  Node* SmiTag(Node* node);
-  Node* IsTagged(Node* node);
-  Node* Untag(Node* node);
-  Node* OffsetMinusTagConstant(int32_t offset);
-  Node* ComputeIndex(const ElementAccess& access, Node* const key);
-  Node* StringComparison(Node* node, bool requires_ordering);
+  // TODO(danno): SimplifiedLowering shouldn't know anything about the source
+  // positions table, but must for now since there currently is no other way to
+  // pass down source position information to nodes created during
+  // lowering. Once this phase becomes a vanilla reducer, it should get source
+  // position information via the SourcePositionWrapper like all other reducers.
+  SourcePositionTable* source_positions_;
+
+  Node* StringComparison(Node* node);
   Node* Int32Div(Node* const node);
   Node* Int32Mod(Node* const node);
   Node* Uint32Div(Node* const node);
@@ -58,6 +63,7 @@
 
   friend class RepresentationSelector;
 
+  Isolate* isolate() { return jsgraph_->isolate(); }
   Zone* zone() { return jsgraph_->zone(); }
   JSGraph* jsgraph() { return jsgraph_; }
   Graph* graph() { return jsgraph()->graph(); }
diff --git a/src/compiler/simplified-operator-reducer.cc b/src/compiler/simplified-operator-reducer.cc
index 9d45e5b..120d792 100644
--- a/src/compiler/simplified-operator-reducer.cc
+++ b/src/compiler/simplified-operator-reducer.cc
@@ -4,18 +4,18 @@
 
 #include "src/compiler/simplified-operator-reducer.h"
 
-#include "src/compiler/access-builder.h"
 #include "src/compiler/js-graph.h"
 #include "src/compiler/machine-operator.h"
 #include "src/compiler/node-matchers.h"
-#include "src/compiler/node-properties-inl.h"
+#include "src/compiler/operator-properties.h"
+#include "src/conversions-inl.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
 SimplifiedOperatorReducer::SimplifiedOperatorReducer(JSGraph* jsgraph)
-    : jsgraph_(jsgraph), simplified_(jsgraph->zone()) {}
+    : jsgraph_(jsgraph) {}
 
 
 SimplifiedOperatorReducer::~SimplifiedOperatorReducer() {}
@@ -23,35 +23,25 @@
 
 Reduction SimplifiedOperatorReducer::Reduce(Node* node) {
   switch (node->opcode()) {
-    case IrOpcode::kAnyToBoolean:
-      return ReduceAnyToBoolean(node);
     case IrOpcode::kBooleanNot: {
-      HeapObjectMatcher<HeapObject> m(node->InputAt(0));
-      if (m.Is(Unique<HeapObject>::CreateImmovable(factory()->false_value()))) {
-        return Replace(jsgraph()->TrueConstant());
+      HeapObjectMatcher m(node->InputAt(0));
+      if (m.HasValue()) {
+        return Replace(jsgraph()->BooleanConstant(!m.Value()->BooleanValue()));
       }
-      if (m.Is(Unique<HeapObject>::CreateImmovable(factory()->true_value()))) {
-        return Replace(jsgraph()->FalseConstant());
-      }
-      if (m.IsBooleanNot()) return Replace(m.node()->InputAt(0));
+      if (m.IsBooleanNot()) return Replace(m.InputAt(0));
       break;
     }
     case IrOpcode::kChangeBitToBool: {
       Int32Matcher m(node->InputAt(0));
       if (m.Is(0)) return Replace(jsgraph()->FalseConstant());
       if (m.Is(1)) return Replace(jsgraph()->TrueConstant());
-      if (m.IsChangeBoolToBit()) return Replace(m.node()->InputAt(0));
+      if (m.IsChangeBoolToBit()) return Replace(m.InputAt(0));
       break;
     }
     case IrOpcode::kChangeBoolToBit: {
-      HeapObjectMatcher<HeapObject> m(node->InputAt(0));
-      if (m.Is(Unique<HeapObject>::CreateImmovable(factory()->false_value()))) {
-        return ReplaceInt32(0);
-      }
-      if (m.Is(Unique<HeapObject>::CreateImmovable(factory()->true_value()))) {
-        return ReplaceInt32(1);
-      }
-      if (m.IsChangeBitToBool()) return Replace(m.node()->InputAt(0));
+      HeapObjectMatcher m(node->InputAt(0));
+      if (m.HasValue()) return ReplaceInt32(m.Value()->BooleanValue());
+      if (m.IsChangeBitToBool()) return Replace(m.InputAt(0));
       break;
     }
     case IrOpcode::kChangeFloat64ToTagged: {
@@ -69,12 +59,10 @@
       if (m.HasValue()) return ReplaceFloat64(m.Value());
       if (m.IsChangeFloat64ToTagged()) return Replace(m.node()->InputAt(0));
       if (m.IsChangeInt32ToTagged()) {
-        return Change(node, machine()->ChangeInt32ToFloat64(),
-                      m.node()->InputAt(0));
+        return Change(node, machine()->ChangeInt32ToFloat64(), m.InputAt(0));
       }
       if (m.IsChangeUint32ToTagged()) {
-        return Change(node, machine()->ChangeUint32ToFloat64(),
-                      m.node()->InputAt(0));
+        return Change(node, machine()->ChangeUint32ToFloat64(), m.InputAt(0));
       }
       break;
     }
@@ -82,20 +70,18 @@
       NumberMatcher m(node->InputAt(0));
       if (m.HasValue()) return ReplaceInt32(DoubleToInt32(m.Value()));
       if (m.IsChangeFloat64ToTagged()) {
-        return Change(node, machine()->ChangeFloat64ToInt32(),
-                      m.node()->InputAt(0));
+        return Change(node, machine()->ChangeFloat64ToInt32(), m.InputAt(0));
       }
-      if (m.IsChangeInt32ToTagged()) return Replace(m.node()->InputAt(0));
+      if (m.IsChangeInt32ToTagged()) return Replace(m.InputAt(0));
       break;
     }
     case IrOpcode::kChangeTaggedToUint32: {
       NumberMatcher m(node->InputAt(0));
       if (m.HasValue()) return ReplaceUint32(DoubleToUint32(m.Value()));
       if (m.IsChangeFloat64ToTagged()) {
-        return Change(node, machine()->ChangeFloat64ToUint32(),
-                      m.node()->InputAt(0));
+        return Change(node, machine()->ChangeFloat64ToUint32(), m.InputAt(0));
       }
-      if (m.IsChangeUint32ToTagged()) return Replace(m.node()->InputAt(0));
+      if (m.IsChangeUint32ToTagged()) return Replace(m.InputAt(0));
       break;
     }
     case IrOpcode::kChangeUint32ToTagged: {
@@ -103,6 +89,8 @@
       if (m.HasValue()) return ReplaceNumber(FastUI2D(m.Value()));
       break;
     }
+    case IrOpcode::kReferenceEqual:
+      return ReduceReferenceEqual(node);
     default:
       break;
   }
@@ -110,27 +98,18 @@
 }
 
 
-Reduction SimplifiedOperatorReducer::ReduceAnyToBoolean(Node* node) {
-  Node* const input = NodeProperties::GetValueInput(node, 0);
-  Type* const input_type = NodeProperties::GetBounds(input).upper;
-  if (input_type->Is(Type::Boolean())) {
-    // AnyToBoolean(x:boolean) => x
-    return Replace(input);
-  }
-  if (input_type->Is(Type::OrderedNumber())) {
-    // AnyToBoolean(x:ordered-number) => BooleanNot(NumberEqual(x, #0))
-    Node* compare = graph()->NewNode(simplified()->NumberEqual(), input,
-                                     jsgraph()->ZeroConstant());
-    return Change(node, simplified()->BooleanNot(), compare);
-  }
-  if (input_type->Is(Type::String())) {
-    // AnyToBoolean(x:string) => BooleanNot(NumberEqual(x.length, #0))
-    FieldAccess const access = AccessBuilder::ForStringLength();
-    Node* length = graph()->NewNode(simplified()->LoadField(access), input,
-                                    graph()->start(), graph()->start());
-    Node* compare = graph()->NewNode(simplified()->NumberEqual(), length,
-                                     jsgraph()->ZeroConstant());
-    return Change(node, simplified()->BooleanNot(), compare);
+Reduction SimplifiedOperatorReducer::ReduceReferenceEqual(Node* node) {
+  DCHECK_EQ(IrOpcode::kReferenceEqual, node->opcode());
+  Node* const left = NodeProperties::GetValueInput(node, 0);
+  Node* const right = NodeProperties::GetValueInput(node, 1);
+  HeapObjectMatcher match_left(left);
+  HeapObjectMatcher match_right(right);
+  if (match_left.HasValue() && match_right.HasValue()) {
+    if (match_left.Value().is_identical_to(match_right.Value())) {
+      return Replace(jsgraph()->TrueConstant());
+    } else {
+      return Replace(jsgraph()->FalseConstant());
+    }
   }
   return NoChange();
 }
@@ -140,8 +119,8 @@
                                             Node* a) {
   DCHECK_EQ(node->InputCount(), OperatorProperties::GetTotalInputCount(op));
   DCHECK_LE(1, node->InputCount());
-  node->set_op(op);
   node->ReplaceInput(0, a);
+  NodeProperties::ChangeOp(node, op);
   return Changed(node);
 }
 
@@ -169,16 +148,6 @@
 Graph* SimplifiedOperatorReducer::graph() const { return jsgraph()->graph(); }
 
 
-Factory* SimplifiedOperatorReducer::factory() const {
-  return jsgraph()->isolate()->factory();
-}
-
-
-CommonOperatorBuilder* SimplifiedOperatorReducer::common() const {
-  return jsgraph()->common();
-}
-
-
 MachineOperatorBuilder* SimplifiedOperatorReducer::machine() const {
   return jsgraph()->machine();
 }
diff --git a/src/compiler/simplified-operator-reducer.h b/src/compiler/simplified-operator-reducer.h
index 1e565b8..979a3d0 100644
--- a/src/compiler/simplified-operator-reducer.h
+++ b/src/compiler/simplified-operator-reducer.h
@@ -6,30 +6,26 @@
 #define V8_COMPILER_SIMPLIFIED_OPERATOR_REDUCER_H_
 
 #include "src/compiler/graph-reducer.h"
-#include "src/compiler/simplified-operator.h"
 
 namespace v8 {
 namespace internal {
-
-// Forward declarations.
-class Heap;
-
 namespace compiler {
 
 // Forward declarations.
-class CommonOperatorBuilder;
 class JSGraph;
 class MachineOperatorBuilder;
+class SimplifiedOperatorBuilder;
 
-class SimplifiedOperatorReducer FINAL : public Reducer {
+
+class SimplifiedOperatorReducer final : public Reducer {
  public:
   explicit SimplifiedOperatorReducer(JSGraph* jsgraph);
-  ~SimplifiedOperatorReducer() FINAL;
+  ~SimplifiedOperatorReducer() final;
 
-  Reduction Reduce(Node* node) FINAL;
+  Reduction Reduce(Node* node) final;
 
  private:
-  Reduction ReduceAnyToBoolean(Node* node);
+  Reduction ReduceReferenceEqual(Node* node);
 
   Reduction Change(Node* node, const Operator* op, Node* a);
   Reduction ReplaceFloat64(double value);
@@ -41,14 +37,11 @@
   Reduction ReplaceNumber(int32_t value);
 
   Graph* graph() const;
-  Factory* factory() const;
   JSGraph* jsgraph() const { return jsgraph_; }
-  CommonOperatorBuilder* common() const;
   MachineOperatorBuilder* machine() const;
-  SimplifiedOperatorBuilder* simplified() { return &simplified_; }
+  SimplifiedOperatorBuilder* simplified() const;
 
-  JSGraph* jsgraph_;
-  SimplifiedOperatorBuilder simplified_;
+  JSGraph* const jsgraph_;
 
   DISALLOW_COPY_AND_ASSIGN(SimplifiedOperatorReducer);
 };
diff --git a/src/compiler/simplified-operator.cc b/src/compiler/simplified-operator.cc
index 9d88d12..1eaa287 100644
--- a/src/compiler/simplified-operator.cc
+++ b/src/compiler/simplified-operator.cc
@@ -29,24 +29,24 @@
   switch (external_array_type_) {
     case kExternalUint8Array:
     case kExternalUint8ClampedArray:
-      return kMachUint8;
+      return MachineType::Uint8();
     case kExternalInt8Array:
-      return kMachInt8;
+      return MachineType::Int8();
     case kExternalUint16Array:
-      return kMachUint16;
+      return MachineType::Uint16();
     case kExternalInt16Array:
-      return kMachInt16;
+      return MachineType::Int16();
     case kExternalUint32Array:
-      return kMachUint32;
+      return MachineType::Uint32();
     case kExternalInt32Array:
-      return kMachInt32;
+      return MachineType::Int32();
     case kExternalFloat32Array:
-      return kMachFloat32;
+      return MachineType::Float32();
     case kExternalFloat64Array:
-      return kMachFloat64;
+      return MachineType::Float64();
   }
   UNREACHABLE();
-  return kMachNone;
+  return MachineType::None();
 }
 
 
@@ -157,39 +157,46 @@
 }
 
 
-#define PURE_OP_LIST(V)                                \
-  V(AnyToBoolean, Operator::kNoProperties, 1)          \
-  V(BooleanNot, Operator::kNoProperties, 1)            \
-  V(BooleanToNumber, Operator::kNoProperties, 1)       \
-  V(NumberEqual, Operator::kCommutative, 2)            \
-  V(NumberLessThan, Operator::kNoProperties, 2)        \
-  V(NumberLessThanOrEqual, Operator::kNoProperties, 2) \
-  V(NumberAdd, Operator::kCommutative, 2)              \
-  V(NumberSubtract, Operator::kNoProperties, 2)        \
-  V(NumberMultiply, Operator::kCommutative, 2)         \
-  V(NumberDivide, Operator::kNoProperties, 2)          \
-  V(NumberModulus, Operator::kNoProperties, 2)         \
-  V(NumberToInt32, Operator::kNoProperties, 1)         \
-  V(NumberToUint32, Operator::kNoProperties, 1)        \
-  V(StringEqual, Operator::kCommutative, 2)            \
-  V(StringLessThan, Operator::kNoProperties, 2)        \
-  V(StringLessThanOrEqual, Operator::kNoProperties, 2) \
-  V(StringAdd, Operator::kNoProperties, 2)             \
-  V(ChangeTaggedToInt32, Operator::kNoProperties, 1)   \
-  V(ChangeTaggedToUint32, Operator::kNoProperties, 1)  \
-  V(ChangeTaggedToFloat64, Operator::kNoProperties, 1) \
-  V(ChangeInt32ToTagged, Operator::kNoProperties, 1)   \
-  V(ChangeUint32ToTagged, Operator::kNoProperties, 1)  \
-  V(ChangeFloat64ToTagged, Operator::kNoProperties, 1) \
-  V(ChangeBoolToBit, Operator::kNoProperties, 1)       \
-  V(ChangeBitToBool, Operator::kNoProperties, 1)       \
-  V(ObjectIsSmi, Operator::kNoProperties, 1)           \
-  V(ObjectIsNonNegativeSmi, Operator::kNoProperties, 1)
+#define PURE_OP_LIST(V)                                  \
+  V(BooleanNot, Operator::kNoProperties, 1)              \
+  V(BooleanToNumber, Operator::kNoProperties, 1)         \
+  V(NumberEqual, Operator::kCommutative, 2)              \
+  V(NumberLessThan, Operator::kNoProperties, 2)          \
+  V(NumberLessThanOrEqual, Operator::kNoProperties, 2)   \
+  V(NumberAdd, Operator::kCommutative, 2)                \
+  V(NumberSubtract, Operator::kNoProperties, 2)          \
+  V(NumberMultiply, Operator::kCommutative, 2)           \
+  V(NumberDivide, Operator::kNoProperties, 2)            \
+  V(NumberModulus, Operator::kNoProperties, 2)           \
+  V(NumberBitwiseOr, Operator::kCommutative, 2)          \
+  V(NumberBitwiseXor, Operator::kCommutative, 2)         \
+  V(NumberBitwiseAnd, Operator::kCommutative, 2)         \
+  V(NumberShiftLeft, Operator::kNoProperties, 2)         \
+  V(NumberShiftRight, Operator::kNoProperties, 2)        \
+  V(NumberShiftRightLogical, Operator::kNoProperties, 2) \
+  V(NumberToInt32, Operator::kNoProperties, 1)           \
+  V(NumberToUint32, Operator::kNoProperties, 1)          \
+  V(NumberIsHoleNaN, Operator::kNoProperties, 1)         \
+  V(PlainPrimitiveToNumber, Operator::kNoProperties, 1)  \
+  V(ChangeTaggedToInt32, Operator::kNoProperties, 1)     \
+  V(ChangeTaggedToUint32, Operator::kNoProperties, 1)    \
+  V(ChangeTaggedToFloat64, Operator::kNoProperties, 1)   \
+  V(ChangeInt32ToTagged, Operator::kNoProperties, 1)     \
+  V(ChangeUint32ToTagged, Operator::kNoProperties, 1)    \
+  V(ChangeFloat64ToTagged, Operator::kNoProperties, 1)   \
+  V(ChangeBoolToBit, Operator::kNoProperties, 1)         \
+  V(ChangeBitToBool, Operator::kNoProperties, 1)         \
+  V(ObjectIsNumber, Operator::kNoProperties, 1)          \
+  V(ObjectIsSmi, Operator::kNoProperties, 1)
 
+#define NO_THROW_OP_LIST(V)                 \
+  V(StringEqual, Operator::kCommutative, 2) \
+  V(StringLessThan, Operator::kNoThrow, 2)  \
+  V(StringLessThanOrEqual, Operator::kNoThrow, 2)
 
-struct SimplifiedOperatorGlobalCache FINAL {
+struct SimplifiedOperatorGlobalCache final {
 #define PURE(Name, properties, input_count)                                \
-  struct Name##Operator FINAL : public Operator {                          \
+  struct Name##Operator final : public Operator {                          \
     Name##Operator()                                                       \
         : Operator(IrOpcode::k##Name, Operator::kPure | properties, #Name, \
                    input_count, 0, 0, 1, 0, 0) {}                          \
@@ -198,15 +205,25 @@
   PURE_OP_LIST(PURE)
 #undef PURE
 
+#define NO_THROW(Name, properties, input_count)                               \
+  struct Name##Operator final : public Operator {                             \
+    Name##Operator()                                                          \
+        : Operator(IrOpcode::k##Name, Operator::kNoThrow | properties, #Name, \
+                   input_count, 1, 1, 1, 1, 0) {}                             \
+  };                                                                          \
+  Name##Operator k##Name;
+  NO_THROW_OP_LIST(NO_THROW)
+#undef NO_THROW
+
 #define BUFFER_ACCESS(Type, type, TYPE, ctype, size)                          \
-  struct LoadBuffer##Type##Operator FINAL : public Operator1<BufferAccess> {  \
+  struct LoadBuffer##Type##Operator final : public Operator1<BufferAccess> {  \
     LoadBuffer##Type##Operator()                                              \
         : Operator1<BufferAccess>(IrOpcode::kLoadBuffer,                      \
                                   Operator::kNoThrow | Operator::kNoWrite,    \
                                   "LoadBuffer", 3, 1, 1, 1, 1, 0,             \
                                   BufferAccess(kExternal##Type##Array)) {}    \
   };                                                                          \
-  struct StoreBuffer##Type##Operator FINAL : public Operator1<BufferAccess> { \
+  struct StoreBuffer##Type##Operator final : public Operator1<BufferAccess> { \
     StoreBuffer##Type##Operator()                                             \
         : Operator1<BufferAccess>(IrOpcode::kStoreBuffer,                     \
                                   Operator::kNoRead | Operator::kNoThrow,     \
@@ -228,10 +245,11 @@
     : cache_(kCache.Get()), zone_(zone) {}
 
 
-#define PURE(Name, properties, input_count) \
+#define GET_FROM_CACHE(Name, properties, input_count) \
   const Operator* SimplifiedOperatorBuilder::Name() { return &cache_.k##Name; }
-PURE_OP_LIST(PURE)
-#undef PURE
+PURE_OP_LIST(GET_FROM_CACHE)
+NO_THROW_OP_LIST(GET_FROM_CACHE)
+#undef GET_FROM_CACHE
 
 
 const Operator* SimplifiedOperatorBuilder::ReferenceEqual(Type* type) {
@@ -242,6 +260,13 @@
 }
 
 
+const Operator* SimplifiedOperatorBuilder::Allocate(PretenureFlag pretenure) {
+  return new (zone())
+      Operator1<PretenureFlag>(IrOpcode::kAllocate, Operator::kNoThrow,
+                               "Allocate", 1, 1, 1, 1, 1, 0, pretenure);
+}
+
+
 const Operator* SimplifiedOperatorBuilder::LoadBuffer(BufferAccess access) {
   switch (access.external_array_type()) {
 #define LOAD_BUFFER(Type, type, TYPE, ctype, size) \
diff --git a/src/compiler/simplified-operator.h b/src/compiler/simplified-operator.h
index 22664fa..3821a6d 100644
--- a/src/compiler/simplified-operator.h
+++ b/src/compiler/simplified-operator.h
@@ -7,8 +7,9 @@
 
 #include <iosfwd>
 
-#include "src/compiler/machine-type.h"
 #include "src/handles.h"
+#include "src/machine-type.h"
+#include "src/objects.h"
 
 namespace v8 {
 namespace internal {
@@ -34,7 +35,7 @@
 
 
 // An access descriptor for loads/stores of array buffers.
-class BufferAccess FINAL {
+class BufferAccess final {
  public:
   explicit BufferAccess(ExternalArrayType external_array_type)
       : external_array_type_(external_array_type) {}
@@ -124,12 +125,10 @@
 //   - Bool: a tagged pointer to either the canonical JS #false or
 //           the canonical JS #true object
 //   - Bit: an untagged integer 0 or 1, but word-sized
-class SimplifiedOperatorBuilder FINAL {
+class SimplifiedOperatorBuilder final : public ZoneObject {
  public:
   explicit SimplifiedOperatorBuilder(Zone* zone);
 
-  const Operator* AnyToBoolean();
-
   const Operator* BooleanNot();
   const Operator* BooleanToNumber();
 
@@ -141,15 +140,23 @@
   const Operator* NumberMultiply();
   const Operator* NumberDivide();
   const Operator* NumberModulus();
+  const Operator* NumberBitwiseOr();
+  const Operator* NumberBitwiseXor();
+  const Operator* NumberBitwiseAnd();
+  const Operator* NumberShiftLeft();
+  const Operator* NumberShiftRight();
+  const Operator* NumberShiftRightLogical();
   const Operator* NumberToInt32();
   const Operator* NumberToUint32();
+  const Operator* NumberIsHoleNaN();
+
+  const Operator* PlainPrimitiveToNumber();
 
   const Operator* ReferenceEqual(Type* type);
 
   const Operator* StringEqual();
   const Operator* StringLessThan();
   const Operator* StringLessThanOrEqual();
-  const Operator* StringAdd();
 
   const Operator* ChangeTaggedToInt32();
   const Operator* ChangeTaggedToUint32();
@@ -160,8 +167,10 @@
   const Operator* ChangeBoolToBit();
   const Operator* ChangeBitToBool();
 
+  const Operator* ObjectIsNumber();
   const Operator* ObjectIsSmi();
-  const Operator* ObjectIsNonNegativeSmi();
+
+  const Operator* Allocate(PretenureFlag pretenure = NOT_TENURED);
 
   const Operator* LoadField(FieldAccess const&);
   const Operator* StoreField(FieldAccess const&);
diff --git a/src/compiler/source-position.cc b/src/compiler/source-position.cc
index 9e21ae4..48361ec 100644
--- a/src/compiler/source-position.cc
+++ b/src/compiler/source-position.cc
@@ -4,19 +4,18 @@
 
 #include "src/compiler/source-position.h"
 #include "src/compiler/graph.h"
-#include "src/compiler/node-aux-data-inl.h"
+#include "src/compiler/node-aux-data.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
-class SourcePositionTable::Decorator FINAL : public GraphDecorator {
+class SourcePositionTable::Decorator final : public GraphDecorator {
  public:
   explicit Decorator(SourcePositionTable* source_positions)
       : source_positions_(source_positions) {}
 
-  void Decorate(Node* node) FINAL {
-    DCHECK(!source_positions_->current_position_.IsInvalid());
+  void Decorate(Node* node) final {
     source_positions_->table_.Set(node, source_positions_->current_position_);
   }
 
@@ -27,22 +26,22 @@
 
 SourcePositionTable::SourcePositionTable(Graph* graph)
     : graph_(graph),
-      decorator_(NULL),
-      current_position_(SourcePosition::Invalid()),
+      decorator_(nullptr),
+      current_position_(SourcePosition::Unknown()),
       table_(graph->zone()) {}
 
 
 void SourcePositionTable::AddDecorator() {
-  DCHECK(decorator_ == NULL);
+  DCHECK_NULL(decorator_);
   decorator_ = new (graph_->zone()) Decorator(this);
   graph_->AddDecorator(decorator_);
 }
 
 
 void SourcePositionTable::RemoveDecorator() {
-  DCHECK(decorator_ != NULL);
+  DCHECK_NOT_NULL(decorator_);
   graph_->RemoveDecorator(decorator_);
-  decorator_ = NULL;
+  decorator_ = nullptr;
 }
 
 
@@ -50,6 +49,24 @@
   return table_.Get(node);
 }
 
+
+void SourcePositionTable::Print(std::ostream& os) const {
+  os << "{";
+  bool needs_comma = false;
+  for (auto i : table_) {
+    SourcePosition pos = i.second;
+    if (pos.IsKnown()) {
+      if (needs_comma) {
+        os << ",";
+      }
+      os << "\"" << i.first << "\""
+         << ":" << pos.raw();
+      needs_comma = true;
+    }
+  }
+  os << "}";
+}
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/src/compiler/source-position.h b/src/compiler/source-position.h
index 390a17d..81db1d2 100644
--- a/src/compiler/source-position.h
+++ b/src/compiler/source-position.h
@@ -14,22 +14,18 @@
 
 // Encapsulates encoding and decoding of sources positions from which Nodes
 // originated.
-class SourcePosition FINAL {
+class SourcePosition final {
  public:
   explicit SourcePosition(int raw = kUnknownPosition) : raw_(raw) {}
 
   static SourcePosition Unknown() { return SourcePosition(kUnknownPosition); }
   bool IsUnknown() const { return raw() == kUnknownPosition; }
-
-  static SourcePosition Invalid() { return SourcePosition(kInvalidPosition); }
-  bool IsInvalid() const { return raw() == kInvalidPosition; }
+  bool IsKnown() const { return raw() != kUnknownPosition; }
 
   int raw() const { return raw_; }
 
  private:
-  static const int kInvalidPosition = -2;
   static const int kUnknownPosition = RelocInfo::kNoPosition;
-  STATIC_ASSERT(kInvalidPosition != kUnknownPosition);
   int raw_;
 };
 
@@ -43,9 +39,9 @@
 }
 
 
-class SourcePositionTable FINAL {
+class SourcePositionTable final {
  public:
-  class Scope {
+  class Scope final {
    public:
     Scope(SourcePositionTable* source_positions, SourcePosition position)
         : source_positions_(source_positions),
@@ -61,19 +57,17 @@
 
    private:
     void Init(SourcePosition position) {
-      if (!position.IsUnknown() || prev_position_.IsInvalid()) {
-        source_positions_->current_position_ = position;
-      }
+      if (position.IsKnown()) source_positions_->current_position_ = position;
     }
 
-    SourcePositionTable* source_positions_;
-    SourcePosition prev_position_;
+    SourcePositionTable* const source_positions_;
+    SourcePosition const prev_position_;
     DISALLOW_COPY_AND_ASSIGN(Scope);
   };
 
   explicit SourcePositionTable(Graph* graph);
   ~SourcePositionTable() {
-    if (decorator_ != NULL) RemoveDecorator();
+    if (decorator_) RemoveDecorator();
   }
 
   void AddDecorator();
@@ -81,10 +75,12 @@
 
   SourcePosition GetSourcePosition(Node* node) const;
 
+  void Print(std::ostream& os) const;
+
  private:
   class Decorator;
 
-  Graph* graph_;
+  Graph* const graph_;
   Decorator* decorator_;
   SourcePosition current_position_;
   NodeAuxData<SourcePosition> table_;
@@ -96,4 +92,4 @@
 }  // namespace internal
 }  // namespace v8
 
-#endif
+#endif  // V8_COMPILER_SOURCE_POSITION_H_
diff --git a/src/compiler/state-values-utils.cc b/src/compiler/state-values-utils.cc
new file mode 100644
index 0000000..77cc227
--- /dev/null
+++ b/src/compiler/state-values-utils.cc
@@ -0,0 +1,317 @@
+// Copyright 2015 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/state-values-utils.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+StateValuesCache::StateValuesCache(JSGraph* js_graph)
+    : js_graph_(js_graph),
+      hash_map_(AreKeysEqual, ZoneHashMap::kDefaultHashMapCapacity,
+                ZoneAllocationPolicy(zone())),
+      working_space_(zone()),
+      empty_state_values_(nullptr) {}
+
+
+// static
+bool StateValuesCache::AreKeysEqual(void* key1, void* key2) {
+  NodeKey* node_key1 = reinterpret_cast<NodeKey*>(key1);
+  NodeKey* node_key2 = reinterpret_cast<NodeKey*>(key2);
+
+  if (node_key1->node == nullptr) {
+    if (node_key2->node == nullptr) {
+      return AreValueKeysEqual(reinterpret_cast<StateValuesKey*>(key1),
+                               reinterpret_cast<StateValuesKey*>(key2));
+    } else {
+      return IsKeysEqualToNode(reinterpret_cast<StateValuesKey*>(key1),
+                               node_key2->node);
+    }
+  } else {
+    if (node_key2->node == nullptr) {
+      // If the nodes are already processed, they must be the same.
+      return IsKeysEqualToNode(reinterpret_cast<StateValuesKey*>(key2),
+                               node_key1->node);
+    } else {
+      return node_key1->node == node_key2->node;
+    }
+  }
+  UNREACHABLE();
+}
+
+
+// static
+bool StateValuesCache::IsKeysEqualToNode(StateValuesKey* key, Node* node) {
+  if (key->count != static_cast<size_t>(node->InputCount())) {
+    return false;
+  }
+  for (size_t i = 0; i < key->count; i++) {
+    if (key->values[i] != node->InputAt(static_cast<int>(i))) {
+      return false;
+    }
+  }
+  return true;
+}
+
+
+// static
+bool StateValuesCache::AreValueKeysEqual(StateValuesKey* key1,
+                                         StateValuesKey* key2) {
+  if (key1->count != key2->count) {
+    return false;
+  }
+  for (size_t i = 0; i < key1->count; i++) {
+    if (key1->values[i] != key2->values[i]) {
+      return false;
+    }
+  }
+  return true;
+}
+
+
+Node* StateValuesCache::GetEmptyStateValues() {
+  if (empty_state_values_ == nullptr) {
+    empty_state_values_ = graph()->NewNode(common()->StateValues(0));
+  }
+  return empty_state_values_;
+}
+
+
+NodeVector* StateValuesCache::GetWorkingSpace(size_t level) {
+  while (working_space_.size() <= level) {
+    void* space = zone()->New(sizeof(NodeVector));
+    working_space_.push_back(new (space)
+                                 NodeVector(kMaxInputCount, nullptr, zone()));
+  }
+  return working_space_[level];
+}
+
+namespace {
+
+int StateValuesHashKey(Node** nodes, size_t count) {
+  size_t hash = count;
+  for (size_t i = 0; i < count; i++) {
+    hash = hash * 23 + nodes[i]->id();
+  }
+  return static_cast<int>(hash & 0x7fffffff);
+}
+
+}  // namespace
+
+
+Node* StateValuesCache::GetValuesNodeFromCache(Node** nodes, size_t count) {
+  StateValuesKey key(count, nodes);
+  int hash = StateValuesHashKey(nodes, count);
+  ZoneHashMap::Entry* lookup =
+      hash_map_.LookupOrInsert(&key, hash, ZoneAllocationPolicy(zone()));
+  DCHECK_NOT_NULL(lookup);
+  Node* node;
+  if (lookup->value == nullptr) {
+    int input_count = static_cast<int>(count);
+    node = graph()->NewNode(common()->StateValues(input_count), input_count,
+                            nodes);
+    NodeKey* new_key = new (zone()->New(sizeof(NodeKey))) NodeKey(node);
+    lookup->key = new_key;
+    lookup->value = node;
+  } else {
+    node = reinterpret_cast<Node*>(lookup->value);
+  }
+  return node;
+}
+
+
+class StateValuesCache::ValueArrayIterator {
+ public:
+  ValueArrayIterator(Node** values, size_t count)
+      : values_(values), count_(count), current_(0) {}
+
+  void Advance() {
+    if (!done()) {
+      current_++;
+    }
+  }
+
+  bool done() { return current_ >= count_; }
+
+  Node* node() {
+    DCHECK(!done());
+    return values_[current_];
+  }
+
+ private:
+  Node** values_;
+  size_t count_;
+  size_t current_;
+};
+
+
+Node* StateValuesCache::BuildTree(ValueArrayIterator* it, size_t max_height) {
+  if (max_height == 0) {
+    Node* node = it->node();
+    it->Advance();
+    return node;
+  }
+  DCHECK(!it->done());
+
+  NodeVector* buffer = GetWorkingSpace(max_height);
+  size_t count = 0;
+  for (; count < kMaxInputCount; count++) {
+    if (it->done()) break;
+    (*buffer)[count] = BuildTree(it, max_height - 1);
+  }
+  if (count == 1) {
+    return (*buffer)[0];
+  } else {
+    return GetValuesNodeFromCache(&(buffer->front()), count);
+  }
+}
+
+
+Node* StateValuesCache::GetNodeForValues(Node** values, size_t count) {
+#if DEBUG
+  for (size_t i = 0; i < count; i++) {
+    DCHECK_NE(values[i]->opcode(), IrOpcode::kStateValues);
+    DCHECK_NE(values[i]->opcode(), IrOpcode::kTypedStateValues);
+  }
+#endif
+  if (count == 0) {
+    return GetEmptyStateValues();
+  }
+  size_t height = 0;
+  size_t max_nodes = 1;
+  while (count > max_nodes) {
+    height++;
+    max_nodes *= kMaxInputCount;
+  }
+
+  ValueArrayIterator it(values, count);
+
+  Node* tree = BuildTree(&it, height);
+
+  // If the 'tree' is a single node, equip it with a StateValues wrapper.
+  if (tree->opcode() != IrOpcode::kStateValues &&
+      tree->opcode() != IrOpcode::kTypedStateValues) {
+    tree = GetValuesNodeFromCache(&tree, 1);
+  }
+
+  return tree;
+}
+
+
+StateValuesAccess::iterator::iterator(Node* node) : current_depth_(0) {
+  // A hacky way initialize - just set the index before the node we want
+  // to process and then advance to it.
+  stack_[current_depth_].node = node;
+  stack_[current_depth_].index = -1;
+  Advance();
+}
+
+
+StateValuesAccess::iterator::StatePos* StateValuesAccess::iterator::Top() {
+  DCHECK(current_depth_ >= 0);
+  DCHECK(current_depth_ < kMaxInlineDepth);
+  return &(stack_[current_depth_]);
+}
+
+
+void StateValuesAccess::iterator::Push(Node* node) {
+  current_depth_++;
+  CHECK(current_depth_ < kMaxInlineDepth);
+  stack_[current_depth_].node = node;
+  stack_[current_depth_].index = 0;
+}
+
+
+void StateValuesAccess::iterator::Pop() {
+  DCHECK(current_depth_ >= 0);
+  current_depth_--;
+}
+
+
+bool StateValuesAccess::iterator::done() { return current_depth_ < 0; }
+
+
+void StateValuesAccess::iterator::Advance() {
+  // Advance the current index.
+  Top()->index++;
+
+  // Fix up the position to point to a valid node.
+  while (true) {
+    // TODO(jarin): Factor to a separate method.
+    Node* node = Top()->node;
+    int index = Top()->index;
+
+    if (index >= node->InputCount()) {
+      // Pop stack and move to the next sibling.
+      Pop();
+      if (done()) {
+        // Stack is exhausted, we have reached the end.
+        return;
+      }
+      Top()->index++;
+    } else if (node->InputAt(index)->opcode() == IrOpcode::kStateValues ||
+               node->InputAt(index)->opcode() == IrOpcode::kTypedStateValues) {
+      // Nested state, we need to push to the stack.
+      Push(node->InputAt(index));
+    } else {
+      // We are on a valid node, we can stop the iteration.
+      return;
+    }
+  }
+}
+
+
+Node* StateValuesAccess::iterator::node() {
+  return Top()->node->InputAt(Top()->index);
+}
+
+
+MachineType StateValuesAccess::iterator::type() {
+  Node* state = Top()->node;
+  if (state->opcode() == IrOpcode::kStateValues) {
+    return MachineType::AnyTagged();
+  } else {
+    DCHECK_EQ(IrOpcode::kTypedStateValues, state->opcode());
+    const ZoneVector<MachineType>* types =
+        OpParameter<const ZoneVector<MachineType>*>(state);
+    return (*types)[Top()->index];
+  }
+}
+
+
+bool StateValuesAccess::iterator::operator!=(iterator& other) {
+  // We only allow comparison with end().
+  CHECK(other.done());
+  return !done();
+}
+
+
+StateValuesAccess::iterator& StateValuesAccess::iterator::operator++() {
+  Advance();
+  return *this;
+}
+
+
+StateValuesAccess::TypedNode StateValuesAccess::iterator::operator*() {
+  return TypedNode(node(), type());
+}
+
+
+size_t StateValuesAccess::size() {
+  size_t count = 0;
+  for (int i = 0; i < node_->InputCount(); i++) {
+    if (node_->InputAt(i)->opcode() == IrOpcode::kStateValues ||
+        node_->InputAt(i)->opcode() == IrOpcode::kTypedStateValues) {
+      count += StateValuesAccess(node_->InputAt(i)).size();
+    } else {
+      count++;
+    }
+  }
+  return count;
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/state-values-utils.h b/src/compiler/state-values-utils.h
new file mode 100644
index 0000000..79550bd
--- /dev/null
+++ b/src/compiler/state-values-utils.h
@@ -0,0 +1,120 @@
+// Copyright 2015 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.
+
+#ifndef V8_COMPILER_STATE_VALUES_UTILS_H_
+#define V8_COMPILER_STATE_VALUES_UTILS_H_
+
+#include "src/compiler/js-graph.h"
+
+namespace v8 {
+namespace internal {
+
+namespace compiler {
+
+class Graph;
+
+class StateValuesCache {
+ public:
+  explicit StateValuesCache(JSGraph* js_graph);
+
+  Node* GetNodeForValues(Node** values, size_t count);
+
+ private:
+  static const size_t kMaxInputCount = 8;
+
+  struct NodeKey {
+    Node* node;
+
+    explicit NodeKey(Node* node) : node(node) {}
+  };
+
+  struct StateValuesKey : public NodeKey {
+    // ValueArray - array of nodes ({node} has to be nullptr).
+    size_t count;
+    Node** values;
+
+    StateValuesKey(size_t count, Node** values)
+        : NodeKey(nullptr), count(count), values(values) {}
+  };
+
+  class ValueArrayIterator;
+
+  static bool AreKeysEqual(void* key1, void* key2);
+  static bool IsKeysEqualToNode(StateValuesKey* key, Node* node);
+  static bool AreValueKeysEqual(StateValuesKey* key1, StateValuesKey* key2);
+
+  Node* BuildTree(ValueArrayIterator* it, size_t max_height);
+  NodeVector* GetWorkingSpace(size_t level);
+  Node* GetEmptyStateValues();
+  Node* GetValuesNodeFromCache(Node** nodes, size_t count);
+
+  Graph* graph() { return js_graph_->graph(); }
+  CommonOperatorBuilder* common() { return js_graph_->common(); }
+
+  Zone* zone() { return graph()->zone(); }
+
+  JSGraph* js_graph_;
+  ZoneHashMap hash_map_;
+  ZoneVector<NodeVector*> working_space_;  // One working space per level.
+  Node* empty_state_values_;
+};
+
+class StateValuesAccess {
+ public:
+  struct TypedNode {
+    Node* node;
+    MachineType type;
+    TypedNode(Node* node, MachineType type) : node(node), type(type) {}
+  };
+
+  class iterator {
+   public:
+    // Bare minimum of operators needed for range iteration.
+    bool operator!=(iterator& other);
+    iterator& operator++();
+    TypedNode operator*();
+
+   private:
+    friend class StateValuesAccess;
+
+    iterator() : current_depth_(-1) {}
+    explicit iterator(Node* node);
+
+    Node* node();
+    MachineType type();
+    bool done();
+    void Advance();
+
+    struct StatePos {
+      Node* node;
+      int index;
+
+      explicit StatePos(Node* node) : node(node), index(0) {}
+      StatePos() {}
+    };
+
+    StatePos* Top();
+    void Push(Node* node);
+    void Pop();
+
+    static const int kMaxInlineDepth = 8;
+    StatePos stack_[kMaxInlineDepth];
+    int current_depth_;
+  };
+
+  explicit StateValuesAccess(Node* node) : node_(node) {}
+
+  size_t size();
+  iterator begin() { return iterator(node_); }
+  iterator end() { return iterator(); }
+
+ private:
+  Node* node_;
+};
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_STATE_VALUES_UTILS_H_
diff --git a/src/compiler/tail-call-optimization.cc b/src/compiler/tail-call-optimization.cc
new file mode 100644
index 0000000..6635fb9
--- /dev/null
+++ b/src/compiler/tail-call-optimization.cc
@@ -0,0 +1,83 @@
+// Copyright 2015 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/tail-call-optimization.h"
+
+#include "src/compiler/common-operator.h"
+#include "src/compiler/graph.h"
+#include "src/compiler/linkage.h"
+#include "src/compiler/node-properties.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+Reduction TailCallOptimization::Reduce(Node* node) {
+  if (node->opcode() != IrOpcode::kReturn) return NoChange();
+  // The value which is returned must be the result of a potential tail call,
+  // there must be no try/catch/finally around the Call, and there must be no
+  // other effect between the Call and the Return nodes.
+  Node* const call = NodeProperties::GetValueInput(node, 0);
+  if (call->opcode() == IrOpcode::kCall &&
+      OpParameter<CallDescriptor const*>(call)->SupportsTailCalls() &&
+      NodeProperties::GetEffectInput(node) == call &&
+      !NodeProperties::IsExceptionalCall(call)) {
+    Node* const control = NodeProperties::GetControlInput(node);
+    if (control->opcode() == IrOpcode::kIfSuccess &&
+        call->OwnedBy(node, control) && control->OwnedBy(node)) {
+      // Furthermore, control has to flow via an IfSuccess from the Call, so
+      // the Return node value and effect depends directly on the Call node,
+      // and indirectly control depends on the Call via an IfSuccess.
+
+      // Value1 ... ValueN Effect Control
+      //   ^          ^      ^       ^
+      //   |          |      |       |
+      //   |          +--+ +-+       |
+      //   +----------+  | |  +------+
+      //               \ | | /
+      //             Call[Descriptor]
+      //                ^ ^ ^
+      //                | | |
+      //              +-+ | |
+      //              |   | |
+      //              | +-+ |
+      //              | | IfSuccess
+      //              | |  ^
+      //              | |  |
+      //              Return
+      //                ^
+      //                |
+
+      // The resulting graph looks like this:
+
+      // Value1 ... ValueN Effect Control
+      //   ^          ^      ^       ^
+      //   |          |      |       |
+      //   |          +--+ +-+       |
+      //   +----------+  | |  +------+
+      //               \ | | /
+      //           TailCall[Descriptor]
+      //                 ^
+      //                 |
+
+      DCHECK_EQ(call, NodeProperties::GetControlInput(control, 0));
+      DCHECK_EQ(3, node->InputCount());
+      node->ReplaceInput(0, NodeProperties::GetEffectInput(call));
+      node->ReplaceInput(1, NodeProperties::GetControlInput(call));
+      node->RemoveInput(2);
+      for (int index = 0; index < call->op()->ValueInputCount(); ++index) {
+        node->InsertInput(graph()->zone(), index,
+                          NodeProperties::GetValueInput(call, index));
+      }
+      NodeProperties::ChangeOp(
+          node, common()->TailCall(OpParameter<CallDescriptor const*>(call)));
+      return Changed(node);
+    }
+  }
+  return NoChange();
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/tail-call-optimization.h b/src/compiler/tail-call-optimization.h
new file mode 100644
index 0000000..b5d4f96
--- /dev/null
+++ b/src/compiler/tail-call-optimization.h
@@ -0,0 +1,40 @@
+// Copyright 2015 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.
+
+#ifndef V8_COMPILER_TAIL_CALL_OPTIMIZATION_H_
+#define V8_COMPILER_TAIL_CALL_OPTIMIZATION_H_
+
+#include "src/compiler/graph-reducer.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+// Forward declarations.
+class CommonOperatorBuilder;
+class Graph;
+
+
+// Performs tail call optimization by replacing certain combinations of Return
+// and Call nodes with a single TailCall.
+class TailCallOptimization final : public Reducer {
+ public:
+  TailCallOptimization(CommonOperatorBuilder* common, Graph* graph)
+      : common_(common), graph_(graph) {}
+
+  Reduction Reduce(Node* node) final;
+
+ private:
+  CommonOperatorBuilder* common() const { return common_; }
+  Graph* graph() const { return graph_; }
+
+  CommonOperatorBuilder* const common_;
+  Graph* const graph_;
+};
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_TAIL_CALL_OPTIMIZATION_H_
diff --git a/src/compiler/type-hint-analyzer.cc b/src/compiler/type-hint-analyzer.cc
new file mode 100644
index 0000000..42c4627
--- /dev/null
+++ b/src/compiler/type-hint-analyzer.cc
@@ -0,0 +1,98 @@
+// Copyright 2015 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/type-hint-analyzer.h"
+
+#include "src/assembler.h"
+#include "src/code-stubs.h"
+#include "src/compiler/type-hints.h"
+#include "src/ic/ic-state.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+namespace {
+
+// TODO(bmeurer): This detour via types is ugly.
+BinaryOperationHints::Hint ToHint(Type* type) {
+  if (type->Is(Type::None())) return BinaryOperationHints::kNone;
+  if (type->Is(Type::SignedSmall())) return BinaryOperationHints::kSignedSmall;
+  if (type->Is(Type::Signed32())) return BinaryOperationHints::kSigned32;
+  if (type->Is(Type::Number())) return BinaryOperationHints::kNumber;
+  if (type->Is(Type::String())) return BinaryOperationHints::kString;
+  return BinaryOperationHints::kAny;
+}
+
+}  // namespace
+
+
+bool TypeHintAnalysis::GetBinaryOperationHints(
+    TypeFeedbackId id, BinaryOperationHints* hints) const {
+  auto i = infos_.find(id);
+  if (i == infos_.end()) return false;
+  Handle<Code> code = i->second;
+  DCHECK_EQ(Code::BINARY_OP_IC, code->kind());
+  BinaryOpICState state(code->GetIsolate(), code->extra_ic_state());
+  *hints = BinaryOperationHints(ToHint(state.GetLeftType()),
+                                ToHint(state.GetRightType()),
+                                ToHint(state.GetResultType()));
+  return true;
+}
+
+
+bool TypeHintAnalysis::GetToBooleanHints(TypeFeedbackId id,
+                                         ToBooleanHints* hints) const {
+  auto i = infos_.find(id);
+  if (i == infos_.end()) return false;
+  Handle<Code> code = i->second;
+  DCHECK_EQ(Code::TO_BOOLEAN_IC, code->kind());
+  ToBooleanStub stub(code->GetIsolate(), code->extra_ic_state());
+// TODO(bmeurer): Replace ToBooleanStub::Types with ToBooleanHints.
+#define ASSERT_COMPATIBLE(NAME, Name)       \
+  STATIC_ASSERT(1 << ToBooleanStub::NAME == \
+                static_cast<int>(ToBooleanHint::k##Name))
+  ASSERT_COMPATIBLE(UNDEFINED, Undefined);
+  ASSERT_COMPATIBLE(BOOLEAN, Boolean);
+  ASSERT_COMPATIBLE(NULL_TYPE, Null);
+  ASSERT_COMPATIBLE(SMI, SmallInteger);
+  ASSERT_COMPATIBLE(SPEC_OBJECT, Receiver);
+  ASSERT_COMPATIBLE(STRING, String);
+  ASSERT_COMPATIBLE(SYMBOL, Symbol);
+  ASSERT_COMPATIBLE(HEAP_NUMBER, HeapNumber);
+  ASSERT_COMPATIBLE(SIMD_VALUE, SimdValue);
+#undef ASSERT_COMPATIBLE
+  *hints = ToBooleanHints(stub.types().ToIntegral());
+  return true;
+}
+
+
+TypeHintAnalysis* TypeHintAnalyzer::Analyze(Handle<Code> code) {
+  DisallowHeapAllocation no_gc;
+  TypeHintAnalysis::Infos infos(zone());
+  Isolate* const isolate = code->GetIsolate();
+  int const mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET_WITH_ID);
+  for (RelocIterator it(*code, mask); !it.done(); it.next()) {
+    RelocInfo* rinfo = it.rinfo();
+    Address target_address = rinfo->target_address();
+    Code* target = Code::GetCodeFromTargetAddress(target_address);
+    switch (target->kind()) {
+      case Code::BINARY_OP_IC:
+      case Code::TO_BOOLEAN_IC: {
+        // Add this feedback to the {infos}.
+        TypeFeedbackId id(static_cast<unsigned>(rinfo->data()));
+        infos.insert(std::make_pair(id, handle(target, isolate)));
+        break;
+      }
+      default:
+        // Ignore the remaining code objects.
+        break;
+    }
+  }
+  return new (zone()) TypeHintAnalysis(infos);
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/type-hint-analyzer.h b/src/compiler/type-hint-analyzer.h
new file mode 100644
index 0000000..1a79905
--- /dev/null
+++ b/src/compiler/type-hint-analyzer.h
@@ -0,0 +1,51 @@
+// Copyright 2015 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.
+
+#ifndef V8_COMPILER_TYPE_HINT_ANALYZER_H_
+#define V8_COMPILER_TYPE_HINT_ANALYZER_H_
+
+#include "src/compiler/type-hints.h"
+#include "src/handles.h"
+#include "src/zone-containers.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+// The result of analyzing type hints.
+class TypeHintAnalysis final : public ZoneObject {
+ public:
+  typedef ZoneMap<TypeFeedbackId, Handle<Code>> Infos;
+
+  explicit TypeHintAnalysis(Infos const& infos) : infos_(infos) {}
+
+  bool GetBinaryOperationHints(TypeFeedbackId id,
+                               BinaryOperationHints* hints) const;
+  bool GetToBooleanHints(TypeFeedbackId id, ToBooleanHints* hints) const;
+
+ private:
+  Infos const infos_;
+};
+
+
+// The class that performs type hint analysis on the fullcodegen code object.
+class TypeHintAnalyzer final {
+ public:
+  explicit TypeHintAnalyzer(Zone* zone) : zone_(zone) {}
+
+  TypeHintAnalysis* Analyze(Handle<Code> code);
+
+ private:
+  Zone* zone() const { return zone_; }
+
+  Zone* const zone_;
+
+  DISALLOW_COPY_AND_ASSIGN(TypeHintAnalyzer);
+};
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_TYPE_HINT_ANALYZER_H_
diff --git a/src/compiler/type-hints.cc b/src/compiler/type-hints.cc
new file mode 100644
index 0000000..06abad6
--- /dev/null
+++ b/src/compiler/type-hints.cc
@@ -0,0 +1,83 @@
+// Copyright 2015 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/type-hints.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+std::ostream& operator<<(std::ostream& os, BinaryOperationHints::Hint hint) {
+  switch (hint) {
+    case BinaryOperationHints::kNone:
+      return os << "None";
+    case BinaryOperationHints::kSignedSmall:
+      return os << "SignedSmall";
+    case BinaryOperationHints::kSigned32:
+      return os << "Signed32";
+    case BinaryOperationHints::kNumber:
+      return os << "Number";
+    case BinaryOperationHints::kString:
+      return os << "String";
+    case BinaryOperationHints::kAny:
+      return os << "Any";
+  }
+  UNREACHABLE();
+  return os;
+}
+
+
+std::ostream& operator<<(std::ostream& os, BinaryOperationHints hints) {
+  return os << hints.left() << "*" << hints.right() << "->" << hints.result();
+}
+
+
+std::ostream& operator<<(std::ostream& os, ToBooleanHint hint) {
+  switch (hint) {
+    case ToBooleanHint::kNone:
+      return os << "None";
+    case ToBooleanHint::kUndefined:
+      return os << "Undefined";
+    case ToBooleanHint::kBoolean:
+      return os << "Boolean";
+    case ToBooleanHint::kNull:
+      return os << "Null";
+    case ToBooleanHint::kSmallInteger:
+      return os << "SmallInteger";
+    case ToBooleanHint::kReceiver:
+      return os << "Receiver";
+    case ToBooleanHint::kString:
+      return os << "String";
+    case ToBooleanHint::kSymbol:
+      return os << "Symbol";
+    case ToBooleanHint::kHeapNumber:
+      return os << "HeapNumber";
+    case ToBooleanHint::kSimdValue:
+      return os << "SimdValue";
+    case ToBooleanHint::kAny:
+      return os << "Any";
+  }
+  UNREACHABLE();
+  return os;
+}
+
+
+std::ostream& operator<<(std::ostream& os, ToBooleanHints hints) {
+  if (hints == ToBooleanHint::kAny) return os << "Any";
+  if (hints == ToBooleanHint::kNone) return os << "None";
+  bool first = true;
+  for (ToBooleanHints::mask_type i = 0; i < sizeof(i) * CHAR_BIT; ++i) {
+    ToBooleanHint const hint = static_cast<ToBooleanHint>(1u << i);
+    if (hints & hint) {
+      if (!first) os << "|";
+      first = false;
+      os << hint;
+    }
+  }
+  return os;
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/type-hints.h b/src/compiler/type-hints.h
new file mode 100644
index 0000000..f1cc640
--- /dev/null
+++ b/src/compiler/type-hints.h
@@ -0,0 +1,84 @@
+// Copyright 2015 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.
+
+#ifndef V8_COMPILER_TYPE_HINTS_H_
+#define V8_COMPILER_TYPE_HINTS_H_
+
+#include "src/base/flags.h"
+#include "src/utils.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+// Type hints for an binary operation.
+class BinaryOperationHints final {
+ public:
+  enum Hint { kNone, kSignedSmall, kSigned32, kNumber, kString, kAny };
+
+  BinaryOperationHints() : BinaryOperationHints(kNone, kNone, kNone) {}
+  BinaryOperationHints(Hint left, Hint right, Hint result)
+      : bit_field_(LeftField::encode(left) | RightField::encode(right) |
+                   ResultField::encode(result)) {}
+
+  static BinaryOperationHints Any() {
+    return BinaryOperationHints(kAny, kAny, kAny);
+  }
+
+  Hint left() const { return LeftField::decode(bit_field_); }
+  Hint right() const { return RightField::decode(bit_field_); }
+  Hint result() const { return ResultField::decode(bit_field_); }
+
+  bool operator==(BinaryOperationHints const& that) const {
+    return this->bit_field_ == that.bit_field_;
+  }
+  bool operator!=(BinaryOperationHints const& that) const {
+    return !(*this == that);
+  }
+
+  friend size_t hash_value(BinaryOperationHints const& hints) {
+    return hints.bit_field_;
+  }
+
+ private:
+  typedef BitField<Hint, 0, 3> LeftField;
+  typedef BitField<Hint, 3, 3> RightField;
+  typedef BitField<Hint, 6, 3> ResultField;
+
+  uint32_t bit_field_;
+};
+
+std::ostream& operator<<(std::ostream&, BinaryOperationHints::Hint);
+std::ostream& operator<<(std::ostream&, BinaryOperationHints);
+
+
+// Type hints for the ToBoolean type conversion.
+enum class ToBooleanHint : uint16_t {
+  kNone = 0u,
+  kUndefined = 1u << 0,
+  kBoolean = 1u << 1,
+  kNull = 1u << 2,
+  kSmallInteger = 1u << 3,
+  kReceiver = 1u << 4,
+  kString = 1u << 5,
+  kSymbol = 1u << 6,
+  kHeapNumber = 1u << 7,
+  kSimdValue = 1u << 8,
+  kAny = kUndefined | kBoolean | kNull | kSmallInteger | kReceiver | kString |
+         kSymbol | kHeapNumber | kSimdValue
+};
+
+std::ostream& operator<<(std::ostream&, ToBooleanHint);
+
+typedef base::Flags<ToBooleanHint, uint16_t> ToBooleanHints;
+
+std::ostream& operator<<(std::ostream&, ToBooleanHints);
+
+DEFINE_OPERATORS_FOR_FLAGS(ToBooleanHints)
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_TYPE_HINTS_H_
diff --git a/src/compiler/typer.cc b/src/compiler/typer.cc
index 137829e..c1f816d 100644
--- a/src/compiler/typer.cc
+++ b/src/compiler/typer.cc
@@ -2,220 +2,71 @@
 // 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/compiler/graph-inl.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.h"
-#include "src/compiler/node-properties-inl.h"
 #include "src/compiler/node-properties.h"
 #include "src/compiler/simplified-operator.h"
-#include "src/compiler/typer.h"
+#include "src/objects-inl.h"
+#include "src/type-cache.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
-#define NATIVE_TYPES(V) \
-  V(Int8)               \
-  V(Uint8)              \
-  V(Int16)              \
-  V(Uint16)             \
-  V(Int32)              \
-  V(Uint32)             \
-  V(Float32)            \
-  V(Float64)
-
-enum LazyCachedType {
-  kNumberFunc0,
-  kNumberFunc1,
-  kNumberFunc2,
-  kImulFunc,
-  kClz32Func,
-  kArrayBufferFunc,
-#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
-  k##Type, k##Type##Array, k##Type##ArrayFunc,
-  TYPED_ARRAYS(TYPED_ARRAY_CASE)
-#undef TYPED_ARRAY_CASE
-      kNumLazyCachedTypes
-};
-
-
-// Constructs and caches types lazily.
-// TODO(turbofan): these types could be globally cached or cached per isolate.
-class LazyTypeCache FINAL : public ZoneObject {
- public:
-  explicit LazyTypeCache(Zone* zone) : zone_(zone) {
-    memset(cache_, 0, sizeof(cache_));
-  }
-
-  inline Type* Get(LazyCachedType type) {
-    int index = static_cast<int>(type);
-    DCHECK(index < kNumLazyCachedTypes);
-    if (cache_[index] == NULL) cache_[index] = Create(type);
-    return cache_[index];
-  }
-
- private:
-  Type* Create(LazyCachedType type) {
-    switch (type) {
-      case kInt8:
-        return CreateNative(CreateRange<int8_t>(), Type::UntaggedSigned8());
-      case kUint8:
-        return CreateNative(CreateRange<uint8_t>(), Type::UntaggedUnsigned8());
-      case kInt16:
-        return CreateNative(CreateRange<int16_t>(), Type::UntaggedSigned16());
-      case kUint16:
-        return CreateNative(CreateRange<uint16_t>(),
-                            Type::UntaggedUnsigned16());
-      case kInt32:
-        return CreateNative(Type::Signed32(), Type::UntaggedSigned32());
-      case kUint32:
-        return CreateNative(Type::Unsigned32(), Type::UntaggedUnsigned32());
-      case kFloat32:
-        return CreateNative(Type::Number(), Type::UntaggedFloat32());
-      case kFloat64:
-        return CreateNative(Type::Number(), Type::UntaggedFloat64());
-      case kUint8Clamped:
-        return Get(kUint8);
-      case kNumberFunc0:
-        return Type::Function(Type::Number(), zone());
-      case kNumberFunc1:
-        return Type::Function(Type::Number(), Type::Number(), zone());
-      case kNumberFunc2:
-        return Type::Function(Type::Number(), Type::Number(), Type::Number(),
-                              zone());
-      case kImulFunc:
-        return Type::Function(Type::Signed32(), Type::Integral32(),
-                              Type::Integral32(), zone());
-      case kClz32Func:
-        return Type::Function(CreateRange(0, 32), Type::Number(), zone());
-      case kArrayBufferFunc:
-        return Type::Function(Type::Object(zone()), Type::Unsigned32(), zone());
-#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
-  case k##Type##Array:                                  \
-    return CreateArray(Get(k##Type));                   \
-  case k##Type##ArrayFunc:                              \
-    return CreateArrayFunction(Get(k##Type##Array));
-        TYPED_ARRAYS(TYPED_ARRAY_CASE)
-#undef TYPED_ARRAY_CASE
-      case kNumLazyCachedTypes:
-        break;
-    }
-    UNREACHABLE();
-    return NULL;
-  }
-
-  Type* CreateArray(Type* element) const {
-    return Type::Array(element, zone());
-  }
-
-  Type* CreateArrayFunction(Type* array) const {
-    Type* arg1 = Type::Union(Type::Unsigned32(), Type::Object(), zone());
-    Type* arg2 = Type::Union(Type::Unsigned32(), Type::Undefined(), zone());
-    Type* arg3 = arg2;
-    return Type::Function(array, arg1, arg2, arg3, zone());
-  }
-
-  Type* CreateNative(Type* semantic, Type* representation) const {
-    return Type::Intersect(semantic, representation, zone());
-  }
-
-  template <typename T>
-  Type* CreateRange() const {
-    return CreateRange(std::numeric_limits<T>::min(),
-                       std::numeric_limits<T>::max());
-  }
-
-  Type* CreateRange(double min, double max) const {
-    return Type::Range(factory()->NewNumber(min), factory()->NewNumber(max),
-                       zone());
-  }
-
-  Factory* factory() const { return isolate()->factory(); }
-  Isolate* isolate() const { return zone()->isolate(); }
-  Zone* zone() const { return zone_; }
-
-  Type* cache_[kNumLazyCachedTypes];
-  Zone* zone_;
-};
-
-
-class Typer::Decorator FINAL : public GraphDecorator {
+class Typer::Decorator final : public GraphDecorator {
  public:
   explicit Decorator(Typer* typer) : typer_(typer) {}
-  void Decorate(Node* node) FINAL;
+  void Decorate(Node* node) final;
 
  private:
-  Typer* typer_;
+  Typer* const typer_;
 };
 
 
-Typer::Typer(Graph* graph, MaybeHandle<Context> context)
-    : graph_(graph),
-      context_(context),
-      decorator_(NULL),
-      cache_(new (graph->zone()) LazyTypeCache(graph->zone())),
-      weaken_min_limits_(graph->zone()),
-      weaken_max_limits_(graph->zone()) {
+Typer::Typer(Isolate* isolate, Graph* graph, Flags flags,
+             CompilationDependencies* dependencies,
+             Type::FunctionType* function_type)
+    : isolate_(isolate),
+      graph_(graph),
+      flags_(flags),
+      dependencies_(dependencies),
+      function_type_(function_type),
+      decorator_(nullptr),
+      cache_(TypeCache::Get()) {
   Zone* zone = this->zone();
-  Factory* f = zone->isolate()->factory();
+  Factory* const factory = isolate->factory();
 
-  Handle<Object> zero = f->NewNumber(0);
-  Handle<Object> one = f->NewNumber(1);
-  Handle<Object> infinity = f->NewNumber(+V8_INFINITY);
-  Handle<Object> minusinfinity = f->NewNumber(-V8_INFINITY);
-
-  Type* number = Type::Number();
-  Type* signed32 = Type::Signed32();
-  Type* unsigned32 = Type::Unsigned32();
-  Type* nan_or_minuszero = Type::Union(Type::NaN(), Type::MinusZero(), zone);
+  Type* infinity = Type::Constant(factory->infinity_value(), zone);
+  Type* minus_infinity = Type::Constant(factory->minus_infinity_value(), zone);
+  // TODO(neis): 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(Type::Constant(infinity, zone),
-                              Type::Constant(minusinfinity, zone), zone),
-                  nan_or_minuszero, zone);
+      Type::Union(Type::Union(infinity, minus_infinity, zone),
+                  Type::MinusZeroOrNaN(), zone);
+  DCHECK(!truncating_to_zero->Maybe(Type::Integral32()));
 
-  boolean_or_number = Type::Union(Type::Boolean(), Type::Number(), zone);
-  undefined_or_null = Type::Union(Type::Undefined(), Type::Null(), zone);
-  undefined_or_number = Type::Union(Type::Undefined(), Type::Number(), zone);
-  singleton_false = Type::Constant(f->false_value(), zone);
-  singleton_true = Type::Constant(f->true_value(), zone);
-  singleton_zero = Type::Range(zero, zero, zone);
-  singleton_one = Type::Range(one, one, zone);
-  zero_or_one = Type::Union(singleton_zero, singleton_one, zone);
-  zeroish = Type::Union(singleton_zero, nan_or_minuszero, zone);
-  signed32ish = Type::Union(signed32, truncating_to_zero, zone);
-  unsigned32ish = Type::Union(unsigned32, truncating_to_zero, zone);
-  falsish = Type::Union(Type::Undetectable(),
-                        Type::Union(Type::Union(singleton_false, zeroish, zone),
-                                    undefined_or_null, zone),
-                        zone);
-  truish = Type::Union(
-      singleton_true,
+  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(Type::Union(singleton_false_, cache_.kZeroish, zone),
+                      Type::NullOrUndefined(), zone),
+          singleton_the_hole_, zone),
+      zone);
+  truish_ = Type::Union(
+      singleton_true_,
       Type::Union(Type::DetectableReceiver(), Type::Symbol(), zone), zone);
-  integer = Type::Range(minusinfinity, infinity, zone);
-  weakint = Type::Union(integer, nan_or_minuszero, zone);
-
-  number_fun0_ = Type::Function(number, zone);
-  number_fun1_ = Type::Function(number, number, zone);
-  number_fun2_ = Type::Function(number, number, number, zone);
-
-  weakint_fun1_ = Type::Function(weakint, number, zone);
-  random_fun_ = Type::Function(Type::OrderedNumber(), zone);
-
-  const int limits_count = 20;
-
-  weaken_min_limits_.reserve(limits_count + 1);
-  weaken_max_limits_.reserve(limits_count + 1);
-
-  double limit = 1 << 30;
-  weaken_min_limits_.push_back(f->NewNumber(0));
-  weaken_max_limits_.push_back(f->NewNumber(0));
-  for (int i = 0; i < limits_count; i++) {
-    weaken_min_limits_.push_back(f->NewNumber(-limit));
-    weaken_max_limits_.push_back(f->NewNumber(limit - 1));
-    limit *= 2;
-  }
 
   decorator_ = new (zone) Decorator(this);
   graph_->AddDecorator(decorator_);
@@ -229,21 +80,23 @@
 
 class Typer::Visitor : public Reducer {
  public:
-  explicit Visitor(Typer* typer) : typer_(typer) {}
+  explicit Visitor(Typer* typer)
+      : typer_(typer), weakened_nodes_(typer->zone()) {}
 
-  Reduction Reduce(Node* node) OVERRIDE {
+  Reduction Reduce(Node* node) override {
     if (node->op()->ValueOutputCount() == 0) return NoChange();
     switch (node->opcode()) {
 #define DECLARE_CASE(x) \
   case IrOpcode::k##x:  \
-    return UpdateBounds(node, TypeBinaryOp(node, x##Typer));
+    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 UpdateBounds(node, Type##x(node));
+    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)
@@ -255,15 +108,30 @@
 #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(Return)
+      DECLARE_CASE(TailCall)
+      DECLARE_CASE(Terminate)
+      DECLARE_CASE(OsrNormalEntry)
+      DECLARE_CASE(OsrLoopEntry)
+      DECLARE_CASE(Throw)
       DECLARE_CASE(End)
-      INNER_CONTROL_OP_LIST(DECLARE_CASE)
 #undef DECLARE_CASE
       break;
     }
     return NoChange();
   }
 
-  Bounds TypeNode(Node* node) {
+  Type* TypeNode(Node* node) {
     switch (node->opcode()) {
 #define DECLARE_CASE(x) \
       case IrOpcode::k##x: return TypeBinaryOp(node, x##Typer);
@@ -272,6 +140,7 @@
 
 #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)
@@ -283,64 +152,93 @@
 #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(Return)
+      DECLARE_CASE(TailCall)
+      DECLARE_CASE(Terminate)
+      DECLARE_CASE(OsrNormalEntry)
+      DECLARE_CASE(OsrLoopEntry)
+      DECLARE_CASE(Throw)
       DECLARE_CASE(End)
-      INNER_CONTROL_OP_LIST(DECLARE_CASE)
 #undef DECLARE_CASE
       break;
     }
     UNREACHABLE();
-    return Bounds();
+    return nullptr;
   }
 
   Type* TypeConstant(Handle<Object> value);
 
  private:
   Typer* typer_;
-  MaybeHandle<Context> context_;
+  ZoneSet<NodeId> weakened_nodes_;
 
-#define DECLARE_METHOD(x) inline Bounds Type##x(Node* node);
+#define DECLARE_METHOD(x) inline Type* Type##x(Node* node);
   DECLARE_METHOD(Start)
+  DECLARE_METHOD(IfException)
   VALUE_OP_LIST(DECLARE_METHOD)
 #undef DECLARE_METHOD
 
-  Bounds BoundsOrNone(Node* node) {
-    return NodeProperties::IsTyped(node) ? NodeProperties::GetBounds(node)
-                                         : Bounds(Type::None());
+  Type* TypeOrNone(Node* node) {
+    return NodeProperties::IsTyped(node) ? NodeProperties::GetType(node)
+                                         : Type::None();
   }
 
-  Bounds Operand(Node* node, int i) {
+  Type* Operand(Node* node, int i) {
     Node* operand_node = NodeProperties::GetValueInput(node, i);
-    return BoundsOrNone(operand_node);
+    return TypeOrNone(operand_node);
   }
 
-  Bounds ContextOperand(Node* node) {
-    Bounds result = BoundsOrNone(NodeProperties::GetContextInput(node));
-    DCHECK(result.upper->Maybe(Type::Internal()));
-    // TODO(rossberg): More precisely, instead of the above assertion, we should
-    // back-propagate the constraint that it has to be a subtype of Internal.
-    return result;
-  }
-
-  Type* Weaken(Type* current_type, Type* previous_type);
+  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(); }
-  MaybeHandle<Context> context() { return typer_->context(); }
+  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);
 
-  Bounds TypeUnaryOp(Node* node, UnaryTyperFun);
-  Bounds TypeBinaryOp(Node* node, BinaryTyperFun);
+  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(Type*, Typer*);
+  static Type* FalsifyUndefined(ComparisonOutcome, Typer*);
   static Type* Rangify(Type*, 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* NumberToInt32(Type*, Typer*);
   static Type* NumberToUint32(Type*, Typer*);
@@ -351,68 +249,52 @@
   static Type* JSDivideRanger(Type::RangeType*, Type::RangeType*, Typer*);
   static Type* JSModulusRanger(Type::RangeType*, Type::RangeType*, Typer*);
 
-  static Type* JSCompareTyper(Type*, 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* JSUnaryNotTyper(Type*, Typer*);
+  static Type* JSTypeOfTyper(Type*, Typer*);
   static Type* JSLoadPropertyTyper(Type*, Type*, Typer*);
   static Type* JSCallFunctionTyper(Type*, Typer*);
 
-  Reduction UpdateBounds(Node* node, Bounds current) {
+  static Type* ReferenceEqualTyper(Type*, Type*, Typer*);
+
+  Reduction UpdateType(Node* node, Type* current) {
     if (NodeProperties::IsTyped(node)) {
-      // Widen the bounds of a previously typed node.
-      Bounds previous = NodeProperties::GetBounds(node);
-      // Speed up termination in the presence of range types:
-      current.upper = Weaken(current.upper, previous.upper);
-      current.lower = Weaken(current.lower, previous.lower);
+      // 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);
+      }
 
-      // Types should not get less precise.
-      DCHECK(previous.lower->Is(current.lower));
-      DCHECK(previous.upper->Is(current.upper));
+      CHECK(previous->Is(current));
 
-      NodeProperties::SetBounds(node, current);
-      if (!(previous.Narrows(current) && current.Narrows(previous))) {
+      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 bounds.
-      NodeProperties::SetBounds(node, current);
+      // No previous type, simply update the type.
+      NodeProperties::SetType(node, current);
       return Changed(node);
     }
   }
 };
 
 
-void Typer::Run() {
-  {
-    // TODO(titzer): this is a hack. Reset types for interior nodes first.
-    NodeDeque deque(zone());
-    NodeMarker<bool> marked(graph(), 2);
-    deque.push_front(graph()->end());
-    marked.Set(graph()->end(), true);
-    while (!deque.empty()) {
-      Node* node = deque.front();
-      deque.pop_front();
-      // TODO(titzer): there shouldn't be a need to retype constants.
-      if (node->op()->ValueOutputCount() > 0)
-        NodeProperties::RemoveBounds(node);
-      for (Node* input : node->inputs()) {
-        if (!marked.Get(input)) {
-          marked.Set(input, true);
-          deque.push_back(input);
-        }
-      }
-    }
-  }
+void Typer::Run() { Run(NodeVector(zone())); }
 
+
+void Typer::Run(const NodeVector& roots) {
   Visitor visitor(this);
-  GraphReducer graph_reducer(graph(), zone());
+  GraphReducer graph_reducer(zone(), graph());
   graph_reducer.AddReducer(&visitor);
+  for (Node* const root : roots) graph_reducer.ReduceNode(root);
   graph_reducer.ReduceGraph();
 }
 
@@ -424,12 +306,12 @@
     bool is_typed = NodeProperties::IsTyped(node);
     if (is_typed || NodeProperties::AllValueInputsAreTyped(node)) {
       Visitor typing(typer_);
-      Bounds bounds = typing.TypeNode(node);
+      Type* type = typing.TypeNode(node);
       if (is_typed) {
-        bounds =
-          Bounds::Both(bounds, NodeProperties::GetBounds(node), typer_->zone());
+        type = Type::Intersect(type, NodeProperties::GetType(node),
+                               typer_->zone());
       }
-      NodeProperties::SetBounds(node, bounds);
+      NodeProperties::SetType(node, type);
     }
   }
 }
@@ -442,54 +324,54 @@
 // as an argument.
 
 
-Bounds Typer::Visitor::TypeUnaryOp(Node* node, UnaryTyperFun f) {
-  Bounds input = Operand(node, 0);
-  Type* upper = input.upper->Is(Type::None())
-      ? Type::None()
-      : f(input.upper, typer_);
-  Type* lower = input.lower->Is(Type::None())
-      ? Type::None()
-      : (input.lower == input.upper || upper->IsConstant())
-      ? upper  // TODO(neis): Extend this to Range(x,x), NaN, MinusZero, ...?
-      : f(input.lower, typer_);
-  // TODO(neis): Figure out what to do with lower bound.
-  return Bounds(lower, upper);
+Type* Typer::Visitor::TypeUnaryOp(Node* node, UnaryTyperFun f) {
+  Type* input = Operand(node, 0);
+  return input->IsInhabited() ? f(input, typer_) : Type::None();
 }
 
 
-Bounds Typer::Visitor::TypeBinaryOp(Node* node, BinaryTyperFun f) {
-  Bounds left = Operand(node, 0);
-  Bounds right = Operand(node, 1);
-  Type* upper = left.upper->Is(Type::None()) || right.upper->Is(Type::None())
-      ? Type::None()
-      : f(left.upper, right.upper, typer_);
-  Type* lower = left.lower->Is(Type::None()) || right.lower->Is(Type::None())
-      ? Type::None()
-      : ((left.lower == left.upper && right.lower == right.upper) ||
-         upper->IsConstant())
-      ? upper
-      : f(left.lower, right.lower, typer_);
-  // TODO(neis): Figure out what to do with lower bound.
-  return Bounds(lower, upper);
+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) {
-  if (type->Is(t->singleton_false)) return t->singleton_true;
-  if (type->Is(t->singleton_true)) return t->singleton_false;
+  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;
 }
 
 
-Type* Typer::Visitor::FalsifyUndefined(Type* type, Typer* t) {
-  if (type->Is(Type::Undefined())) 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* Typer::Visitor::Rangify(Type* type, Typer* t) {
   if (type->IsRange()) return type;        // Shortcut.
-  if (!type->Is(t->integer) && !type->Is(Type::Integral32())) {
+  if (!type->Is(t->cache_.kInteger)) {
     return type;  // Give up on non-integer types.
   }
   double min = type->Min();
@@ -500,8 +382,7 @@
     DCHECK(std::isnan(max));
     return type;
   }
-  Factory* f = t->isolate()->factory();
-  return Type::Range(f->NewNumber(min), f->NewNumber(max), t->zone());
+  return Type::Range(min, max, t->zone());
 }
 
 
@@ -518,38 +399,84 @@
 
 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(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 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;
+  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::Null())) return t->singleton_zero;
-  if (type->Is(Type::Undefined())) return Type::NaN();
-  if (type->Is(t->undefined_or_null)) {
-    return Type::Union(Type::NaN(), t->singleton_zero, t->zone());
+  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(t->undefined_or_number)) {
+  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->singleton_zero;
-  if (type->Is(t->singleton_true)) return t->singleton_one;
-  if (type->Is(Type::Boolean())) return t->zero_or_one;
-  if (type->Is(t->boolean_or_number)) {
+  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->zero_or_one, 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::Undetectable())) 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();
 }
@@ -558,10 +485,11 @@
 Type* Typer::Visitor::NumberToInt32(Type* type, Typer* t) {
   // TODO(neis): DCHECK(type->Is(Type::Number()));
   if (type->Is(Type::Signed32())) return type;
-  if (type->Is(t->zeroish)) return t->singleton_zero;
-  if (type->Is(t->signed32ish)) {
-    return Type::Intersect(Type::Union(type, t->singleton_zero, t->zone()),
-                           Type::Signed32(), t->zone());
+  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();
 }
@@ -570,10 +498,11 @@
 Type* Typer::Visitor::NumberToUint32(Type* type, Typer* t) {
   // TODO(neis): DCHECK(type->Is(Type::Number()));
   if (type->Is(Type::Unsigned32())) return type;
-  if (type->Is(t->zeroish)) return t->singleton_zero;
-  if (type->Is(t->unsigned32ish)) {
-    return Type::Intersect(Type::Union(type, t->singleton_zero, t->zone()),
-                           Type::Unsigned32(), t->zone());
+  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();
 }
@@ -585,135 +514,167 @@
 // Control operators.
 
 
-Bounds Typer::Visitor::TypeStart(Node* node) {
-  return Bounds(Type::None(zone()), Type::Internal(zone()));
-}
+Type* Typer::Visitor::TypeStart(Node* node) { return Type::Internal(zone()); }
+
+
+Type* Typer::Visitor::TypeIfException(Node* node) { return Type::Any(); }
 
 
 // Common operators.
 
 
-Bounds Typer::Visitor::TypeParameter(Node* node) {
-  return Bounds::Unbounded(zone());
-}
-
-
-Bounds Typer::Visitor::TypeInt32Constant(Node* node) {
-  Factory* f = isolate()->factory();
-  Handle<Object> number = f->NewNumber(OpParameter<int32_t>(node));
-  return Bounds(Type::Intersect(
-      Type::Range(number, number, zone()), Type::UntaggedSigned32(), zone()));
-}
-
-
-Bounds Typer::Visitor::TypeInt64Constant(Node* node) {
-  // TODO(rossberg): This actually seems to be a PointerConstant so far...
-  return Bounds(Type::Internal());  // TODO(rossberg): Add int64 bitset type?
-}
-
-
-Bounds Typer::Visitor::TypeFloat32Constant(Node* node) {
-  return Bounds(Type::Intersect(
-      Type::Of(OpParameter<float>(node), zone()),
-      Type::UntaggedFloat32(), zone()));
-}
-
-
-Bounds Typer::Visitor::TypeFloat64Constant(Node* node) {
-  return Bounds(Type::Intersect(
-      Type::Of(OpParameter<double>(node), zone()),
-      Type::UntaggedFloat64(), zone()));
-}
-
-
-Bounds Typer::Visitor::TypeNumberConstant(Node* node) {
-  Factory* f = isolate()->factory();
-  return Bounds(Type::Constant(
-      f->NewNumber(OpParameter<double>(node)), zone()));
-}
-
-
-Bounds Typer::Visitor::TypeHeapConstant(Node* node) {
-  return Bounds(TypeConstant(OpParameter<Unique<HeapObject> >(node).handle()));
-}
-
-
-Bounds Typer::Visitor::TypeExternalConstant(Node* node) {
-  return Bounds(Type::None(zone()), Type::Internal(zone()));
-}
-
-
-Bounds Typer::Visitor::TypeSelect(Node* node) {
-  return Bounds::Either(Operand(node, 1), Operand(node, 2), zone());
-}
-
-
-Bounds Typer::Visitor::TypePhi(Node* node) {
-  int arity = node->op()->ValueInputCount();
-  Bounds bounds = Operand(node, 0);
-  for (int i = 1; i < arity; ++i) {
-    bounds = Bounds::Either(bounds, Operand(node, i), zone());
+Type* Typer::Visitor::TypeParameter(Node* node) {
+  if (Type::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 bounds;
+  return Type::Any();
 }
 
 
-Bounds Typer::Visitor::TypeEffectPhi(Node* node) {
+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?
+}
+
+
+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(zone());
+}
+
+
+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 Bounds();
+  return nullptr;
 }
 
 
-Bounds Typer::Visitor::TypeValueEffect(Node* node) {
+Type* Typer::Visitor::TypeEffectSet(Node* node) {
   UNREACHABLE();
-  return Bounds();
+  return nullptr;
 }
 
 
-Bounds Typer::Visitor::TypeFinish(Node* node) {
-  return Operand(node, 0);
+Type* Typer::Visitor::TypeGuard(Node* node) {
+  Type* input_type = Operand(node, 0);
+  Type* guard_type = OpParameter<Type*>(node);
+  return Type::Intersect(input_type, guard_type, zone());
 }
 
 
-Bounds Typer::Visitor::TypeFrameState(Node* node) {
+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 Bounds(Type::None(zone()), Type::Internal(zone()));
+  return Type::Internal(zone());
 }
 
 
-Bounds Typer::Visitor::TypeStateValues(Node* node) {
-  return Bounds(Type::None(zone()), Type::Internal(zone()));
+Type* Typer::Visitor::TypeStateValues(Node* node) {
+  return Type::Internal(zone());
 }
 
 
-Bounds Typer::Visitor::TypeCall(Node* node) {
-  return Bounds::Unbounded(zone());
+Type* Typer::Visitor::TypeObjectState(Node* node) {
+  return Type::Internal(zone());
 }
 
 
-Bounds Typer::Visitor::TypeProjection(Node* node) {
+Type* Typer::Visitor::TypeTypedStateValues(Node* node) {
+  return Type::Internal(zone());
+}
+
+
+Type* Typer::Visitor::TypeCall(Node* node) { return Type::Any(); }
+
+
+Type* Typer::Visitor::TypeProjection(Node* node) {
   // TODO(titzer): use the output type of the input to determine the bounds.
-  return Bounds::Unbounded(zone());
+  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(t->undefined_or_null) && rhs->Is(t->undefined_or_null)) {
-    return t->singleton_true;
+  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;
+    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.
     // TODO(neis): Extend this to Range(x,x), MinusZero, ...?
-    return t->singleton_true;
+    return t->singleton_true_;
   }
   return Type::Boolean();
 }
@@ -737,16 +698,20 @@
 
 
 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 (!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;
+    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 t->singleton_true_;
   }
   return Type::Boolean();
 }
@@ -761,26 +726,41 @@
 // (<, <=, >=, >) 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.
-Type* Typer::Visitor::JSCompareTyper(Type* lhs, Type* rhs, Typer* t) {
+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 Type::Boolean();
+    return ComparisonOutcome(kComparisonTrue) |
+           ComparisonOutcome(kComparisonFalse);
   }
   lhs = ToNumber(lhs, t);
   rhs = ToNumber(rhs, t);
-  if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::Undefined();
+
+  // 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,
-    // which is not NaN due to the previous check.
-    return t->singleton_false;
+    // 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);
   }
-  if (lhs->Min() >= rhs->Max()) return t->singleton_false;
-  if (lhs->Max() < rhs->Min() &&
-      !lhs->Maybe(Type::NaN()) && !rhs->Maybe(Type::NaN())) {
-    return t->singleton_true;
+  // Add the undefined if we could see NaN.
+  if (lhs->Maybe(Type::NaN()) || rhs->Maybe(Type::NaN())) {
+    result |= kComparisonUndefined;
   }
-  return Type::Boolean();
+  return result;
 }
 
 
@@ -809,7 +789,6 @@
 
 
 Type* Typer::Visitor::JSBitwiseOrTyper(Type* lhs, Type* rhs, Typer* t) {
-  Factory* f = t->isolate()->factory();
   lhs = NumberToInt32(ToNumber(lhs, t), t);
   rhs = NumberToInt32(ToNumber(rhs, t), t);
   double lmin = lhs->Min();
@@ -837,13 +816,12 @@
     // value.
     max = std::min(max, -1.0);
   }
-  return Type::Range(f->NewNumber(min), f->NewNumber(max), t->zone());
+  return Type::Range(min, max, t->zone());
   // TODO(neis): Be precise for singleton inputs, here and elsewhere.
 }
 
 
 Type* Typer::Visitor::JSBitwiseAndTyper(Type* lhs, Type* rhs, Typer* t) {
-  Factory* f = t->isolate()->factory();
   lhs = NumberToInt32(ToNumber(lhs, t), t);
   rhs = NumberToInt32(ToNumber(rhs, t), t);
   double lmin = lhs->Min();
@@ -865,7 +843,7 @@
     min = 0;
     max = std::min(max, rmax);
   }
-  return Type::Range(f->NewNumber(min), f->NewNumber(max), t->zone());
+  return Type::Range(min, max, t->zone());
 }
 
 
@@ -878,12 +856,12 @@
   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::NonNegativeSigned32();
+    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::NegativeSigned32();
+    return Type::Negative32();
   }
   return Type::Signed32();
 }
@@ -903,11 +881,17 @@
     // 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.
@@ -919,8 +903,7 @@
   // TODO(jarin) Ideally, the following micro-optimization should be performed
   // by the type constructor.
   if (max != Type::Signed32()->Max() || min != Type::Signed32()->Min()) {
-    Factory* f = t->isolate()->factory();
-    return Type::Range(f->NewNumber(min), f->NewNumber(max), t->zone());
+    return Type::Range(min, max, t->zone());
   }
   return Type::Signed32();
 }
@@ -928,11 +911,8 @@
 
 Type* Typer::Visitor::JSShiftRightLogicalTyper(Type* lhs, Type* rhs, Typer* t) {
   lhs = NumberToUint32(ToNumber(lhs, t), t);
-  Factory* f = t->isolate()->factory();
   // Logical right-shifting any value cannot make it larger.
-  Handle<Object> min = f->NewNumber(0);
-  Handle<Object> max = f->NewNumber(lhs->Max());
-  return Type::Range(min, max, t->zone());
+  return Type::Range(0.0, lhs->Max(), t->zone());
 }
 
 
@@ -974,10 +954,10 @@
 Type* Typer::Visitor::JSAddRanger(Type::RangeType* lhs, Type::RangeType* rhs,
                                   Typer* t) {
   double results[4];
-  results[0] = lhs->Min()->Number() + rhs->Min()->Number();
-  results[1] = lhs->Min()->Number() + rhs->Max()->Number();
-  results[2] = lhs->Max()->Number() + rhs->Min()->Number();
-  results[3] = lhs->Max()->Number() + rhs->Max()->Number();
+  results[0] = lhs->Min() + rhs->Min();
+  results[1] = lhs->Min() + rhs->Max();
+  results[2] = lhs->Max() + rhs->Min();
+  results[3] = lhs->Max() + rhs->Max();
   // Since none of the inputs can be -0, the result cannot be -0 either.
   // However, it can be nan (the sum of two infinities of opposite sign).
   // On the other hand, if none of the "results" above is nan, then the actual
@@ -987,9 +967,8 @@
     if (std::isnan(results[i])) ++nans;
   }
   if (nans == 4) return Type::NaN();  // [-inf..-inf] + [inf..inf] or vice versa
-  Factory* f = t->isolate()->factory();
-  Type* range = Type::Range(f->NewNumber(array_min(results, 4)),
-                            f->NewNumber(array_max(results, 4)), t->zone());
+  Type* range =
+      Type::Range(array_min(results, 4), array_max(results, 4), t->zone());
   return nans == 0 ? range : Type::Union(range, Type::NaN(), t->zone());
   // Examples:
   //   [-inf, -inf] + [+inf, +inf] = NaN
@@ -1023,10 +1002,10 @@
 Type* Typer::Visitor::JSSubtractRanger(Type::RangeType* lhs,
                                        Type::RangeType* rhs, Typer* t) {
   double results[4];
-  results[0] = lhs->Min()->Number() - rhs->Min()->Number();
-  results[1] = lhs->Min()->Number() - rhs->Max()->Number();
-  results[2] = lhs->Max()->Number() - rhs->Min()->Number();
-  results[3] = lhs->Max()->Number() - rhs->Max()->Number();
+  results[0] = lhs->Min() - rhs->Min();
+  results[1] = lhs->Min() - rhs->Max();
+  results[2] = lhs->Max() - rhs->Min();
+  results[3] = lhs->Max() - rhs->Max();
   // Since none of the inputs can be -0, the result cannot be -0.
   // However, it can be nan (the subtraction of two infinities of same sign).
   // On the other hand, if none of the "results" above is nan, then the actual
@@ -1036,9 +1015,8 @@
     if (std::isnan(results[i])) ++nans;
   }
   if (nans == 4) return Type::NaN();  // [inf..inf] - [inf..inf] (all same sign)
-  Factory* f = t->isolate()->factory();
-  Type* range = Type::Range(f->NewNumber(array_min(results, 4)),
-                            f->NewNumber(array_max(results, 4)), t->zone());
+  Type* range =
+      Type::Range(array_min(results, 4), array_max(results, 4), t->zone());
   return nans == 0 ? range : Type::Union(range, Type::NaN(), t->zone());
   // Examples:
   //   [-inf, +inf] - [-inf, +inf] = [-inf, +inf] \/ NaN
@@ -1062,10 +1040,10 @@
 Type* Typer::Visitor::JSMultiplyRanger(Type::RangeType* lhs,
                                        Type::RangeType* rhs, Typer* t) {
   double results[4];
-  double lmin = lhs->Min()->Number();
-  double lmax = lhs->Max()->Number();
-  double rmin = rhs->Min()->Number();
-  double rmax = rhs->Max()->Number();
+  double lmin = lhs->Min();
+  double lmax = lhs->Max();
+  double rmin = rhs->Min();
+  double rmax = rhs->Max();
   results[0] = lmin * rmin;
   results[1] = lmin * rmax;
   results[2] = lmax * rmin;
@@ -1074,16 +1052,15 @@
   // the discontinuity makes it too complicated.  Note that even if none of the
   // "results" above is nan, the actual result may still be, so we have to do a
   // different check:
-  bool maybe_nan = (lhs->Maybe(t->singleton_zero) &&
+  bool maybe_nan = (lhs->Maybe(t->cache_.kSingletonZero) &&
                     (rmin == -V8_INFINITY || rmax == +V8_INFINITY)) ||
-                   (rhs->Maybe(t->singleton_zero) &&
+                   (rhs->Maybe(t->cache_.kSingletonZero) &&
                     (lmin == -V8_INFINITY || lmax == +V8_INFINITY));
-  if (maybe_nan) return t->weakint;  // Giving up.
-  bool maybe_minuszero = (lhs->Maybe(t->singleton_zero) && rmin < 0) ||
-                         (rhs->Maybe(t->singleton_zero) && lmin < 0);
-  Factory* f = t->isolate()->factory();
-  Type* range = Type::Range(f->NewNumber(array_min(results, 4)),
-                            f->NewNumber(array_max(results, 4)), t->zone());
+  if (maybe_nan) return t->cache_.kIntegerOrMinusZeroOrNaN;  // Giving up.
+  bool maybe_minuszero = (lhs->Maybe(t->cache_.kSingletonZero) && rmin < 0) ||
+                         (rhs->Maybe(t->cache_.kSingletonZero) && lmin < 0);
+  Type* range =
+      Type::Range(array_min(results, 4), array_max(results, 4), t->zone());
   return maybe_minuszero ? Type::Union(range, Type::MinusZero(), t->zone())
                          : range;
 }
@@ -1107,7 +1084,7 @@
   // Division is tricky, so all we do is try ruling out nan.
   // TODO(neis): try ruling out -0 as well?
   bool maybe_nan =
-      lhs->Maybe(Type::NaN()) || rhs->Maybe(t->zeroish) ||
+      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();
@@ -1116,10 +1093,10 @@
 
 Type* Typer::Visitor::JSModulusRanger(Type::RangeType* lhs,
                                       Type::RangeType* rhs, Typer* t) {
-  double lmin = lhs->Min()->Number();
-  double lmax = lhs->Max()->Number();
-  double rmin = rhs->Min()->Number();
-  double rmax = rhs->Max()->Number();
+  double lmin = lhs->Min();
+  double lmax = lhs->Max();
+  double rmin = rhs->Min();
+  double rmax = rhs->Max();
 
   double labs = std::max(std::abs(lmin), std::abs(lmax));
   double rabs = std::max(std::abs(rmin), std::abs(rmax)) - 1;
@@ -1140,8 +1117,7 @@
     maybe_minus_zero = true;
   }
 
-  Factory* f = t->isolate()->factory();
-  Type* result = Type::Range(f->NewNumber(omin), f->NewNumber(omax), t->zone());
+  Type* result = Type::Range(omin, omax, t->zone());
   if (maybe_minus_zero)
     result = Type::Union(result, Type::MinusZero(), t->zone());
   return result;
@@ -1153,7 +1129,7 @@
   rhs = ToNumber(rhs, t);
   if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
 
-  if (lhs->Maybe(Type::NaN()) || rhs->Maybe(t->zeroish) ||
+  if (lhs->Maybe(Type::NaN()) || rhs->Maybe(t->cache_.kZeroish) ||
       lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) {
     // Result maybe NaN.
     return Type::Number();
@@ -1171,54 +1147,102 @@
 // JS unary operators.
 
 
-Type* Typer::Visitor::JSUnaryNotTyper(Type* type, Typer* t) {
-  return Invert(ToBoolean(type, t), t);
+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::Undetectable(),
+                                  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();
 }
 
 
-Bounds Typer::Visitor::TypeJSUnaryNot(Node* node) {
-  return TypeUnaryOp(node, JSUnaryNotTyper);
-}
-
-
-Bounds Typer::Visitor::TypeJSTypeOf(Node* node) {
-  return Bounds(Type::None(zone()), Type::InternalizedString(zone()));
+Type* Typer::Visitor::TypeJSTypeOf(Node* node) {
+  return TypeUnaryOp(node, JSTypeOfTyper);
 }
 
 
 // JS conversion operators.
 
 
-Bounds Typer::Visitor::TypeJSToBoolean(Node* node) {
+Type* Typer::Visitor::TypeJSToBoolean(Node* node) {
   return TypeUnaryOp(node, ToBoolean);
 }
 
 
-Bounds Typer::Visitor::TypeJSToNumber(Node* node) {
+Type* Typer::Visitor::TypeJSToNumber(Node* node) {
   return TypeUnaryOp(node, ToNumber);
 }
 
 
-Bounds Typer::Visitor::TypeJSToString(Node* node) {
+Type* Typer::Visitor::TypeJSToString(Node* node) {
   return TypeUnaryOp(node, ToString);
 }
 
 
-Bounds Typer::Visitor::TypeJSToName(Node* node) {
-  return Bounds(Type::None(), Type::Name());
+Type* Typer::Visitor::TypeJSToName(Node* node) {
+  return TypeUnaryOp(node, ToName);
 }
 
 
-Bounds Typer::Visitor::TypeJSToObject(Node* node) {
-  return Bounds(Type::None(), Type::Receiver());
+Type* Typer::Visitor::TypeJSToObject(Node* node) {
+  return TypeUnaryOp(node, ToObject);
 }
 
 
 // JS object operators.
 
 
-Bounds Typer::Visitor::TypeJSCreate(Node* node) {
-  return Bounds(Type::None(), Type::Object());
+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();
 }
 
 
@@ -1232,819 +1256,253 @@
 }
 
 
-Bounds Typer::Visitor::TypeJSLoadProperty(Node* node) {
+Type* Typer::Visitor::TypeJSLoadProperty(Node* node) {
   return TypeBinaryOp(node, JSLoadPropertyTyper);
 }
 
 
-Bounds Typer::Visitor::TypeJSLoadNamed(Node* node) {
-  return Bounds::Unbounded(zone());
+Type* Typer::Visitor::TypeJSLoadNamed(Node* node) {
+  Factory* const f = isolate()->factory();
+  Handle<Name> name = NamedAccessOf(node->op()).name();
+  if (name.is_identical_to(f->prototype_string())) {
+    Type* receiver = Operand(node, 0);
+    if (receiver->Is(Type::None())) return Type::None();
+    if (receiver->IsConstant() &&
+        receiver->AsConstant()->Value()->IsJSFunction()) {
+      Handle<JSFunction> function =
+          Handle<JSFunction>::cast(receiver->AsConstant()->Value());
+      if (function->has_prototype()) {
+        // We need to add a code dependency on the initial map of the {function}
+        // in order to be notified about changes to "prototype" of {function},
+        // so we can only infer a constant type if deoptimization is enabled.
+        if (flags() & kDeoptimizationEnabled) {
+          JSFunction::EnsureHasInitialMap(function);
+          Handle<Map> initial_map(function->initial_map(), isolate());
+          dependencies()->AssumeInitialMapCantChange(initial_map);
+          return Type::Constant(handle(initial_map->prototype(), isolate()),
+                                zone());
+        }
+      }
+    } else if (receiver->IsClass() &&
+               receiver->AsClass()->Map()->IsJSFunctionMap()) {
+      Handle<Map> map = receiver->AsClass()->Map();
+      return map->has_non_instance_prototype() ? Type::Primitive(zone())
+                                               : Type::Receiver(zone());
+    }
+  }
+  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(Type* current_type, Type* previous_type) {
-  Type::RangeType* previous = previous_type->GetRange();
-  Type::RangeType* current = current_type->GetRange();
-  if (previous != NULL && current != NULL) {
-    double current_min = current->Min()->Number();
-    Handle<Object> new_min = current->Min();
+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));
 
-    // Find the closest lower entry in the list of allowed
-    // minima (or negative infinity if there is no such entry).
-    if (current_min != previous->Min()->Number()) {
-      new_min = typer_->integer->AsRange()->Min();
-      for (const auto val : typer_->weaken_min_limits_) {
-        if (val->Number() <= current_min) {
-          new_min = val;
-          break;
-        }
-      }
-    }
-
-    double current_max = current->Max()->Number();
-    Handle<Object> 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->Max()->Number()) {
-      new_max = typer_->integer->AsRange()->Max();
-      for (const auto val : typer_->weaken_max_limits_) {
-        if (val->Number() >= current_max) {
-          new_max = val;
-          break;
-        }
-      }
-    }
-
-    return Type::Union(current_type,
-                       Type::Range(new_min, new_max, typer_->zone()),
-                       typer_->zone());
+  // 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;
   }
-  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::RangeType* previous = previous_integer->GetRange();
+    Type::RangeType* 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());
 }
 
 
-Bounds Typer::Visitor::TypeJSStoreProperty(Node* node) {
+Type* Typer::Visitor::TypeJSStoreProperty(Node* node) {
   UNREACHABLE();
-  return Bounds();
+  return nullptr;
 }
 
 
-Bounds Typer::Visitor::TypeJSStoreNamed(Node* node) {
+Type* Typer::Visitor::TypeJSStoreNamed(Node* node) {
   UNREACHABLE();
-  return Bounds();
+  return nullptr;
 }
 
 
-Bounds Typer::Visitor::TypeJSDeleteProperty(Node* node) {
-  return Bounds(Type::None(zone()), Type::Boolean(zone()));
+Type* Typer::Visitor::TypeJSStoreGlobal(Node* node) {
+  UNREACHABLE();
+  return nullptr;
 }
 
 
-Bounds Typer::Visitor::TypeJSHasProperty(Node* node) {
-  return Bounds(Type::None(zone()), Type::Boolean(zone()));
+Type* Typer::Visitor::TypeJSDeleteProperty(Node* node) {
+  return Type::Boolean(zone());
 }
 
 
-Bounds Typer::Visitor::TypeJSInstanceOf(Node* node) {
-  return Bounds(Type::None(zone()), Type::Boolean(zone()));
+Type* Typer::Visitor::TypeJSHasProperty(Node* node) {
+  return Type::Boolean(zone());
+}
+
+
+Type* Typer::Visitor::TypeJSInstanceOf(Node* node) {
+  return Type::Boolean(zone());
 }
 
 
 // JS context operators.
 
 
-Bounds Typer::Visitor::TypeJSLoadContext(Node* node) {
-  Bounds outer = Operand(node, 0);
-  Type* context_type = outer.upper;
-  if (context_type->Is(Type::None())) {
-    // Upper bound of context is not yet known.
-    return Bounds(Type::None(), Type::Any());
+Type* Typer::Visitor::TypeJSLoadContext(Node* node) {
+  ContextAccess const& access = ContextAccessOf(node->op());
+  if (access.index() == Context::EXTENSION_INDEX) {
+    return Type::TaggedPointer();
   }
-
-  DCHECK(context_type->Maybe(Type::Internal()));
-  // TODO(rossberg): More precisely, instead of the above assertion, we should
-  // back-propagate the constraint that it has to be a subtype of Internal.
-
-  ContextAccess access = OpParameter<ContextAccess>(node);
-  MaybeHandle<Context> context;
-  if (context_type->IsConstant()) {
-    context = Handle<Context>::cast(context_type->AsConstant()->Value());
-  }
-  // Walk context chain (as far as known), mirroring dynamic lookup.
-  // Since contexts are mutable, the information is only useful as a lower
-  // bound.
-  // TODO(rossberg): Could use scope info to fix upper bounds for constant
-  // bindings if we know that this code is never shared.
-  for (size_t i = access.depth(); i > 0; --i) {
-    if (context_type->IsContext()) {
-      context_type = context_type->AsContext()->Outer();
-      if (context_type->IsConstant()) {
-        context = Handle<Context>::cast(context_type->AsConstant()->Value());
-      }
-    } else if (!context.is_null()) {
-      context = handle(context.ToHandleChecked()->previous(), isolate());
-    }
-  }
-  if (context.is_null()) {
-    return Bounds::Unbounded(zone());
-  } else {
-    Handle<Object> value =
-        handle(context.ToHandleChecked()->get(static_cast<int>(access.index())),
-               isolate());
-    Type* lower = TypeConstant(value);
-    return Bounds(lower, Type::Any());
-  }
+  // Since contexts are mutable, we just return the top.
+  return Type::Any();
 }
 
 
-Bounds Typer::Visitor::TypeJSStoreContext(Node* node) {
+Type* Typer::Visitor::TypeJSStoreContext(Node* node) {
   UNREACHABLE();
-  return Bounds();
+  return nullptr;
 }
 
 
-Bounds Typer::Visitor::TypeJSCreateFunctionContext(Node* node) {
-  Bounds outer = ContextOperand(node);
-  return Bounds(Type::Context(outer.upper, zone()));
+Type* Typer::Visitor::TypeJSLoadDynamic(Node* node) { return Type::Any(); }
+
+
+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());
+  }
 }
 
 
-Bounds Typer::Visitor::TypeJSCreateCatchContext(Node* node) {
-  Bounds outer = ContextOperand(node);
-  return Bounds(Type::Context(outer.upper, zone()));
+Type* Typer::Visitor::TypeJSCreateFunctionContext(Node* node) {
+  return WrapContextTypeForInput(node);
 }
 
 
-Bounds Typer::Visitor::TypeJSCreateWithContext(Node* node) {
-  Bounds outer = ContextOperand(node);
-  return Bounds(Type::Context(outer.upper, zone()));
+Type* Typer::Visitor::TypeJSCreateCatchContext(Node* node) {
+  return WrapContextTypeForInput(node);
 }
 
 
-Bounds Typer::Visitor::TypeJSCreateBlockContext(Node* node) {
-  Bounds outer = ContextOperand(node);
-  return Bounds(Type::Context(outer.upper, zone()));
+Type* Typer::Visitor::TypeJSCreateWithContext(Node* node) {
+  return WrapContextTypeForInput(node);
 }
 
 
-Bounds Typer::Visitor::TypeJSCreateModuleContext(Node* node) {
+Type* Typer::Visitor::TypeJSCreateBlockContext(Node* node) {
+  return WrapContextTypeForInput(node);
+}
+
+
+Type* Typer::Visitor::TypeJSCreateModuleContext(Node* node) {
   // TODO(rossberg): this is probably incorrect
-  Bounds outer = ContextOperand(node);
-  return Bounds(Type::Context(outer.upper, zone()));
+  return WrapContextTypeForInput(node);
 }
 
 
-Bounds Typer::Visitor::TypeJSCreateScriptContext(Node* node) {
-  Bounds outer = ContextOperand(node);
-  return Bounds(Type::Context(outer.upper, zone()));
+Type* Typer::Visitor::TypeJSCreateScriptContext(Node* node) {
+  return WrapContextTypeForInput(node);
 }
 
 
 // JS other operators.
 
 
-Bounds Typer::Visitor::TypeJSYield(Node* node) {
-  return Bounds::Unbounded(zone());
-}
+Type* Typer::Visitor::TypeJSYield(Node* node) { return Type::Any(); }
 
 
-Bounds Typer::Visitor::TypeJSCallConstruct(Node* node) {
-  return Bounds(Type::None(), Type::Receiver());
+Type* Typer::Visitor::TypeJSCallConstruct(Node* node) {
+  return Type::Receiver();
 }
 
 
 Type* Typer::Visitor::JSCallFunctionTyper(Type* fun, Typer* t) {
-  return fun->IsFunction() ? fun->AsFunction()->Result() : Type::Any();
-}
-
-
-Bounds Typer::Visitor::TypeJSCallFunction(Node* node) {
-  return TypeUnaryOp(node, JSCallFunctionTyper);  // We ignore argument types.
-}
-
-
-Bounds Typer::Visitor::TypeJSCallRuntime(Node* node) {
-  return Bounds::Unbounded(zone());
-}
-
-
-Bounds Typer::Visitor::TypeJSDebugger(Node* node) {
-  return Bounds::Unbounded(zone());
-}
-
-
-// Simplified operators.
-
-
-Bounds Typer::Visitor::TypeAnyToBoolean(Node* node) {
-  return TypeUnaryOp(node, ToBoolean);
-}
-
-
-Bounds Typer::Visitor::TypeBooleanNot(Node* node) {
-  return Bounds(Type::None(zone()), Type::Boolean(zone()));
-}
-
-
-Bounds Typer::Visitor::TypeBooleanToNumber(Node* node) {
-  return Bounds(Type::None(zone()), typer_->zero_or_one);
-}
-
-
-Bounds Typer::Visitor::TypeNumberEqual(Node* node) {
-  return Bounds(Type::None(zone()), Type::Boolean(zone()));
-}
-
-
-Bounds Typer::Visitor::TypeNumberLessThan(Node* node) {
-  return Bounds(Type::None(zone()), Type::Boolean(zone()));
-}
-
-
-Bounds Typer::Visitor::TypeNumberLessThanOrEqual(Node* node) {
-  return Bounds(Type::None(zone()), Type::Boolean(zone()));
-}
-
-
-Bounds Typer::Visitor::TypeNumberAdd(Node* node) {
-  return Bounds(Type::None(zone()), Type::Number(zone()));
-}
-
-
-Bounds Typer::Visitor::TypeNumberSubtract(Node* node) {
-  return Bounds(Type::None(zone()), Type::Number(zone()));
-}
-
-
-Bounds Typer::Visitor::TypeNumberMultiply(Node* node) {
-  return Bounds(Type::None(zone()), Type::Number(zone()));
-}
-
-
-Bounds Typer::Visitor::TypeNumberDivide(Node* node) {
-  return Bounds(Type::None(zone()), Type::Number(zone()));
-}
-
-
-Bounds Typer::Visitor::TypeNumberModulus(Node* node) {
-  return Bounds(Type::None(zone()), Type::Number(zone()));
-}
-
-
-Bounds Typer::Visitor::TypeNumberToInt32(Node* node) {
-  return TypeUnaryOp(node, NumberToInt32);
-}
-
-
-Bounds Typer::Visitor::TypeNumberToUint32(Node* node) {
-  return TypeUnaryOp(node, NumberToUint32);
-}
-
-
-Bounds Typer::Visitor::TypeReferenceEqual(Node* node) {
-  return Bounds(Type::None(zone()), Type::Boolean(zone()));
-}
-
-
-Bounds Typer::Visitor::TypeStringEqual(Node* node) {
-  return Bounds(Type::None(zone()), Type::Boolean(zone()));
-}
-
-
-Bounds Typer::Visitor::TypeStringLessThan(Node* node) {
-  return Bounds(Type::None(zone()), Type::Boolean(zone()));
-}
-
-
-Bounds Typer::Visitor::TypeStringLessThanOrEqual(Node* node) {
-  return Bounds(Type::None(zone()), Type::Boolean(zone()));
-}
-
-
-Bounds Typer::Visitor::TypeStringAdd(Node* node) {
-  return Bounds(Type::None(zone()), Type::String(zone()));
-}
-
-
-static Type* ChangeRepresentation(Type* type, Type* rep, Zone* zone) {
-  // TODO(neis): Enable when expressible.
-  /*
-  return Type::Union(
-      Type::Intersect(type, Type::Semantic(), zone),
-      Type::Intersect(rep, Type::Representation(), zone), zone);
-  */
-  return type;
-}
-
-
-Bounds Typer::Visitor::TypeChangeTaggedToInt32(Node* node) {
-  Bounds arg = Operand(node, 0);
-  // TODO(neis): DCHECK(arg.upper->Is(Type::Signed32()));
-  return Bounds(
-      ChangeRepresentation(arg.lower, Type::UntaggedSigned32(), zone()),
-      ChangeRepresentation(arg.upper, Type::UntaggedSigned32(), zone()));
-}
-
-
-Bounds Typer::Visitor::TypeChangeTaggedToUint32(Node* node) {
-  Bounds arg = Operand(node, 0);
-  // TODO(neis): DCHECK(arg.upper->Is(Type::Unsigned32()));
-  return Bounds(
-      ChangeRepresentation(arg.lower, Type::UntaggedUnsigned32(), zone()),
-      ChangeRepresentation(arg.upper, Type::UntaggedUnsigned32(), zone()));
-}
-
-
-Bounds Typer::Visitor::TypeChangeTaggedToFloat64(Node* node) {
-  Bounds arg = Operand(node, 0);
-  // TODO(neis): DCHECK(arg.upper->Is(Type::Number()));
-  return Bounds(
-      ChangeRepresentation(arg.lower, Type::UntaggedFloat64(), zone()),
-      ChangeRepresentation(arg.upper, Type::UntaggedFloat64(), zone()));
-}
-
-
-Bounds Typer::Visitor::TypeChangeInt32ToTagged(Node* node) {
-  Bounds arg = Operand(node, 0);
-  // TODO(neis): DCHECK(arg.upper->Is(Type::Signed32()));
-  return Bounds(
-      ChangeRepresentation(arg.lower, Type::Tagged(), zone()),
-      ChangeRepresentation(arg.upper, Type::Tagged(), zone()));
-}
-
-
-Bounds Typer::Visitor::TypeChangeUint32ToTagged(Node* node) {
-  Bounds arg = Operand(node, 0);
-  // TODO(neis): DCHECK(arg.upper->Is(Type::Unsigned32()));
-  return Bounds(
-      ChangeRepresentation(arg.lower, Type::Tagged(), zone()),
-      ChangeRepresentation(arg.upper, Type::Tagged(), zone()));
-}
-
-
-Bounds Typer::Visitor::TypeChangeFloat64ToTagged(Node* node) {
-  Bounds arg = Operand(node, 0);
-  // TODO(neis): CHECK(arg.upper->Is(Type::Number()));
-  return Bounds(
-      ChangeRepresentation(arg.lower, Type::Tagged(), zone()),
-      ChangeRepresentation(arg.upper, Type::Tagged(), zone()));
-}
-
-
-Bounds Typer::Visitor::TypeChangeBoolToBit(Node* node) {
-  Bounds arg = Operand(node, 0);
-  // TODO(neis): DCHECK(arg.upper->Is(Type::Boolean()));
-  return Bounds(
-      ChangeRepresentation(arg.lower, Type::UntaggedBit(), zone()),
-      ChangeRepresentation(arg.upper, Type::UntaggedBit(), zone()));
-}
-
-
-Bounds Typer::Visitor::TypeChangeBitToBool(Node* node) {
-  Bounds arg = Operand(node, 0);
-  // TODO(neis): DCHECK(arg.upper->Is(Type::Boolean()));
-  return Bounds(
-      ChangeRepresentation(arg.lower, Type::TaggedPointer(), zone()),
-      ChangeRepresentation(arg.upper, Type::TaggedPointer(), zone()));
-}
-
-
-Bounds Typer::Visitor::TypeLoadField(Node* node) {
-  return Bounds(FieldAccessOf(node->op()).type);
-}
-
-
-Bounds 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(Type, type, TYPE, ctype, size) \
-  case kExternal##Type##Array:                          \
-    return Bounds(typer_->cache_->Get(k##Type));
-    TYPED_ARRAYS(TYPED_ARRAY_CASE)
-#undef TYPED_ARRAY_CASE
+  if (fun->IsFunction()) {
+    return fun->AsFunction()->Result();
   }
-  UNREACHABLE();
-  return Bounds();
-}
-
-
-Bounds Typer::Visitor::TypeLoadElement(Node* node) {
-  return Bounds(ElementAccessOf(node->op()).type);
-}
-
-
-Bounds Typer::Visitor::TypeStoreField(Node* node) {
-  UNREACHABLE();
-  return Bounds();
-}
-
-
-Bounds Typer::Visitor::TypeStoreBuffer(Node* node) {
-  UNREACHABLE();
-  return Bounds();
-}
-
-
-Bounds Typer::Visitor::TypeStoreElement(Node* node) {
-  UNREACHABLE();
-  return Bounds();
-}
-
-
-Bounds Typer::Visitor::TypeObjectIsSmi(Node* node) {
-  return Bounds(Type::Boolean());
-}
-
-
-Bounds Typer::Visitor::TypeObjectIsNonNegativeSmi(Node* node) {
-  return Bounds(Type::Boolean());
-}
-
-
-// Machine operators.
-
-Bounds Typer::Visitor::TypeLoad(Node* node) {
-  return Bounds::Unbounded(zone());
-}
-
-
-Bounds Typer::Visitor::TypeStore(Node* node) {
-  UNREACHABLE();
-  return Bounds();
-}
-
-
-Bounds Typer::Visitor::TypeWord32And(Node* node) {
-  return Bounds(Type::Integral32());
-}
-
-
-Bounds Typer::Visitor::TypeWord32Or(Node* node) {
-  return Bounds(Type::Integral32());
-}
-
-
-Bounds Typer::Visitor::TypeWord32Xor(Node* node) {
-  return Bounds(Type::Integral32());
-}
-
-
-Bounds Typer::Visitor::TypeWord32Shl(Node* node) {
-  return Bounds(Type::Integral32());
-}
-
-
-Bounds Typer::Visitor::TypeWord32Shr(Node* node) {
-  return Bounds(Type::Integral32());
-}
-
-
-Bounds Typer::Visitor::TypeWord32Sar(Node* node) {
-  return Bounds(Type::Integral32());
-}
-
-
-Bounds Typer::Visitor::TypeWord32Ror(Node* node) {
-  return Bounds(Type::Integral32());
-}
-
-
-Bounds Typer::Visitor::TypeWord32Equal(Node* node) {
-  return Bounds(Type::Boolean());
-}
-
-
-Bounds Typer::Visitor::TypeWord64And(Node* node) {
-  return Bounds(Type::Internal());
-}
-
-
-Bounds Typer::Visitor::TypeWord64Or(Node* node) {
-  return Bounds(Type::Internal());
-}
-
-
-Bounds Typer::Visitor::TypeWord64Xor(Node* node) {
-  return Bounds(Type::Internal());
-}
-
-
-Bounds Typer::Visitor::TypeWord64Shl(Node* node) {
-  return Bounds(Type::Internal());
-}
-
-
-Bounds Typer::Visitor::TypeWord64Shr(Node* node) {
-  return Bounds(Type::Internal());
-}
-
-
-Bounds Typer::Visitor::TypeWord64Sar(Node* node) {
-  return Bounds(Type::Internal());
-}
-
-
-Bounds Typer::Visitor::TypeWord64Ror(Node* node) {
-  return Bounds(Type::Internal());
-}
-
-
-Bounds Typer::Visitor::TypeWord64Equal(Node* node) {
-  return Bounds(Type::Boolean());
-}
-
-
-Bounds Typer::Visitor::TypeInt32Add(Node* node) {
-  return Bounds(Type::Integral32());
-}
-
-
-Bounds Typer::Visitor::TypeInt32AddWithOverflow(Node* node) {
-  return Bounds(Type::Internal());
-}
-
-
-Bounds Typer::Visitor::TypeInt32Sub(Node* node) {
-  return Bounds(Type::Integral32());
-}
-
-
-Bounds Typer::Visitor::TypeInt32SubWithOverflow(Node* node) {
-  return Bounds(Type::Internal());
-}
-
-
-Bounds Typer::Visitor::TypeInt32Mul(Node* node) {
-  return Bounds(Type::Integral32());
-}
-
-
-Bounds Typer::Visitor::TypeInt32MulHigh(Node* node) {
-  return Bounds(Type::Signed32());
-}
-
-
-Bounds Typer::Visitor::TypeInt32Div(Node* node) {
-  return Bounds(Type::Integral32());
-}
-
-
-Bounds Typer::Visitor::TypeInt32Mod(Node* node) {
-  return Bounds(Type::Integral32());
-}
-
-
-Bounds Typer::Visitor::TypeInt32LessThan(Node* node) {
-  return Bounds(Type::Boolean());
-}
-
-
-Bounds Typer::Visitor::TypeInt32LessThanOrEqual(Node* node) {
-  return Bounds(Type::Boolean());
-}
-
-
-Bounds Typer::Visitor::TypeUint32Div(Node* node) {
-  return Bounds(Type::Unsigned32());
-}
-
-
-Bounds Typer::Visitor::TypeUint32LessThan(Node* node) {
-  return Bounds(Type::Boolean());
-}
-
-
-Bounds Typer::Visitor::TypeUint32LessThanOrEqual(Node* node) {
-  return Bounds(Type::Boolean());
-}
-
-
-Bounds Typer::Visitor::TypeUint32Mod(Node* node) {
-  return Bounds(Type::Unsigned32());
-}
-
-
-Bounds Typer::Visitor::TypeUint32MulHigh(Node* node) {
-  return Bounds(Type::Unsigned32());
-}
-
-
-Bounds Typer::Visitor::TypeInt64Add(Node* node) {
-  return Bounds(Type::Internal());
-}
-
-
-Bounds Typer::Visitor::TypeInt64Sub(Node* node) {
-  return Bounds(Type::Internal());
-}
-
-
-Bounds Typer::Visitor::TypeInt64Mul(Node* node) {
-  return Bounds(Type::Internal());
-}
-
-
-Bounds Typer::Visitor::TypeInt64Div(Node* node) {
-  return Bounds(Type::Internal());
-}
-
-
-Bounds Typer::Visitor::TypeInt64Mod(Node* node) {
-  return Bounds(Type::Internal());
-}
-
-
-Bounds Typer::Visitor::TypeInt64LessThan(Node* node) {
-  return Bounds(Type::Boolean());
-}
-
-
-Bounds Typer::Visitor::TypeInt64LessThanOrEqual(Node* node) {
-  return Bounds(Type::Boolean());
-}
-
-
-Bounds Typer::Visitor::TypeUint64Div(Node* node) {
-  return Bounds(Type::Internal());
-}
-
-
-Bounds Typer::Visitor::TypeUint64LessThan(Node* node) {
-  return Bounds(Type::Boolean());
-}
-
-
-Bounds Typer::Visitor::TypeUint64Mod(Node* node) {
-  return Bounds(Type::Internal());
-}
-
-
-Bounds Typer::Visitor::TypeChangeFloat32ToFloat64(Node* node) {
-  return Bounds(Type::Intersect(
-      Type::Number(), Type::UntaggedFloat64(), zone()));
-}
-
-
-Bounds Typer::Visitor::TypeChangeFloat64ToInt32(Node* node) {
-  return Bounds(Type::Intersect(
-      Type::Signed32(), Type::UntaggedSigned32(), zone()));
-}
-
-
-Bounds Typer::Visitor::TypeChangeFloat64ToUint32(Node* node) {
-  return Bounds(Type::Intersect(
-      Type::Unsigned32(), Type::UntaggedUnsigned32(), zone()));
-}
-
-
-Bounds Typer::Visitor::TypeChangeInt32ToFloat64(Node* node) {
-  return Bounds(Type::Intersect(
-      Type::Signed32(), Type::UntaggedFloat64(), zone()));
-}
-
-
-Bounds Typer::Visitor::TypeChangeInt32ToInt64(Node* node) {
-  return Bounds(Type::Internal());
-}
-
-
-Bounds Typer::Visitor::TypeChangeUint32ToFloat64(Node* node) {
-  return Bounds(Type::Intersect(
-      Type::Unsigned32(), Type::UntaggedFloat64(), zone()));
-}
-
-
-Bounds Typer::Visitor::TypeChangeUint32ToUint64(Node* node) {
-  return Bounds(Type::Internal());
-}
-
-
-Bounds Typer::Visitor::TypeTruncateFloat64ToFloat32(Node* node) {
-  return Bounds(Type::Intersect(
-      Type::Number(), Type::UntaggedFloat32(), zone()));
-}
-
-
-Bounds Typer::Visitor::TypeTruncateFloat64ToInt32(Node* node) {
-  return Bounds(Type::Intersect(
-      Type::Signed32(), Type::UntaggedSigned32(), zone()));
-}
-
-
-Bounds Typer::Visitor::TypeTruncateInt64ToInt32(Node* node) {
-  return Bounds(Type::Intersect(
-      Type::Signed32(), Type::UntaggedSigned32(), zone()));
-}
-
-
-Bounds Typer::Visitor::TypeFloat64Add(Node* node) {
-  return Bounds(Type::Number());
-}
-
-
-Bounds Typer::Visitor::TypeFloat64Sub(Node* node) {
-  return Bounds(Type::Number());
-}
-
-
-Bounds Typer::Visitor::TypeFloat64Mul(Node* node) {
-  return Bounds(Type::Number());
-}
-
-
-Bounds Typer::Visitor::TypeFloat64Div(Node* node) {
-  return Bounds(Type::Number());
-}
-
-
-Bounds Typer::Visitor::TypeFloat64Mod(Node* node) {
-  return Bounds(Type::Number());
-}
-
-
-Bounds Typer::Visitor::TypeFloat64Sqrt(Node* node) {
-  return Bounds(Type::Number());
-}
-
-
-Bounds Typer::Visitor::TypeFloat64Equal(Node* node) {
-  return Bounds(Type::Boolean());
-}
-
-
-Bounds Typer::Visitor::TypeFloat64LessThan(Node* node) {
-  return Bounds(Type::Boolean());
-}
-
-
-Bounds Typer::Visitor::TypeFloat64LessThanOrEqual(Node* node) {
-  return Bounds(Type::Boolean());
-}
-
-
-Bounds Typer::Visitor::TypeFloat64Floor(Node* node) {
-  // TODO(sigurds): We could have a tighter bound here.
-  return Bounds(Type::Number());
-}
-
-
-Bounds Typer::Visitor::TypeFloat64Ceil(Node* node) {
-  // TODO(sigurds): We could have a tighter bound here.
-  return Bounds(Type::Number());
-}
-
-
-Bounds Typer::Visitor::TypeFloat64RoundTruncate(Node* node) {
-  // TODO(sigurds): We could have a tighter bound here.
-  return Bounds(Type::Number());
-}
-
-
-Bounds Typer::Visitor::TypeFloat64RoundTiesAway(Node* node) {
-  // TODO(sigurds): We could have a tighter bound here.
-  return Bounds(Type::Number());
-}
-
-
-Bounds Typer::Visitor::TypeLoadStackPointer(Node* node) {
-  return Bounds(Type::Internal());
-}
-
-
-Bounds Typer::Visitor::TypeCheckedLoad(Node* node) {
-  return Bounds::Unbounded(zone());
-}
-
-
-Bounds Typer::Visitor::TypeCheckedStore(Node* node) {
-  UNREACHABLE();
-  return Bounds();
-}
-
-
-// Heap constants.
-
-
-Type* Typer::Visitor::TypeConstant(Handle<Object> value) {
-  if (value->IsJSFunction()) {
-    if (JSFunction::cast(*value)->shared()->HasBuiltinFunctionId()) {
-      switch (JSFunction::cast(*value)->shared()->builtin_function_id()) {
+  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 typer_->random_fun_;
+          return Type::OrderedNumber();
         case kMathFloor:
-          return typer_->weakint_fun1_;
         case kMathRound:
-          return typer_->weakint_fun1_;
         case kMathCeil:
-          return typer_->weakint_fun1_;
+          return t->cache_.kIntegerOrMinusZeroOrNaN;
         // Unary math functions.
-        case kMathAbs:  // TODO(rossberg): can't express overloading
+        case kMathAbs:
         case kMathLog:
         case kMathExp:
         case kMathSqrt:
@@ -2055,52 +1513,925 @@
         case kMathAsin:
         case kMathAtan:
         case kMathFround:
-          return typer_->cache_->Get(kNumberFunc1);
+          return Type::Number();
         // Binary math functions.
         case kMathAtan2:
         case kMathPow:
         case kMathMax:
         case kMathMin:
-          return typer_->cache_->Get(kNumberFunc2);
+          return Type::Number();
         case kMathImul:
-          return typer_->cache_->Get(kImulFunc);
+          return Type::Signed32();
         case kMathClz32:
-          return typer_->cache_->Get(kClz32Func);
+          return t->cache_.kZeroToThirtyTwo;
+        // String functions.
+        case kStringCharAt:
+        case kStringFromCharCode:
+          return Type::String();
+        // Array functions.
+        case kArrayIndexOf:
+        case kArrayLastIndexOf:
+          return Type::Number();
         default:
           break;
       }
-    } else if (JSFunction::cast(*value)->IsBuiltin() && !context().is_null()) {
-      Handle<Context> native =
-          handle(context().ToHandleChecked()->native_context(), isolate());
-      if (*value == native->array_buffer_fun()) {
-        return typer_->cache_->Get(kArrayBufferFunc);
-      } else if (*value == native->int8_array_fun()) {
-        return typer_->cache_->Get(kInt8ArrayFunc);
-      } else if (*value == native->int16_array_fun()) {
-        return typer_->cache_->Get(kInt16ArrayFunc);
-      } else if (*value == native->int32_array_fun()) {
-        return typer_->cache_->Get(kInt32ArrayFunc);
-      } else if (*value == native->uint8_array_fun()) {
-        return typer_->cache_->Get(kUint8ArrayFunc);
-      } else if (*value == native->uint16_array_fun()) {
-        return typer_->cache_->Get(kUint16ArrayFunc);
-      } else if (*value == native->uint32_array_fun()) {
-        return typer_->cache_->Get(kUint32ArrayFunc);
-      } else if (*value == native->float32_array_fun()) {
-        return typer_->cache_->Get(kFloat32ArrayFunc);
-      } else if (*value == native->float64_array_fun()) {
-        return typer_->cache_->Get(kFloat64ArrayFunc);
-      }
     }
-  } else if (value->IsJSTypedArray()) {
+  }
+  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::kInlineIsSmi:
+    case Runtime::kInlineIsArray:
+    case Runtime::kInlineIsDate:
+    case Runtime::kInlineIsTypedArray:
+    case Runtime::kInlineIsMinusZero:
+    case Runtime::kInlineIsFunction:
+    case Runtime::kInlineIsRegExp:
+    case Runtime::kInlineIsJSReceiver:
+      return Type::Boolean(zone());
+    case Runtime::kInlineDoubleLo:
+    case Runtime::kInlineDoubleHi:
+      return Type::Signed32();
+    case Runtime::kInlineConstructDouble:
+    case Runtime::kInlineMathFloor:
+    case Runtime::kInlineMathSqrt:
+    case Runtime::kInlineMathAcos:
+    case Runtime::kInlineMathAsin:
+    case Runtime::kInlineMathAtan:
+    case Runtime::kInlineMathAtan2:
+      return Type::Number();
+    case Runtime::kInlineMathClz32:
+      return Type::Range(0, 32, zone());
+    case Runtime::kInlineCreateIterResultObject:
+    case Runtime::kInlineRegExpConstructResult:
+      return Type::OtherObject();
+    case Runtime::kInlineSubString:
+      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) {
+  // TODO(bmeurer): Return a tuple type here.
+  return Type::Any();
+}
+
+
+Type* Typer::Visitor::TypeJSForInDone(Node* node) {
+  return Type::Boolean(zone());
+}
+
+
+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::TypeJSStackCheck(Node* node) { return Type::Any(); }
+
+
+// Simplified operators.
+
+
+Type* Typer::Visitor::TypeBooleanNot(Node* node) {
+  return Type::Boolean(zone());
+}
+
+
+Type* Typer::Visitor::TypeBooleanToNumber(Node* node) {
+  return TypeUnaryOp(node, ToNumber);
+}
+
+
+Type* Typer::Visitor::TypeNumberEqual(Node* node) {
+  return Type::Boolean(zone());
+}
+
+
+Type* Typer::Visitor::TypeNumberLessThan(Node* node) {
+  return Type::Boolean(zone());
+}
+
+
+Type* Typer::Visitor::TypeNumberLessThanOrEqual(Node* node) {
+  return Type::Boolean(zone());
+}
+
+
+Type* Typer::Visitor::TypeNumberAdd(Node* node) { return Type::Number(zone()); }
+
+
+Type* Typer::Visitor::TypeNumberSubtract(Node* node) {
+  return Type::Number(zone());
+}
+
+
+Type* Typer::Visitor::TypeNumberMultiply(Node* node) {
+  return Type::Number(zone());
+}
+
+
+Type* Typer::Visitor::TypeNumberDivide(Node* node) {
+  return Type::Number(zone());
+}
+
+
+Type* Typer::Visitor::TypeNumberModulus(Node* node) {
+  return Type::Number(zone());
+}
+
+
+Type* Typer::Visitor::TypeNumberBitwiseOr(Node* node) {
+  return Type::Signed32(zone());
+}
+
+
+Type* Typer::Visitor::TypeNumberBitwiseXor(Node* node) {
+  return Type::Signed32(zone());
+}
+
+
+Type* Typer::Visitor::TypeNumberBitwiseAnd(Node* node) {
+  return Type::Signed32(zone());
+}
+
+
+Type* Typer::Visitor::TypeNumberShiftLeft(Node* node) {
+  return Type::Signed32(zone());
+}
+
+
+Type* Typer::Visitor::TypeNumberShiftRight(Node* node) {
+  return Type::Signed32(zone());
+}
+
+
+Type* Typer::Visitor::TypeNumberShiftRightLogical(Node* node) {
+  return Type::Unsigned32(zone());
+}
+
+
+Type* Typer::Visitor::TypeNumberToInt32(Node* node) {
+  return TypeUnaryOp(node, NumberToInt32);
+}
+
+
+Type* Typer::Visitor::TypeNumberToUint32(Node* node) {
+  return TypeUnaryOp(node, NumberToUint32);
+}
+
+
+Type* Typer::Visitor::TypeNumberIsHoleNaN(Node* node) {
+  return Type::Boolean(zone());
+}
+
+
+Type* Typer::Visitor::TypePlainPrimitiveToNumber(Node* node) {
+  return TypeUnaryOp(node, ToNumber);
+}
+
+
+// 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(zone());
+}
+
+
+Type* Typer::Visitor::TypeStringLessThan(Node* node) {
+  return Type::Boolean(zone());
+}
+
+
+Type* Typer::Visitor::TypeStringLessThanOrEqual(Node* node) {
+  return Type::Boolean(zone());
+}
+
+
+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::TypeChangeTaggedToInt32(Node* node) {
+  Type* arg = Operand(node, 0);
+  // TODO(neis): DCHECK(arg->Is(Type::Signed32()));
+  return ChangeRepresentation(arg, Type::UntaggedIntegral32(), zone());
+}
+
+
+Type* Typer::Visitor::TypeChangeTaggedToUint32(Node* node) {
+  Type* arg = Operand(node, 0);
+  // TODO(neis): DCHECK(arg->Is(Type::Unsigned32()));
+  return ChangeRepresentation(arg, Type::UntaggedIntegral32(), zone());
+}
+
+
+Type* Typer::Visitor::TypeChangeTaggedToFloat64(Node* node) {
+  Type* arg = Operand(node, 0);
+  // TODO(neis): DCHECK(arg->Is(Type::Number()));
+  return ChangeRepresentation(arg, Type::UntaggedFloat64(), zone());
+}
+
+
+Type* Typer::Visitor::TypeChangeInt32ToTagged(Node* node) {
+  Type* arg = Operand(node, 0);
+  // TODO(neis): DCHECK(arg->Is(Type::Signed32()));
+  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(neis): DCHECK(arg->Is(Type::Unsigned32()));
+  return ChangeRepresentation(arg, Type::Tagged(), zone());
+}
+
+
+Type* Typer::Visitor::TypeChangeFloat64ToTagged(Node* node) {
+  Type* arg = Operand(node, 0);
+  // TODO(neis): CHECK(arg.upper->Is(Type::Number()));
+  return ChangeRepresentation(arg, Type::Tagged(), zone());
+}
+
+
+Type* Typer::Visitor::TypeChangeBoolToBit(Node* node) {
+  Type* arg = Operand(node, 0);
+  // TODO(neis): DCHECK(arg.upper->Is(Type::Boolean()));
+  return ChangeRepresentation(arg, Type::UntaggedBit(), zone());
+}
+
+
+Type* Typer::Visitor::TypeChangeBitToBool(Node* node) {
+  Type* arg = Operand(node, 0);
+  // TODO(neis): DCHECK(arg.upper->Is(Type::Boolean()));
+  return ChangeRepresentation(arg, Type::TaggedPointer(), 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(Type, type, TYPE, ctype, size) \
+  case kExternal##Type##Array:                          \
+    return typer_->cache_.k##Type;
+    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::TypeObjectIsNumber(Node* node) {
+  Type* arg = Operand(node, 0);
+  if (arg->Is(Type::None())) return Type::None();
+  if (arg->Is(Type::Number())) return typer_->singleton_true_;
+  if (!arg->Maybe(Type::Number())) return typer_->singleton_false_;
+  return Type::Boolean();
+}
+
+
+Type* Typer::Visitor::TypeObjectIsSmi(Node* node) {
+  Type* arg = Operand(node, 0);
+  if (arg->Is(Type::None())) return Type::None();
+  if (arg->Is(Type::TaggedSigned())) return typer_->singleton_true_;
+  if (arg->Is(Type::TaggedPointer())) return typer_->singleton_false_;
+  return Type::Boolean();
+}
+
+
+// Machine operators.
+
+Type* Typer::Visitor::TypeLoad(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::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::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::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::TypeChangeFloat64ToUint32(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::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::TypeTruncateFloat64ToInt32(Node* node) {
+  return Type::Intersect(Type::Signed32(), Type::UntaggedIntegral32(), zone());
+}
+
+
+Type* Typer::Visitor::TypeTruncateInt64ToInt32(Node* node) {
+  return Type::Intersect(Type::Signed32(), Type::UntaggedIntegral32(), 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::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::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::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::TypeFloat64Sqrt(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::TypeCheckedLoad(Node* node) { return Type::Any(); }
+
+
+Type* Typer::Visitor::TypeCheckedStore(Node* node) {
+  UNREACHABLE();
+  return nullptr;
+}
+
+
+// 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_->Get(k##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());
 }
 
diff --git a/src/compiler/typer.h b/src/compiler/typer.h
index b65a9a5..4177026 100644
--- a/src/compiler/typer.h
+++ b/src/compiler/typer.h
@@ -5,70 +5,70 @@
 #ifndef V8_COMPILER_TYPER_H_
 #define V8_COMPILER_TYPER_H_
 
-#include "src/v8.h"
-
+#include "src/base/flags.h"
 #include "src/compiler/graph.h"
-#include "src/compiler/opcodes.h"
 #include "src/types.h"
 
 namespace v8 {
 namespace internal {
-namespace compiler {
 
 // Forward declarations.
-class LazyTypeCache;
+class CompilationDependencies;
+class TypeCache;
+
+namespace compiler {
 
 
 class Typer {
  public:
-  explicit Typer(Graph* graph, MaybeHandle<Context> context);
+  // Flags that control the mode of operation.
+  enum Flag {
+    kNoFlags = 0u,
+    kDeoptimizationEnabled = 1u << 0,
+  };
+  typedef base::Flags<Flag> Flags;
+
+  Typer(Isolate* isolate, Graph* graph, Flags flags = kNoFlags,
+        CompilationDependencies* dependencies = nullptr,
+        Type::FunctionType* function_type = nullptr);
   ~Typer();
 
   void Run();
-
-  Graph* graph() { return graph_; }
-  MaybeHandle<Context> context() { return context_; }
-  Zone* zone() { return graph_->zone(); }
-  Isolate* isolate() { return zone()->isolate(); }
+  // TODO(bmeurer,jarin): Remove this once we have a notion of "roots" on Graph.
+  void Run(const ZoneVector<Node*>& roots);
 
  private:
   class Visitor;
   class Decorator;
 
-  Graph* graph_;
-  MaybeHandle<Context> context_;
+  Graph* graph() const { return graph_; }
+  Zone* zone() const { return graph()->zone(); }
+  Isolate* isolate() const { return isolate_; }
+  Flags flags() const { return flags_; }
+  CompilationDependencies* dependencies() const { return dependencies_; }
+  Type::FunctionType* function_type() const { return function_type_; }
+
+  Isolate* const isolate_;
+  Graph* const graph_;
+  Flags const flags_;
+  CompilationDependencies* const dependencies_;
+  Type::FunctionType* function_type_;
   Decorator* decorator_;
+  TypeCache const& cache_;
 
-  Zone* zone_;
-  Type* boolean_or_number;
-  Type* undefined_or_null;
-  Type* undefined_or_number;
-  Type* negative_signed32;
-  Type* non_negative_signed32;
-  Type* singleton_false;
-  Type* singleton_true;
-  Type* singleton_zero;
-  Type* singleton_one;
-  Type* zero_or_one;
-  Type* zeroish;
-  Type* signed32ish;
-  Type* unsigned32ish;
-  Type* falsish;
-  Type* truish;
-  Type* integer;
-  Type* weakint;
-  Type* number_fun0_;
-  Type* number_fun1_;
-  Type* number_fun2_;
-  Type* weakint_fun1_;
-  Type* random_fun_;
-  LazyTypeCache* cache_;
+  Type* singleton_false_;
+  Type* singleton_true_;
+  Type* singleton_the_hole_;
+  Type* signed32ish_;
+  Type* unsigned32ish_;
+  Type* falsish_;
+  Type* truish_;
 
-  ZoneVector<Handle<Object> > weaken_min_limits_;
-  ZoneVector<Handle<Object> > weaken_max_limits_;
   DISALLOW_COPY_AND_ASSIGN(Typer);
 };
 
+DEFINE_OPERATORS_FOR_FLAGS(Typer::Flags)
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/src/compiler/value-numbering-reducer.cc b/src/compiler/value-numbering-reducer.cc
index 734b3e8..555570d 100644
--- a/src/compiler/value-numbering-reducer.cc
+++ b/src/compiler/value-numbering-reducer.cc
@@ -50,7 +50,7 @@
 
 
 Reduction ValueNumberingReducer::Reduce(Node* node) {
-  if (!node->op()->HasProperty(Operator::kEliminatable)) return NoChange();
+  if (!node->op()->HasProperty(Operator::kIdempotent)) return NoChange();
 
   const size_t hash = HashCode(node);
   if (!entries_) {
@@ -135,7 +135,7 @@
   Node** const old_entries = entries_;
   size_t const old_capacity = capacity_;
   capacity_ *= kCapacityToSizeRatio;
-  entries_ = zone()->NewArray<Node*>(static_cast<int>(capacity_));
+  entries_ = zone()->NewArray<Node*>(capacity_);
   memset(entries_, 0, sizeof(*entries_) * capacity_);
   size_ = 0;
   size_t const mask = capacity_ - 1;
diff --git a/src/compiler/value-numbering-reducer.h b/src/compiler/value-numbering-reducer.h
index 546226c..822b607 100644
--- a/src/compiler/value-numbering-reducer.h
+++ b/src/compiler/value-numbering-reducer.h
@@ -11,12 +11,12 @@
 namespace internal {
 namespace compiler {
 
-class ValueNumberingReducer FINAL : public Reducer {
+class ValueNumberingReducer final : public Reducer {
  public:
   explicit ValueNumberingReducer(Zone* zone);
   ~ValueNumberingReducer();
 
-  Reduction Reduce(Node* node) OVERRIDE;
+  Reduction Reduce(Node* node) override;
 
  private:
   enum { kInitialCapacity = 256u, kCapacityToSizeRatio = 2u };
diff --git a/src/compiler/verifier.cc b/src/compiler/verifier.cc
index 693b414..1a3ef8e 100644
--- a/src/compiler/verifier.cc
+++ b/src/compiler/verifier.cc
@@ -4,23 +4,25 @@
 
 #include "src/compiler/verifier.h"
 
+#include <algorithm>
 #include <deque>
 #include <queue>
 #include <sstream>
 #include <string>
 
 #include "src/bit-vector.h"
-#include "src/compiler/generic-algorithm.h"
-#include "src/compiler/graph-inl.h"
+#include "src/compiler/all-nodes.h"
+#include "src/compiler/common-operator.h"
 #include "src/compiler/graph.h"
 #include "src/compiler/node.h"
-#include "src/compiler/node-properties-inl.h"
 #include "src/compiler/node-properties.h"
 #include "src/compiler/opcodes.h"
 #include "src/compiler/operator.h"
+#include "src/compiler/operator-properties.h"
 #include "src/compiler/schedule.h"
 #include "src/compiler/simplified-operator.h"
 #include "src/ostreams.h"
+#include "src/types-inl.h"
 
 namespace v8 {
 namespace internal {
@@ -28,97 +30,83 @@
 
 
 static bool IsDefUseChainLinkPresent(Node* def, Node* use) {
-  Node::Uses uses = def->uses();
-  for (Node::Uses::iterator it = uses.begin(); it != uses.end(); ++it) {
-    if (*it == use) return true;
-  }
-  return false;
+  auto const uses = def->uses();
+  return std::find(uses.begin(), uses.end(), use) != uses.end();
 }
 
 
 static bool IsUseDefChainLinkPresent(Node* def, Node* use) {
-  Node::Inputs inputs = use->inputs();
-  for (Node::Inputs::iterator it = inputs.begin(); it != inputs.end(); ++it) {
-    if (*it == def) return true;
-  }
-  return false;
+  auto const inputs = use->inputs();
+  return std::find(inputs.begin(), inputs.end(), def) != inputs.end();
 }
 
 
-class Verifier::Visitor : public NullNodeVisitor {
+class Verifier::Visitor {
  public:
   Visitor(Zone* z, Typing typed) : zone(z), typing(typed) {}
 
-  // Fulfills the PreNodeCallback interface.
-  void Pre(Node* node);
+  void Check(Node* node);
 
   Zone* zone;
   Typing typing;
 
  private:
-  // TODO(rossberg): Get rid of these once we got rid of NodeProperties.
-  Bounds bounds(Node* node) { return NodeProperties::GetBounds(node); }
-  Node* ValueInput(Node* node, int i = 0) {
-    return NodeProperties::GetValueInput(node, i);
-  }
-  FieldAccess Field(Node* node) {
-    DCHECK(node->opcode() == IrOpcode::kLoadField ||
-           node->opcode() == IrOpcode::kStoreField);
-    return OpParameter<FieldAccess>(node);
-  }
-  ElementAccess Element(Node* node) {
-    DCHECK(node->opcode() == IrOpcode::kLoadElement ||
-           node->opcode() == IrOpcode::kStoreElement);
-    return OpParameter<ElementAccess>(node);
-  }
   void CheckNotTyped(Node* node) {
     if (NodeProperties::IsTyped(node)) {
       std::ostringstream str;
-      str << "TypeError: node #" << node->opcode() << ":"
-          << node->op()->mnemonic() << " should never have a type";
-      V8_Fatal(__FILE__, __LINE__, str.str().c_str());
+      str << "TypeError: node #" << node->id() << ":" << *node->op()
+          << " should never have a type";
+      FATAL(str.str().c_str());
     }
   }
   void CheckUpperIs(Node* node, Type* type) {
-    if (typing == TYPED && !bounds(node).upper->Is(type)) {
+    if (typing == TYPED && !NodeProperties::GetType(node)->Is(type)) {
       std::ostringstream str;
-      str << "TypeError: node #" << node->opcode() << ":"
-          << node->op()->mnemonic() << " upper bound ";
-      bounds(node).upper->PrintTo(str);
+      str << "TypeError: node #" << node->id() << ":" << *node->op()
+          << " type ";
+      NodeProperties::GetType(node)->PrintTo(str);
       str << " is not ";
       type->PrintTo(str);
-      V8_Fatal(__FILE__, __LINE__, str.str().c_str());
+      FATAL(str.str().c_str());
     }
   }
   void CheckUpperMaybe(Node* node, Type* type) {
-    if (typing == TYPED && !bounds(node).upper->Maybe(type)) {
+    if (typing == TYPED && !NodeProperties::GetType(node)->Maybe(type)) {
       std::ostringstream str;
-      str << "TypeError: node #" << node->opcode() << ":"
-          << node->op()->mnemonic() << " upper bound ";
-      bounds(node).upper->PrintTo(str);
+      str << "TypeError: node #" << node->id() << ":" << *node->op()
+          << " type ";
+      NodeProperties::GetType(node)->PrintTo(str);
       str << " must intersect ";
       type->PrintTo(str);
-      V8_Fatal(__FILE__, __LINE__, str.str().c_str());
+      FATAL(str.str().c_str());
     }
   }
   void CheckValueInputIs(Node* node, int i, Type* type) {
-    Node* input = ValueInput(node, i);
-    if (typing == TYPED && !bounds(input).upper->Is(type)) {
+    Node* input = NodeProperties::GetValueInput(node, i);
+    if (typing == TYPED && !NodeProperties::GetType(input)->Is(type)) {
       std::ostringstream str;
-      str << "TypeError: node #" << node->opcode() << ":"
-          << node->op()->mnemonic() << "(input @" << i << " = "
-          << input->opcode() << ":" << input->op()->mnemonic()
-          << ") upper bound ";
-      bounds(input).upper->PrintTo(str);
+      str << "TypeError: node #" << node->id() << ":" << *node->op()
+          << "(input @" << i << " = " << input->opcode() << ":"
+          << input->op()->mnemonic() << ") type ";
+      NodeProperties::GetType(input)->PrintTo(str);
       str << " is not ";
       type->PrintTo(str);
-      V8_Fatal(__FILE__, __LINE__, str.str().c_str());
+      FATAL(str.str().c_str());
+    }
+  }
+  void CheckOutput(Node* node, Node* use, int count, const char* kind) {
+    if (count <= 0) {
+      std::ostringstream str;
+      str << "GraphError: node #" << node->id() << ":" << *node->op()
+          << " does not produce " << kind << " output used by node #"
+          << use->id() << ":" << *use->op();
+      FATAL(str.str().c_str());
     }
   }
 };
 
 
-void Verifier::Visitor::Pre(Node* node) {
+void Verifier::Visitor::Check(Node* node) {
   int value_count = node->op()->ValueInputCount();
   int context_count = OperatorProperties::GetContextInputCount(node->op());
   int frame_state_count =
@@ -132,12 +120,12 @@
   CHECK_EQ(input_count, node->InputCount());
 
   // Verify that frame state has been inserted for the nodes that need it.
-  if (OperatorProperties::HasFrameStateInput(node->op())) {
-    Node* frame_state = NodeProperties::GetFrameStateInput(node);
+  for (int i = 0; i < frame_state_count; i++) {
+    Node* frame_state = NodeProperties::GetFrameStateInput(node, i);
     CHECK(frame_state->opcode() == IrOpcode::kFrameState ||
-          // kFrameState uses undefined as a sentinel.
+          // kFrameState uses Start as a sentinel.
           (node->opcode() == IrOpcode::kFrameState &&
-           frame_state->opcode() == IrOpcode::kHeapConstant));
+           frame_state->opcode() == IrOpcode::kStart));
     CHECK(IsDefUseChainLinkPresent(frame_state, node));
     CHECK(IsUseDefChainLinkPresent(frame_state, node));
   }
@@ -145,7 +133,7 @@
   // Verify all value inputs actually produce a value.
   for (int i = 0; i < value_count; ++i) {
     Node* value = NodeProperties::GetValueInput(node, i);
-    CHECK(value->op()->ValueOutputCount() > 0);
+    CheckOutput(value, node, value->op()->ValueOutputCount(), "value");
     CHECK(IsDefUseChainLinkPresent(value, node));
     CHECK(IsUseDefChainLinkPresent(value, node));
   }
@@ -153,7 +141,7 @@
   // Verify all context inputs are value nodes.
   for (int i = 0; i < context_count; ++i) {
     Node* context = NodeProperties::GetContextInput(node);
-    CHECK(context->op()->ValueOutputCount() > 0);
+    CheckOutput(context, node, context->op()->ValueOutputCount(), "context");
     CHECK(IsDefUseChainLinkPresent(context, node));
     CHECK(IsUseDefChainLinkPresent(context, node));
   }
@@ -161,7 +149,7 @@
   // Verify all effect inputs actually have an effect.
   for (int i = 0; i < effect_count; ++i) {
     Node* effect = NodeProperties::GetEffectInput(node);
-    CHECK(effect->op()->EffectOutputCount() > 0);
+    CheckOutput(effect, node, effect->op()->EffectOutputCount(), "effect");
     CHECK(IsDefUseChainLinkPresent(effect, node));
     CHECK(IsUseDefChainLinkPresent(effect, node));
   }
@@ -169,7 +157,7 @@
   // Verify all control inputs are control nodes.
   for (int i = 0; i < control_count; ++i) {
     Node* control = NodeProperties::GetControlInput(node, i);
-    CHECK(control->op()->ControlOutputCount() > 0);
+    CheckOutput(control, node, control->op()->ControlOutputCount(), "control");
     CHECK(IsDefUseChainLinkPresent(control, node));
     CHECK(IsUseDefChainLinkPresent(control, node));
   }
@@ -203,17 +191,18 @@
     case IrOpcode::kDead:
       // Dead is never connected to the graph.
       UNREACHABLE();
+      break;
     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;
+      for (auto use : node->uses()) {
+        CHECK(use->opcode() == IrOpcode::kIfTrue ||
+              use->opcode() == IrOpcode::kIfFalse);
+        if (use->opcode() == IrOpcode::kIfTrue) ++count_true;
+        if (use->opcode() == IrOpcode::kIfFalse) ++count_false;
       }
-      CHECK(count_true == 1 && count_false == 1);
+      CHECK_EQ(1, count_true);
+      CHECK_EQ(1, count_false);
       // Type is empty.
       CheckNotTyped(node);
       break;
@@ -225,27 +214,99 @@
       // Type is empty.
       CheckNotTyped(node);
       break;
+    case IrOpcode::kIfSuccess: {
+      // IfSuccess and IfException continuation only on throwing nodes.
+      Node* input = NodeProperties::GetControlInput(node, 0);
+      CHECK(!input->op()->HasProperty(Operator::kNoThrow));
+      // Type is empty.
+      CheckNotTyped(node);
+      break;
+    }
+    case IrOpcode::kIfException: {
+      // IfSuccess and IfException continuation only on throwing nodes.
+      Node* input = NodeProperties::GetControlInput(node, 0);
+      CHECK(!input->op()->HasProperty(Operator::kNoThrow));
+      // Type can be anything.
+      CheckUpperIs(node, Type::Any());
+      break;
+    }
+    case IrOpcode::kSwitch: {
+      // Switch uses are Case and Default.
+      int count_case = 0, count_default = 0;
+      for (auto use : node->uses()) {
+        switch (use->opcode()) {
+          case IrOpcode::kIfValue: {
+            for (auto user : node->uses()) {
+              if (user != use && user->opcode() == IrOpcode::kIfValue) {
+                CHECK_NE(OpParameter<int32_t>(use->op()),
+                         OpParameter<int32_t>(user->op()));
+              }
+            }
+            ++count_case;
+            break;
+          }
+          case IrOpcode::kIfDefault: {
+            ++count_default;
+            break;
+          }
+          default: {
+            V8_Fatal(__FILE__, __LINE__, "Switch #%d illegally used by #%d:%s",
+                     node->id(), use->id(), use->op()->mnemonic());
+            break;
+          }
+        }
+      }
+      CHECK_EQ(1, count_default);
+      CHECK_EQ(node->op()->ControlOutputCount(), count_case + count_default);
+      // Type is empty.
+      CheckNotTyped(node);
+      break;
+    }
+    case IrOpcode::kIfValue:
+    case IrOpcode::kIfDefault:
+      CHECK_EQ(IrOpcode::kSwitch,
+               NodeProperties::GetControlInput(node)->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::kDeoptimize:
     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?
+      // Deoptimize, Return and Throw uses are End.
+      for (auto use : node->uses()) {
+        CHECK_EQ(IrOpcode::kEnd, use->opcode());
+      }
       // Type is empty.
       CheckNotTyped(node);
       break;
     case IrOpcode::kTerminate:
+      // Terminates take one loop and effect.
+      CHECK_EQ(1, control_count);
+      CHECK_EQ(1, effect_count);
+      CHECK_EQ(2, input_count);
+      CHECK_EQ(IrOpcode::kLoop,
+               NodeProperties::GetControlInput(node)->opcode());
+      // Terminate uses are End.
+      for (auto use : node->uses()) {
+        CHECK_EQ(IrOpcode::kEnd, use->opcode());
+      }
       // Type is empty.
       CheckNotTyped(node);
+      break;
+    case IrOpcode::kOsrNormalEntry:
+    case IrOpcode::kOsrLoopEntry:
+      // Osr entries take one control and effect.
       CHECK_EQ(1, control_count);
-      CHECK_EQ(input_count, 1 + effect_count);
+      CHECK_EQ(1, effect_count);
+      CHECK_EQ(2, input_count);
+      // Type is empty.
+      CheckNotTyped(node);
       break;
 
     // Common operators
@@ -253,13 +314,13 @@
     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);
+      int const index = ParameterIndexOf(node->op());
+      Node* const start = NodeProperties::GetValueInput(node, 0);
+      CHECK_EQ(IrOpcode::kStart, start->opcode());
       // Currently, parameter indices start at -1 instead of 0.
-      CHECK_GT(input->op()->ValueOutputCount(), index + 1);
+      CHECK_LE(-1, index);
+      CHECK_LT(index + 1, start->op()->ValueOutputCount());
       // Type can be anything.
       CheckUpperIs(node, Type::Any());
       break;
@@ -297,9 +358,16 @@
       // Type is considered internal.
       CheckUpperIs(node, Type::Internal());
       break;
+    case IrOpcode::kOsrValue:
+      // OSR values have a value and a control input.
+      CHECK_EQ(1, control_count);
+      CHECK_EQ(1, input_count);
+      // Type is merged from other values in the graph and could be any.
+      CheckUpperIs(node, Type::Any());
+      break;
     case IrOpcode::kProjection: {
       // Projection has an input that produces enough values.
-      int index = static_cast<int>(OpParameter<size_t>(node->op()));
+      int index = static_cast<int>(ProjectionIndexOf(node->op()));
       Node* input = NodeProperties::GetValueInput(node, 0);
       CHECK_GT(input->op()->ValueOutputCount(), index);
       // Type can be anything.
@@ -325,9 +393,7 @@
       // 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));
+        CHECK(type_of(ValueInput(node, i))->Is(type_of(node)));
       }
       */
       break;
@@ -341,27 +407,45 @@
       CHECK_EQ(input_count, 1 + effect_count);
       break;
     }
-    case IrOpcode::kValueEffect:
+    case IrOpcode::kEffectSet: {
+      CHECK_EQ(0, value_count);
+      CHECK_EQ(0, control_count);
+      CHECK_LT(1, effect_count);
+      break;
+    }
+    case IrOpcode::kGuard:
+      // TODO(bmeurer): what are the constraints on these?
+      break;
+    case IrOpcode::kBeginRegion:
       // TODO(rossberg): what are the constraints on these?
       break;
-    case IrOpcode::kFinish: {
+    case IrOpcode::kFinishRegion: {
       // 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));
+        Node* val = NodeProperties::GetValueInput(node, 0);
+        CHECK(NodeProperties::GetType(val)->Is(NodeProperties::GetType(node)));
       }
       break;
     }
     case IrOpcode::kFrameState:
       // TODO(jarin): what are the constraints on these?
+      CHECK_EQ(5, value_count);
+      CHECK_EQ(0, control_count);
+      CHECK_EQ(0, effect_count);
+      CHECK_EQ(6, input_count);
       break;
     case IrOpcode::kStateValues:
+    case IrOpcode::kObjectState:
+    case IrOpcode::kTypedStateValues:
       // TODO(jarin): what are the constraints on these?
       break;
     case IrOpcode::kCall:
       // TODO(rossberg): what are the constraints on these?
       break;
+    case IrOpcode::kTailCall:
+      // TODO(bmeurer): what are the constraints on these?
+      break;
 
     // JavaScript operators
     // --------------------
@@ -373,7 +457,6 @@
     case IrOpcode::kJSGreaterThan:
     case IrOpcode::kJSLessThanOrEqual:
     case IrOpcode::kJSGreaterThanOrEqual:
-    case IrOpcode::kJSUnaryNot:
       // Type is Boolean.
       CheckUpperIs(node, Type::Boolean());
       break;
@@ -424,13 +507,37 @@
       // Type is Object.
       CheckUpperIs(node, Type::Object());
       break;
+    case IrOpcode::kJSCreateArguments:
+      // Type is OtherObject.
+      CheckUpperIs(node, Type::OtherObject());
+      break;
+    case IrOpcode::kJSCreateArray:
+      // Type is OtherObject.
+      CheckUpperIs(node, Type::OtherObject());
+      break;
+    case IrOpcode::kJSCreateClosure:
+      // Type is Function.
+      CheckUpperIs(node, Type::Function());
+      break;
+    case IrOpcode::kJSCreateIterResultObject:
+      // Type is OtherObject.
+      CheckUpperIs(node, Type::OtherObject());
+      break;
+    case IrOpcode::kJSCreateLiteralArray:
+    case IrOpcode::kJSCreateLiteralObject:
+    case IrOpcode::kJSCreateLiteralRegExp:
+      // Type is OtherObject.
+      CheckUpperIs(node, Type::OtherObject());
+      break;
     case IrOpcode::kJSLoadProperty:
     case IrOpcode::kJSLoadNamed:
+    case IrOpcode::kJSLoadGlobal:
       // Type can be anything.
       CheckUpperIs(node, Type::Any());
       break;
     case IrOpcode::kJSStoreProperty:
     case IrOpcode::kJSStoreNamed:
+    case IrOpcode::kJSStoreGlobal:
       // Type is empty.
       CheckNotTyped(node);
       break;
@@ -446,6 +553,7 @@
       break;
 
     case IrOpcode::kJSLoadContext:
+    case IrOpcode::kJSLoadDynamic:
       // Type can be anything.
       CheckUpperIs(node, Type::Any());
       break;
@@ -464,28 +572,56 @@
       // 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());
+      if (typing == TYPED) CHECK(NodeProperties::GetType(node)->IsContext());
       break;
     }
 
     case IrOpcode::kJSCallConstruct:
+    case IrOpcode::kJSConvertReceiver:
       // 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;
 
+    case IrOpcode::kJSForInPrepare: {
+      // TODO(bmeurer): What are the constraints on thse?
+      CheckUpperIs(node, Type::Any());
+      break;
+    }
+    case IrOpcode::kJSForInDone: {
+      // TODO(bmeurer): OSR breaks this invariant, although the node is not user
+      // visible, so we know it is safe (fullcodegen has an unsigned smi there).
+      // CheckValueInputIs(node, 0, Type::UnsignedSmall());
+      break;
+    }
+    case IrOpcode::kJSForInNext: {
+      CheckUpperIs(node, Type::Union(Type::Name(), Type::Undefined(), zone));
+      break;
+    }
+    case IrOpcode::kJSForInStep: {
+      // TODO(bmeurer): OSR breaks this invariant, although the node is not user
+      // visible, so we know it is safe (fullcodegen has an unsigned smi there).
+      // CheckValueInputIs(node, 0, Type::UnsignedSmall());
+      CheckUpperIs(node, Type::UnsignedSmall());
+      break;
+    }
+
+    case IrOpcode::kJSLoadMessage:
+    case IrOpcode::kJSStoreMessage:
+      break;
+
+    case IrOpcode::kJSStackCheck:
+      // Type is empty.
+      CheckNotTyped(node);
+      break;
+
     // Simplified operators
     // -------------------------------
-    case IrOpcode::kAnyToBoolean:
-      // Type is Boolean.
-      CheckUpperIs(node, Type::Boolean());
-      break;
     case IrOpcode::kBooleanNot:
       // Boolean -> Boolean
       CheckValueInputIs(node, 0, Type::Boolean());
@@ -515,6 +651,27 @@
       // TODO(rossberg): activate once we retype after opcode changes.
       // CheckUpperIs(node, Type::Number());
       break;
+    case IrOpcode::kNumberBitwiseOr:
+    case IrOpcode::kNumberBitwiseXor:
+    case IrOpcode::kNumberBitwiseAnd:
+      // (Signed32, Signed32) -> Signed32
+      CheckValueInputIs(node, 0, Type::Signed32());
+      CheckValueInputIs(node, 1, Type::Signed32());
+      CheckUpperIs(node, Type::Signed32());
+      break;
+    case IrOpcode::kNumberShiftLeft:
+    case IrOpcode::kNumberShiftRight:
+      // (Signed32, Unsigned32) -> Signed32
+      CheckValueInputIs(node, 0, Type::Signed32());
+      CheckValueInputIs(node, 1, Type::Unsigned32());
+      CheckUpperIs(node, Type::Signed32());
+      break;
+    case IrOpcode::kNumberShiftRightLogical:
+      // (Unsigned32, Unsigned32) -> Unsigned32
+      CheckValueInputIs(node, 0, Type::Unsigned32());
+      CheckValueInputIs(node, 1, Type::Unsigned32());
+      CheckUpperIs(node, Type::Unsigned32());
+      break;
     case IrOpcode::kNumberToInt32:
       // Number -> Signed32
       CheckValueInputIs(node, 0, Type::Number());
@@ -525,6 +682,16 @@
       CheckValueInputIs(node, 0, Type::Number());
       CheckUpperIs(node, Type::Unsigned32());
       break;
+    case IrOpcode::kNumberIsHoleNaN:
+      // Number -> Boolean
+      CheckValueInputIs(node, 0, Type::Number());
+      CheckUpperIs(node, Type::Boolean());
+      break;
+    case IrOpcode::kPlainPrimitiveToNumber:
+      // PlainPrimitive -> Number
+      CheckValueInputIs(node, 0, Type::PlainPrimitive());
+      CheckUpperIs(node, Type::Number());
+      break;
     case IrOpcode::kStringEqual:
     case IrOpcode::kStringLessThan:
     case IrOpcode::kStringLessThanOrEqual:
@@ -533,29 +700,20 @@
       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()));
-      }
       CheckUpperIs(node, Type::Boolean());
       break;
     }
+    case IrOpcode::kObjectIsNumber:
     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());
+    case IrOpcode::kAllocate:
+      CheckValueInputIs(node, 0, Type::PlainNumber());
+      CheckUpperIs(node, Type::TaggedPointer());
       break;
 
     case IrOpcode::kChangeTaggedToInt32: {
@@ -635,7 +793,7 @@
       // Object -> fieldtype
       // TODO(rossberg): activate once machine ops are typed.
       // CheckValueInputIs(node, 0, Type::Object());
-      // CheckUpperIs(node, Field(node).type));
+      // CheckUpperIs(node, FieldAccessOf(node->op()).type));
       break;
     case IrOpcode::kLoadBuffer:
       break;
@@ -643,13 +801,13 @@
       // Object -> elementtype
       // TODO(rossberg): activate once machine ops are typed.
       // CheckValueInputIs(node, 0, Type::Object());
-      // CheckUpperIs(node, Element(node).type));
+      // CheckUpperIs(node, ElementAccessOf(node->op()).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));
+      // CheckValueInputIs(node, 1, FieldAccessOf(node->op()).type));
       CheckNotTyped(node);
       break;
     case IrOpcode::kStoreBuffer:
@@ -658,7 +816,7 @@
       // (Object, elementtype) -> _|_
       // TODO(rossberg): activate once machine ops are typed.
       // CheckValueInputIs(node, 0, Type::Object());
-      // CheckValueInputIs(node, 1, Element(node).type));
+      // CheckValueInputIs(node, 1, ElementAccessOf(node->op()).type));
       CheckNotTyped(node);
       break;
 
@@ -674,6 +832,9 @@
     case IrOpcode::kWord32Sar:
     case IrOpcode::kWord32Ror:
     case IrOpcode::kWord32Equal:
+    case IrOpcode::kWord32Clz:
+    case IrOpcode::kWord32Ctz:
+    case IrOpcode::kWord32Popcnt:
     case IrOpcode::kWord64And:
     case IrOpcode::kWord64Or:
     case IrOpcode::kWord64Xor:
@@ -681,6 +842,9 @@
     case IrOpcode::kWord64Shr:
     case IrOpcode::kWord64Sar:
     case IrOpcode::kWord64Ror:
+    case IrOpcode::kWord64Clz:
+    case IrOpcode::kWord64Popcnt:
+    case IrOpcode::kWord64Ctz:
     case IrOpcode::kWord64Equal:
     case IrOpcode::kInt32Add:
     case IrOpcode::kInt32AddWithOverflow:
@@ -698,7 +862,9 @@
     case IrOpcode::kUint32LessThan:
     case IrOpcode::kUint32LessThanOrEqual:
     case IrOpcode::kInt64Add:
+    case IrOpcode::kInt64AddWithOverflow:
     case IrOpcode::kInt64Sub:
+    case IrOpcode::kInt64SubWithOverflow:
     case IrOpcode::kInt64Mul:
     case IrOpcode::kInt64Div:
     case IrOpcode::kInt64Mod:
@@ -707,22 +873,50 @@
     case IrOpcode::kUint64Div:
     case IrOpcode::kUint64Mod:
     case IrOpcode::kUint64LessThan:
+    case IrOpcode::kUint64LessThanOrEqual:
+    case IrOpcode::kFloat32Add:
+    case IrOpcode::kFloat32Sub:
+    case IrOpcode::kFloat32Mul:
+    case IrOpcode::kFloat32Div:
+    case IrOpcode::kFloat32Max:
+    case IrOpcode::kFloat32Min:
+    case IrOpcode::kFloat32Abs:
+    case IrOpcode::kFloat32Sqrt:
+    case IrOpcode::kFloat32Equal:
+    case IrOpcode::kFloat32LessThan:
+    case IrOpcode::kFloat32LessThanOrEqual:
     case IrOpcode::kFloat64Add:
     case IrOpcode::kFloat64Sub:
     case IrOpcode::kFloat64Mul:
     case IrOpcode::kFloat64Div:
     case IrOpcode::kFloat64Mod:
+    case IrOpcode::kFloat64Max:
+    case IrOpcode::kFloat64Min:
+    case IrOpcode::kFloat64Abs:
     case IrOpcode::kFloat64Sqrt:
-    case IrOpcode::kFloat64Floor:
-    case IrOpcode::kFloat64Ceil:
+    case IrOpcode::kFloat32RoundDown:
+    case IrOpcode::kFloat64RoundDown:
+    case IrOpcode::kFloat32RoundUp:
+    case IrOpcode::kFloat64RoundUp:
+    case IrOpcode::kFloat32RoundTruncate:
     case IrOpcode::kFloat64RoundTruncate:
     case IrOpcode::kFloat64RoundTiesAway:
+    case IrOpcode::kFloat32RoundTiesEven:
+    case IrOpcode::kFloat64RoundTiesEven:
     case IrOpcode::kFloat64Equal:
     case IrOpcode::kFloat64LessThan:
     case IrOpcode::kFloat64LessThanOrEqual:
     case IrOpcode::kTruncateInt64ToInt32:
+    case IrOpcode::kRoundInt64ToFloat32:
+    case IrOpcode::kRoundInt64ToFloat64:
+    case IrOpcode::kRoundUint64ToFloat64:
+    case IrOpcode::kRoundUint64ToFloat32:
     case IrOpcode::kTruncateFloat64ToFloat32:
     case IrOpcode::kTruncateFloat64ToInt32:
+    case IrOpcode::kBitcastFloat32ToInt32:
+    case IrOpcode::kBitcastFloat64ToInt64:
+    case IrOpcode::kBitcastInt32ToFloat32:
+    case IrOpcode::kBitcastInt64ToFloat64:
     case IrOpcode::kChangeInt32ToInt64:
     case IrOpcode::kChangeUint32ToUint64:
     case IrOpcode::kChangeInt32ToFloat64:
@@ -730,20 +924,46 @@
     case IrOpcode::kChangeFloat32ToFloat64:
     case IrOpcode::kChangeFloat64ToInt32:
     case IrOpcode::kChangeFloat64ToUint32:
+    case IrOpcode::kTryTruncateFloat32ToInt64:
+    case IrOpcode::kTryTruncateFloat64ToInt64:
+    case IrOpcode::kTryTruncateFloat32ToUint64:
+    case IrOpcode::kTryTruncateFloat64ToUint64:
+    case IrOpcode::kFloat64ExtractLowWord32:
+    case IrOpcode::kFloat64ExtractHighWord32:
+    case IrOpcode::kFloat64InsertLowWord32:
+    case IrOpcode::kFloat64InsertHighWord32:
     case IrOpcode::kLoadStackPointer:
+    case IrOpcode::kLoadFramePointer:
     case IrOpcode::kCheckedLoad:
     case IrOpcode::kCheckedStore:
       // TODO(rossberg): Check.
       break;
   }
-}
+}  // NOLINT(readability/fn_size)
 
 
 void Verifier::Run(Graph* graph, Typing typing) {
-  Visitor visitor(graph->zone(), typing);
-  CHECK_NE(NULL, graph->start());
-  CHECK_NE(NULL, graph->end());
-  graph->VisitNodeInputsFromEnd(&visitor);
+  CHECK_NOT_NULL(graph->start());
+  CHECK_NOT_NULL(graph->end());
+  Zone zone;
+  Visitor visitor(&zone, typing);
+  AllNodes all(&zone, graph);
+  for (Node* node : all.live) visitor.Check(node);
+
+  // Check the uniqueness of projections.
+  for (Node* proj : all.live) {
+    if (proj->opcode() != IrOpcode::kProjection) continue;
+    Node* node = proj->InputAt(0);
+    for (Node* other : node->uses()) {
+      if (all.IsLive(other) && other != proj &&
+          other->opcode() == IrOpcode::kProjection &&
+          ProjectionIndexOf(other->op()) == ProjectionIndexOf(proj->op())) {
+        V8_Fatal(__FILE__, __LINE__,
+                 "Node #%d:%s has duplicate projections #%d and #%d",
+                 node->id(), node->op()->mnemonic(), proj->id(), other->id());
+      }
+    }
+  }
 }
 
 
@@ -759,7 +979,7 @@
       use_pos--;
     }
     block = block->dominator();
-    if (block == NULL) break;
+    if (block == nullptr) break;
     use_pos = static_cast<int>(block->NodeCount()) - 1;
     if (node == block->control_input()) return true;
   }
@@ -770,7 +990,7 @@
 static bool Dominates(Schedule* schedule, Node* dominator, Node* dominatee) {
   BasicBlock* dom = schedule->block(dominator);
   BasicBlock* sub = schedule->block(dominatee);
-  while (sub != NULL) {
+  while (sub != nullptr) {
     if (sub == dom) {
       return true;
     }
@@ -793,7 +1013,7 @@
                           use_pos)) {
       V8_Fatal(__FILE__, __LINE__,
                "Node #%d:%s in B%d is not dominated by input@%d #%d:%s",
-               node->id(), node->op()->mnemonic(), block->id().ToInt(), j,
+               node->id(), node->op()->mnemonic(), block->rpo_number(), j,
                input->id(), input->op()->mnemonic());
     }
   }
@@ -806,8 +1026,8 @@
     if (!Dominates(schedule, ctl, node)) {
       V8_Fatal(__FILE__, __LINE__,
                "Node #%d:%s in B%d is not dominated by control input #%d:%s",
-               node->id(), node->op()->mnemonic(), block->id(), ctl->id(),
-               ctl->op()->mnemonic());
+               node->id(), node->op()->mnemonic(), block->rpo_number(),
+               ctl->id(), ctl->op()->mnemonic());
     }
   }
 }
@@ -815,7 +1035,7 @@
 
 void ScheduleVerifier::Run(Schedule* schedule) {
   const size_t count = schedule->BasicBlockCount();
-  Zone tmp_zone(schedule->zone()->isolate());
+  Zone tmp_zone;
   Zone* zone = &tmp_zone;
   BasicBlock* start = schedule->start();
   BasicBlockVector* rpo_order = schedule->rpo_order();
@@ -826,15 +1046,13 @@
        ++b) {
     CHECK_EQ((*b), schedule->GetBlockById((*b)->id()));
     // All predecessors and successors should be in rpo and in this schedule.
-    for (BasicBlock::Predecessors::iterator j = (*b)->predecessors_begin();
-         j != (*b)->predecessors_end(); ++j) {
-      CHECK_GE((*j)->rpo_number(), 0);
-      CHECK_EQ((*j), schedule->GetBlockById((*j)->id()));
+    for (BasicBlock const* predecessor : (*b)->predecessors()) {
+      CHECK_GE(predecessor->rpo_number(), 0);
+      CHECK_EQ(predecessor, schedule->GetBlockById(predecessor->id()));
     }
-    for (BasicBlock::Successors::iterator j = (*b)->successors_begin();
-         j != (*b)->successors_end(); ++j) {
-      CHECK_GE((*j)->rpo_number(), 0);
-      CHECK_EQ((*j), schedule->GetBlockById((*j)->id()));
+    for (BasicBlock const* successor : (*b)->successors()) {
+      CHECK_GE(successor->rpo_number(), 0);
+      CHECK_EQ(successor, schedule->GetBlockById(successor->id()));
     }
   }
 
@@ -846,10 +1064,10 @@
     BasicBlock* dom = block->dominator();
     if (b == 0) {
       // All blocks except start should have a dominator.
-      CHECK_EQ(NULL, dom);
+      CHECK_NULL(dom);
     } else {
       // Check that the immediate dominator appears somewhere before the block.
-      CHECK_NE(NULL, dom);
+      CHECK_NOT_NULL(dom);
       CHECK_LT(dom->rpo_number(), block->rpo_number());
     }
   }
@@ -888,7 +1106,7 @@
   {
     // Verify the dominance relation.
     ZoneVector<BitVector*> dominators(zone);
-    dominators.resize(count, NULL);
+    dominators.resize(count, nullptr);
 
     // Compute a set of all the nodes that dominate a given node by using
     // a forward fixpoint. O(n^2).
@@ -901,15 +1119,15 @@
       queue.pop();
       BitVector* block_doms = dominators[block->id().ToSize()];
       BasicBlock* idom = block->dominator();
-      if (idom != NULL && !block_doms->Contains(idom->id().ToInt())) {
+      if (idom != nullptr && !block_doms->Contains(idom->id().ToInt())) {
         V8_Fatal(__FILE__, __LINE__, "Block B%d is not dominated by B%d",
-                 block->id().ToInt(), idom->id().ToInt());
+                 block->rpo_number(), idom->rpo_number());
       }
       for (size_t s = 0; s < block->SuccessorCount(); s++) {
         BasicBlock* succ = block->SuccessorAt(s);
         BitVector* succ_doms = dominators[succ->id().ToSize()];
 
-        if (succ_doms == NULL) {
+        if (succ_doms == nullptr) {
           // First time visiting the node. S.doms = B U B.doms
           succ_doms = new (zone) BitVector(static_cast<int>(count), zone);
           succ_doms->CopyFrom(*block_doms);
@@ -931,7 +1149,7 @@
          b != rpo_order->end(); ++b) {
       BasicBlock* block = *b;
       BasicBlock* idom = block->dominator();
-      if (idom == NULL) continue;
+      if (idom == nullptr) continue;
       BitVector* block_doms = dominators[block->id().ToSize()];
 
       for (BitVector::Iterator it(block_doms); !it.Done(); it.Advance()) {
@@ -941,7 +1159,7 @@
             !dominators[idom->id().ToSize()]->Contains(dom->id().ToInt())) {
           V8_Fatal(__FILE__, __LINE__,
                    "Block B%d is not immediately dominated by B%d",
-                   block->id().ToInt(), idom->id().ToInt());
+                   block->rpo_number(), idom->rpo_number());
         }
       }
     }
@@ -971,7 +1189,7 @@
 
     // Check inputs to control for this block.
     Node* control = block->control_input();
-    if (control != NULL) {
+    if (control != nullptr) {
       CHECK_EQ(block, schedule->block(control));
       CheckInputsDominate(schedule, block, control,
                           static_cast<int>(block->NodeCount()) - 1);
@@ -983,6 +1201,68 @@
     }
   }
 }
+
+
+#ifdef DEBUG
+
+// static
+void Verifier::VerifyNode(Node* node) {
+  CHECK_EQ(OperatorProperties::GetTotalInputCount(node->op()),
+           node->InputCount());
+  // If this node has no effect or no control outputs,
+  // we check that no its uses are effect or control inputs.
+  bool check_no_control = node->op()->ControlOutputCount() == 0;
+  bool check_no_effect = node->op()->EffectOutputCount() == 0;
+  bool check_no_frame_state = node->opcode() != IrOpcode::kFrameState;
+  if (check_no_effect || check_no_control) {
+    for (Edge edge : node->use_edges()) {
+      Node* const user = edge.from();
+      CHECK(!user->IsDead());
+      if (NodeProperties::IsControlEdge(edge)) {
+        CHECK(!check_no_control);
+      } else if (NodeProperties::IsEffectEdge(edge)) {
+        CHECK(!check_no_effect);
+      } else if (NodeProperties::IsFrameStateEdge(edge)) {
+        CHECK(!check_no_frame_state);
+      }
+    }
+  }
+  // Frame state inputs should be frame states (or sentinels).
+  for (int i = 0; i < OperatorProperties::GetFrameStateInputCount(node->op());
+       i++) {
+    Node* input = NodeProperties::GetFrameStateInput(node, i);
+    CHECK(input->opcode() == IrOpcode::kFrameState ||
+          input->opcode() == IrOpcode::kStart ||
+          input->opcode() == IrOpcode::kDead);
+  }
+  // Effect inputs should be effect-producing nodes (or sentinels).
+  for (int i = 0; i < node->op()->EffectInputCount(); i++) {
+    Node* input = NodeProperties::GetEffectInput(node, i);
+    CHECK(input->op()->EffectOutputCount() > 0 ||
+          input->opcode() == IrOpcode::kDead);
+  }
+  // Control inputs should be control-producing nodes (or sentinels).
+  for (int i = 0; i < node->op()->ControlInputCount(); i++) {
+    Node* input = NodeProperties::GetControlInput(node, i);
+    CHECK(input->op()->ControlOutputCount() > 0 ||
+          input->opcode() == IrOpcode::kDead);
+  }
 }
+
+
+void Verifier::VerifyEdgeInputReplacement(const Edge& edge,
+                                          const Node* replacement) {
+  // Check that the user does not misuse the replacement.
+  DCHECK(!NodeProperties::IsControlEdge(edge) ||
+         replacement->op()->ControlOutputCount() > 0);
+  DCHECK(!NodeProperties::IsEffectEdge(edge) ||
+         replacement->op()->EffectOutputCount() > 0);
+  DCHECK(!NodeProperties::IsFrameStateEdge(edge) ||
+         replacement->opcode() == IrOpcode::kFrameState);
 }
-}  // namespace v8::internal::compiler
+
+#endif  // DEBUG
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/verifier.h b/src/compiler/verifier.h
index 67b7ba6..428558d 100644
--- a/src/compiler/verifier.h
+++ b/src/compiler/verifier.h
@@ -5,13 +5,15 @@
 #ifndef V8_COMPILER_VERIFIER_H_
 #define V8_COMPILER_VERIFIER_H_
 
-#include "src/v8.h"
+#include "src/base/macros.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
 class Graph;
+class Edge;
+class Node;
 class Schedule;
 
 // Verifies properties of a graph, such as the well-formedness of inputs to
@@ -22,6 +24,28 @@
 
   static void Run(Graph* graph, Typing typing = TYPED);
 
+#ifdef DEBUG
+  // Verifies consistency of node inputs and uses:
+  // - node inputs should agree with the input count computed from
+  //   the node's operator.
+  // - effect inputs should have effect outputs.
+  // - control inputs should have control outputs.
+  // - frame state inputs should be frame states.
+  // - if the node has control uses, it should produce control.
+  // - if the node has effect uses, it should produce effect.
+  // - if the node has frame state uses, it must be a frame state.
+  static void VerifyNode(Node* node);
+
+  // Verify that {replacement} has the required outputs
+  // (effect, control or frame state) to be used as an input for {edge}.
+  static void VerifyEdgeInputReplacement(const Edge& edge,
+                                         const Node* replacement);
+#else
+  static void VerifyNode(Node* node) {}
+  static void VerifyEdgeInputReplacement(const Edge& edge,
+                                         const Node* replacement) {}
+#endif  // DEBUG
+
  private:
   class Visitor;
   DISALLOW_COPY_AND_ASSIGN(Verifier);
@@ -32,8 +56,8 @@
  public:
   static void Run(Schedule* schedule);
 };
-}
-}
-}  // namespace v8::internal::compiler
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
 
 #endif  // V8_COMPILER_VERIFIER_H_
diff --git a/src/compiler/wasm-compiler.cc b/src/compiler/wasm-compiler.cc
new file mode 100644
index 0000000..17065d6
--- /dev/null
+++ b/src/compiler/wasm-compiler.cc
@@ -0,0 +1,2031 @@
+// Copyright 2015 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/wasm-compiler.h"
+
+#include "src/isolate-inl.h"
+
+#include "src/base/platform/platform.h"
+
+#include "src/compiler/access-builder.h"
+#include "src/compiler/change-lowering.h"
+#include "src/compiler/common-operator.h"
+#include "src/compiler/diamond.h"
+#include "src/compiler/graph.h"
+#include "src/compiler/graph-visualizer.h"
+#include "src/compiler/instruction-selector.h"
+#include "src/compiler/js-generic-lowering.h"
+#include "src/compiler/js-graph.h"
+#include "src/compiler/js-operator.h"
+#include "src/compiler/linkage.h"
+#include "src/compiler/machine-operator.h"
+#include "src/compiler/node-matchers.h"
+#include "src/compiler/pipeline.h"
+#include "src/compiler/simplified-lowering.h"
+#include "src/compiler/simplified-operator.h"
+#include "src/compiler/source-position.h"
+#include "src/compiler/typer.h"
+
+#include "src/code-factory.h"
+#include "src/code-stubs.h"
+
+#include "src/wasm/ast-decoder.h"
+#include "src/wasm/wasm-module.h"
+#include "src/wasm/wasm-opcodes.h"
+
+// TODO(titzer): pull WASM_64 up to a common header.
+#if !V8_TARGET_ARCH_32_BIT || V8_TARGET_ARCH_X64
+#define WASM_64 1
+#else
+#define WASM_64 0
+#endif
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+namespace {
+const Operator* UnsupportedOpcode(wasm::WasmOpcode opcode) {
+  if (wasm::WasmOpcodes::IsSupported(opcode)) {
+    V8_Fatal(__FILE__, __LINE__,
+             "Unsupported opcode #%d:%s reported as supported", opcode,
+             wasm::WasmOpcodes::OpcodeName(opcode));
+  }
+  V8_Fatal(__FILE__, __LINE__, "Unsupported opcode #%d:%s", opcode,
+           wasm::WasmOpcodes::OpcodeName(opcode));
+  return nullptr;
+}
+
+
+void MergeControlToEnd(JSGraph* jsgraph, Node* node) {
+  Graph* g = jsgraph->graph();
+  if (g->end()) {
+    NodeProperties::MergeControlToEnd(g, jsgraph->common(), node);
+  } else {
+    g->SetEnd(g->NewNode(jsgraph->common()->End(1), node));
+  }
+}
+
+
+enum TrapReason {
+  kTrapUnreachable,
+  kTrapMemOutOfBounds,
+  kTrapDivByZero,
+  kTrapDivUnrepresentable,
+  kTrapRemByZero,
+  kTrapFloatUnrepresentable,
+  kTrapFuncInvalid,
+  kTrapFuncSigMismatch,
+  kTrapCount
+};
+
+
+static const char* kTrapMessages[] = {
+    "unreachable",       "memory access out of bounds",
+    "divide by zero",    "divide result unrepresentable",
+    "remainder by zero", "integer result unrepresentable",
+    "invalid function",  "function signature mismatch"};
+}  // namespace
+
+
+// A helper that handles building graph fragments for trapping.
+// To avoid generating a ton of redundant code that just calls the runtime
+// to trap, we generate a per-trap-reason block of code that all trap sites
+// in this function will branch to.
+class WasmTrapHelper : public ZoneObject {
+ public:
+  explicit WasmTrapHelper(WasmGraphBuilder* builder)
+      : builder_(builder),
+        jsgraph_(builder->jsgraph()),
+        graph_(builder->jsgraph() ? builder->jsgraph()->graph() : nullptr) {
+    for (int i = 0; i < kTrapCount; i++) traps_[i] = nullptr;
+  }
+
+  // Make the current control path trap to unreachable.
+  void Unreachable() { ConnectTrap(kTrapUnreachable); }
+
+  // Add a check that traps if {node} is equal to {val}.
+  Node* TrapIfEq32(TrapReason reason, Node* node, int32_t val) {
+    Int32Matcher m(node);
+    if (m.HasValue() && !m.Is(val)) return graph()->start();
+    if (val == 0) {
+      AddTrapIfFalse(reason, node);
+    } else {
+      AddTrapIfTrue(reason,
+                    graph()->NewNode(jsgraph()->machine()->Word32Equal(), node,
+                                     jsgraph()->Int32Constant(val)));
+    }
+    return builder_->Control();
+  }
+
+  // Add a check that traps if {node} is zero.
+  Node* ZeroCheck32(TrapReason reason, Node* node) {
+    return TrapIfEq32(reason, node, 0);
+  }
+
+  // Add a check that traps if {node} is equal to {val}.
+  Node* TrapIfEq64(TrapReason reason, Node* node, int64_t val) {
+    Int64Matcher m(node);
+    if (m.HasValue() && !m.Is(val)) return graph()->start();
+    AddTrapIfTrue(reason,
+                  graph()->NewNode(jsgraph()->machine()->Word64Equal(), node,
+                                   jsgraph()->Int64Constant(val)));
+    return builder_->Control();
+  }
+
+  // Add a check that traps if {node} is zero.
+  Node* ZeroCheck64(TrapReason reason, Node* node) {
+    return TrapIfEq64(reason, node, 0);
+  }
+
+  // Add a trap if {cond} is true.
+  void AddTrapIfTrue(TrapReason reason, Node* cond) {
+    AddTrapIf(reason, cond, true);
+  }
+
+  // Add a trap if {cond} is false.
+  void AddTrapIfFalse(TrapReason reason, Node* cond) {
+    AddTrapIf(reason, cond, false);
+  }
+
+  // Add a trap if {cond} is true or false according to {iftrue}.
+  void AddTrapIf(TrapReason reason, Node* cond, bool iftrue) {
+    Node** effect_ptr = builder_->effect_;
+    Node** control_ptr = builder_->control_;
+    Node* before = *effect_ptr;
+    BranchHint hint = iftrue ? BranchHint::kFalse : BranchHint::kTrue;
+    Node* branch = graph()->NewNode(common()->Branch(hint), cond, *control_ptr);
+    Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
+    Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+
+    *control_ptr = iftrue ? if_true : if_false;
+    ConnectTrap(reason);
+    *control_ptr = iftrue ? if_false : if_true;
+    *effect_ptr = before;
+  }
+
+ private:
+  WasmGraphBuilder* builder_;
+  JSGraph* jsgraph_;
+  Graph* graph_;
+  Node* traps_[kTrapCount];
+  Node* effects_[kTrapCount];
+
+  JSGraph* jsgraph() { return jsgraph_; }
+  Graph* graph() { return jsgraph_->graph(); }
+  CommonOperatorBuilder* common() { return jsgraph()->common(); }
+
+  void ConnectTrap(TrapReason reason) {
+    if (traps_[reason] == nullptr) {
+      // Create trap code for the first time this trap is used.
+      return BuildTrapCode(reason);
+    }
+    // Connect the current control and effect to the existing trap code.
+    builder_->AppendToMerge(traps_[reason], builder_->Control());
+    builder_->AppendToPhi(traps_[reason], effects_[reason], builder_->Effect());
+  }
+
+  void BuildTrapCode(TrapReason reason) {
+    Node* exception = builder_->String(kTrapMessages[reason]);
+    Node* end;
+    Node** control_ptr = builder_->control_;
+    Node** effect_ptr = builder_->effect_;
+    wasm::ModuleEnv* module = builder_->module_;
+    *control_ptr = traps_[reason] =
+        graph()->NewNode(common()->Merge(1), *control_ptr);
+    *effect_ptr = effects_[reason] =
+        graph()->NewNode(common()->EffectPhi(1), *effect_ptr, *control_ptr);
+
+    if (module && !module->context.is_null()) {
+      // Use the module context to call the runtime to throw an exception.
+      Runtime::FunctionId f = Runtime::kThrow;
+      const Runtime::Function* fun = Runtime::FunctionForId(f);
+      CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor(
+          jsgraph()->zone(), f, fun->nargs, Operator::kNoProperties,
+          CallDescriptor::kNoFlags);
+      Node* inputs[] = {
+          jsgraph()->CEntryStubConstant(fun->result_size),  // C entry
+          exception,                                        // exception
+          jsgraph()->ExternalConstant(
+              ExternalReference(f, jsgraph()->isolate())),  // ref
+          jsgraph()->Int32Constant(fun->nargs),             // arity
+          jsgraph()->Constant(module->context),             // context
+          *effect_ptr,
+          *control_ptr};
+
+      Node* node = graph()->NewNode(
+          common()->Call(desc), static_cast<int>(arraysize(inputs)), inputs);
+      *control_ptr = node;
+      *effect_ptr = node;
+    }
+    if (false) {
+      // End the control flow with a throw
+      Node* thrw =
+          graph()->NewNode(common()->Throw(), jsgraph()->ZeroConstant(),
+                           *effect_ptr, *control_ptr);
+      end = thrw;
+    } else {
+      // End the control flow with returning 0xdeadbeef
+      Node* ret_value;
+      if (builder_->GetFunctionSignature()->return_count() > 0) {
+        switch (builder_->GetFunctionSignature()->GetReturn()) {
+          case wasm::kAstI32:
+            ret_value = jsgraph()->Int32Constant(0xdeadbeef);
+            break;
+          case wasm::kAstI64:
+            ret_value = jsgraph()->Int64Constant(0xdeadbeefdeadbeef);
+            break;
+          case wasm::kAstF32:
+            ret_value = jsgraph()->Float32Constant(bit_cast<float>(0xdeadbeef));
+            break;
+          case wasm::kAstF64:
+            ret_value = jsgraph()->Float64Constant(
+                bit_cast<double>(0xdeadbeefdeadbeef));
+            break;
+          default:
+            UNREACHABLE();
+            ret_value = nullptr;
+        }
+      } else {
+        ret_value = jsgraph()->Int32Constant(0xdeadbeef);
+      }
+      end = graph()->NewNode(jsgraph()->common()->Return(), ret_value,
+                             *effect_ptr, *control_ptr);
+    }
+
+    MergeControlToEnd(jsgraph(), end);
+  }
+};
+
+
+WasmGraphBuilder::WasmGraphBuilder(Zone* zone, JSGraph* jsgraph,
+                                   wasm::FunctionSig* function_signature)
+    : zone_(zone),
+      jsgraph_(jsgraph),
+      module_(nullptr),
+      mem_buffer_(nullptr),
+      mem_size_(nullptr),
+      function_table_(nullptr),
+      control_(nullptr),
+      effect_(nullptr),
+      cur_buffer_(def_buffer_),
+      cur_bufsize_(kDefaultBufferSize),
+      trap_(new (zone) WasmTrapHelper(this)),
+      function_signature_(function_signature) {
+  DCHECK_NOT_NULL(jsgraph_);
+}
+
+
+Node* WasmGraphBuilder::Error() { return jsgraph()->Dead(); }
+
+
+Node* WasmGraphBuilder::Start(unsigned params) {
+  Node* start = graph()->NewNode(jsgraph()->common()->Start(params));
+  graph()->SetStart(start);
+  return start;
+}
+
+
+Node* WasmGraphBuilder::Param(unsigned index, wasm::LocalType type) {
+  return graph()->NewNode(jsgraph()->common()->Parameter(index),
+                          graph()->start());
+}
+
+
+Node* WasmGraphBuilder::Loop(Node* entry) {
+  return graph()->NewNode(jsgraph()->common()->Loop(1), entry);
+}
+
+
+Node* WasmGraphBuilder::Terminate(Node* effect, Node* control) {
+  Node* terminate =
+      graph()->NewNode(jsgraph()->common()->Terminate(), effect, control);
+  MergeControlToEnd(jsgraph(), terminate);
+  return terminate;
+}
+
+
+unsigned WasmGraphBuilder::InputCount(Node* node) {
+  return static_cast<unsigned>(node->InputCount());
+}
+
+
+bool WasmGraphBuilder::IsPhiWithMerge(Node* phi, Node* merge) {
+  return phi && IrOpcode::IsPhiOpcode(phi->opcode()) &&
+         NodeProperties::GetControlInput(phi) == merge;
+}
+
+
+void WasmGraphBuilder::AppendToMerge(Node* merge, Node* from) {
+  DCHECK(IrOpcode::IsMergeOpcode(merge->opcode()));
+  merge->AppendInput(jsgraph()->zone(), from);
+  int new_size = merge->InputCount();
+  NodeProperties::ChangeOp(
+      merge, jsgraph()->common()->ResizeMergeOrPhi(merge->op(), new_size));
+}
+
+
+void WasmGraphBuilder::AppendToPhi(Node* merge, Node* phi, Node* from) {
+  DCHECK(IrOpcode::IsPhiOpcode(phi->opcode()));
+  DCHECK(IrOpcode::IsMergeOpcode(merge->opcode()));
+  int new_size = phi->InputCount();
+  phi->InsertInput(jsgraph()->zone(), phi->InputCount() - 1, from);
+  NodeProperties::ChangeOp(
+      phi, jsgraph()->common()->ResizeMergeOrPhi(phi->op(), new_size));
+}
+
+
+Node* WasmGraphBuilder::Merge(unsigned count, Node** controls) {
+  return graph()->NewNode(jsgraph()->common()->Merge(count), count, controls);
+}
+
+
+Node* WasmGraphBuilder::Phi(wasm::LocalType type, unsigned count, Node** vals,
+                            Node* control) {
+  DCHECK(IrOpcode::IsMergeOpcode(control->opcode()));
+  Node** buf = Realloc(vals, count);
+  buf = Realloc(buf, count + 1);
+  buf[count] = control;
+  return graph()->NewNode(jsgraph()->common()->Phi(type, count), count + 1,
+                          buf);
+}
+
+
+Node* WasmGraphBuilder::EffectPhi(unsigned count, Node** effects,
+                                  Node* control) {
+  DCHECK(IrOpcode::IsMergeOpcode(control->opcode()));
+  Node** buf = Realloc(effects, count);
+  buf = Realloc(buf, count + 1);
+  buf[count] = control;
+  return graph()->NewNode(jsgraph()->common()->EffectPhi(count), count + 1,
+                          buf);
+}
+
+
+Node* WasmGraphBuilder::Int32Constant(int32_t value) {
+  return jsgraph()->Int32Constant(value);
+}
+
+
+Node* WasmGraphBuilder::Int64Constant(int64_t value) {
+  return jsgraph()->Int64Constant(value);
+}
+
+
+Node* WasmGraphBuilder::Binop(wasm::WasmOpcode opcode, Node* left,
+                              Node* right) {
+  const Operator* op;
+  MachineOperatorBuilder* m = jsgraph()->machine();
+  switch (opcode) {
+    case wasm::kExprI32Add:
+      op = m->Int32Add();
+      break;
+    case wasm::kExprI32Sub:
+      op = m->Int32Sub();
+      break;
+    case wasm::kExprI32Mul:
+      op = m->Int32Mul();
+      break;
+    case wasm::kExprI32DivS: {
+      trap_->ZeroCheck32(kTrapDivByZero, right);
+      Node* before = *control_;
+      Node* denom_is_m1;
+      Node* denom_is_not_m1;
+      Branch(graph()->NewNode(jsgraph()->machine()->Word32Equal(), right,
+                              jsgraph()->Int32Constant(-1)),
+             &denom_is_m1, &denom_is_not_m1);
+      *control_ = denom_is_m1;
+      trap_->TrapIfEq32(kTrapDivUnrepresentable, left, kMinInt);
+      if (*control_ != denom_is_m1) {
+        *control_ = graph()->NewNode(jsgraph()->common()->Merge(2),
+                                     denom_is_not_m1, *control_);
+      } else {
+        *control_ = before;
+      }
+      return graph()->NewNode(m->Int32Div(), left, right, *control_);
+    }
+    case wasm::kExprI32DivU:
+      op = m->Uint32Div();
+      return graph()->NewNode(op, left, right,
+                              trap_->ZeroCheck32(kTrapDivByZero, right));
+    case wasm::kExprI32RemS: {
+      trap_->ZeroCheck32(kTrapRemByZero, right);
+      Diamond d(graph(), jsgraph()->common(),
+                graph()->NewNode(jsgraph()->machine()->Word32Equal(), right,
+                                 jsgraph()->Int32Constant(-1)));
+
+      Node* rem = graph()->NewNode(m->Int32Mod(), left, right, d.if_false);
+
+      return d.Phi(MachineRepresentation::kWord32, jsgraph()->Int32Constant(0),
+                   rem);
+    }
+    case wasm::kExprI32RemU:
+      op = m->Uint32Mod();
+      return graph()->NewNode(op, left, right,
+                              trap_->ZeroCheck32(kTrapRemByZero, right));
+    case wasm::kExprI32And:
+      op = m->Word32And();
+      break;
+    case wasm::kExprI32Ior:
+      op = m->Word32Or();
+      break;
+    case wasm::kExprI32Xor:
+      op = m->Word32Xor();
+      break;
+    case wasm::kExprI32Shl:
+      op = m->Word32Shl();
+      break;
+    case wasm::kExprI32ShrU:
+      op = m->Word32Shr();
+      break;
+    case wasm::kExprI32ShrS:
+      op = m->Word32Sar();
+      break;
+    case wasm::kExprI32Eq:
+      op = m->Word32Equal();
+      break;
+    case wasm::kExprI32Ne:
+      return Invert(Binop(wasm::kExprI32Eq, left, right));
+    case wasm::kExprI32LtS:
+      op = m->Int32LessThan();
+      break;
+    case wasm::kExprI32LeS:
+      op = m->Int32LessThanOrEqual();
+      break;
+    case wasm::kExprI32LtU:
+      op = m->Uint32LessThan();
+      break;
+    case wasm::kExprI32LeU:
+      op = m->Uint32LessThanOrEqual();
+      break;
+    case wasm::kExprI32GtS:
+      op = m->Int32LessThan();
+      std::swap(left, right);
+      break;
+    case wasm::kExprI32GeS:
+      op = m->Int32LessThanOrEqual();
+      std::swap(left, right);
+      break;
+    case wasm::kExprI32GtU:
+      op = m->Uint32LessThan();
+      std::swap(left, right);
+      break;
+    case wasm::kExprI32GeU:
+      op = m->Uint32LessThanOrEqual();
+      std::swap(left, right);
+      break;
+#if WASM_64
+    // Opcodes only supported on 64-bit platforms.
+    // TODO(titzer): query the machine operator builder here instead of #ifdef.
+    case wasm::kExprI64Add:
+      op = m->Int64Add();
+      break;
+    case wasm::kExprI64Sub:
+      op = m->Int64Sub();
+      break;
+    case wasm::kExprI64Mul:
+      op = m->Int64Mul();
+      break;
+    case wasm::kExprI64DivS: {
+      trap_->ZeroCheck64(kTrapDivByZero, right);
+      Node* before = *control_;
+      Node* denom_is_m1;
+      Node* denom_is_not_m1;
+      Branch(graph()->NewNode(jsgraph()->machine()->Word64Equal(), right,
+                              jsgraph()->Int64Constant(-1)),
+             &denom_is_m1, &denom_is_not_m1);
+      *control_ = denom_is_m1;
+      trap_->TrapIfEq64(kTrapDivUnrepresentable, left,
+                        std::numeric_limits<int64_t>::min());
+      if (*control_ != denom_is_m1) {
+        *control_ = graph()->NewNode(jsgraph()->common()->Merge(2),
+                                     denom_is_not_m1, *control_);
+      } else {
+        *control_ = before;
+      }
+      return graph()->NewNode(m->Int64Div(), left, right, *control_);
+    }
+    case wasm::kExprI64DivU:
+      op = m->Uint64Div();
+      return graph()->NewNode(op, left, right,
+                              trap_->ZeroCheck64(kTrapDivByZero, right));
+    case wasm::kExprI64RemS: {
+      trap_->ZeroCheck64(kTrapRemByZero, right);
+      Diamond d(jsgraph()->graph(), jsgraph()->common(),
+                graph()->NewNode(jsgraph()->machine()->Word64Equal(), right,
+                                 jsgraph()->Int64Constant(-1)));
+
+      Node* rem = graph()->NewNode(m->Int64Mod(), left, right, d.if_false);
+
+      return d.Phi(MachineRepresentation::kWord64, jsgraph()->Int64Constant(0),
+                   rem);
+    }
+    case wasm::kExprI64RemU:
+      op = m->Uint64Mod();
+      return graph()->NewNode(op, left, right,
+                              trap_->ZeroCheck64(kTrapRemByZero, right));
+    case wasm::kExprI64And:
+      op = m->Word64And();
+      break;
+    case wasm::kExprI64Ior:
+      op = m->Word64Or();
+      break;
+    case wasm::kExprI64Xor:
+      op = m->Word64Xor();
+      break;
+    case wasm::kExprI64Shl:
+      op = m->Word64Shl();
+      break;
+    case wasm::kExprI64ShrU:
+      op = m->Word64Shr();
+      break;
+    case wasm::kExprI64ShrS:
+      op = m->Word64Sar();
+      break;
+    case wasm::kExprI64Eq:
+      op = m->Word64Equal();
+      break;
+    case wasm::kExprI64Ne:
+      return Invert(Binop(wasm::kExprI64Eq, left, right));
+    case wasm::kExprI64LtS:
+      op = m->Int64LessThan();
+      break;
+    case wasm::kExprI64LeS:
+      op = m->Int64LessThanOrEqual();
+      break;
+    case wasm::kExprI64LtU:
+      op = m->Uint64LessThan();
+      break;
+    case wasm::kExprI64LeU:
+      op = m->Uint64LessThanOrEqual();
+      break;
+    case wasm::kExprI64GtS:
+      op = m->Int64LessThan();
+      std::swap(left, right);
+      break;
+    case wasm::kExprI64GeS:
+      op = m->Int64LessThanOrEqual();
+      std::swap(left, right);
+      break;
+    case wasm::kExprI64GtU:
+      op = m->Uint64LessThan();
+      std::swap(left, right);
+      break;
+    case wasm::kExprI64GeU:
+      op = m->Uint64LessThanOrEqual();
+      std::swap(left, right);
+      break;
+#endif
+
+    case wasm::kExprF32CopySign:
+      return BuildF32CopySign(left, right);
+    case wasm::kExprF64CopySign:
+      return BuildF64CopySign(left, right);
+    case wasm::kExprF32Add:
+      op = m->Float32Add();
+      break;
+    case wasm::kExprF32Sub:
+      op = m->Float32Sub();
+      break;
+    case wasm::kExprF32Mul:
+      op = m->Float32Mul();
+      break;
+    case wasm::kExprF32Div:
+      op = m->Float32Div();
+      break;
+    case wasm::kExprF32Eq:
+      op = m->Float32Equal();
+      break;
+    case wasm::kExprF32Ne:
+      return Invert(Binop(wasm::kExprF32Eq, left, right));
+    case wasm::kExprF32Lt:
+      op = m->Float32LessThan();
+      break;
+    case wasm::kExprF32Ge:
+      op = m->Float32LessThanOrEqual();
+      std::swap(left, right);
+      break;
+    case wasm::kExprF32Gt:
+      op = m->Float32LessThan();
+      std::swap(left, right);
+      break;
+    case wasm::kExprF32Le:
+      op = m->Float32LessThanOrEqual();
+      break;
+    case wasm::kExprF64Add:
+      op = m->Float64Add();
+      break;
+    case wasm::kExprF64Sub:
+      op = m->Float64Sub();
+      break;
+    case wasm::kExprF64Mul:
+      op = m->Float64Mul();
+      break;
+    case wasm::kExprF64Div:
+      op = m->Float64Div();
+      break;
+    case wasm::kExprF64Eq:
+      op = m->Float64Equal();
+      break;
+    case wasm::kExprF64Ne:
+      return Invert(Binop(wasm::kExprF64Eq, left, right));
+    case wasm::kExprF64Lt:
+      op = m->Float64LessThan();
+      break;
+    case wasm::kExprF64Le:
+      op = m->Float64LessThanOrEqual();
+      break;
+    case wasm::kExprF64Gt:
+      op = m->Float64LessThan();
+      std::swap(left, right);
+      break;
+    case wasm::kExprF64Ge:
+      op = m->Float64LessThanOrEqual();
+      std::swap(left, right);
+      break;
+    case wasm::kExprF32Min:
+      return BuildF32Min(left, right);
+    case wasm::kExprF64Min:
+      return BuildF64Min(left, right);
+    case wasm::kExprF32Max:
+      return BuildF32Max(left, right);
+    case wasm::kExprF64Max:
+      return BuildF64Max(left, right);
+    default:
+      op = UnsupportedOpcode(opcode);
+  }
+  return graph()->NewNode(op, left, right);
+}
+
+
+Node* WasmGraphBuilder::Unop(wasm::WasmOpcode opcode, Node* input) {
+  const Operator* op;
+  MachineOperatorBuilder* m = jsgraph()->machine();
+  switch (opcode) {
+    case wasm::kExprBoolNot:
+      op = m->Word32Equal();
+      return graph()->NewNode(op, input, jsgraph()->Int32Constant(0));
+    case wasm::kExprF32Abs:
+      op = m->Float32Abs();
+      break;
+    case wasm::kExprF32Neg:
+      return BuildF32Neg(input);
+    case wasm::kExprF32Sqrt:
+      op = m->Float32Sqrt();
+      break;
+    case wasm::kExprF64Abs:
+      op = m->Float64Abs();
+      break;
+    case wasm::kExprF64Neg:
+      return BuildF64Neg(input);
+    case wasm::kExprF64Sqrt:
+      op = m->Float64Sqrt();
+      break;
+    case wasm::kExprI32SConvertF64:
+      return BuildI32SConvertF64(input);
+    case wasm::kExprI32UConvertF64:
+      return BuildI32UConvertF64(input);
+    case wasm::kExprF32ConvertF64:
+      op = m->TruncateFloat64ToFloat32();
+      break;
+    case wasm::kExprF64SConvertI32:
+      op = m->ChangeInt32ToFloat64();
+      break;
+    case wasm::kExprF64UConvertI32:
+      op = m->ChangeUint32ToFloat64();
+      break;
+    case wasm::kExprF32SConvertI32:
+      op = m->ChangeInt32ToFloat64();  // TODO(titzer): two conversions
+      input = graph()->NewNode(op, input);
+      op = m->TruncateFloat64ToFloat32();
+      break;
+    case wasm::kExprF32UConvertI32:
+      op = m->ChangeUint32ToFloat64();
+      input = graph()->NewNode(op, input);
+      op = m->TruncateFloat64ToFloat32();
+      break;
+    case wasm::kExprI32SConvertF32:
+      return BuildI32SConvertF32(input);
+    case wasm::kExprI32UConvertF32:
+      return BuildI32UConvertF32(input);
+    case wasm::kExprF64ConvertF32:
+      op = m->ChangeFloat32ToFloat64();
+      break;
+    case wasm::kExprF32ReinterpretI32:
+      op = m->BitcastInt32ToFloat32();
+      break;
+    case wasm::kExprI32ReinterpretF32:
+      op = m->BitcastFloat32ToInt32();
+      break;
+    case wasm::kExprI32Clz:
+      op = m->Word32Clz();
+      break;
+    case wasm::kExprI32Ctz: {
+      if (m->Word32Ctz().IsSupported()) {
+        op = m->Word32Ctz().op();
+        break;
+      } else {
+        return BuildI32Ctz(input);
+      }
+    }
+    case wasm::kExprI32Popcnt: {
+      if (m->Word32Popcnt().IsSupported()) {
+        op = m->Word32Popcnt().op();
+        break;
+      } else {
+        return BuildI32Popcnt(input);
+      }
+    }
+    case wasm::kExprF32Floor: {
+      if (m->Float32RoundDown().IsSupported()) {
+        op = m->Float32RoundDown().op();
+        break;
+      } else {
+        op = UnsupportedOpcode(opcode);
+        break;
+      }
+    }
+    case wasm::kExprF32Ceil: {
+      if (m->Float32RoundUp().IsSupported()) {
+        op = m->Float32RoundUp().op();
+        break;
+      } else {
+        op = UnsupportedOpcode(opcode);
+        break;
+      }
+    }
+    case wasm::kExprF32Trunc: {
+      if (m->Float32RoundTruncate().IsSupported()) {
+        op = m->Float32RoundTruncate().op();
+        break;
+      } else {
+        op = UnsupportedOpcode(opcode);
+        break;
+      }
+    }
+    case wasm::kExprF32NearestInt: {
+      if (m->Float32RoundTiesEven().IsSupported()) {
+        op = m->Float32RoundTiesEven().op();
+        break;
+      } else {
+        op = UnsupportedOpcode(opcode);
+        break;
+      }
+    }
+    case wasm::kExprF64Floor: {
+      if (m->Float64RoundDown().IsSupported()) {
+        op = m->Float64RoundDown().op();
+        break;
+      } else {
+        op = UnsupportedOpcode(opcode);
+        break;
+      }
+    }
+    case wasm::kExprF64Ceil: {
+      if (m->Float64RoundUp().IsSupported()) {
+        op = m->Float64RoundUp().op();
+        break;
+      } else {
+        op = UnsupportedOpcode(opcode);
+        break;
+      }
+    }
+    case wasm::kExprF64Trunc: {
+      if (m->Float64RoundTruncate().IsSupported()) {
+        op = m->Float64RoundTruncate().op();
+        break;
+      } else {
+        op = UnsupportedOpcode(opcode);
+        break;
+      }
+    }
+    case wasm::kExprF64NearestInt: {
+      if (m->Float64RoundTiesEven().IsSupported()) {
+        op = m->Float64RoundTiesEven().op();
+        break;
+      } else {
+        op = UnsupportedOpcode(opcode);
+        break;
+      }
+    }
+
+#if WASM_64
+    // Opcodes only supported on 64-bit platforms.
+    // TODO(titzer): query the machine operator builder here instead of #ifdef.
+    case wasm::kExprI32ConvertI64:
+      op = m->TruncateInt64ToInt32();
+      break;
+    case wasm::kExprI64SConvertI32:
+      op = m->ChangeInt32ToInt64();
+      break;
+    case wasm::kExprI64UConvertI32:
+      op = m->ChangeUint32ToUint64();
+      break;
+    case wasm::kExprF32SConvertI64:
+      op = m->RoundInt64ToFloat32();
+      break;
+    case wasm::kExprF32UConvertI64:
+      op = m->RoundUint64ToFloat32();
+      break;
+    case wasm::kExprF64SConvertI64:
+      op = m->RoundInt64ToFloat64();
+      break;
+    case wasm::kExprF64UConvertI64:
+      op = m->RoundUint64ToFloat64();
+      break;
+    case wasm::kExprI64SConvertF32: {
+      Node* trunc = graph()->NewNode(m->TryTruncateFloat32ToInt64(), input);
+      Node* result =
+          graph()->NewNode(jsgraph()->common()->Projection(0), trunc);
+      Node* overflow =
+          graph()->NewNode(jsgraph()->common()->Projection(1), trunc);
+      trap_->ZeroCheck64(kTrapFloatUnrepresentable, overflow);
+      return result;
+    }
+    case wasm::kExprI64SConvertF64: {
+      Node* trunc = graph()->NewNode(m->TryTruncateFloat64ToInt64(), input);
+      Node* result =
+          graph()->NewNode(jsgraph()->common()->Projection(0), trunc);
+      Node* overflow =
+          graph()->NewNode(jsgraph()->common()->Projection(1), trunc);
+      trap_->ZeroCheck64(kTrapFloatUnrepresentable, overflow);
+      return result;
+    }
+    case wasm::kExprI64UConvertF32: {
+      Node* trunc = graph()->NewNode(m->TryTruncateFloat32ToUint64(), input);
+      Node* result =
+          graph()->NewNode(jsgraph()->common()->Projection(0), trunc);
+      Node* overflow =
+          graph()->NewNode(jsgraph()->common()->Projection(1), trunc);
+      trap_->ZeroCheck64(kTrapFloatUnrepresentable, overflow);
+      return result;
+    }
+    case wasm::kExprI64UConvertF64: {
+      Node* trunc = graph()->NewNode(m->TryTruncateFloat64ToUint64(), input);
+      Node* result =
+          graph()->NewNode(jsgraph()->common()->Projection(0), trunc);
+      Node* overflow =
+          graph()->NewNode(jsgraph()->common()->Projection(1), trunc);
+      trap_->ZeroCheck64(kTrapFloatUnrepresentable, overflow);
+      return result;
+    }
+    case wasm::kExprF64ReinterpretI64:
+      op = m->BitcastInt64ToFloat64();
+      break;
+    case wasm::kExprI64ReinterpretF64:
+      op = m->BitcastFloat64ToInt64();
+      break;
+    case wasm::kExprI64Clz:
+      op = m->Word64Clz();
+      break;
+    case wasm::kExprI64Ctz: {
+      if (m->Word64Ctz().IsSupported()) {
+        op = m->Word64Ctz().op();
+        break;
+      } else {
+        return BuildI64Ctz(input);
+      }
+    }
+    case wasm::kExprI64Popcnt: {
+      if (m->Word64Popcnt().IsSupported()) {
+        op = m->Word64Popcnt().op();
+        break;
+      } else {
+        return BuildI64Popcnt(input);
+      }
+    }
+#endif
+    default:
+      op = UnsupportedOpcode(opcode);
+  }
+  return graph()->NewNode(op, input);
+}
+
+
+Node* WasmGraphBuilder::Float32Constant(float value) {
+  return jsgraph()->Float32Constant(value);
+}
+
+
+Node* WasmGraphBuilder::Float64Constant(double value) {
+  return jsgraph()->Float64Constant(value);
+}
+
+
+Node* WasmGraphBuilder::Constant(Handle<Object> value) {
+  return jsgraph()->Constant(value);
+}
+
+
+Node* WasmGraphBuilder::Branch(Node* cond, Node** true_node,
+                               Node** false_node) {
+  DCHECK_NOT_NULL(cond);
+  DCHECK_NOT_NULL(*control_);
+  Node* branch =
+      graph()->NewNode(jsgraph()->common()->Branch(), cond, *control_);
+  *true_node = graph()->NewNode(jsgraph()->common()->IfTrue(), branch);
+  *false_node = graph()->NewNode(jsgraph()->common()->IfFalse(), branch);
+  return branch;
+}
+
+
+Node* WasmGraphBuilder::Switch(unsigned count, Node* key) {
+  return graph()->NewNode(jsgraph()->common()->Switch(count), key, *control_);
+}
+
+
+Node* WasmGraphBuilder::IfValue(int32_t value, Node* sw) {
+  DCHECK_EQ(IrOpcode::kSwitch, sw->opcode());
+  return graph()->NewNode(jsgraph()->common()->IfValue(value), sw);
+}
+
+
+Node* WasmGraphBuilder::IfDefault(Node* sw) {
+  DCHECK_EQ(IrOpcode::kSwitch, sw->opcode());
+  return graph()->NewNode(jsgraph()->common()->IfDefault(), sw);
+}
+
+
+Node* WasmGraphBuilder::Return(unsigned count, Node** vals) {
+  DCHECK_NOT_NULL(*control_);
+  DCHECK_NOT_NULL(*effect_);
+
+  if (count == 0) {
+    // Handle a return of void.
+    vals[0] = jsgraph()->Int32Constant(0);
+    count = 1;
+  }
+
+  Node** buf = Realloc(vals, count);
+  buf = Realloc(buf, count + 2);
+  buf[count] = *effect_;
+  buf[count + 1] = *control_;
+  Node* ret = graph()->NewNode(jsgraph()->common()->Return(), count + 2, vals);
+
+  MergeControlToEnd(jsgraph(), ret);
+  return ret;
+}
+
+
+Node* WasmGraphBuilder::ReturnVoid() { return Return(0, Buffer(0)); }
+
+
+Node* WasmGraphBuilder::Unreachable() {
+  trap_->Unreachable();
+  return nullptr;
+}
+
+
+Node* WasmGraphBuilder::BuildF32Neg(Node* input) {
+  Node* result =
+      Unop(wasm::kExprF32ReinterpretI32,
+           Binop(wasm::kExprI32Xor, Unop(wasm::kExprI32ReinterpretF32, input),
+                 jsgraph()->Int32Constant(0x80000000)));
+
+  return result;
+}
+
+
+Node* WasmGraphBuilder::BuildF64Neg(Node* input) {
+#if WASM_64
+  Node* result =
+      Unop(wasm::kExprF64ReinterpretI64,
+           Binop(wasm::kExprI64Xor, Unop(wasm::kExprI64ReinterpretF64, input),
+                 jsgraph()->Int64Constant(0x8000000000000000)));
+
+  return result;
+#else
+  MachineOperatorBuilder* m = jsgraph()->machine();
+
+  Node* old_high_word = graph()->NewNode(m->Float64ExtractHighWord32(), input);
+  Node* new_high_word = Binop(wasm::kExprI32Xor, old_high_word,
+                              jsgraph()->Int32Constant(0x80000000));
+
+  return graph()->NewNode(m->Float64InsertHighWord32(), input, new_high_word);
+#endif
+}
+
+
+Node* WasmGraphBuilder::BuildF32CopySign(Node* left, Node* right) {
+  Node* result = Unop(
+      wasm::kExprF32ReinterpretI32,
+      Binop(wasm::kExprI32Ior,
+            Binop(wasm::kExprI32And, Unop(wasm::kExprI32ReinterpretF32, left),
+                  jsgraph()->Int32Constant(0x7fffffff)),
+            Binop(wasm::kExprI32And, Unop(wasm::kExprI32ReinterpretF32, right),
+                  jsgraph()->Int32Constant(0x80000000))));
+
+  return result;
+}
+
+
+Node* WasmGraphBuilder::BuildF64CopySign(Node* left, Node* right) {
+#if WASM_64
+  Node* result = Unop(
+      wasm::kExprF64ReinterpretI64,
+      Binop(wasm::kExprI64Ior,
+            Binop(wasm::kExprI64And, Unop(wasm::kExprI64ReinterpretF64, left),
+                  jsgraph()->Int64Constant(0x7fffffffffffffff)),
+            Binop(wasm::kExprI64And, Unop(wasm::kExprI64ReinterpretF64, right),
+                  jsgraph()->Int64Constant(0x8000000000000000))));
+
+  return result;
+#else
+  MachineOperatorBuilder* m = jsgraph()->machine();
+
+  Node* high_word_left = graph()->NewNode(m->Float64ExtractHighWord32(), left);
+  Node* high_word_right =
+      graph()->NewNode(m->Float64ExtractHighWord32(), right);
+
+  Node* new_high_word =
+      Binop(wasm::kExprI32Ior, Binop(wasm::kExprI32And, high_word_left,
+                                     jsgraph()->Int32Constant(0x7fffffff)),
+            Binop(wasm::kExprI32And, high_word_right,
+                  jsgraph()->Int32Constant(0x80000000)));
+
+  return graph()->NewNode(m->Float64InsertHighWord32(), left, new_high_word);
+#endif
+}
+
+
+Node* WasmGraphBuilder::BuildF32Min(Node* left, Node* right) {
+  Diamond left_le_right(graph(), jsgraph()->common(),
+                        Binop(wasm::kExprF32Le, left, right));
+
+  Diamond right_lt_left(graph(), jsgraph()->common(),
+                        Binop(wasm::kExprF32Lt, right, left));
+
+  Diamond left_is_not_nan(graph(), jsgraph()->common(),
+                          Binop(wasm::kExprF32Eq, left, left));
+
+  return left_le_right.Phi(
+      wasm::kAstF32, left,
+      right_lt_left.Phi(wasm::kAstF32, right,
+                        left_is_not_nan.Phi(wasm::kAstF32, right, left)));
+}
+
+
+Node* WasmGraphBuilder::BuildF32Max(Node* left, Node* right) {
+  Diamond left_ge_right(graph(), jsgraph()->common(),
+                        Binop(wasm::kExprF32Ge, left, right));
+
+  Diamond right_gt_left(graph(), jsgraph()->common(),
+                        Binop(wasm::kExprF32Gt, right, left));
+
+  Diamond left_is_not_nan(graph(), jsgraph()->common(),
+                          Binop(wasm::kExprF32Eq, left, left));
+
+  return left_ge_right.Phi(
+      wasm::kAstF32, left,
+      right_gt_left.Phi(wasm::kAstF32, right,
+                        left_is_not_nan.Phi(wasm::kAstF32, right, left)));
+}
+
+
+Node* WasmGraphBuilder::BuildF64Min(Node* left, Node* right) {
+  Diamond left_le_right(graph(), jsgraph()->common(),
+                        Binop(wasm::kExprF64Le, left, right));
+
+  Diamond right_lt_left(graph(), jsgraph()->common(),
+                        Binop(wasm::kExprF64Lt, right, left));
+
+  Diamond left_is_not_nan(graph(), jsgraph()->common(),
+                          Binop(wasm::kExprF64Eq, left, left));
+
+  return left_le_right.Phi(
+      wasm::kAstF64, left,
+      right_lt_left.Phi(wasm::kAstF64, right,
+                        left_is_not_nan.Phi(wasm::kAstF64, right, left)));
+}
+
+
+Node* WasmGraphBuilder::BuildF64Max(Node* left, Node* right) {
+  Diamond left_ge_right(graph(), jsgraph()->common(),
+                        Binop(wasm::kExprF64Ge, left, right));
+
+  Diamond right_gt_left(graph(), jsgraph()->common(),
+                        Binop(wasm::kExprF64Lt, right, left));
+
+  Diamond left_is_not_nan(graph(), jsgraph()->common(),
+                          Binop(wasm::kExprF64Eq, left, left));
+
+  return left_ge_right.Phi(
+      wasm::kAstF64, left,
+      right_gt_left.Phi(wasm::kAstF64, right,
+                        left_is_not_nan.Phi(wasm::kAstF64, right, left)));
+}
+
+
+Node* WasmGraphBuilder::BuildI32SConvertF32(Node* input) {
+  MachineOperatorBuilder* m = jsgraph()->machine();
+  // Truncation of the input value is needed for the overflow check later.
+  Node* trunc = Unop(wasm::kExprF32Trunc, input);
+  // TODO(titzer): two conversions
+  Node* f64_trunc = graph()->NewNode(m->ChangeFloat32ToFloat64(), trunc);
+  Node* result = graph()->NewNode(m->ChangeFloat64ToInt32(), f64_trunc);
+
+  // Convert the result back to f64. If we end up at a different value than the
+  // truncated input value, then there has been an overflow and we trap.
+  Node* check = Unop(wasm::kExprF64SConvertI32, result);
+  Node* overflow = Binop(wasm::kExprF64Ne, f64_trunc, check);
+  trap_->AddTrapIfTrue(kTrapFloatUnrepresentable, overflow);
+
+  return result;
+}
+
+
+Node* WasmGraphBuilder::BuildI32SConvertF64(Node* input) {
+  MachineOperatorBuilder* m = jsgraph()->machine();
+  // Truncation of the input value is needed for the overflow check later.
+  Node* trunc = Unop(wasm::kExprF64Trunc, input);
+  Node* result = graph()->NewNode(m->ChangeFloat64ToInt32(), trunc);
+
+  // Convert the result back to f64. If we end up at a different value than the
+  // truncated input value, then there has been an overflow and we trap.
+  Node* check = Unop(wasm::kExprF64SConvertI32, result);
+  Node* overflow = Binop(wasm::kExprF64Ne, trunc, check);
+  trap_->AddTrapIfTrue(kTrapFloatUnrepresentable, overflow);
+
+  return result;
+}
+
+
+Node* WasmGraphBuilder::BuildI32UConvertF32(Node* input) {
+  MachineOperatorBuilder* m = jsgraph()->machine();
+  // Truncation of the input value is needed for the overflow check later.
+  Node* trunc = Unop(wasm::kExprF32Trunc, input);
+  // TODO(titzer): two conversions
+  Node* f64_trunc = graph()->NewNode(m->ChangeFloat32ToFloat64(), trunc);
+  Node* result = graph()->NewNode(m->ChangeFloat64ToUint32(), f64_trunc);
+
+  // Convert the result back to f64. If we end up at a different value than the
+  // truncated input value, then there has been an overflow and we trap.
+  Node* check = Unop(wasm::kExprF64UConvertI32, result);
+  Node* overflow = Binop(wasm::kExprF64Ne, f64_trunc, check);
+  trap_->AddTrapIfTrue(kTrapFloatUnrepresentable, overflow);
+
+  return result;
+}
+
+
+Node* WasmGraphBuilder::BuildI32UConvertF64(Node* input) {
+  MachineOperatorBuilder* m = jsgraph()->machine();
+  // Truncation of the input value is needed for the overflow check later.
+  Node* trunc = Unop(wasm::kExprF64Trunc, input);
+  Node* result = graph()->NewNode(m->ChangeFloat64ToUint32(), trunc);
+
+  // Convert the result back to f64. If we end up at a different value than the
+  // truncated input value, then there has been an overflow and we trap.
+  Node* check = Unop(wasm::kExprF64UConvertI32, result);
+  Node* overflow = Binop(wasm::kExprF64Ne, trunc, check);
+  trap_->AddTrapIfTrue(kTrapFloatUnrepresentable, overflow);
+
+  return result;
+}
+
+
+Node* WasmGraphBuilder::BuildI32Ctz(Node* input) {
+  //// Implement the following code as TF graph.
+  // value = value | (value << 1);
+  // value = value | (value << 2);
+  // value = value | (value << 4);
+  // value = value | (value << 8);
+  // value = value | (value << 16);
+  // return CountPopulation32(0xffffffff XOR value);
+
+  Node* result =
+      Binop(wasm::kExprI32Ior, input,
+            Binop(wasm::kExprI32Shl, input, jsgraph()->Int32Constant(1)));
+
+  result = Binop(wasm::kExprI32Ior, result,
+                 Binop(wasm::kExprI32Shl, result, jsgraph()->Int32Constant(2)));
+
+  result = Binop(wasm::kExprI32Ior, result,
+                 Binop(wasm::kExprI32Shl, result, jsgraph()->Int32Constant(4)));
+
+  result = Binop(wasm::kExprI32Ior, result,
+                 Binop(wasm::kExprI32Shl, result, jsgraph()->Int32Constant(8)));
+
+  result =
+      Binop(wasm::kExprI32Ior, result,
+            Binop(wasm::kExprI32Shl, result, jsgraph()->Int32Constant(16)));
+
+  result = BuildI32Popcnt(
+      Binop(wasm::kExprI32Xor, jsgraph()->Int32Constant(0xffffffff), result));
+
+  return result;
+}
+
+
+Node* WasmGraphBuilder::BuildI64Ctz(Node* input) {
+  //// Implement the following code as TF graph.
+  // value = value | (value << 1);
+  // value = value | (value << 2);
+  // value = value | (value << 4);
+  // value = value | (value << 8);
+  // value = value | (value << 16);
+  // value = value | (value << 32);
+  // return CountPopulation64(0xffffffffffffffff XOR value);
+
+  Node* result =
+      Binop(wasm::kExprI64Ior, input,
+            Binop(wasm::kExprI64Shl, input, jsgraph()->Int64Constant(1)));
+
+  result = Binop(wasm::kExprI64Ior, result,
+                 Binop(wasm::kExprI64Shl, result, jsgraph()->Int64Constant(2)));
+
+  result = Binop(wasm::kExprI64Ior, result,
+                 Binop(wasm::kExprI64Shl, result, jsgraph()->Int64Constant(4)));
+
+  result = Binop(wasm::kExprI64Ior, result,
+                 Binop(wasm::kExprI64Shl, result, jsgraph()->Int64Constant(8)));
+
+  result =
+      Binop(wasm::kExprI64Ior, result,
+            Binop(wasm::kExprI64Shl, result, jsgraph()->Int64Constant(16)));
+
+  result =
+      Binop(wasm::kExprI64Ior, result,
+            Binop(wasm::kExprI64Shl, result, jsgraph()->Int64Constant(32)));
+
+  result = BuildI64Popcnt(Binop(
+      wasm::kExprI64Xor, jsgraph()->Int64Constant(0xffffffffffffffff), result));
+
+  return result;
+}
+
+
+Node* WasmGraphBuilder::BuildI32Popcnt(Node* input) {
+  //// Implement the following code as a TF graph.
+  // value = ((value >> 1) & 0x55555555) + (value & 0x55555555);
+  // value = ((value >> 2) & 0x33333333) + (value & 0x33333333);
+  // value = ((value >> 4) & 0x0f0f0f0f) + (value & 0x0f0f0f0f);
+  // value = ((value >> 8) & 0x00ff00ff) + (value & 0x00ff00ff);
+  // value = ((value >> 16) & 0x0000ffff) + (value & 0x0000ffff);
+
+  Node* result = Binop(
+      wasm::kExprI32Add,
+      Binop(wasm::kExprI32And,
+            Binop(wasm::kExprI32ShrU, input, jsgraph()->Int32Constant(1)),
+            jsgraph()->Int32Constant(0x55555555)),
+      Binop(wasm::kExprI32And, input, jsgraph()->Int32Constant(0x55555555)));
+
+  result = Binop(
+      wasm::kExprI32Add,
+      Binop(wasm::kExprI32And,
+            Binop(wasm::kExprI32ShrU, result, jsgraph()->Int32Constant(2)),
+            jsgraph()->Int32Constant(0x33333333)),
+      Binop(wasm::kExprI32And, result, jsgraph()->Int32Constant(0x33333333)));
+
+  result = Binop(
+      wasm::kExprI32Add,
+      Binop(wasm::kExprI32And,
+            Binop(wasm::kExprI32ShrU, result, jsgraph()->Int32Constant(4)),
+            jsgraph()->Int32Constant(0x0f0f0f0f)),
+      Binop(wasm::kExprI32And, result, jsgraph()->Int32Constant(0x0f0f0f0f)));
+
+  result = Binop(
+      wasm::kExprI32Add,
+      Binop(wasm::kExprI32And,
+            Binop(wasm::kExprI32ShrU, result, jsgraph()->Int32Constant(8)),
+            jsgraph()->Int32Constant(0x00ff00ff)),
+      Binop(wasm::kExprI32And, result, jsgraph()->Int32Constant(0x00ff00ff)));
+
+  result = Binop(
+      wasm::kExprI32Add,
+      Binop(wasm::kExprI32And,
+            Binop(wasm::kExprI32ShrU, result, jsgraph()->Int32Constant(16)),
+            jsgraph()->Int32Constant(0x0000ffff)),
+      Binop(wasm::kExprI32And, result, jsgraph()->Int32Constant(0x0000ffff)));
+
+  return result;
+}
+
+
+Node* WasmGraphBuilder::BuildI64Popcnt(Node* input) {
+  //// Implement the following code as a TF graph.
+  // value = ((value >> 1) & 0x5555555555555555) + (value & 0x5555555555555555);
+  // value = ((value >> 2) & 0x3333333333333333) + (value & 0x3333333333333333);
+  // value = ((value >> 4) & 0x0f0f0f0f0f0f0f0f) + (value & 0x0f0f0f0f0f0f0f0f);
+  // value = ((value >> 8) & 0x00ff00ff00ff00ff) + (value & 0x00ff00ff00ff00ff);
+  // value = ((value >> 16) & 0x0000ffff0000ffff) + (value &
+  // 0x0000ffff0000ffff);
+  // value = ((value >> 32) & 0x00000000ffffffff) + (value &
+  // 0x00000000ffffffff);
+
+  Node* result =
+      Binop(wasm::kExprI64Add,
+            Binop(wasm::kExprI64And,
+                  Binop(wasm::kExprI64ShrU, input, jsgraph()->Int64Constant(1)),
+                  jsgraph()->Int64Constant(0x5555555555555555)),
+            Binop(wasm::kExprI64And, input,
+                  jsgraph()->Int64Constant(0x5555555555555555)));
+
+  result = Binop(wasm::kExprI64Add,
+                 Binop(wasm::kExprI64And, Binop(wasm::kExprI64ShrU, result,
+                                                jsgraph()->Int64Constant(2)),
+                       jsgraph()->Int64Constant(0x3333333333333333)),
+                 Binop(wasm::kExprI64And, result,
+                       jsgraph()->Int64Constant(0x3333333333333333)));
+
+  result = Binop(wasm::kExprI64Add,
+                 Binop(wasm::kExprI64And, Binop(wasm::kExprI64ShrU, result,
+                                                jsgraph()->Int64Constant(4)),
+                       jsgraph()->Int64Constant(0x0f0f0f0f0f0f0f0f)),
+                 Binop(wasm::kExprI64And, result,
+                       jsgraph()->Int64Constant(0x0f0f0f0f0f0f0f0f)));
+
+  result = Binop(wasm::kExprI64Add,
+                 Binop(wasm::kExprI64And, Binop(wasm::kExprI64ShrU, result,
+                                                jsgraph()->Int64Constant(8)),
+                       jsgraph()->Int64Constant(0x00ff00ff00ff00ff)),
+                 Binop(wasm::kExprI64And, result,
+                       jsgraph()->Int64Constant(0x00ff00ff00ff00ff)));
+
+  result = Binop(wasm::kExprI64Add,
+                 Binop(wasm::kExprI64And, Binop(wasm::kExprI64ShrU, result,
+                                                jsgraph()->Int64Constant(16)),
+                       jsgraph()->Int64Constant(0x0000ffff0000ffff)),
+                 Binop(wasm::kExprI64And, result,
+                       jsgraph()->Int64Constant(0x0000ffff0000ffff)));
+
+  result = Binop(wasm::kExprI64Add,
+                 Binop(wasm::kExprI64And, Binop(wasm::kExprI64ShrU, result,
+                                                jsgraph()->Int64Constant(32)),
+                       jsgraph()->Int64Constant(0x00000000ffffffff)),
+                 Binop(wasm::kExprI64And, result,
+                       jsgraph()->Int64Constant(0x00000000ffffffff)));
+
+  return result;
+}
+
+
+Node* WasmGraphBuilder::BuildWasmCall(wasm::FunctionSig* sig, Node** args) {
+  const size_t params = sig->parameter_count();
+  const size_t extra = 2;  // effect and control inputs.
+  const size_t count = 1 + params + extra;
+
+  // Reallocate the buffer to make space for extra inputs.
+  args = Realloc(args, count);
+
+  // Add effect and control inputs.
+  args[params + 1] = *effect_;
+  args[params + 2] = *control_;
+
+  const Operator* op = jsgraph()->common()->Call(
+      module_->GetWasmCallDescriptor(jsgraph()->zone(), sig));
+  Node* call = graph()->NewNode(op, static_cast<int>(count), args);
+
+  *effect_ = call;
+  return call;
+}
+
+
+Node* WasmGraphBuilder::CallDirect(uint32_t index, Node** args) {
+  DCHECK_NULL(args[0]);
+
+  // Add code object as constant.
+  args[0] = Constant(module_->GetFunctionCode(index));
+  wasm::FunctionSig* sig = module_->GetFunctionSignature(index);
+
+  return BuildWasmCall(sig, args);
+}
+
+
+Node* WasmGraphBuilder::CallIndirect(uint32_t index, Node** args) {
+  DCHECK_NOT_NULL(args[0]);
+
+  MachineOperatorBuilder* machine = jsgraph()->machine();
+
+  // Compute the code object by loading it from the function table.
+  Node* key = args[0];
+  Node* table = FunctionTable();
+
+  // Bounds check the index.
+  int table_size = static_cast<int>(module_->FunctionTableSize());
+  {
+    Node* size = Int32Constant(static_cast<int>(table_size));
+    Node* in_bounds = graph()->NewNode(machine->Uint32LessThan(), key, size);
+    trap_->AddTrapIfFalse(kTrapFuncInvalid, in_bounds);
+  }
+
+  // Load signature from the table and check.
+  // The table is a FixedArray; signatures are encoded as SMIs.
+  // [sig1, sig2, sig3, ...., code1, code2, code3 ...]
+  ElementAccess access = AccessBuilder::ForFixedArrayElement();
+  const int fixed_offset = access.header_size - access.tag();
+  {
+    Node* load_sig = graph()->NewNode(
+        machine->Load(MachineType::AnyTagged()), table,
+        graph()->NewNode(machine->Int32Add(),
+                         graph()->NewNode(machine->Word32Shl(), key,
+                                          Int32Constant(kPointerSizeLog2)),
+                         Int32Constant(fixed_offset)),
+        *effect_, *control_);
+    Node* sig_match = graph()->NewNode(machine->WordEqual(), load_sig,
+                                       jsgraph()->SmiConstant(index));
+    trap_->AddTrapIfFalse(kTrapFuncSigMismatch, sig_match);
+  }
+
+  // Load code object from the table.
+  int offset = fixed_offset + kPointerSize * table_size;
+  Node* load_code = graph()->NewNode(
+      machine->Load(MachineType::AnyTagged()), table,
+      graph()->NewNode(machine->Int32Add(),
+                       graph()->NewNode(machine->Word32Shl(), key,
+                                        Int32Constant(kPointerSizeLog2)),
+                       Int32Constant(offset)),
+      *effect_, *control_);
+
+  args[0] = load_code;
+  wasm::FunctionSig* sig = module_->GetSignature(index);
+  return BuildWasmCall(sig, args);
+}
+
+
+Node* WasmGraphBuilder::ToJS(Node* node, Node* context, wasm::LocalType type) {
+  SimplifiedOperatorBuilder simplified(jsgraph()->zone());
+  switch (type) {
+    case wasm::kAstI32:
+      return graph()->NewNode(simplified.ChangeInt32ToTagged(), node);
+    case wasm::kAstI64:
+      // TODO(titzer): i64->JS has no good solution right now. Using lower 32
+      // bits.
+      node =
+          graph()->NewNode(jsgraph()->machine()->TruncateInt64ToInt32(), node);
+      return graph()->NewNode(simplified.ChangeInt32ToTagged(), node);
+    case wasm::kAstF32:
+      node = graph()->NewNode(jsgraph()->machine()->ChangeFloat32ToFloat64(),
+                              node);
+      return graph()->NewNode(simplified.ChangeFloat64ToTagged(), node);
+    case wasm::kAstF64:
+      return graph()->NewNode(simplified.ChangeFloat64ToTagged(), node);
+    case wasm::kAstStmt:
+      return jsgraph()->UndefinedConstant();
+    default:
+      UNREACHABLE();
+      return nullptr;
+  }
+}
+
+
+Node* WasmGraphBuilder::FromJS(Node* node, Node* context,
+                               wasm::LocalType type) {
+  // Do a JavaScript ToNumber.
+  Node* num =
+      graph()->NewNode(jsgraph()->javascript()->ToNumber(), node, context,
+                       jsgraph()->EmptyFrameState(), *effect_, *control_);
+  *control_ = num;
+  *effect_ = num;
+
+  // Change representation.
+  SimplifiedOperatorBuilder simplified(jsgraph()->zone());
+  num = graph()->NewNode(simplified.ChangeTaggedToFloat64(), num);
+
+  switch (type) {
+    case wasm::kAstI32: {
+      num = graph()->NewNode(jsgraph()->machine()->TruncateFloat64ToInt32(
+                                 TruncationMode::kJavaScript),
+                             num);
+      break;
+    }
+    case wasm::kAstI64:
+      // TODO(titzer): JS->i64 has no good solution right now. Using 32 bits.
+      num = graph()->NewNode(jsgraph()->machine()->TruncateFloat64ToInt32(
+                                 TruncationMode::kJavaScript),
+                             num);
+      num = graph()->NewNode(jsgraph()->machine()->ChangeInt32ToInt64(), num);
+      break;
+    case wasm::kAstF32:
+      num = graph()->NewNode(jsgraph()->machine()->TruncateFloat64ToFloat32(),
+                             num);
+      break;
+    case wasm::kAstF64:
+      break;
+    case wasm::kAstStmt:
+      num = jsgraph()->Int32Constant(0);
+      break;
+    default:
+      UNREACHABLE();
+      return nullptr;
+  }
+  return num;
+}
+
+
+Node* WasmGraphBuilder::Invert(Node* node) {
+  return Unop(wasm::kExprBoolNot, node);
+}
+
+
+void WasmGraphBuilder::BuildJSToWasmWrapper(Handle<Code> wasm_code,
+                                            wasm::FunctionSig* sig) {
+  int params = static_cast<int>(sig->parameter_count());
+  int count = params + 3;
+  Node** args = Buffer(count);
+
+  // Build the start and the JS parameter nodes.
+  Node* start = Start(params + 3);
+  *control_ = start;
+  *effect_ = start;
+  // JS context is the last parameter.
+  Node* context = graph()->NewNode(
+      jsgraph()->common()->Parameter(params + 1, "context"), start);
+
+  int pos = 0;
+  args[pos++] = Constant(wasm_code);
+
+  // Convert JS parameters to WASM numbers.
+  for (int i = 0; i < params; i++) {
+    Node* param = graph()->NewNode(jsgraph()->common()->Parameter(i), start);
+    args[pos++] = FromJS(param, context, sig->GetParam(i));
+  }
+
+  args[pos++] = *effect_;
+  args[pos++] = *control_;
+
+  // Call the WASM code.
+  CallDescriptor* desc = module_->GetWasmCallDescriptor(jsgraph()->zone(), sig);
+  Node* call = graph()->NewNode(jsgraph()->common()->Call(desc), count, args);
+  Node* jsval =
+      ToJS(call, context,
+           sig->return_count() == 0 ? wasm::kAstStmt : sig->GetReturn());
+  Node* ret =
+      graph()->NewNode(jsgraph()->common()->Return(), jsval, call, start);
+
+  MergeControlToEnd(jsgraph(), ret);
+}
+
+
+void WasmGraphBuilder::BuildWasmToJSWrapper(Handle<JSFunction> function,
+                                            wasm::FunctionSig* sig) {
+  int js_count = function->shared()->internal_formal_parameter_count();
+  int wasm_count = static_cast<int>(sig->parameter_count());
+
+  // Build the start and the parameter nodes.
+  Isolate* isolate = jsgraph()->isolate();
+  CallDescriptor* desc;
+  Node* start = Start(wasm_count + 3);
+  *effect_ = start;
+  *control_ = start;
+  // JS context is the last parameter.
+  Node* context = Constant(Handle<Context>(function->context(), isolate));
+  Node** args = Buffer(wasm_count + 7);
+
+  bool arg_count_before_args = false;
+  bool add_new_target_undefined = false;
+
+  int pos = 0;
+  if (js_count == wasm_count) {
+    // exact arity match, just call the function directly.
+    desc = Linkage::GetJSCallDescriptor(graph()->zone(), false, wasm_count + 1,
+                                        CallDescriptor::kNoFlags);
+    arg_count_before_args = false;
+    add_new_target_undefined = true;
+  } else {
+    // Use the Call builtin.
+    Callable callable = CodeFactory::Call(isolate);
+    args[pos++] = jsgraph()->HeapConstant(callable.code());
+    desc = Linkage::GetStubCallDescriptor(isolate, graph()->zone(),
+                                          callable.descriptor(), wasm_count + 1,
+                                          CallDescriptor::kNoFlags);
+    arg_count_before_args = true;
+  }
+
+  args[pos++] = jsgraph()->Constant(function);  // JS function.
+  if (arg_count_before_args) {
+    args[pos++] = jsgraph()->Int32Constant(wasm_count);  // argument count
+  }
+  // JS receiver.
+  Handle<Object> global(function->context()->global_object(), isolate);
+  args[pos++] = jsgraph()->Constant(global);
+
+  // Convert WASM numbers to JS values.
+  for (int i = 0; i < wasm_count; i++) {
+    Node* param = graph()->NewNode(jsgraph()->common()->Parameter(i), start);
+    args[pos++] = ToJS(param, context, sig->GetParam(i));
+  }
+
+  if (add_new_target_undefined) {
+    args[pos++] = jsgraph()->UndefinedConstant();  // new target
+  }
+
+  if (!arg_count_before_args) {
+    args[pos++] = jsgraph()->Int32Constant(wasm_count);  // argument count
+  }
+  args[pos++] = context;
+  args[pos++] = *effect_;
+  args[pos++] = *control_;
+
+  Node* call = graph()->NewNode(jsgraph()->common()->Call(desc), pos, args);
+
+  // Convert the return value back.
+  Node* val =
+      FromJS(call, context,
+             sig->return_count() == 0 ? wasm::kAstStmt : sig->GetReturn());
+  Node* ret = graph()->NewNode(jsgraph()->common()->Return(), val, call, start);
+
+  MergeControlToEnd(jsgraph(), ret);
+}
+
+
+Node* WasmGraphBuilder::MemBuffer(uint32_t offset) {
+  if (offset == 0) {
+    if (!mem_buffer_)
+      mem_buffer_ = jsgraph()->IntPtrConstant(module_->mem_start);
+    return mem_buffer_;
+  } else {
+    return jsgraph()->IntPtrConstant(module_->mem_start + offset);
+  }
+}
+
+
+Node* WasmGraphBuilder::MemSize(uint32_t offset) {
+  int32_t size = static_cast<int>(module_->mem_end - module_->mem_start);
+  if (offset == 0) {
+    if (!mem_size_) mem_size_ = jsgraph()->Int32Constant(size);
+    return mem_size_;
+  } else {
+    return jsgraph()->Int32Constant(size + offset);
+  }
+}
+
+
+Node* WasmGraphBuilder::FunctionTable() {
+  if (!function_table_) {
+    DCHECK(!module_->function_table.is_null());
+    function_table_ = jsgraph()->Constant(module_->function_table);
+  }
+  return function_table_;
+}
+
+
+Node* WasmGraphBuilder::LoadGlobal(uint32_t index) {
+  MachineType mem_type = module_->GetGlobalType(index);
+  Node* addr = jsgraph()->IntPtrConstant(
+      module_->globals_area + module_->module->globals->at(index).offset);
+  const Operator* op = jsgraph()->machine()->Load(mem_type);
+  Node* node = graph()->NewNode(op, addr, jsgraph()->Int32Constant(0), *effect_,
+                                *control_);
+  *effect_ = node;
+  return node;
+}
+
+
+Node* WasmGraphBuilder::StoreGlobal(uint32_t index, Node* val) {
+  MachineType mem_type = module_->GetGlobalType(index);
+  Node* addr = jsgraph()->IntPtrConstant(
+      module_->globals_area + module_->module->globals->at(index).offset);
+  const Operator* op = jsgraph()->machine()->Store(
+      StoreRepresentation(mem_type.representation(), kNoWriteBarrier));
+  Node* node = graph()->NewNode(op, addr, jsgraph()->Int32Constant(0), val,
+                                *effect_, *control_);
+  *effect_ = node;
+  return node;
+}
+
+
+void WasmGraphBuilder::BoundsCheckMem(MachineType memtype, Node* index,
+                                      uint32_t offset) {
+  // TODO(turbofan): fold bounds checks for constant indexes.
+  CHECK_GE(module_->mem_end, module_->mem_start);
+  ptrdiff_t size = module_->mem_end - module_->mem_start;
+  byte memsize = wasm::WasmOpcodes::MemSize(memtype);
+  Node* cond;
+  if (static_cast<ptrdiff_t>(offset) >= size ||
+      static_cast<ptrdiff_t>(offset + memsize) > size) {
+    // The access will always throw.
+    cond = jsgraph()->Int32Constant(0);
+  } else {
+    // Check against the limit.
+    size_t limit = size - offset - memsize;
+    CHECK(limit <= kMaxUInt32);
+    cond = graph()->NewNode(
+        jsgraph()->machine()->Uint32LessThanOrEqual(), index,
+        jsgraph()->Int32Constant(static_cast<uint32_t>(limit)));
+  }
+
+  trap_->AddTrapIfFalse(kTrapMemOutOfBounds, cond);
+}
+
+
+Node* WasmGraphBuilder::LoadMem(wasm::LocalType type, MachineType memtype,
+                                Node* index, uint32_t offset) {
+  Node* load;
+
+  if (module_ && module_->asm_js) {
+    // asm.js semantics use CheckedLoad (i.e. OOB reads return 0ish).
+    DCHECK_EQ(0, offset);
+    const Operator* op = jsgraph()->machine()->CheckedLoad(memtype);
+    load = graph()->NewNode(op, MemBuffer(0), index, MemSize(0), *effect_,
+                            *control_);
+  } else {
+    // WASM semantics throw on OOB. Introduce explicit bounds check.
+    BoundsCheckMem(memtype, index, offset);
+    load = graph()->NewNode(jsgraph()->machine()->Load(memtype),
+                            MemBuffer(offset), index, *effect_, *control_);
+  }
+
+  *effect_ = load;
+
+  if (type == wasm::kAstI64 &&
+      ElementSizeLog2Of(memtype.representation()) < 3) {
+    // TODO(titzer): TF zeroes the upper bits of 64-bit loads for subword sizes.
+    if (memtype.IsSigned()) {
+      // sign extend
+      load = graph()->NewNode(jsgraph()->machine()->ChangeInt32ToInt64(), load);
+    } else {
+      // zero extend
+      load =
+          graph()->NewNode(jsgraph()->machine()->ChangeUint32ToUint64(), load);
+    }
+  }
+
+  return load;
+}
+
+
+Node* WasmGraphBuilder::StoreMem(MachineType memtype, Node* index,
+                                 uint32_t offset, Node* val) {
+  Node* store;
+  if (module_ && module_->asm_js) {
+    // asm.js semantics use CheckedStore (i.e. ignore OOB writes).
+    DCHECK_EQ(0, offset);
+    const Operator* op =
+        jsgraph()->machine()->CheckedStore(memtype.representation());
+    store = graph()->NewNode(op, MemBuffer(0), index, MemSize(0), val, *effect_,
+                             *control_);
+  } else {
+    // WASM semantics throw on OOB. Introduce explicit bounds check.
+    BoundsCheckMem(memtype, index, offset);
+    StoreRepresentation rep(memtype.representation(), kNoWriteBarrier);
+    store =
+        graph()->NewNode(jsgraph()->machine()->Store(rep), MemBuffer(offset),
+                         index, val, *effect_, *control_);
+  }
+  *effect_ = store;
+  return store;
+}
+
+
+void WasmGraphBuilder::PrintDebugName(Node* node) {
+  PrintF("#%d:%s", node->id(), node->op()->mnemonic());
+}
+
+
+Node* WasmGraphBuilder::String(const char* string) {
+  return jsgraph()->Constant(
+      jsgraph()->isolate()->factory()->NewStringFromAsciiChecked(string));
+}
+
+
+Graph* WasmGraphBuilder::graph() { return jsgraph()->graph(); }
+
+
+Handle<JSFunction> CompileJSToWasmWrapper(
+    Isolate* isolate, wasm::ModuleEnv* module, Handle<String> name,
+    Handle<Code> wasm_code, Handle<JSObject> module_object, uint32_t index) {
+  wasm::WasmFunction* func = &module->module->functions->at(index);
+
+  //----------------------------------------------------------------------------
+  // Create the JSFunction object.
+  //----------------------------------------------------------------------------
+  Handle<SharedFunctionInfo> shared =
+      isolate->factory()->NewSharedFunctionInfo(name, wasm_code, false);
+  int params = static_cast<int>(func->sig->parameter_count());
+  shared->set_length(params);
+  shared->set_internal_formal_parameter_count(1 + params);
+  Handle<JSFunction> function = isolate->factory()->NewFunction(
+      isolate->wasm_function_map(), name, MaybeHandle<Code>());
+  function->SetInternalField(0, *module_object);
+  function->set_shared(*shared);
+
+  //----------------------------------------------------------------------------
+  // Create the Graph
+  //----------------------------------------------------------------------------
+  Zone zone;
+  Graph graph(&zone);
+  CommonOperatorBuilder common(&zone);
+  JSOperatorBuilder javascript(&zone);
+  MachineOperatorBuilder machine(&zone);
+  JSGraph jsgraph(isolate, &graph, &common, &javascript, nullptr, &machine);
+
+  Node* control = nullptr;
+  Node* effect = nullptr;
+
+  WasmGraphBuilder builder(&zone, &jsgraph, func->sig);
+  builder.set_control_ptr(&control);
+  builder.set_effect_ptr(&effect);
+  builder.set_module(module);
+  builder.BuildJSToWasmWrapper(wasm_code, func->sig);
+
+  //----------------------------------------------------------------------------
+  // Run the compilation pipeline.
+  //----------------------------------------------------------------------------
+  {
+    // Changes lowering requires types.
+    Typer typer(isolate, &graph);
+    NodeVector roots(&zone);
+    jsgraph.GetCachedNodes(&roots);
+    typer.Run(roots);
+
+    // Run generic and change lowering.
+    JSGenericLowering generic(true, &jsgraph);
+    ChangeLowering changes(&jsgraph);
+    GraphReducer graph_reducer(&zone, &graph, jsgraph.Dead());
+    graph_reducer.AddReducer(&changes);
+    graph_reducer.AddReducer(&generic);
+    graph_reducer.ReduceGraph();
+
+    if (FLAG_trace_turbo_graph) {  // Simple textual RPO.
+      OFStream os(stdout);
+      os << "-- Graph after change lowering -- " << std::endl;
+      os << AsRPO(graph);
+    }
+
+    // Schedule and compile to machine code.
+    int params = static_cast<int>(
+        module->GetFunctionSignature(index)->parameter_count());
+    CallDescriptor* incoming = Linkage::GetJSCallDescriptor(
+        &zone, false, params + 1, CallDescriptor::kNoFlags);
+    CompilationInfo info("js-to-wasm", isolate, &zone);
+    // TODO(titzer): this is technically a WASM wrapper, not a wasm function.
+    info.set_output_code_kind(Code::WASM_FUNCTION);
+    Handle<Code> code =
+        Pipeline::GenerateCodeForTesting(&info, incoming, &graph, nullptr);
+
+#ifdef ENABLE_DISASSEMBLER
+    // Disassemble the wrapper code for debugging.
+    if (!code.is_null() && FLAG_print_opt_code) {
+      Vector<char> buffer;
+      const char* name = "";
+      if (func->name_offset > 0) {
+        const byte* ptr = module->module->module_start + func->name_offset;
+        name = reinterpret_cast<const char*>(ptr);
+      }
+      SNPrintF(buffer, "JS->WASM function wrapper #%d:%s", index, name);
+      OFStream os(stdout);
+      code->Disassemble(buffer.start(), os);
+    }
+#endif
+    // Set the JSFunction's machine code.
+    function->set_code(*code);
+  }
+  return function;
+}
+
+
+Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, wasm::ModuleEnv* module,
+                                    Handle<JSFunction> function,
+                                    uint32_t index) {
+  wasm::WasmFunction* func = &module->module->functions->at(index);
+
+  //----------------------------------------------------------------------------
+  // Create the Graph
+  //----------------------------------------------------------------------------
+  Zone zone;
+  Graph graph(&zone);
+  CommonOperatorBuilder common(&zone);
+  JSOperatorBuilder javascript(&zone);
+  MachineOperatorBuilder machine(&zone);
+  JSGraph jsgraph(isolate, &graph, &common, &javascript, nullptr, &machine);
+
+  Node* control = nullptr;
+  Node* effect = nullptr;
+
+  WasmGraphBuilder builder(&zone, &jsgraph, func->sig);
+  builder.set_control_ptr(&control);
+  builder.set_effect_ptr(&effect);
+  builder.set_module(module);
+  builder.BuildWasmToJSWrapper(function, func->sig);
+
+  Handle<Code> code = Handle<Code>::null();
+  {
+    // Changes lowering requires types.
+    Typer typer(isolate, &graph);
+    NodeVector roots(&zone);
+    jsgraph.GetCachedNodes(&roots);
+    typer.Run(roots);
+
+    // Run generic and change lowering.
+    JSGenericLowering generic(true, &jsgraph);
+    ChangeLowering changes(&jsgraph);
+    GraphReducer graph_reducer(&zone, &graph, jsgraph.Dead());
+    graph_reducer.AddReducer(&changes);
+    graph_reducer.AddReducer(&generic);
+    graph_reducer.ReduceGraph();
+
+    if (FLAG_trace_turbo_graph) {  // Simple textual RPO.
+      OFStream os(stdout);
+      os << "-- Graph after change lowering -- " << std::endl;
+      os << AsRPO(graph);
+    }
+
+    // Schedule and compile to machine code.
+    CallDescriptor* incoming = module->GetWasmCallDescriptor(&zone, func->sig);
+    CompilationInfo info("wasm-to-js", isolate, &zone);
+    // TODO(titzer): this is technically a WASM wrapper, not a wasm function.
+    info.set_output_code_kind(Code::WASM_FUNCTION);
+    code = Pipeline::GenerateCodeForTesting(&info, incoming, &graph, nullptr);
+
+#ifdef ENABLE_DISASSEMBLER
+    // Disassemble the wrapper code for debugging.
+    if (!code.is_null() && FLAG_print_opt_code) {
+      Vector<char> buffer;
+      const char* name = "";
+      if (func->name_offset > 0) {
+        const byte* ptr = module->module->module_start + func->name_offset;
+        name = reinterpret_cast<const char*>(ptr);
+      }
+      SNPrintF(buffer, "WASM->JS function wrapper #%d:%s", index, name);
+      OFStream os(stdout);
+      code->Disassemble(buffer.start(), os);
+    }
+#endif
+  }
+  return code;
+}
+
+
+// Helper function to compile a single function.
+Handle<Code> CompileWasmFunction(wasm::ErrorThrower& thrower, Isolate* isolate,
+                                 wasm::ModuleEnv* module_env,
+                                 const wasm::WasmFunction& function,
+                                 int index) {
+  if (FLAG_trace_wasm_compiler || FLAG_trace_wasm_decode_time) {
+    // TODO(titzer): clean me up a bit.
+    OFStream os(stdout);
+    os << "Compiling WASM function #" << index << ":";
+    if (function.name_offset > 0) {
+      os << module_env->module->GetName(function.name_offset);
+    }
+    os << std::endl;
+  }
+  // Initialize the function environment for decoding.
+  wasm::FunctionEnv env;
+  env.module = module_env;
+  env.sig = function.sig;
+  env.local_int32_count = function.local_int32_count;
+  env.local_int64_count = function.local_int64_count;
+  env.local_float32_count = function.local_float32_count;
+  env.local_float64_count = function.local_float64_count;
+  env.SumLocals();
+
+  // Create a TF graph during decoding.
+  Zone zone;
+  Graph graph(&zone);
+  CommonOperatorBuilder common(&zone);
+  MachineOperatorBuilder machine(
+      &zone, MachineType::PointerRepresentation(),
+      InstructionSelector::SupportedMachineOperatorFlags());
+  JSGraph jsgraph(isolate, &graph, &common, nullptr, nullptr, &machine);
+  WasmGraphBuilder builder(&zone, &jsgraph, function.sig);
+  wasm::TreeResult result = wasm::BuildTFGraph(
+      &builder, &env,                                                 // --
+      module_env->module->module_start,                               // --
+      module_env->module->module_start + function.code_start_offset,  // --
+      module_env->module->module_start + function.code_end_offset);   // --
+
+  if (result.failed()) {
+    if (FLAG_trace_wasm_compiler) {
+      OFStream os(stdout);
+      os << "Compilation failed: " << result << std::endl;
+    }
+    // Add the function as another context for the exception
+    Vector<char> buffer;
+    SNPrintF(buffer, "Compiling WASM function #%d:%s failed:", index,
+             module_env->module->GetName(function.name_offset));
+    thrower.Failed(buffer.start(), result);
+    return Handle<Code>::null();
+  }
+
+  // Run the compiler pipeline to generate machine code.
+  CallDescriptor* descriptor = const_cast<CallDescriptor*>(
+      module_env->GetWasmCallDescriptor(&zone, function.sig));
+  CompilationInfo info("wasm", isolate, &zone);
+  info.set_output_code_kind(Code::WASM_FUNCTION);
+  Handle<Code> code =
+      Pipeline::GenerateCodeForTesting(&info, descriptor, &graph);
+
+#ifdef ENABLE_DISASSEMBLER
+  // Disassemble the code for debugging.
+  if (!code.is_null() && FLAG_print_opt_code) {
+    Vector<char> buffer;
+    const char* name = "";
+    if (function.name_offset > 0) {
+      const byte* ptr = module_env->module->module_start + function.name_offset;
+      name = reinterpret_cast<const char*>(ptr);
+    }
+    SNPrintF(buffer, "WASM function #%d:%s", index, name);
+    OFStream os(stdout);
+    code->Disassemble(buffer.start(), os);
+  }
+#endif
+  return code;
+}
+
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/wasm-compiler.h b/src/compiler/wasm-compiler.h
new file mode 100644
index 0000000..1a17a83
--- /dev/null
+++ b/src/compiler/wasm-compiler.h
@@ -0,0 +1,190 @@
+// Copyright 2015 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.
+
+#ifndef V8_COMPILER_WASM_COMPILER_H_
+#define V8_COMPILER_WASM_COMPILER_H_
+
+// Clients of this interface shouldn't depend on lots of compiler internals.
+// Do not include anything from src/compiler here!
+#include "src/wasm/wasm-opcodes.h"
+#include "src/zone.h"
+
+namespace v8 {
+namespace internal {
+
+namespace compiler {
+// Forward declarations for some compiler data structures.
+class Node;
+class JSGraph;
+class Graph;
+}
+
+namespace wasm {
+// Forward declarations for some WASM data structures.
+struct ModuleEnv;
+struct WasmFunction;
+class ErrorThrower;
+
+// Expose {Node} and {Graph} opaquely as {wasm::TFNode} and {wasm::TFGraph}.
+typedef compiler::Node TFNode;
+typedef compiler::JSGraph TFGraph;
+}
+
+namespace compiler {
+// Compiles a single function, producing a code object.
+Handle<Code> CompileWasmFunction(wasm::ErrorThrower& thrower, Isolate* isolate,
+                                 wasm::ModuleEnv* module_env,
+                                 const wasm::WasmFunction& function, int index);
+
+// Wraps a JS function, producing a code object that can be called from WASM.
+Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, wasm::ModuleEnv* module,
+                                    Handle<JSFunction> function,
+                                    uint32_t index);
+
+// Wraps a given wasm code object, producing a JSFunction that can be called
+// from JavaScript.
+Handle<JSFunction> CompileJSToWasmWrapper(
+    Isolate* isolate, wasm::ModuleEnv* module, Handle<String> name,
+    Handle<Code> wasm_code, Handle<JSObject> module_object, uint32_t index);
+
+// Abstracts details of building TurboFan graph nodes for WASM to separate
+// the WASM decoder from the internal details of TurboFan.
+class WasmTrapHelper;
+class WasmGraphBuilder {
+ public:
+  WasmGraphBuilder(Zone* z, JSGraph* g, wasm::FunctionSig* function_signature);
+
+  Node** Buffer(size_t count) {
+    if (count > cur_bufsize_) {
+      size_t new_size = count + cur_bufsize_ + 5;
+      cur_buffer_ =
+          reinterpret_cast<Node**>(zone_->New(new_size * sizeof(Node*)));
+      cur_bufsize_ = new_size;
+    }
+    return cur_buffer_;
+  }
+
+  //-----------------------------------------------------------------------
+  // Operations independent of {control} or {effect}.
+  //-----------------------------------------------------------------------
+  Node* Error();
+  Node* Start(unsigned params);
+  Node* Param(unsigned index, wasm::LocalType type);
+  Node* Loop(Node* entry);
+  Node* Terminate(Node* effect, Node* control);
+  Node* Merge(unsigned count, Node** controls);
+  Node* Phi(wasm::LocalType type, unsigned count, Node** vals, Node* control);
+  Node* EffectPhi(unsigned count, Node** effects, Node* control);
+  Node* Int32Constant(int32_t value);
+  Node* Int64Constant(int64_t value);
+  Node* Float32Constant(float value);
+  Node* Float64Constant(double value);
+  Node* Constant(Handle<Object> value);
+  Node* Binop(wasm::WasmOpcode opcode, Node* left, Node* right);
+  Node* Unop(wasm::WasmOpcode opcode, Node* input);
+  unsigned InputCount(Node* node);
+  bool IsPhiWithMerge(Node* phi, Node* merge);
+  void AppendToMerge(Node* merge, Node* from);
+  void AppendToPhi(Node* merge, Node* phi, Node* from);
+
+  //-----------------------------------------------------------------------
+  // Operations that read and/or write {control} and {effect}.
+  //-----------------------------------------------------------------------
+  Node* Branch(Node* cond, Node** true_node, Node** false_node);
+  Node* Switch(unsigned count, Node* key);
+  Node* IfValue(int32_t value, Node* sw);
+  Node* IfDefault(Node* sw);
+  Node* Return(unsigned count, Node** vals);
+  Node* ReturnVoid();
+  Node* Unreachable();
+
+  Node* CallDirect(uint32_t index, Node** args);
+  Node* CallIndirect(uint32_t index, Node** args);
+  void BuildJSToWasmWrapper(Handle<Code> wasm_code, wasm::FunctionSig* sig);
+  void BuildWasmToJSWrapper(Handle<JSFunction> function,
+                            wasm::FunctionSig* sig);
+  Node* ToJS(Node* node, Node* context, wasm::LocalType type);
+  Node* FromJS(Node* node, Node* context, wasm::LocalType type);
+  Node* Invert(Node* node);
+  Node* FunctionTable();
+
+  //-----------------------------------------------------------------------
+  // Operations that concern the linear memory.
+  //-----------------------------------------------------------------------
+  Node* MemSize(uint32_t offset);
+  Node* LoadGlobal(uint32_t index);
+  Node* StoreGlobal(uint32_t index, Node* val);
+  Node* LoadMem(wasm::LocalType type, MachineType memtype, Node* index,
+                uint32_t offset);
+  Node* StoreMem(MachineType type, Node* index, uint32_t offset, Node* val);
+
+  static void PrintDebugName(Node* node);
+
+  Node* Control() { return *control_; }
+  Node* Effect() { return *effect_; }
+
+  void set_module(wasm::ModuleEnv* module) { this->module_ = module; }
+
+  void set_control_ptr(Node** control) { this->control_ = control; }
+
+  void set_effect_ptr(Node** effect) { this->effect_ = effect; }
+
+  wasm::FunctionSig* GetFunctionSignature() { return function_signature_; }
+
+ private:
+  static const int kDefaultBufferSize = 16;
+  friend class WasmTrapHelper;
+
+  Zone* zone_;
+  JSGraph* jsgraph_;
+  wasm::ModuleEnv* module_;
+  Node* mem_buffer_;
+  Node* mem_size_;
+  Node* function_table_;
+  Node** control_;
+  Node** effect_;
+  Node** cur_buffer_;
+  size_t cur_bufsize_;
+  Node* def_buffer_[kDefaultBufferSize];
+
+  WasmTrapHelper* trap_;
+  wasm::FunctionSig* function_signature_;
+
+  // Internal helper methods.
+  JSGraph* jsgraph() { return jsgraph_; }
+  Graph* graph();
+
+  Node* String(const char* string);
+  Node* MemBuffer(uint32_t offset);
+  void BoundsCheckMem(MachineType memtype, Node* index, uint32_t offset);
+
+  Node* BuildWasmCall(wasm::FunctionSig* sig, Node** args);
+  Node* BuildF32Neg(Node* input);
+  Node* BuildF64Neg(Node* input);
+  Node* BuildF32CopySign(Node* left, Node* right);
+  Node* BuildF64CopySign(Node* left, Node* right);
+  Node* BuildF32Min(Node* left, Node* right);
+  Node* BuildF32Max(Node* left, Node* right);
+  Node* BuildF64Min(Node* left, Node* right);
+  Node* BuildF64Max(Node* left, Node* right);
+  Node* BuildI32SConvertF32(Node* input);
+  Node* BuildI32SConvertF64(Node* input);
+  Node* BuildI32UConvertF32(Node* input);
+  Node* BuildI32UConvertF64(Node* input);
+  Node* BuildI32Ctz(Node* input);
+  Node* BuildI32Popcnt(Node* input);
+  Node* BuildI64Ctz(Node* input);
+  Node* BuildI64Popcnt(Node* input);
+
+  Node** Realloc(Node** buffer, size_t count) {
+    Node** buf = Buffer(count);
+    if (buf != buffer) memcpy(buf, buffer, count * sizeof(Node*));
+    return buf;
+  }
+};
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_WASM_COMPILER_H_
diff --git a/src/compiler/wasm-linkage.cc b/src/compiler/wasm-linkage.cc
new file mode 100644
index 0000000..92363dd
--- /dev/null
+++ b/src/compiler/wasm-linkage.cc
@@ -0,0 +1,282 @@
+// Copyright 2015 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/assembler.h"
+#include "src/macro-assembler.h"
+
+#include "src/wasm/wasm-module.h"
+
+#include "src/compiler/linkage.h"
+
+#include "src/zone.h"
+
+namespace v8 {
+namespace internal {
+// TODO(titzer): this should not be in the WASM namespace.
+namespace wasm {
+
+using compiler::LocationSignature;
+using compiler::CallDescriptor;
+using compiler::LinkageLocation;
+
+namespace {
+MachineType MachineTypeFor(LocalType type) {
+  switch (type) {
+    case kAstI32:
+      return MachineType::Int32();
+    case kAstI64:
+      return MachineType::Int64();
+    case kAstF64:
+      return MachineType::Float64();
+    case kAstF32:
+      return MachineType::Float32();
+    default:
+      UNREACHABLE();
+      return MachineType::AnyTagged();
+  }
+}
+
+
+// Platform-specific configuration for C calling convention.
+LinkageLocation regloc(Register reg) {
+  return LinkageLocation::ForRegister(reg.code());
+}
+
+
+LinkageLocation regloc(DoubleRegister reg) {
+  return LinkageLocation::ForRegister(reg.code());
+}
+
+
+LinkageLocation stackloc(int i) {
+  return LinkageLocation::ForCallerFrameSlot(i);
+}
+
+
+#if V8_TARGET_ARCH_IA32
+// ===========================================================================
+// == ia32 ===================================================================
+// ===========================================================================
+#define GP_PARAM_REGISTERS eax, edx, ecx, ebx, esi, edi
+#define GP_RETURN_REGISTERS eax, edx
+#define FP_PARAM_REGISTERS xmm1, xmm2, xmm3, xmm4, xmm5, xmm6
+#define FP_RETURN_REGISTERS xmm1, xmm2
+
+#elif V8_TARGET_ARCH_X64
+// ===========================================================================
+// == x64 ====================================================================
+// ===========================================================================
+#define GP_PARAM_REGISTERS rax, rdx, rcx, rbx, rsi, rdi
+#define GP_RETURN_REGISTERS rax, rdx
+#define FP_PARAM_REGISTERS xmm1, xmm2, xmm3, xmm4, xmm5, xmm6
+#define FP_RETURN_REGISTERS xmm1, xmm2
+
+#elif V8_TARGET_ARCH_X87
+// ===========================================================================
+// == x87 ====================================================================
+// ===========================================================================
+#define GP_PARAM_REGISTERS eax, edx, ecx, ebx, esi, edi
+#define GP_RETURN_REGISTERS eax, edx
+#define FP_RETURN_REGISTERS stX_0
+
+#elif V8_TARGET_ARCH_ARM
+// ===========================================================================
+// == arm ====================================================================
+// ===========================================================================
+#define GP_PARAM_REGISTERS r0, r1, r2, r3
+#define GP_RETURN_REGISTERS r0, r1
+#define FP_PARAM_REGISTERS d0, d1, d2, d3, d4, d5, d6, d7
+#define FP_RETURN_REGISTERS d0, d1
+
+#elif V8_TARGET_ARCH_ARM64
+// ===========================================================================
+// == arm64 ====================================================================
+// ===========================================================================
+#define GP_PARAM_REGISTERS x0, x1, x2, x3, x4, x5, x6, x7
+#define GP_RETURN_REGISTERS x0, x1
+#define FP_PARAM_REGISTERS d0, d1, d2, d3, d4, d5, d6, d7
+#define FP_RETURN_REGISTERS d0, d1
+
+#elif V8_TARGET_ARCH_MIPS
+// ===========================================================================
+// == mips ===================================================================
+// ===========================================================================
+#define GP_PARAM_REGISTERS a0, a1, a2, a3
+#define GP_RETURN_REGISTERS v0, v1
+#define FP_PARAM_REGISTERS f2, f4, f6, f8, f10, f12, f14
+#define FP_RETURN_REGISTERS f2, f4
+
+#elif V8_TARGET_ARCH_MIPS64
+// ===========================================================================
+// == mips64 =================================================================
+// ===========================================================================
+#define GP_PARAM_REGISTERS a0, a1, a2, a3, a4, a5, a6, a7
+#define GP_RETURN_REGISTERS v0, v1
+#define FP_PARAM_REGISTERS f2, f4, f6, f8, f10, f12, f14
+#define FP_RETURN_REGISTERS f2, f4
+
+#elif V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_PPC64
+// ===========================================================================
+// == ppc & ppc64 ============================================================
+// ===========================================================================
+#define GP_PARAM_REGISTERS r3, r4, r5, r6, r7, r8, r9, r10
+#define GP_RETURN_REGISTERS r3, r4
+#define FP_PARAM_REGISTERS d1, d2, d3, d4, d5, d6, d7, d8
+#define FP_RETURN_REGISTERS d1, d2
+
+#else
+// ===========================================================================
+// == unknown ================================================================
+// ===========================================================================
+// Don't define anything. We'll just always use the stack.
+#endif
+
+
+// Helper for allocating either an GP or FP reg, or the next stack slot.
+struct Allocator {
+  Allocator(const Register* gp, int gpc, const DoubleRegister* fp, int fpc)
+      : gp_count(gpc),
+        gp_offset(0),
+        gp_regs(gp),
+        fp_count(fpc),
+        fp_offset(0),
+        fp_regs(fp),
+        stack_offset(0) {}
+
+  int gp_count;
+  int gp_offset;
+  const Register* gp_regs;
+
+  int fp_count;
+  int fp_offset;
+  const DoubleRegister* fp_regs;
+
+  int stack_offset;
+
+  LinkageLocation Next(LocalType type) {
+    if (IsFloatingPoint(type)) {
+      // Allocate a floating point register/stack location.
+      if (fp_offset < fp_count) {
+        return regloc(fp_regs[fp_offset++]);
+      } else {
+        int offset = -1 - stack_offset;
+        stack_offset += Words(type);
+        return stackloc(offset);
+      }
+    } else {
+      // Allocate a general purpose register/stack location.
+      if (gp_offset < gp_count) {
+        return regloc(gp_regs[gp_offset++]);
+      } else {
+        int offset = -1 - stack_offset;
+        stack_offset += Words(type);
+        return stackloc(offset);
+      }
+    }
+  }
+  bool IsFloatingPoint(LocalType type) {
+    return type == kAstF32 || type == kAstF64;
+  }
+  int Words(LocalType type) {
+    // The code generation for pushing parameters on the stack does not
+    // distinguish between float32 and float64. Therefore also float32 needs
+    // two words.
+    if (kPointerSize < 8 &&
+        (type == kAstI64 || type == kAstF64 || type == kAstF32)) {
+      return 2;
+    }
+    return 1;
+  }
+};
+}  // namespace
+
+
+// General code uses the above configuration data.
+CallDescriptor* ModuleEnv::GetWasmCallDescriptor(Zone* zone,
+                                                 FunctionSig* fsig) {
+  MachineSignature::Builder msig(zone, fsig->return_count(),
+                                 fsig->parameter_count());
+  LocationSignature::Builder locations(zone, fsig->return_count(),
+                                       fsig->parameter_count());
+
+#ifdef GP_RETURN_REGISTERS
+  static const Register kGPReturnRegisters[] = {GP_RETURN_REGISTERS};
+  static const int kGPReturnRegistersCount =
+      static_cast<int>(arraysize(kGPReturnRegisters));
+#else
+  static const Register* kGPReturnRegisters = nullptr;
+  static const int kGPReturnRegistersCount = 0;
+#endif
+
+#ifdef FP_RETURN_REGISTERS
+  static const DoubleRegister kFPReturnRegisters[] = {FP_RETURN_REGISTERS};
+  static const int kFPReturnRegistersCount =
+      static_cast<int>(arraysize(kFPReturnRegisters));
+#else
+  static const DoubleRegister* kFPReturnRegisters = nullptr;
+  static const int kFPReturnRegistersCount = 0;
+#endif
+
+  Allocator rets(kGPReturnRegisters, kGPReturnRegistersCount,
+                 kFPReturnRegisters, kFPReturnRegistersCount);
+
+  // Add return location(s).
+  const int return_count = static_cast<int>(locations.return_count_);
+  for (int i = 0; i < return_count; i++) {
+    LocalType ret = fsig->GetReturn(i);
+    msig.AddReturn(MachineTypeFor(ret));
+    locations.AddReturn(rets.Next(ret));
+  }
+
+#ifdef GP_PARAM_REGISTERS
+  static const Register kGPParamRegisters[] = {GP_PARAM_REGISTERS};
+  static const int kGPParamRegistersCount =
+      static_cast<int>(arraysize(kGPParamRegisters));
+#else
+  static const Register* kGPParamRegisters = nullptr;
+  static const int kGPParamRegistersCount = 0;
+#endif
+
+#ifdef FP_PARAM_REGISTERS
+  static const DoubleRegister kFPParamRegisters[] = {FP_PARAM_REGISTERS};
+  static const int kFPParamRegistersCount =
+      static_cast<int>(arraysize(kFPParamRegisters));
+#else
+  static const DoubleRegister* kFPParamRegisters = nullptr;
+  static const int kFPParamRegistersCount = 0;
+#endif
+
+  Allocator params(kGPParamRegisters, kGPParamRegistersCount, kFPParamRegisters,
+                   kFPParamRegistersCount);
+
+  // Add register and/or stack parameter(s).
+  const int parameter_count = static_cast<int>(fsig->parameter_count());
+  for (int i = 0; i < parameter_count; i++) {
+    LocalType param = fsig->GetParam(i);
+    msig.AddParam(MachineTypeFor(param));
+    locations.AddParam(params.Next(param));
+  }
+
+  const RegList kCalleeSaveRegisters = 0;
+  const RegList kCalleeSaveFPRegisters = 0;
+
+  // The target for WASM calls is always a code object.
+  MachineType target_type = MachineType::AnyTagged();
+  LinkageLocation target_loc = LinkageLocation::ForAnyRegister();
+  return new (zone) CallDescriptor(       // --
+      CallDescriptor::kCallCodeObject,    // kind
+      target_type,                        // target MachineType
+      target_loc,                         // target location
+      msig.Build(),                       // machine_sig
+      locations.Build(),                  // location_sig
+      params.stack_offset,                // stack_parameter_count
+      compiler::Operator::kNoProperties,  // properties
+      kCalleeSaveRegisters,               // callee-saved registers
+      kCalleeSaveFPRegisters,             // callee-saved fp regs
+      CallDescriptor::kUseNativeStack,    // flags
+      "c-call");
+}
+}  // namespace wasm
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/x64/code-generator-x64.cc b/src/compiler/x64/code-generator-x64.cc
index 0480f9d..be406fb 100644
--- a/src/compiler/x64/code-generator-x64.cc
+++ b/src/compiler/x64/code-generator-x64.cc
@@ -4,11 +4,11 @@
 
 #include "src/compiler/code-generator.h"
 
+#include "src/ast/scopes.h"
 #include "src/compiler/code-generator-impl.h"
 #include "src/compiler/gap-resolver.h"
 #include "src/compiler/node-matchers.h"
-#include "src/compiler/node-properties-inl.h"
-#include "src/scopes.h"
+#include "src/compiler/osr.h"
 #include "src/x64/assembler-x64.h"
 #include "src/x64/macro-assembler-x64.h"
 
@@ -19,33 +19,44 @@
 #define __ masm()->
 
 
+#define kScratchDoubleReg xmm0
+
+
 // Adds X64 specific methods for decoding operands.
 class X64OperandConverter : public InstructionOperandConverter {
  public:
   X64OperandConverter(CodeGenerator* gen, Instruction* instr)
       : InstructionOperandConverter(gen, instr) {}
 
-  Immediate InputImmediate(int index) {
+  Immediate InputImmediate(size_t index) {
     return ToImmediate(instr_->InputAt(index));
   }
 
-  Operand InputOperand(int index) { return ToOperand(instr_->InputAt(index)); }
+  Operand InputOperand(size_t index, int extra = 0) {
+    return ToOperand(instr_->InputAt(index), extra);
+  }
 
   Operand OutputOperand() { return ToOperand(instr_->Output()); }
 
   Immediate ToImmediate(InstructionOperand* operand) {
-    return Immediate(ToConstant(operand).ToInt32());
+    Constant constant = ToConstant(operand);
+    if (constant.type() == Constant::kFloat64) {
+      DCHECK_EQ(0, bit_cast<int64_t>(constant.ToFloat64()));
+      return Immediate(0);
+    }
+    return Immediate(constant.ToInt32());
   }
 
   Operand ToOperand(InstructionOperand* op, int extra = 0) {
     DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot());
-    // The linkage computes where all spill slots are located.
-    FrameOffset offset = linkage()->GetFrameOffset(op->index(), frame(), extra);
-    return Operand(offset.from_stack_pointer() ? rsp : rbp, offset.offset());
+    FrameOffset offset = frame_access_state()->GetFrameOffset(
+        AllocatedOperand::cast(op)->index());
+    return Operand(offset.from_stack_pointer() ? rsp : rbp,
+                   offset.offset() + extra);
   }
 
-  static int NextOffset(int* offset) {
-    int i = *offset;
+  static size_t NextOffset(size_t* offset) {
+    size_t i = *offset;
     (*offset)++;
     return i;
   }
@@ -60,7 +71,7 @@
     return static_cast<ScaleFactor>(scale);
   }
 
-  Operand MemoryOperand(int* offset) {
+  Operand MemoryOperand(size_t* offset) {
     AddressingMode mode = AddressingModeField::decode(instr_->opcode());
     switch (mode) {
       case kMode_MR: {
@@ -125,7 +136,7 @@
     return Operand(no_reg, 0);
   }
 
-  Operand MemoryOperand(int first_input = 0) {
+  Operand MemoryOperand(size_t first_input = 0) {
     return MemoryOperand(&first_input);
   }
 };
@@ -133,44 +144,44 @@
 
 namespace {
 
-bool HasImmediateInput(Instruction* instr, int index) {
+bool HasImmediateInput(Instruction* instr, size_t index) {
   return instr->InputAt(index)->IsImmediate();
 }
 
 
-class OutOfLineLoadZero FINAL : public OutOfLineCode {
+class OutOfLineLoadZero final : public OutOfLineCode {
  public:
   OutOfLineLoadZero(CodeGenerator* gen, Register result)
       : OutOfLineCode(gen), result_(result) {}
 
-  void Generate() FINAL { __ xorl(result_, result_); }
+  void Generate() final { __ xorl(result_, result_); }
 
  private:
   Register const result_;
 };
 
 
-class OutOfLineLoadNaN FINAL : public OutOfLineCode {
+class OutOfLineLoadNaN final : public OutOfLineCode {
  public:
   OutOfLineLoadNaN(CodeGenerator* gen, XMMRegister result)
       : OutOfLineCode(gen), result_(result) {}
 
-  void Generate() FINAL { __ pcmpeqd(result_, result_); }
+  void Generate() final { __ Pcmpeqd(result_, result_); }
 
  private:
   XMMRegister const result_;
 };
 
 
-class OutOfLineTruncateDoubleToI FINAL : public OutOfLineCode {
+class OutOfLineTruncateDoubleToI final : public OutOfLineCode {
  public:
   OutOfLineTruncateDoubleToI(CodeGenerator* gen, Register result,
                              XMMRegister input)
       : OutOfLineCode(gen), result_(result), input_(input) {}
 
-  void Generate() FINAL {
+  void Generate() final {
     __ subp(rsp, Immediate(kDoubleSize));
-    __ movsd(MemOperand(rsp, 0), input_);
+    __ Movsd(MemOperand(rsp, 0), input_);
     __ SlowTruncateToI(result_, rsp, 0);
     __ addp(rsp, Immediate(kDoubleSize));
   }
@@ -180,6 +191,46 @@
   XMMRegister const input_;
 };
 
+
+class OutOfLineRecordWrite final : public OutOfLineCode {
+ public:
+  OutOfLineRecordWrite(CodeGenerator* gen, Register object, Operand operand,
+                       Register value, Register scratch0, Register scratch1,
+                       RecordWriteMode mode)
+      : OutOfLineCode(gen),
+        object_(object),
+        operand_(operand),
+        value_(value),
+        scratch0_(scratch0),
+        scratch1_(scratch1),
+        mode_(mode) {}
+
+  void Generate() final {
+    if (mode_ > RecordWriteMode::kValueIsPointer) {
+      __ JumpIfSmi(value_, exit());
+    }
+    if (mode_ > RecordWriteMode::kValueIsMap) {
+      __ CheckPageFlag(value_, scratch0_,
+                       MemoryChunk::kPointersToHereAreInterestingMask, zero,
+                       exit());
+    }
+    SaveFPRegsMode const save_fp_mode =
+        frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs;
+    RecordWriteStub stub(isolate(), object_, scratch0_, scratch1_,
+                         EMIT_REMEMBERED_SET, save_fp_mode);
+    __ leap(scratch1_, operand_);
+    __ CallStub(&stub);
+  }
+
+ private:
+  Register const object_;
+  Operand const operand_;
+  Register const value_;
+  Register const scratch0_;
+  Register const scratch1_;
+  RecordWriteMode const mode_;
+};
+
 }  // namespace
 
 
@@ -249,7 +300,19 @@
   } while (0)
 
 
-#define ASSEMBLE_DOUBLE_BINOP(asm_instr)                                \
+#define ASSEMBLE_MOVX(asm_instr)                            \
+  do {                                                      \
+    if (instr->addressing_mode() != kMode_None) {           \
+      __ asm_instr(i.OutputRegister(), i.MemoryOperand());  \
+    } else if (instr->InputAt(0)->IsRegister()) {           \
+      __ asm_instr(i.OutputRegister(), i.InputRegister(0)); \
+    } else {                                                \
+      __ asm_instr(i.OutputRegister(), i.InputOperand(0));  \
+    }                                                       \
+  } while (0)
+
+
+#define ASSEMBLE_SSE_BINOP(asm_instr)                                   \
   do {                                                                  \
     if (instr->InputAt(1)->IsDoubleRegister()) {                        \
       __ asm_instr(i.InputDoubleRegister(0), i.InputDoubleRegister(1)); \
@@ -259,7 +322,17 @@
   } while (0)
 
 
-#define ASSEMBLE_AVX_DOUBLE_BINOP(asm_instr)                           \
+#define ASSEMBLE_SSE_UNOP(asm_instr)                                    \
+  do {                                                                  \
+    if (instr->InputAt(0)->IsDoubleRegister()) {                        \
+      __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \
+    } else {                                                            \
+      __ asm_instr(i.OutputDoubleRegister(), i.InputOperand(0));        \
+    }                                                                   \
+  } while (0)
+
+
+#define ASSEMBLE_AVX_BINOP(asm_instr)                                  \
   do {                                                                 \
     CpuFeatureScope avx_scope(masm(), AVX);                            \
     if (instr->InputAt(1)->IsDoubleRegister()) {                       \
@@ -288,7 +361,7 @@
       auto length = i.InputInt32(3);                                         \
       DCHECK_LE(index2, length);                                             \
       __ cmpq(index1, Immediate(length - index2));                           \
-      class OutOfLineLoadFloat FINAL : public OutOfLineCode {                \
+      class OutOfLineLoadFloat final : public OutOfLineCode {                \
        public:                                                               \
         OutOfLineLoadFloat(CodeGenerator* gen, XMMRegister result,           \
                            Register buffer, Register index1, int32_t index2, \
@@ -300,9 +373,9 @@
               index2_(index2),                                               \
               length_(length) {}                                             \
                                                                              \
-        void Generate() FINAL {                                              \
+        void Generate() final {                                              \
           __ leal(kScratchRegister, Operand(index1_, index2_));              \
-          __ pcmpeqd(result_, result_);                                      \
+          __ Pcmpeqd(result_, result_);                                      \
           __ cmpl(kScratchRegister, Immediate(length_));                     \
           __ j(above_equal, exit());                                         \
           __ asm_instr(result_,                                              \
@@ -341,7 +414,7 @@
       auto length = i.InputInt32(3);                                           \
       DCHECK_LE(index2, length);                                               \
       __ cmpq(index1, Immediate(length - index2));                             \
-      class OutOfLineLoadInteger FINAL : public OutOfLineCode {                \
+      class OutOfLineLoadInteger final : public OutOfLineCode {                \
        public:                                                                 \
         OutOfLineLoadInteger(CodeGenerator* gen, Register result,              \
                              Register buffer, Register index1, int32_t index2, \
@@ -353,7 +426,7 @@
               index2_(index2),                                                 \
               length_(length) {}                                               \
                                                                                \
-        void Generate() FINAL {                                                \
+        void Generate() final {                                                \
           Label oob;                                                           \
           __ leal(kScratchRegister, Operand(index1_, index2_));                \
           __ cmpl(kScratchRegister, Immediate(length_));                       \
@@ -399,7 +472,7 @@
       auto length = i.InputInt32(3);                                         \
       DCHECK_LE(index2, length);                                             \
       __ cmpq(index1, Immediate(length - index2));                           \
-      class OutOfLineStoreFloat FINAL : public OutOfLineCode {               \
+      class OutOfLineStoreFloat final : public OutOfLineCode {               \
        public:                                                               \
         OutOfLineStoreFloat(CodeGenerator* gen, Register buffer,             \
                             Register index1, int32_t index2, int32_t length, \
@@ -411,7 +484,7 @@
               length_(length),                                               \
               value_(value) {}                                               \
                                                                              \
-        void Generate() FINAL {                                              \
+        void Generate() final {                                              \
           __ leal(kScratchRegister, Operand(index1_, index2_));              \
           __ cmpl(kScratchRegister, Immediate(length_));                     \
           __ j(above_equal, exit());                                         \
@@ -452,7 +525,7 @@
       auto length = i.InputInt32(3);                                           \
       DCHECK_LE(index2, length);                                               \
       __ cmpq(index1, Immediate(length - index2));                             \
-      class OutOfLineStoreInteger FINAL : public OutOfLineCode {               \
+      class OutOfLineStoreInteger final : public OutOfLineCode {               \
        public:                                                                 \
         OutOfLineStoreInteger(CodeGenerator* gen, Register buffer,             \
                               Register index1, int32_t index2, int32_t length, \
@@ -464,7 +537,7 @@
               length_(length),                                                 \
               value_(value) {}                                                 \
                                                                                \
-        void Generate() FINAL {                                                \
+        void Generate() final {                                                \
           __ leal(kScratchRegister, Operand(index1_, index2_));                \
           __ cmpl(kScratchRegister, Immediate(length_));                       \
           __ j(above_equal, exit());                                           \
@@ -500,6 +573,28 @@
   } while (false)
 
 
+void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) {
+  int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta);
+  if (sp_slot_delta > 0) {
+    __ addq(rsp, Immediate(sp_slot_delta * kPointerSize));
+  }
+  frame_access_state()->SetFrameAccessToDefault();
+}
+
+
+void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) {
+  int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta);
+  if (sp_slot_delta < 0) {
+    __ subq(rsp, Immediate(-sp_slot_delta * kPointerSize));
+    frame_access_state()->IncreaseSPDelta(-sp_slot_delta);
+  }
+  if (frame()->needs_frame()) {
+    __ movq(rbp, MemOperand(rbp, 0));
+  }
+  frame_access_state()->SetFrameAccessToSP();
+}
+
+
 // Assembles an instruction after register allocation, producing machine code.
 void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
   X64OperandConverter i(this, instr);
@@ -512,10 +607,25 @@
         __ Call(code, RelocInfo::CODE_TARGET);
       } else {
         Register reg = i.InputRegister(0);
-        int entry = Code::kHeaderSize - kHeapObjectTag;
-        __ Call(Operand(reg, entry));
+        __ addp(reg, Immediate(Code::kHeaderSize - kHeapObjectTag));
+        __ call(reg);
       }
-      AddSafepointAndDeopt(instr);
+      RecordCallPosition(instr);
+      frame_access_state()->ClearSPDelta();
+      break;
+    }
+    case kArchTailCallCodeObject: {
+      int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
+      AssembleDeconstructActivationRecord(stack_param_delta);
+      if (HasImmediateInput(instr, 0)) {
+        Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0));
+        __ jmp(code, RelocInfo::CODE_TARGET);
+      } else {
+        Register reg = i.InputRegister(0);
+        __ addp(reg, Immediate(Code::kHeaderSize - kHeapObjectTag));
+        __ jmp(reg);
+      }
+      frame_access_state()->ClearSPDelta();
       break;
     }
     case kArchCallJSFunction: {
@@ -527,31 +637,109 @@
         __ Assert(equal, kWrongFunctionContext);
       }
       __ Call(FieldOperand(func, JSFunction::kCodeEntryOffset));
-      AddSafepointAndDeopt(instr);
+      frame_access_state()->ClearSPDelta();
+      RecordCallPosition(instr);
+      break;
+    }
+    case kArchTailCallJSFunction: {
+      Register func = i.InputRegister(0);
+      if (FLAG_debug_code) {
+        // Check the function's context matches the context argument.
+        __ cmpp(rsi, FieldOperand(func, JSFunction::kContextOffset));
+        __ Assert(equal, kWrongFunctionContext);
+      }
+      int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
+      AssembleDeconstructActivationRecord(stack_param_delta);
+      __ jmp(FieldOperand(func, JSFunction::kCodeEntryOffset));
+      frame_access_state()->ClearSPDelta();
+      break;
+    }
+    case kArchLazyBailout: {
+      EnsureSpaceForLazyDeopt();
+      RecordCallPosition(instr);
+      break;
+    }
+    case kArchPrepareCallCFunction: {
+      // Frame alignment requires using FP-relative frame addressing.
+      frame_access_state()->SetFrameAccessToFP();
+      int const num_parameters = MiscField::decode(instr->opcode());
+      __ PrepareCallCFunction(num_parameters);
+      break;
+    }
+    case kArchPrepareTailCall:
+      AssemblePrepareTailCall(i.InputInt32(instr->InputCount() - 1));
+      break;
+    case kArchCallCFunction: {
+      int const num_parameters = MiscField::decode(instr->opcode());
+      if (HasImmediateInput(instr, 0)) {
+        ExternalReference ref = i.InputExternalReference(0);
+        __ CallCFunction(ref, num_parameters);
+      } else {
+        Register func = i.InputRegister(0);
+        __ CallCFunction(func, num_parameters);
+      }
+      frame_access_state()->SetFrameAccessToDefault();
+      frame_access_state()->ClearSPDelta();
       break;
     }
     case kArchJmp:
       AssembleArchJump(i.InputRpo(0));
       break;
+    case kArchLookupSwitch:
+      AssembleArchLookupSwitch(instr);
+      break;
+    case kArchTableSwitch:
+      AssembleArchTableSwitch(instr);
+      break;
     case kArchNop:
+    case kArchThrowTerminator:
       // don't emit code for nops.
       break;
+    case kArchDeoptimize: {
+      int deopt_state_id =
+          BuildTranslation(instr, -1, 0, OutputFrameStateCombine::Ignore());
+      Deoptimizer::BailoutType bailout_type =
+          Deoptimizer::BailoutType(MiscField::decode(instr->opcode()));
+      AssembleDeoptimizerCall(deopt_state_id, bailout_type);
+      break;
+    }
     case kArchRet:
       AssembleReturn();
       break;
     case kArchStackPointer:
       __ movq(i.OutputRegister(), rsp);
       break;
+    case kArchFramePointer:
+      __ movq(i.OutputRegister(), rbp);
+      break;
     case kArchTruncateDoubleToI: {
       auto result = i.OutputRegister();
       auto input = i.InputDoubleRegister(0);
       auto ool = new (zone()) OutOfLineTruncateDoubleToI(this, result, input);
-      __ cvttsd2siq(result, input);
+      __ Cvttsd2siq(result, input);
       __ cmpq(result, Immediate(1));
       __ j(overflow, ool->entry());
       __ bind(ool->exit());
       break;
     }
+    case kArchStoreWithWriteBarrier: {
+      RecordWriteMode mode =
+          static_cast<RecordWriteMode>(MiscField::decode(instr->opcode()));
+      Register object = i.InputRegister(0);
+      size_t index = 0;
+      Operand operand = i.MemoryOperand(&index);
+      Register value = i.InputRegister(index);
+      Register scratch0 = i.TempRegister(0);
+      Register scratch1 = i.TempRegister(1);
+      auto ool = new (zone()) OutOfLineRecordWrite(this, object, operand, value,
+                                                   scratch0, scratch1, mode);
+      __ movp(operand, value);
+      __ CheckPageFlag(object, scratch0,
+                       MemoryChunk::kPointersFromHereAreInterestingMask,
+                       not_zero, ool->entry());
+      __ bind(ool->exit());
+      break;
+    }
     case kX64Add32:
       ASSEMBLE_BINOP(addl);
       break;
@@ -666,27 +854,123 @@
     case kX64Ror:
       ASSEMBLE_SHIFT(rorq, 6);
       break;
+    case kX64Lzcnt:
+      if (instr->InputAt(0)->IsRegister()) {
+        __ Lzcntq(i.OutputRegister(), i.InputRegister(0));
+      } else {
+        __ Lzcntq(i.OutputRegister(), i.InputOperand(0));
+      }
+      break;
+    case kX64Lzcnt32:
+      if (instr->InputAt(0)->IsRegister()) {
+        __ Lzcntl(i.OutputRegister(), i.InputRegister(0));
+      } else {
+        __ Lzcntl(i.OutputRegister(), i.InputOperand(0));
+      }
+      break;
+    case kX64Tzcnt:
+      if (instr->InputAt(0)->IsRegister()) {
+        __ Tzcntq(i.OutputRegister(), i.InputRegister(0));
+      } else {
+        __ Tzcntq(i.OutputRegister(), i.InputOperand(0));
+      }
+      break;
+    case kX64Tzcnt32:
+      if (instr->InputAt(0)->IsRegister()) {
+        __ Tzcntl(i.OutputRegister(), i.InputRegister(0));
+      } else {
+        __ Tzcntl(i.OutputRegister(), i.InputOperand(0));
+      }
+      break;
+    case kX64Popcnt:
+      if (instr->InputAt(0)->IsRegister()) {
+        __ Popcntq(i.OutputRegister(), i.InputRegister(0));
+      } else {
+        __ Popcntq(i.OutputRegister(), i.InputOperand(0));
+      }
+      break;
+    case kX64Popcnt32:
+      if (instr->InputAt(0)->IsRegister()) {
+        __ Popcntl(i.OutputRegister(), i.InputRegister(0));
+      } else {
+        __ Popcntl(i.OutputRegister(), i.InputOperand(0));
+      }
+      break;
+    case kSSEFloat32Cmp:
+      ASSEMBLE_SSE_BINOP(Ucomiss);
+      break;
+    case kSSEFloat32Add:
+      ASSEMBLE_SSE_BINOP(addss);
+      break;
+    case kSSEFloat32Sub:
+      ASSEMBLE_SSE_BINOP(subss);
+      break;
+    case kSSEFloat32Mul:
+      ASSEMBLE_SSE_BINOP(mulss);
+      break;
+    case kSSEFloat32Div:
+      ASSEMBLE_SSE_BINOP(divss);
+      // Don't delete this mov. It may improve performance on some CPUs,
+      // when there is a (v)mulss depending on the result.
+      __ movaps(i.OutputDoubleRegister(), i.OutputDoubleRegister());
+      break;
+    case kSSEFloat32Abs: {
+      // TODO(bmeurer): Use RIP relative 128-bit constants.
+      __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
+      __ psrlq(kScratchDoubleReg, 33);
+      __ andps(i.OutputDoubleRegister(), kScratchDoubleReg);
+      break;
+    }
+    case kSSEFloat32Neg: {
+      // TODO(bmeurer): Use RIP relative 128-bit constants.
+      __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
+      __ psllq(kScratchDoubleReg, 31);
+      __ xorps(i.OutputDoubleRegister(), kScratchDoubleReg);
+      break;
+    }
+    case kSSEFloat32Sqrt:
+      ASSEMBLE_SSE_UNOP(sqrtss);
+      break;
+    case kSSEFloat32Max:
+      ASSEMBLE_SSE_BINOP(maxss);
+      break;
+    case kSSEFloat32Min:
+      ASSEMBLE_SSE_BINOP(minss);
+      break;
+    case kSSEFloat32ToFloat64:
+      ASSEMBLE_SSE_UNOP(Cvtss2sd);
+      break;
+    case kSSEFloat32Round: {
+      CpuFeatureScope sse_scope(masm(), SSE4_1);
+      RoundingMode const mode =
+          static_cast<RoundingMode>(MiscField::decode(instr->opcode()));
+      __ Roundss(i.OutputDoubleRegister(), i.InputDoubleRegister(0), mode);
+      break;
+    }
     case kSSEFloat64Cmp:
-      ASSEMBLE_DOUBLE_BINOP(ucomisd);
+      ASSEMBLE_SSE_BINOP(Ucomisd);
       break;
     case kSSEFloat64Add:
-      ASSEMBLE_DOUBLE_BINOP(addsd);
+      ASSEMBLE_SSE_BINOP(addsd);
       break;
     case kSSEFloat64Sub:
-      ASSEMBLE_DOUBLE_BINOP(subsd);
+      ASSEMBLE_SSE_BINOP(subsd);
       break;
     case kSSEFloat64Mul:
-      ASSEMBLE_DOUBLE_BINOP(mulsd);
+      ASSEMBLE_SSE_BINOP(mulsd);
       break;
     case kSSEFloat64Div:
-      ASSEMBLE_DOUBLE_BINOP(divsd);
+      ASSEMBLE_SSE_BINOP(divsd);
+      // Don't delete this mov. It may improve performance on some CPUs,
+      // when there is a (v)mulsd depending on the result.
+      __ Movapd(i.OutputDoubleRegister(), i.OutputDoubleRegister());
       break;
     case kSSEFloat64Mod: {
       __ subq(rsp, Immediate(kDoubleSize));
       // Move values to st(0) and st(1).
-      __ movsd(Operand(rsp, 0), i.InputDoubleRegister(1));
+      __ Movsd(Operand(rsp, 0), i.InputDoubleRegister(1));
       __ fld_d(Operand(rsp, 0));
-      __ movsd(Operand(rsp, 0), i.InputDoubleRegister(0));
+      __ Movsd(Operand(rsp, 0), i.InputDoubleRegister(0));
       __ fld_d(Operand(rsp, 0));
       // Loop while fprem isn't done.
       Label mod_loop;
@@ -709,107 +993,411 @@
       // Move output to stack and clean up.
       __ fstp(1);
       __ fstp_d(Operand(rsp, 0));
-      __ movsd(i.OutputDoubleRegister(), Operand(rsp, 0));
+      __ Movsd(i.OutputDoubleRegister(), Operand(rsp, 0));
       __ addq(rsp, Immediate(kDoubleSize));
       break;
     }
+    case kSSEFloat64Max:
+      ASSEMBLE_SSE_BINOP(maxsd);
+      break;
+    case kSSEFloat64Min:
+      ASSEMBLE_SSE_BINOP(minsd);
+      break;
+    case kSSEFloat64Abs: {
+      // TODO(bmeurer): Use RIP relative 128-bit constants.
+      __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
+      __ psrlq(kScratchDoubleReg, 1);
+      __ andpd(i.OutputDoubleRegister(), kScratchDoubleReg);
+      break;
+    }
+    case kSSEFloat64Neg: {
+      // TODO(bmeurer): Use RIP relative 128-bit constants.
+      __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
+      __ psllq(kScratchDoubleReg, 63);
+      __ xorpd(i.OutputDoubleRegister(), kScratchDoubleReg);
+      break;
+    }
     case kSSEFloat64Sqrt:
-      if (instr->InputAt(0)->IsDoubleRegister()) {
-        __ sqrtsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
-      } else {
-        __ sqrtsd(i.OutputDoubleRegister(), i.InputOperand(0));
-      }
+      ASSEMBLE_SSE_UNOP(sqrtsd);
       break;
-    case kSSEFloat64Floor: {
+    case kSSEFloat64Round: {
       CpuFeatureScope sse_scope(masm(), SSE4_1);
-      __ roundsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
-                 v8::internal::Assembler::kRoundDown);
+      RoundingMode const mode =
+          static_cast<RoundingMode>(MiscField::decode(instr->opcode()));
+      __ Roundsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0), mode);
       break;
     }
-    case kSSEFloat64Ceil: {
-      CpuFeatureScope sse_scope(masm(), SSE4_1);
-      __ roundsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
-                 v8::internal::Assembler::kRoundUp);
-      break;
-    }
-    case kSSEFloat64RoundTruncate: {
-      CpuFeatureScope sse_scope(masm(), SSE4_1);
-      __ roundsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
-                 v8::internal::Assembler::kRoundToZero);
-      break;
-    }
-    case kSSECvtss2sd:
-      if (instr->InputAt(0)->IsDoubleRegister()) {
-        __ cvtss2sd(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
-      } else {
-        __ cvtss2sd(i.OutputDoubleRegister(), i.InputOperand(0));
-      }
-      break;
-    case kSSECvtsd2ss:
-      if (instr->InputAt(0)->IsDoubleRegister()) {
-        __ cvtsd2ss(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
-      } else {
-        __ cvtsd2ss(i.OutputDoubleRegister(), i.InputOperand(0));
-      }
+    case kSSEFloat64ToFloat32:
+      ASSEMBLE_SSE_UNOP(Cvtsd2ss);
       break;
     case kSSEFloat64ToInt32:
       if (instr->InputAt(0)->IsDoubleRegister()) {
-        __ cvttsd2si(i.OutputRegister(), i.InputDoubleRegister(0));
+        __ Cvttsd2si(i.OutputRegister(), i.InputDoubleRegister(0));
       } else {
-        __ cvttsd2si(i.OutputRegister(), i.InputOperand(0));
+        __ Cvttsd2si(i.OutputRegister(), i.InputOperand(0));
       }
       break;
     case kSSEFloat64ToUint32: {
       if (instr->InputAt(0)->IsDoubleRegister()) {
-        __ cvttsd2siq(i.OutputRegister(), i.InputDoubleRegister(0));
+        __ Cvttsd2siq(i.OutputRegister(), i.InputDoubleRegister(0));
       } else {
-        __ cvttsd2siq(i.OutputRegister(), i.InputOperand(0));
+        __ Cvttsd2siq(i.OutputRegister(), i.InputOperand(0));
       }
       __ AssertZeroExtended(i.OutputRegister());
       break;
     }
+    case kSSEFloat32ToInt64:
+      if (instr->InputAt(0)->IsDoubleRegister()) {
+        __ Cvttss2siq(i.OutputRegister(), i.InputDoubleRegister(0));
+      } else {
+        __ Cvttss2siq(i.OutputRegister(), i.InputOperand(0));
+      }
+      if (instr->OutputCount() > 1) {
+        __ Set(i.OutputRegister(1), 1);
+        Label done;
+        Label fail;
+        __ Move(kScratchDoubleReg, static_cast<float>(INT64_MIN));
+        if (instr->InputAt(0)->IsDoubleRegister()) {
+          __ Ucomiss(kScratchDoubleReg, i.InputDoubleRegister(0));
+        } else {
+          __ Ucomiss(kScratchDoubleReg, i.InputOperand(0));
+        }
+        // If the input is NaN, then the conversion fails.
+        __ j(parity_even, &fail);
+        // If the input is INT64_MIN, then the conversion succeeds.
+        __ j(equal, &done);
+        __ cmpq(i.OutputRegister(0), Immediate(1));
+        // If the conversion results in INT64_MIN, but the input was not
+        // INT64_MIN, then the conversion fails.
+        __ j(no_overflow, &done);
+        __ bind(&fail);
+        __ Set(i.OutputRegister(1), 0);
+        __ bind(&done);
+      }
+      break;
+    case kSSEFloat64ToInt64:
+      if (instr->InputAt(0)->IsDoubleRegister()) {
+        __ Cvttsd2siq(i.OutputRegister(0), i.InputDoubleRegister(0));
+      } else {
+        __ Cvttsd2siq(i.OutputRegister(0), i.InputOperand(0));
+      }
+      if (instr->OutputCount() > 1) {
+        __ Set(i.OutputRegister(1), 1);
+        Label done;
+        Label fail;
+        __ Move(kScratchDoubleReg, static_cast<double>(INT64_MIN));
+        if (instr->InputAt(0)->IsDoubleRegister()) {
+          __ Ucomisd(kScratchDoubleReg, i.InputDoubleRegister(0));
+        } else {
+          __ Ucomisd(kScratchDoubleReg, i.InputOperand(0));
+        }
+        // If the input is NaN, then the conversion fails.
+        __ j(parity_even, &fail);
+        // If the input is INT64_MIN, then the conversion succeeds.
+        __ j(equal, &done);
+        __ cmpq(i.OutputRegister(0), Immediate(1));
+        // If the conversion results in INT64_MIN, but the input was not
+        // INT64_MIN, then the conversion fails.
+        __ j(no_overflow, &done);
+        __ bind(&fail);
+        __ Set(i.OutputRegister(1), 0);
+        __ bind(&done);
+      }
+      break;
+    case kSSEFloat32ToUint64: {
+      Label done;
+      Label success;
+      if (instr->OutputCount() > 1) {
+        __ Set(i.OutputRegister(1), 0);
+      }
+      // There does not exist a Float32ToUint64 instruction, so we have to use
+      // the Float32ToInt64 instruction.
+      if (instr->InputAt(0)->IsDoubleRegister()) {
+        __ Cvttss2siq(i.OutputRegister(), i.InputDoubleRegister(0));
+      } else {
+        __ Cvttss2siq(i.OutputRegister(), i.InputOperand(0));
+      }
+      // Check if the result of the Float32ToInt64 conversion is positive, we
+      // are already done.
+      __ testq(i.OutputRegister(), i.OutputRegister());
+      __ j(positive, &success);
+      // The result of the first conversion was negative, which means that the
+      // input value was not within the positive int64 range. We subtract 2^64
+      // and convert it again to see if it is within the uint64 range.
+      __ Move(kScratchDoubleReg, -9223372036854775808.0f);
+      if (instr->InputAt(0)->IsDoubleRegister()) {
+        __ addss(kScratchDoubleReg, i.InputDoubleRegister(0));
+      } else {
+        __ addss(kScratchDoubleReg, i.InputOperand(0));
+      }
+      __ Cvttss2siq(i.OutputRegister(), kScratchDoubleReg);
+      __ testq(i.OutputRegister(), i.OutputRegister());
+      // The only possible negative value here is 0x80000000000000000, which is
+      // used on x64 to indicate an integer overflow.
+      __ j(negative, &done);
+      // The input value is within uint64 range and the second conversion worked
+      // successfully, but we still have to undo the subtraction we did
+      // earlier.
+      __ Set(kScratchRegister, 0x8000000000000000);
+      __ orq(i.OutputRegister(), kScratchRegister);
+      __ bind(&success);
+      if (instr->OutputCount() > 1) {
+        __ Set(i.OutputRegister(1), 1);
+      }
+      __ bind(&done);
+      break;
+    }
+    case kSSEFloat64ToUint64: {
+      Label done;
+      Label success;
+      if (instr->OutputCount() > 1) {
+        __ Set(i.OutputRegister(1), 0);
+      }
+      // There does not exist a Float64ToUint64 instruction, so we have to use
+      // the Float64ToInt64 instruction.
+      if (instr->InputAt(0)->IsDoubleRegister()) {
+        __ Cvttsd2siq(i.OutputRegister(), i.InputDoubleRegister(0));
+      } else {
+        __ Cvttsd2siq(i.OutputRegister(), i.InputOperand(0));
+      }
+      // Check if the result of the Float64ToInt64 conversion is positive, we
+      // are already done.
+      __ testq(i.OutputRegister(), i.OutputRegister());
+      __ j(positive, &success);
+      // The result of the first conversion was negative, which means that the
+      // input value was not within the positive int64 range. We subtract 2^64
+      // and convert it again to see if it is within the uint64 range.
+      __ Move(kScratchDoubleReg, -9223372036854775808.0);
+      if (instr->InputAt(0)->IsDoubleRegister()) {
+        __ addsd(kScratchDoubleReg, i.InputDoubleRegister(0));
+      } else {
+        __ addsd(kScratchDoubleReg, i.InputOperand(0));
+      }
+      __ Cvttsd2siq(i.OutputRegister(), kScratchDoubleReg);
+      __ testq(i.OutputRegister(), i.OutputRegister());
+      // The only possible negative value here is 0x80000000000000000, which is
+      // used on x64 to indicate an integer overflow.
+      __ j(negative, &done);
+      // The input value is within uint64 range and the second conversion worked
+      // successfully, but we still have to undo the subtraction we did
+      // earlier.
+      __ Set(kScratchRegister, 0x8000000000000000);
+      __ orq(i.OutputRegister(), kScratchRegister);
+      __ bind(&success);
+      if (instr->OutputCount() > 1) {
+        __ Set(i.OutputRegister(1), 1);
+      }
+      __ bind(&done);
+      break;
+    }
     case kSSEInt32ToFloat64:
       if (instr->InputAt(0)->IsRegister()) {
-        __ cvtlsi2sd(i.OutputDoubleRegister(), i.InputRegister(0));
+        __ Cvtlsi2sd(i.OutputDoubleRegister(), i.InputRegister(0));
       } else {
-        __ cvtlsi2sd(i.OutputDoubleRegister(), i.InputOperand(0));
+        __ Cvtlsi2sd(i.OutputDoubleRegister(), i.InputOperand(0));
       }
       break;
+    case kSSEInt64ToFloat32:
+      if (instr->InputAt(0)->IsRegister()) {
+        __ Cvtqsi2ss(i.OutputDoubleRegister(), i.InputRegister(0));
+      } else {
+        __ Cvtqsi2ss(i.OutputDoubleRegister(), i.InputOperand(0));
+      }
+      break;
+    case kSSEInt64ToFloat64:
+      if (instr->InputAt(0)->IsRegister()) {
+        __ Cvtqsi2sd(i.OutputDoubleRegister(), i.InputRegister(0));
+      } else {
+        __ Cvtqsi2sd(i.OutputDoubleRegister(), i.InputOperand(0));
+      }
+      break;
+    case kSSEUint64ToFloat32:
+      if (instr->InputAt(0)->IsRegister()) {
+        __ movq(kScratchRegister, i.InputRegister(0));
+      } else {
+        __ movq(kScratchRegister, i.InputOperand(0));
+      }
+      __ Cvtqui2ss(i.OutputDoubleRegister(), kScratchRegister,
+                   i.TempRegister(0));
+      break;
+    case kSSEUint64ToFloat64:
+      if (instr->InputAt(0)->IsRegister()) {
+        __ movq(kScratchRegister, i.InputRegister(0));
+      } else {
+        __ movq(kScratchRegister, i.InputOperand(0));
+      }
+      __ Cvtqui2sd(i.OutputDoubleRegister(), kScratchRegister,
+                   i.TempRegister(0));
+      break;
     case kSSEUint32ToFloat64:
       if (instr->InputAt(0)->IsRegister()) {
         __ movl(kScratchRegister, i.InputRegister(0));
       } else {
         __ movl(kScratchRegister, i.InputOperand(0));
       }
-      __ cvtqsi2sd(i.OutputDoubleRegister(), kScratchRegister);
+      __ Cvtqsi2sd(i.OutputDoubleRegister(), kScratchRegister);
       break;
+    case kSSEFloat64ExtractLowWord32:
+      if (instr->InputAt(0)->IsDoubleStackSlot()) {
+        __ movl(i.OutputRegister(), i.InputOperand(0));
+      } else {
+        __ Movd(i.OutputRegister(), i.InputDoubleRegister(0));
+      }
+      break;
+    case kSSEFloat64ExtractHighWord32:
+      if (instr->InputAt(0)->IsDoubleStackSlot()) {
+        __ movl(i.OutputRegister(), i.InputOperand(0, kDoubleSize / 2));
+      } else {
+        __ Pextrd(i.OutputRegister(), i.InputDoubleRegister(0), 1);
+      }
+      break;
+    case kSSEFloat64InsertLowWord32:
+      if (instr->InputAt(1)->IsRegister()) {
+        __ Pinsrd(i.OutputDoubleRegister(), i.InputRegister(1), 0);
+      } else {
+        __ Pinsrd(i.OutputDoubleRegister(), i.InputOperand(1), 0);
+      }
+      break;
+    case kSSEFloat64InsertHighWord32:
+      if (instr->InputAt(1)->IsRegister()) {
+        __ Pinsrd(i.OutputDoubleRegister(), i.InputRegister(1), 1);
+      } else {
+        __ Pinsrd(i.OutputDoubleRegister(), i.InputOperand(1), 1);
+      }
+      break;
+    case kSSEFloat64LoadLowWord32:
+      if (instr->InputAt(0)->IsRegister()) {
+        __ Movd(i.OutputDoubleRegister(), i.InputRegister(0));
+      } else {
+        __ Movd(i.OutputDoubleRegister(), i.InputOperand(0));
+      }
+      break;
+    case kAVXFloat32Cmp: {
+      CpuFeatureScope avx_scope(masm(), AVX);
+      if (instr->InputAt(1)->IsDoubleRegister()) {
+        __ vucomiss(i.InputDoubleRegister(0), i.InputDoubleRegister(1));
+      } else {
+        __ vucomiss(i.InputDoubleRegister(0), i.InputOperand(1));
+      }
+      break;
+    }
+    case kAVXFloat32Add:
+      ASSEMBLE_AVX_BINOP(vaddss);
+      break;
+    case kAVXFloat32Sub:
+      ASSEMBLE_AVX_BINOP(vsubss);
+      break;
+    case kAVXFloat32Mul:
+      ASSEMBLE_AVX_BINOP(vmulss);
+      break;
+    case kAVXFloat32Div:
+      ASSEMBLE_AVX_BINOP(vdivss);
+      // Don't delete this mov. It may improve performance on some CPUs,
+      // when there is a (v)mulss depending on the result.
+      __ Movaps(i.OutputDoubleRegister(), i.OutputDoubleRegister());
+      break;
+    case kAVXFloat32Max:
+      ASSEMBLE_AVX_BINOP(vmaxss);
+      break;
+    case kAVXFloat32Min:
+      ASSEMBLE_AVX_BINOP(vminss);
+      break;
+    case kAVXFloat64Cmp: {
+      CpuFeatureScope avx_scope(masm(), AVX);
+      if (instr->InputAt(1)->IsDoubleRegister()) {
+        __ vucomisd(i.InputDoubleRegister(0), i.InputDoubleRegister(1));
+      } else {
+        __ vucomisd(i.InputDoubleRegister(0), i.InputOperand(1));
+      }
+      break;
+    }
     case kAVXFloat64Add:
-      ASSEMBLE_AVX_DOUBLE_BINOP(vaddsd);
+      ASSEMBLE_AVX_BINOP(vaddsd);
       break;
     case kAVXFloat64Sub:
-      ASSEMBLE_AVX_DOUBLE_BINOP(vsubsd);
+      ASSEMBLE_AVX_BINOP(vsubsd);
       break;
     case kAVXFloat64Mul:
-      ASSEMBLE_AVX_DOUBLE_BINOP(vmulsd);
+      ASSEMBLE_AVX_BINOP(vmulsd);
       break;
     case kAVXFloat64Div:
-      ASSEMBLE_AVX_DOUBLE_BINOP(vdivsd);
+      ASSEMBLE_AVX_BINOP(vdivsd);
+      // Don't delete this mov. It may improve performance on some CPUs,
+      // when there is a (v)mulsd depending on the result.
+      __ Movapd(i.OutputDoubleRegister(), i.OutputDoubleRegister());
       break;
-    case kX64Movsxbl:
-      if (instr->addressing_mode() != kMode_None) {
-        __ movsxbl(i.OutputRegister(), i.MemoryOperand());
-      } else if (instr->InputAt(0)->IsRegister()) {
-        __ movsxbl(i.OutputRegister(), i.InputRegister(0));
+    case kAVXFloat64Max:
+      ASSEMBLE_AVX_BINOP(vmaxsd);
+      break;
+    case kAVXFloat64Min:
+      ASSEMBLE_AVX_BINOP(vminsd);
+      break;
+    case kAVXFloat32Abs: {
+      // TODO(bmeurer): Use RIP relative 128-bit constants.
+      CpuFeatureScope avx_scope(masm(), AVX);
+      __ vpcmpeqd(kScratchDoubleReg, kScratchDoubleReg, kScratchDoubleReg);
+      __ vpsrlq(kScratchDoubleReg, kScratchDoubleReg, 33);
+      if (instr->InputAt(0)->IsDoubleRegister()) {
+        __ vandps(i.OutputDoubleRegister(), kScratchDoubleReg,
+                  i.InputDoubleRegister(0));
       } else {
-        __ movsxbl(i.OutputRegister(), i.InputOperand(0));
+        __ vandps(i.OutputDoubleRegister(), kScratchDoubleReg,
+                  i.InputOperand(0));
       }
+      break;
+    }
+    case kAVXFloat32Neg: {
+      // TODO(bmeurer): Use RIP relative 128-bit constants.
+      CpuFeatureScope avx_scope(masm(), AVX);
+      __ vpcmpeqd(kScratchDoubleReg, kScratchDoubleReg, kScratchDoubleReg);
+      __ vpsllq(kScratchDoubleReg, kScratchDoubleReg, 31);
+      if (instr->InputAt(0)->IsDoubleRegister()) {
+        __ vxorps(i.OutputDoubleRegister(), kScratchDoubleReg,
+                  i.InputDoubleRegister(0));
+      } else {
+        __ vxorps(i.OutputDoubleRegister(), kScratchDoubleReg,
+                  i.InputOperand(0));
+      }
+      break;
+    }
+    case kAVXFloat64Abs: {
+      // TODO(bmeurer): Use RIP relative 128-bit constants.
+      CpuFeatureScope avx_scope(masm(), AVX);
+      __ vpcmpeqd(kScratchDoubleReg, kScratchDoubleReg, kScratchDoubleReg);
+      __ vpsrlq(kScratchDoubleReg, kScratchDoubleReg, 1);
+      if (instr->InputAt(0)->IsDoubleRegister()) {
+        __ vandpd(i.OutputDoubleRegister(), kScratchDoubleReg,
+                  i.InputDoubleRegister(0));
+      } else {
+        __ vandpd(i.OutputDoubleRegister(), kScratchDoubleReg,
+                  i.InputOperand(0));
+      }
+      break;
+    }
+    case kAVXFloat64Neg: {
+      // TODO(bmeurer): Use RIP relative 128-bit constants.
+      CpuFeatureScope avx_scope(masm(), AVX);
+      __ vpcmpeqd(kScratchDoubleReg, kScratchDoubleReg, kScratchDoubleReg);
+      __ vpsllq(kScratchDoubleReg, kScratchDoubleReg, 63);
+      if (instr->InputAt(0)->IsDoubleRegister()) {
+        __ vxorpd(i.OutputDoubleRegister(), kScratchDoubleReg,
+                  i.InputDoubleRegister(0));
+      } else {
+        __ vxorpd(i.OutputDoubleRegister(), kScratchDoubleReg,
+                  i.InputOperand(0));
+      }
+      break;
+    }
+    case kX64Movsxbl:
+      ASSEMBLE_MOVX(movsxbl);
       __ AssertZeroExtended(i.OutputRegister());
       break;
     case kX64Movzxbl:
-      __ movzxbl(i.OutputRegister(), i.MemoryOperand());
+      ASSEMBLE_MOVX(movzxbl);
+      __ AssertZeroExtended(i.OutputRegister());
       break;
     case kX64Movb: {
-      int index = 0;
+      size_t index = 0;
       Operand operand = i.MemoryOperand(&index);
       if (HasImmediateInput(instr, index)) {
         __ movb(operand, Immediate(i.InputInt8(index)));
@@ -819,21 +1407,15 @@
       break;
     }
     case kX64Movsxwl:
-      if (instr->addressing_mode() != kMode_None) {
-        __ movsxwl(i.OutputRegister(), i.MemoryOperand());
-      } else if (instr->InputAt(0)->IsRegister()) {
-        __ movsxwl(i.OutputRegister(), i.InputRegister(0));
-      } else {
-        __ movsxwl(i.OutputRegister(), i.InputOperand(0));
-      }
+      ASSEMBLE_MOVX(movsxwl);
       __ AssertZeroExtended(i.OutputRegister());
       break;
     case kX64Movzxwl:
-      __ movzxwl(i.OutputRegister(), i.MemoryOperand());
+      ASSEMBLE_MOVX(movzxwl);
       __ AssertZeroExtended(i.OutputRegister());
       break;
     case kX64Movw: {
-      int index = 0;
+      size_t index = 0;
       Operand operand = i.MemoryOperand(&index);
       if (HasImmediateInput(instr, index)) {
         __ movw(operand, Immediate(i.InputInt16(index)));
@@ -855,7 +1437,7 @@
         }
         __ AssertZeroExtended(i.OutputRegister());
       } else {
-        int index = 0;
+        size_t index = 0;
         Operand operand = i.MemoryOperand(&index);
         if (HasImmediateInput(instr, index)) {
           __ movl(operand, i.InputImmediate(index));
@@ -864,19 +1446,14 @@
         }
       }
       break;
-    case kX64Movsxlq: {
-      if (instr->InputAt(0)->IsRegister()) {
-        __ movsxlq(i.OutputRegister(), i.InputRegister(0));
-      } else {
-        __ movsxlq(i.OutputRegister(), i.InputOperand(0));
-      }
+    case kX64Movsxlq:
+      ASSEMBLE_MOVX(movsxlq);
       break;
-    }
     case kX64Movq:
       if (instr->HasOutput()) {
         __ movq(i.OutputRegister(), i.MemoryOperand());
       } else {
-        int index = 0;
+        size_t index = 0;
         Operand operand = i.MemoryOperand(&index);
         if (HasImmediateInput(instr, index)) {
           __ movq(operand, i.InputImmediate(index));
@@ -889,18 +1466,46 @@
       if (instr->HasOutput()) {
         __ movss(i.OutputDoubleRegister(), i.MemoryOperand());
       } else {
-        int index = 0;
+        size_t index = 0;
         Operand operand = i.MemoryOperand(&index);
         __ movss(operand, i.InputDoubleRegister(index));
       }
       break;
     case kX64Movsd:
       if (instr->HasOutput()) {
-        __ movsd(i.OutputDoubleRegister(), i.MemoryOperand());
+        __ Movsd(i.OutputDoubleRegister(), i.MemoryOperand());
       } else {
-        int index = 0;
+        size_t index = 0;
         Operand operand = i.MemoryOperand(&index);
-        __ movsd(operand, i.InputDoubleRegister(index));
+        __ Movsd(operand, i.InputDoubleRegister(index));
+      }
+      break;
+    case kX64BitcastFI:
+      if (instr->InputAt(0)->IsDoubleStackSlot()) {
+        __ movl(i.OutputRegister(), i.InputOperand(0));
+      } else {
+        __ Movd(i.OutputRegister(), i.InputDoubleRegister(0));
+      }
+      break;
+    case kX64BitcastDL:
+      if (instr->InputAt(0)->IsDoubleStackSlot()) {
+        __ movq(i.OutputRegister(), i.InputOperand(0));
+      } else {
+        __ Movq(i.OutputRegister(), i.InputDoubleRegister(0));
+      }
+      break;
+    case kX64BitcastIF:
+      if (instr->InputAt(0)->IsRegister()) {
+        __ Movd(i.OutputDoubleRegister(), i.InputRegister(0));
+      } else {
+        __ movss(i.OutputDoubleRegister(), i.InputOperand(0));
+      }
+      break;
+    case kX64BitcastLD:
+      if (instr->InputAt(0)->IsRegister()) {
+        __ Movq(i.OutputDoubleRegister(), i.InputRegister(0));
+      } else {
+        __ Movsd(i.OutputDoubleRegister(), i.InputOperand(0));
       }
       break;
     case kX64Lea32: {
@@ -949,24 +1554,29 @@
     case kX64Push:
       if (HasImmediateInput(instr, 0)) {
         __ pushq(i.InputImmediate(0));
+        frame_access_state()->IncreaseSPDelta(1);
       } else {
         if (instr->InputAt(0)->IsRegister()) {
           __ pushq(i.InputRegister(0));
+          frame_access_state()->IncreaseSPDelta(1);
+        } else if (instr->InputAt(0)->IsDoubleRegister()) {
+          // TODO(titzer): use another machine instruction?
+          __ subq(rsp, Immediate(kDoubleSize));
+          frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize);
+          __ Movsd(Operand(rsp, 0), i.InputDoubleRegister(0));
         } else {
           __ pushq(i.InputOperand(0));
+          frame_access_state()->IncreaseSPDelta(1);
         }
       }
       break;
-    case kX64StoreWriteBarrier: {
-      Register object = i.InputRegister(0);
-      Register index = i.InputRegister(1);
-      Register value = i.InputRegister(2);
-      __ movsxlq(index, index);
-      __ movq(Operand(object, index, times_1, 0), value);
-      __ leaq(index, Operand(object, index, times_1, 0));
-      SaveFPRegsMode mode =
-          frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs;
-      __ RecordWrite(object, index, value, mode);
+    case kX64Poke: {
+      int const slot = MiscField::decode(instr->opcode());
+      if (HasImmediateInput(instr, 0)) {
+        __ movq(Operand(rsp, slot * kPointerSize), i.InputImmediate(0));
+      } else {
+        __ movq(Operand(rsp, slot * kPointerSize), i.InputRegister(0));
+      }
       break;
     }
     case kCheckedLoadInt8:
@@ -984,11 +1594,14 @@
     case kCheckedLoadWord32:
       ASSEMBLE_CHECKED_LOAD_INTEGER(movl);
       break;
+    case kCheckedLoadWord64:
+      ASSEMBLE_CHECKED_LOAD_INTEGER(movq);
+      break;
     case kCheckedLoadFloat32:
-      ASSEMBLE_CHECKED_LOAD_FLOAT(movss);
+      ASSEMBLE_CHECKED_LOAD_FLOAT(Movss);
       break;
     case kCheckedLoadFloat64:
-      ASSEMBLE_CHECKED_LOAD_FLOAT(movsd);
+      ASSEMBLE_CHECKED_LOAD_FLOAT(Movsd);
       break;
     case kCheckedStoreWord8:
       ASSEMBLE_CHECKED_STORE_INTEGER(movb);
@@ -999,14 +1612,20 @@
     case kCheckedStoreWord32:
       ASSEMBLE_CHECKED_STORE_INTEGER(movl);
       break;
+    case kCheckedStoreWord64:
+      ASSEMBLE_CHECKED_STORE_INTEGER(movq);
+      break;
     case kCheckedStoreFloat32:
-      ASSEMBLE_CHECKED_STORE_FLOAT(movss);
+      ASSEMBLE_CHECKED_STORE_FLOAT(Movss);
       break;
     case kCheckedStoreFloat64:
-      ASSEMBLE_CHECKED_STORE_FLOAT(movsd);
+      ASSEMBLE_CHECKED_STORE_FLOAT(Movsd);
+      break;
+    case kX64StackCheck:
+      __ CompareRoot(rsp, Heap::kStackLimitRootIndex);
       break;
   }
-}
+}  // NOLINT(readability/fn_size)
 
 
 // Assembles branches after this instruction.
@@ -1041,27 +1660,15 @@
     case kSignedGreaterThan:
       __ j(greater, tlabel);
       break;
-    case kUnorderedLessThan:
-      __ j(parity_even, flabel, flabel_distance);
-    // Fall through.
     case kUnsignedLessThan:
       __ j(below, tlabel);
       break;
-    case kUnorderedGreaterThanOrEqual:
-      __ j(parity_even, tlabel);
-    // Fall through.
     case kUnsignedGreaterThanOrEqual:
       __ j(above_equal, tlabel);
       break;
-    case kUnorderedLessThanOrEqual:
-      __ j(parity_even, flabel, flabel_distance);
-    // Fall through.
     case kUnsignedLessThanOrEqual:
       __ j(below_equal, tlabel);
       break;
-    case kUnorderedGreaterThan:
-      __ j(parity_even, tlabel);
-    // Fall through.
     case kUnsignedGreaterThan:
       __ j(above, tlabel);
       break;
@@ -1071,12 +1678,15 @@
     case kNotOverflow:
       __ j(no_overflow, tlabel);
       break;
+    default:
+      UNREACHABLE();
+      break;
   }
   if (!branch->fallthru) __ jmp(flabel, flabel_distance);
 }
 
 
-void CodeGenerator::AssembleArchJump(BasicBlock::RpoNumber target) {
+void CodeGenerator::AssembleArchJump(RpoNumber target) {
   if (!IsNextInAssemblyOrder(target)) __ jmp(GetLabel(target));
 }
 
@@ -1090,8 +1700,8 @@
   // Materialize a full 64-bit 1 or 0 value. The result register is always the
   // last output of the instruction.
   Label check;
-  DCHECK_NE(0, static_cast<int>(instr->OutputCount()));
-  Register reg = i.OutputRegister(static_cast<int>(instr->OutputCount() - 1));
+  DCHECK_NE(0u, instr->OutputCount());
+  Register reg = i.OutputRegister(instr->OutputCount() - 1);
   Condition cc = no_condition;
   switch (condition) {
     case kUnorderedEqual:
@@ -1122,35 +1732,15 @@
     case kSignedGreaterThan:
       cc = greater;
       break;
-    case kUnorderedLessThan:
-      __ j(parity_odd, &check, Label::kNear);
-      __ movl(reg, Immediate(0));
-      __ jmp(&done, Label::kNear);
-    // Fall through.
     case kUnsignedLessThan:
       cc = below;
       break;
-    case kUnorderedGreaterThanOrEqual:
-      __ j(parity_odd, &check, Label::kNear);
-      __ movl(reg, Immediate(1));
-      __ jmp(&done, Label::kNear);
-    // Fall through.
     case kUnsignedGreaterThanOrEqual:
       cc = above_equal;
       break;
-    case kUnorderedLessThanOrEqual:
-      __ j(parity_odd, &check, Label::kNear);
-      __ movl(reg, Immediate(0));
-      __ jmp(&done, Label::kNear);
-    // Fall through.
     case kUnsignedLessThanOrEqual:
       cc = below_equal;
       break;
-    case kUnorderedGreaterThan:
-      __ j(parity_odd, &check, Label::kNear);
-      __ movl(reg, Immediate(1));
-      __ jmp(&done, Label::kNear);
-    // Fall through.
     case kUnsignedGreaterThan:
       cc = above;
       break;
@@ -1160,6 +1750,9 @@
     case kNotOverflow:
       cc = no_overflow;
       break;
+    default:
+      UNREACHABLE();
+      break;
   }
   __ bind(&check);
   __ setcc(cc, reg);
@@ -1168,84 +1761,166 @@
 }
 
 
-void CodeGenerator::AssembleDeoptimizerCall(int deoptimization_id) {
+void CodeGenerator::AssembleArchLookupSwitch(Instruction* instr) {
+  X64OperandConverter i(this, instr);
+  Register input = i.InputRegister(0);
+  for (size_t index = 2; index < instr->InputCount(); index += 2) {
+    __ cmpl(input, Immediate(i.InputInt32(index + 0)));
+    __ j(equal, GetLabel(i.InputRpo(index + 1)));
+  }
+  AssembleArchJump(i.InputRpo(1));
+}
+
+
+void CodeGenerator::AssembleArchTableSwitch(Instruction* instr) {
+  X64OperandConverter i(this, instr);
+  Register input = i.InputRegister(0);
+  int32_t const case_count = static_cast<int32_t>(instr->InputCount() - 2);
+  Label** cases = zone()->NewArray<Label*>(case_count);
+  for (int32_t index = 0; index < case_count; ++index) {
+    cases[index] = GetLabel(i.InputRpo(index + 2));
+  }
+  Label* const table = AddJumpTable(cases, case_count);
+  __ cmpl(input, Immediate(case_count));
+  __ j(above_equal, GetLabel(i.InputRpo(1)));
+  __ leaq(kScratchRegister, Operand(table));
+  __ jmp(Operand(kScratchRegister, input, times_8, 0));
+}
+
+
+void CodeGenerator::AssembleDeoptimizerCall(
+    int deoptimization_id, Deoptimizer::BailoutType bailout_type) {
   Address deopt_entry = Deoptimizer::GetDeoptimizationEntry(
-      isolate(), deoptimization_id, Deoptimizer::LAZY);
+      isolate(), deoptimization_id, bailout_type);
   __ call(deopt_entry, RelocInfo::RUNTIME_ENTRY);
 }
 
 
+namespace {
+
+static const int kQuadWordSize = 16;
+
+}  // namespace
+
+
 void CodeGenerator::AssemblePrologue() {
   CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
-  int stack_slots = frame()->GetSpillSlotCount();
-  if (descriptor->kind() == CallDescriptor::kCallAddress) {
+  if (descriptor->IsCFunctionCall()) {
     __ pushq(rbp);
     __ movq(rbp, rsp);
-    const RegList saves = descriptor->CalleeSavedRegisters();
-    if (saves != 0) {  // Save callee-saved registers.
-      int register_save_area_size = 0;
-      for (int i = Register::kNumRegisters - 1; i >= 0; i--) {
-        if (!((1 << i) & saves)) continue;
-        __ pushq(Register::from_code(i));
-        register_save_area_size += kPointerSize;
-      }
-      frame()->SetRegisterSaveAreaSize(register_save_area_size);
-    }
   } else if (descriptor->IsJSFunctionCall()) {
-    CompilationInfo* info = this->info();
-    __ Prologue(info->IsCodePreAgingActive());
-    frame()->SetRegisterSaveAreaSize(
-        StandardFrameConstants::kFixedFrameSizeFromFp);
-  } else {
+    __ Prologue(this->info()->GeneratePreagedPrologue());
+  } else if (frame()->needs_frame()) {
     __ StubPrologue();
-    frame()->SetRegisterSaveAreaSize(
-        StandardFrameConstants::kFixedFrameSizeFromFp);
+  } else {
+    frame()->SetElidedFrameSizeInSlots(kPCOnStackSize / kPointerSize);
   }
-  if (stack_slots > 0) {
-    __ subq(rsp, Immediate(stack_slots * kPointerSize));
+  frame_access_state()->SetFrameAccessToDefault();
+
+  int stack_shrink_slots = frame()->GetSpillSlotCount();
+  if (info()->is_osr()) {
+    // TurboFan OSR-compiled functions cannot be entered directly.
+    __ Abort(kShouldNotDirectlyEnterOsrFunction);
+
+    // Unoptimized code jumps directly to this entrypoint while the unoptimized
+    // frame is still on the stack. Optimized code uses OSR values directly from
+    // the unoptimized frame. Thus, all that needs to be done is to allocate the
+    // remaining stack slots.
+    if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --");
+    osr_pc_offset_ = __ pc_offset();
+    // TODO(titzer): cannot address target function == local #-1
+    __ movq(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
+    stack_shrink_slots -=
+        static_cast<int>(OsrHelper(info()).UnoptimizedFrameSlots());
+  }
+
+  const RegList saves_fp = descriptor->CalleeSavedFPRegisters();
+  if (saves_fp != 0) {
+    stack_shrink_slots += frame()->AlignSavedCalleeRegisterSlots();
+  }
+  if (stack_shrink_slots > 0) {
+    __ subq(rsp, Immediate(stack_shrink_slots * kPointerSize));
+  }
+
+  if (saves_fp != 0) {  // Save callee-saved XMM registers.
+    const uint32_t saves_fp_count = base::bits::CountPopulation32(saves_fp);
+    const int stack_size = saves_fp_count * kQuadWordSize;
+    // Adjust the stack pointer.
+    __ subp(rsp, Immediate(stack_size));
+    // Store the registers on the stack.
+    int slot_idx = 0;
+    for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) {
+      if (!((1 << i) & saves_fp)) continue;
+      __ movdqu(Operand(rsp, kQuadWordSize * slot_idx),
+                XMMRegister::from_code(i));
+      slot_idx++;
+    }
+    frame()->AllocateSavedCalleeRegisterSlots(saves_fp_count *
+                                              (kQuadWordSize / kPointerSize));
+  }
+
+  const RegList saves = descriptor->CalleeSavedRegisters();
+  if (saves != 0) {  // Save callee-saved registers.
+    for (int i = Register::kNumRegisters - 1; i >= 0; i--) {
+      if (!((1 << i) & saves)) continue;
+      __ pushq(Register::from_code(i));
+      frame()->AllocateSavedCalleeRegisterSlots(1);
+    }
   }
 }
 
 
 void CodeGenerator::AssembleReturn() {
   CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
-  if (descriptor->kind() == CallDescriptor::kCallAddress) {
-    if (frame()->GetRegisterSaveAreaSize() > 0) {
-      // Remove this frame's spill slots first.
-      int stack_slots = frame()->GetSpillSlotCount();
-      if (stack_slots > 0) {
-        __ addq(rsp, Immediate(stack_slots * kPointerSize));
-      }
-      const RegList saves = descriptor->CalleeSavedRegisters();
-      // Restore registers.
-      if (saves != 0) {
-        for (int i = 0; i < Register::kNumRegisters; i++) {
-          if (!((1 << i) & saves)) continue;
-          __ popq(Register::from_code(i));
-        }
-      }
-      __ popq(rbp);  // Pop caller's frame pointer.
-      __ ret(0);
-    } else {
-      // No saved registers.
-      __ movq(rsp, rbp);  // Move stack pointer back to frame pointer.
-      __ popq(rbp);       // Pop caller's frame pointer.
-      __ ret(0);
+
+  // Restore registers.
+  const RegList saves = descriptor->CalleeSavedRegisters();
+  if (saves != 0) {
+    for (int i = 0; i < Register::kNumRegisters; i++) {
+      if (!((1 << i) & saves)) continue;
+      __ popq(Register::from_code(i));
     }
-  } else {
+  }
+  const RegList saves_fp = descriptor->CalleeSavedFPRegisters();
+  if (saves_fp != 0) {
+    const uint32_t saves_fp_count = base::bits::CountPopulation32(saves_fp);
+    const int stack_size = saves_fp_count * kQuadWordSize;
+    // Load the registers from the stack.
+    int slot_idx = 0;
+    for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) {
+      if (!((1 << i) & saves_fp)) continue;
+      __ movdqu(XMMRegister::from_code(i),
+                Operand(rsp, kQuadWordSize * slot_idx));
+      slot_idx++;
+    }
+    // Adjust the stack pointer.
+    __ addp(rsp, Immediate(stack_size));
+  }
+
+  if (descriptor->IsCFunctionCall()) {
     __ movq(rsp, rbp);  // Move stack pointer back to frame pointer.
     __ popq(rbp);       // Pop caller's frame pointer.
-    int pop_count = descriptor->IsJSFunctionCall()
-                        ? static_cast<int>(descriptor->JSParameterCount())
-                        : 0;
-    __ ret(pop_count * kPointerSize);
+  } else if (frame()->needs_frame()) {
+    // Canonicalize JSFunction return sites for now.
+    if (return_label_.is_bound()) {
+      __ jmp(&return_label_);
+      return;
+    } else {
+      __ bind(&return_label_);
+      __ movq(rsp, rbp);  // Move stack pointer back to frame pointer.
+      __ popq(rbp);       // Pop caller's frame pointer.
+    }
   }
+  size_t pop_size = descriptor->StackParameterCount() * kPointerSize;
+  // Might need rcx for scratch if pop_size is too big.
+  DCHECK_EQ(0u, descriptor->CalleeSavedRegisters() & rcx.bit());
+  __ Ret(static_cast<int>(pop_size), rcx);
 }
 
 
 void CodeGenerator::AssembleMove(InstructionOperand* source,
                                  InstructionOperand* destination) {
-  X64OperandConverter g(this, NULL);
+  X64OperandConverter g(this, nullptr);
   // Dispatch on the source and destination operand kinds.  Not all
   // combinations are possible.
   if (source->IsRegister()) {
@@ -1295,9 +1970,19 @@
         case Constant::kExternalReference:
           __ Move(dst, src.ToExternalReference());
           break;
-        case Constant::kHeapObject:
-          __ Move(dst, src.ToHeapObject());
+        case Constant::kHeapObject: {
+          Handle<HeapObject> src_object = src.ToHeapObject();
+          Heap::RootListIndex index;
+          int offset;
+          if (IsMaterializableFromFrame(src_object, &offset)) {
+            __ movp(dst, Operand(rbp, offset));
+          } else if (IsMaterializableFromRoot(src_object, &index)) {
+            __ LoadRoot(dst, index);
+          } else {
+            __ Move(dst, src_object);
+          }
           break;
+        }
         case Constant::kRpoNumber:
           UNREACHABLE();  // TODO(dcarney): load of labels on x64.
           break;
@@ -1330,23 +2015,23 @@
     XMMRegister src = g.ToDoubleRegister(source);
     if (destination->IsDoubleRegister()) {
       XMMRegister dst = g.ToDoubleRegister(destination);
-      __ movsd(dst, src);
+      __ Movapd(dst, src);
     } else {
       DCHECK(destination->IsDoubleStackSlot());
       Operand dst = g.ToOperand(destination);
-      __ movsd(dst, src);
+      __ Movsd(dst, src);
     }
   } else if (source->IsDoubleStackSlot()) {
     DCHECK(destination->IsDoubleRegister() || destination->IsDoubleStackSlot());
     Operand src = g.ToOperand(source);
     if (destination->IsDoubleRegister()) {
       XMMRegister dst = g.ToDoubleRegister(destination);
-      __ movsd(dst, src);
+      __ Movsd(dst, src);
     } else {
       // We rely on having xmm0 available as a fixed scratch register.
       Operand dst = g.ToOperand(destination);
-      __ movsd(xmm0, src);
-      __ movsd(dst, xmm0);
+      __ Movsd(xmm0, src);
+      __ Movsd(dst, xmm0);
     }
   } else {
     UNREACHABLE();
@@ -1356,16 +2041,25 @@
 
 void CodeGenerator::AssembleSwap(InstructionOperand* source,
                                  InstructionOperand* destination) {
-  X64OperandConverter g(this, NULL);
+  X64OperandConverter g(this, nullptr);
   // Dispatch on the source and destination operand kinds.  Not all
   // combinations are possible.
   if (source->IsRegister() && destination->IsRegister()) {
     // Register-register.
-    __ xchgq(g.ToRegister(source), g.ToRegister(destination));
+    Register src = g.ToRegister(source);
+    Register dst = g.ToRegister(destination);
+    __ movq(kScratchRegister, src);
+    __ movq(src, dst);
+    __ movq(dst, kScratchRegister);
   } else if (source->IsRegister() && destination->IsStackSlot()) {
     Register src = g.ToRegister(source);
+    __ pushq(src);
+    frame_access_state()->IncreaseSPDelta(1);
     Operand dst = g.ToOperand(destination);
-    __ xchgq(src, dst);
+    __ movq(src, dst);
+    frame_access_state()->IncreaseSPDelta(-1);
+    dst = g.ToOperand(destination);
+    __ popq(dst);
   } else if ((source->IsStackSlot() && destination->IsStackSlot()) ||
              (source->IsDoubleStackSlot() &&
               destination->IsDoubleStackSlot())) {
@@ -1374,24 +2068,29 @@
     Operand src = g.ToOperand(source);
     Operand dst = g.ToOperand(destination);
     __ movq(tmp, dst);
-    __ xchgq(tmp, src);
-    __ movq(dst, tmp);
+    __ pushq(src);
+    frame_access_state()->IncreaseSPDelta(1);
+    src = g.ToOperand(source);
+    __ movq(src, tmp);
+    frame_access_state()->IncreaseSPDelta(-1);
+    dst = g.ToOperand(destination);
+    __ popq(dst);
   } else if (source->IsDoubleRegister() && destination->IsDoubleRegister()) {
     // XMM register-register swap. We rely on having xmm0
     // available as a fixed scratch register.
     XMMRegister src = g.ToDoubleRegister(source);
     XMMRegister dst = g.ToDoubleRegister(destination);
-    __ movsd(xmm0, src);
-    __ movsd(src, dst);
-    __ movsd(dst, xmm0);
+    __ Movapd(xmm0, src);
+    __ Movapd(src, dst);
+    __ Movapd(dst, xmm0);
   } else if (source->IsDoubleRegister() && destination->IsDoubleStackSlot()) {
     // XMM register-memory swap.  We rely on having xmm0
     // available as a fixed scratch register.
     XMMRegister src = g.ToDoubleRegister(source);
     Operand dst = g.ToOperand(destination);
-    __ movsd(xmm0, src);
-    __ movsd(src, dst);
-    __ movsd(dst, xmm0);
+    __ Movsd(xmm0, src);
+    __ Movsd(src, dst);
+    __ Movsd(dst, xmm0);
   } else {
     // No other combinations are possible.
     UNREACHABLE();
@@ -1399,25 +2098,33 @@
 }
 
 
+void CodeGenerator::AssembleJumpTable(Label** targets, size_t target_count) {
+  for (size_t index = 0; index < target_count; ++index) {
+    __ dq(targets[index]);
+  }
+}
+
+
 void CodeGenerator::AddNopForSmiCodeInlining() { __ nop(); }
 
 
 void CodeGenerator::EnsureSpaceForLazyDeopt() {
-  int space_needed = Deoptimizer::patch_size();
-  if (!info()->IsStub()) {
-    // Ensure that we have enough space after the previous lazy-bailout
-    // instruction for patching the code here.
-    int current_pc = masm()->pc_offset();
-    if (current_pc < last_lazy_deopt_pc_ + space_needed) {
-      int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc;
-      __ Nop(padding_size);
-    }
+  if (!info()->ShouldEnsureSpaceForLazyDeopt()) {
+    return;
   }
-  MarkLazyDeoptSite();
+
+  int space_needed = Deoptimizer::patch_size();
+  // Ensure that we have enough space after the previous lazy-bailout
+  // instruction for patching the code here.
+  int current_pc = masm()->pc_offset();
+  if (current_pc < last_lazy_deopt_pc_ + space_needed) {
+    int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc;
+    __ Nop(padding_size);
+  }
 }
 
 #undef __
 
-}  // namespace internal
 }  // namespace compiler
+}  // namespace internal
 }  // namespace v8
diff --git a/src/compiler/x64/instruction-codes-x64.h b/src/compiler/x64/instruction-codes-x64.h
index 77e3e52..8e8e765 100644
--- a/src/compiler/x64/instruction-codes-x64.h
+++ b/src/compiler/x64/instruction-codes-x64.h
@@ -46,26 +46,72 @@
   V(X64Sar32)                      \
   V(X64Ror)                        \
   V(X64Ror32)                      \
+  V(X64Lzcnt)                      \
+  V(X64Lzcnt32)                    \
+  V(X64Tzcnt)                      \
+  V(X64Tzcnt32)                    \
+  V(X64Popcnt)                     \
+  V(X64Popcnt32)                   \
+  V(SSEFloat32Cmp)                 \
+  V(SSEFloat32Add)                 \
+  V(SSEFloat32Sub)                 \
+  V(SSEFloat32Mul)                 \
+  V(SSEFloat32Div)                 \
+  V(SSEFloat32Abs)                 \
+  V(SSEFloat32Neg)                 \
+  V(SSEFloat32Sqrt)                \
+  V(SSEFloat32Max)                 \
+  V(SSEFloat32Min)                 \
+  V(SSEFloat32ToFloat64)           \
+  V(SSEFloat32Round)               \
   V(SSEFloat64Cmp)                 \
   V(SSEFloat64Add)                 \
   V(SSEFloat64Sub)                 \
   V(SSEFloat64Mul)                 \
   V(SSEFloat64Div)                 \
   V(SSEFloat64Mod)                 \
+  V(SSEFloat64Abs)                 \
+  V(SSEFloat64Neg)                 \
   V(SSEFloat64Sqrt)                \
-  V(SSEFloat64Floor)               \
-  V(SSEFloat64Ceil)                \
-  V(SSEFloat64RoundTruncate)       \
-  V(SSECvtss2sd)                   \
-  V(SSECvtsd2ss)                   \
+  V(SSEFloat64Round)               \
+  V(SSEFloat64Max)                 \
+  V(SSEFloat64Min)                 \
+  V(SSEFloat64ToFloat32)           \
   V(SSEFloat64ToInt32)             \
   V(SSEFloat64ToUint32)            \
+  V(SSEFloat32ToInt64)             \
+  V(SSEFloat64ToInt64)             \
+  V(SSEFloat32ToUint64)            \
+  V(SSEFloat64ToUint64)            \
   V(SSEInt32ToFloat64)             \
+  V(SSEInt64ToFloat32)             \
+  V(SSEInt64ToFloat64)             \
+  V(SSEUint64ToFloat32)            \
+  V(SSEUint64ToFloat64)            \
   V(SSEUint32ToFloat64)            \
+  V(SSEFloat64ExtractLowWord32)    \
+  V(SSEFloat64ExtractHighWord32)   \
+  V(SSEFloat64InsertLowWord32)     \
+  V(SSEFloat64InsertHighWord32)    \
+  V(SSEFloat64LoadLowWord32)       \
+  V(AVXFloat32Cmp)                 \
+  V(AVXFloat32Add)                 \
+  V(AVXFloat32Sub)                 \
+  V(AVXFloat32Mul)                 \
+  V(AVXFloat32Div)                 \
+  V(AVXFloat32Max)                 \
+  V(AVXFloat32Min)                 \
+  V(AVXFloat64Cmp)                 \
   V(AVXFloat64Add)                 \
   V(AVXFloat64Sub)                 \
   V(AVXFloat64Mul)                 \
   V(AVXFloat64Div)                 \
+  V(AVXFloat64Max)                 \
+  V(AVXFloat64Min)                 \
+  V(AVXFloat64Abs)                 \
+  V(AVXFloat64Neg)                 \
+  V(AVXFloat32Abs)                 \
+  V(AVXFloat32Neg)                 \
   V(X64Movsxbl)                    \
   V(X64Movzxbl)                    \
   V(X64Movb)                       \
@@ -77,12 +123,17 @@
   V(X64Movq)                       \
   V(X64Movsd)                      \
   V(X64Movss)                      \
+  V(X64BitcastFI)                  \
+  V(X64BitcastDL)                  \
+  V(X64BitcastIF)                  \
+  V(X64BitcastLD)                  \
   V(X64Lea32)                      \
   V(X64Lea)                        \
   V(X64Dec32)                      \
   V(X64Inc32)                      \
   V(X64Push)                       \
-  V(X64StoreWriteBarrier)
+  V(X64Poke)                       \
+  V(X64StackCheck)
 
 
 // Addressing modes represent the "shape" of inputs to an instruction.
diff --git a/src/compiler/x64/instruction-scheduler-x64.cc b/src/compiler/x64/instruction-scheduler-x64.cc
new file mode 100644
index 0000000..f8537c8
--- /dev/null
+++ b/src/compiler/x64/instruction-scheduler-x64.cc
@@ -0,0 +1,182 @@
+// Copyright 2015 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/instruction-scheduler.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+bool InstructionScheduler::SchedulerSupported() { return true; }
+
+
+int InstructionScheduler::GetTargetInstructionFlags(
+    const Instruction* instr) const {
+  switch (instr->arch_opcode()) {
+    case kX64Add:
+    case kX64Add32:
+    case kX64And:
+    case kX64And32:
+    case kX64Cmp:
+    case kX64Cmp32:
+    case kX64Test:
+    case kX64Test32:
+    case kX64Or:
+    case kX64Or32:
+    case kX64Xor:
+    case kX64Xor32:
+    case kX64Sub:
+    case kX64Sub32:
+    case kX64Imul:
+    case kX64Imul32:
+    case kX64ImulHigh32:
+    case kX64UmulHigh32:
+    case kX64Idiv:
+    case kX64Idiv32:
+    case kX64Udiv:
+    case kX64Udiv32:
+    case kX64Not:
+    case kX64Not32:
+    case kX64Neg:
+    case kX64Neg32:
+    case kX64Shl:
+    case kX64Shl32:
+    case kX64Shr:
+    case kX64Shr32:
+    case kX64Sar:
+    case kX64Sar32:
+    case kX64Ror:
+    case kX64Ror32:
+    case kX64Lzcnt:
+    case kX64Lzcnt32:
+    case kX64Tzcnt:
+    case kX64Tzcnt32:
+    case kX64Popcnt:
+    case kX64Popcnt32:
+    case kSSEFloat32Cmp:
+    case kSSEFloat32Add:
+    case kSSEFloat32Sub:
+    case kSSEFloat32Mul:
+    case kSSEFloat32Div:
+    case kSSEFloat32Abs:
+    case kSSEFloat32Neg:
+    case kSSEFloat32Sqrt:
+    case kSSEFloat32Round:
+    case kSSEFloat32Max:
+    case kSSEFloat32Min:
+    case kSSEFloat32ToFloat64:
+    case kSSEFloat64Cmp:
+    case kSSEFloat64Add:
+    case kSSEFloat64Sub:
+    case kSSEFloat64Mul:
+    case kSSEFloat64Div:
+    case kSSEFloat64Mod:
+    case kSSEFloat64Abs:
+    case kSSEFloat64Neg:
+    case kSSEFloat64Sqrt:
+    case kSSEFloat64Round:
+    case kSSEFloat64Max:
+    case kSSEFloat64Min:
+    case kSSEFloat64ToFloat32:
+    case kSSEFloat64ToInt32:
+    case kSSEFloat64ToUint32:
+    case kSSEFloat64ToInt64:
+    case kSSEFloat32ToInt64:
+    case kSSEFloat64ToUint64:
+    case kSSEFloat32ToUint64:
+    case kSSEInt32ToFloat64:
+    case kSSEInt64ToFloat32:
+    case kSSEInt64ToFloat64:
+    case kSSEUint64ToFloat32:
+    case kSSEUint64ToFloat64:
+    case kSSEUint32ToFloat64:
+    case kSSEFloat64ExtractLowWord32:
+    case kSSEFloat64ExtractHighWord32:
+    case kSSEFloat64InsertLowWord32:
+    case kSSEFloat64InsertHighWord32:
+    case kSSEFloat64LoadLowWord32:
+    case kAVXFloat32Cmp:
+    case kAVXFloat32Add:
+    case kAVXFloat32Sub:
+    case kAVXFloat32Mul:
+    case kAVXFloat32Div:
+    case kAVXFloat32Max:
+    case kAVXFloat32Min:
+    case kAVXFloat64Cmp:
+    case kAVXFloat64Add:
+    case kAVXFloat64Sub:
+    case kAVXFloat64Mul:
+    case kAVXFloat64Div:
+    case kAVXFloat64Max:
+    case kAVXFloat64Min:
+    case kAVXFloat64Abs:
+    case kAVXFloat64Neg:
+    case kAVXFloat32Abs:
+    case kAVXFloat32Neg:
+    case kX64BitcastFI:
+    case kX64BitcastDL:
+    case kX64BitcastIF:
+    case kX64BitcastLD:
+    case kX64Lea32:
+    case kX64Lea:
+    case kX64Dec32:
+    case kX64Inc32:
+      return (instr->addressing_mode() == kMode_None)
+          ? kNoOpcodeFlags
+          : kIsLoadOperation | kHasSideEffect;
+
+    case kX64Movsxbl:
+    case kX64Movzxbl:
+    case kX64Movsxwl:
+    case kX64Movzxwl:
+    case kX64Movsxlq:
+      DCHECK(instr->InputCount() >= 1);
+      return instr->InputAt(0)->IsRegister() ? kNoOpcodeFlags
+                                             : kIsLoadOperation;
+
+    case kX64Movb:
+    case kX64Movw:
+      return kHasSideEffect;
+
+    case kX64Movl:
+      if (instr->HasOutput()) {
+        DCHECK(instr->InputCount() >= 1);
+        return instr->InputAt(0)->IsRegister() ? kNoOpcodeFlags
+                                               : kIsLoadOperation;
+      } else {
+        return kHasSideEffect;
+      }
+
+    case kX64Movq:
+    case kX64Movsd:
+    case kX64Movss:
+      return instr->HasOutput() ? kIsLoadOperation : kHasSideEffect;
+
+    case kX64StackCheck:
+      return kIsLoadOperation;
+
+    case kX64Push:
+    case kX64Poke:
+      return kHasSideEffect;
+
+#define CASE(Name) case k##Name:
+    COMMON_ARCH_OPCODE_LIST(CASE)
+#undef CASE
+      // Already covered in architecture independent code.
+      UNREACHABLE();
+  }
+
+  UNREACHABLE();
+  return kNoOpcodeFlags;
+}
+
+
+int InstructionScheduler::GetInstructionLatency(const Instruction* instr) {
+  // TODO(all): Add instruction cost modeling.
+  return 1;
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/x64/instruction-selector-x64.cc b/src/compiler/x64/instruction-selector-x64.cc
index aba480d..c47a42e 100644
--- a/src/compiler/x64/instruction-selector-x64.cc
+++ b/src/compiler/x64/instruction-selector-x64.cc
@@ -2,24 +2,23 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <algorithm>
+
+#include "src/base/adapters.h"
 #include "src/compiler/instruction-selector-impl.h"
 #include "src/compiler/node-matchers.h"
+#include "src/compiler/node-properties.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
 // Adds X64-specific methods for generating operands.
-class X64OperandGenerator FINAL : public OperandGenerator {
+class X64OperandGenerator final : public OperandGenerator {
  public:
   explicit X64OperandGenerator(InstructionSelector* selector)
       : OperandGenerator(selector) {}
 
-  InstructionOperand* TempRegister(Register reg) {
-    return new (zone()) UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER,
-                                           Register::ToAllocationIndex(reg));
-  }
-
   bool CanBeImmediate(Node* node) {
     switch (node->opcode()) {
       case IrOpcode::kInt32Constant:
@@ -28,6 +27,10 @@
         const int64_t value = OpParameter<int64_t>(node);
         return value == static_cast<int64_t>(static_cast<int32_t>(value));
       }
+      case IrOpcode::kNumberConstant: {
+        const double value = OpParameter<double>(node);
+        return bit_cast<int64_t>(value) == 0;
+      }
       default:
         return false;
     }
@@ -35,15 +38,15 @@
 
   AddressingMode GenerateMemoryOperandInputs(Node* index, int scale_exponent,
                                              Node* base, Node* displacement,
-                                             InstructionOperand* inputs[],
+                                             InstructionOperand inputs[],
                                              size_t* input_count) {
     AddressingMode mode = kMode_MRI;
-    if (base != NULL) {
+    if (base != nullptr) {
       inputs[(*input_count)++] = UseRegister(base);
-      if (index != NULL) {
+      if (index != nullptr) {
         DCHECK(scale_exponent >= 0 && scale_exponent <= 3);
         inputs[(*input_count)++] = UseRegister(index);
-        if (displacement != NULL) {
+        if (displacement != nullptr) {
           inputs[(*input_count)++] = UseImmediate(displacement);
           static const AddressingMode kMRnI_modes[] = {kMode_MR1I, kMode_MR2I,
                                                        kMode_MR4I, kMode_MR8I};
@@ -54,7 +57,7 @@
           mode = kMRn_modes[scale_exponent];
         }
       } else {
-        if (displacement == NULL) {
+        if (displacement == nullptr) {
           mode = kMode_MR;
         } else {
           inputs[(*input_count)++] = UseImmediate(displacement);
@@ -62,10 +65,10 @@
         }
       }
     } else {
-      DCHECK(index != NULL);
+      DCHECK_NOT_NULL(index);
       DCHECK(scale_exponent >= 0 && scale_exponent <= 3);
       inputs[(*input_count)++] = UseRegister(index);
-      if (displacement != NULL) {
+      if (displacement != nullptr) {
         inputs[(*input_count)++] = UseImmediate(displacement);
         static const AddressingMode kMnI_modes[] = {kMode_MRI, kMode_M2I,
                                                     kMode_M4I, kMode_M8I};
@@ -84,11 +87,11 @@
   }
 
   AddressingMode GetEffectiveAddressMemoryOperand(Node* operand,
-                                                  InstructionOperand* inputs[],
+                                                  InstructionOperand inputs[],
                                                   size_t* input_count) {
     BaseWithIndexAndDisplacement64Matcher m(operand, true);
     DCHECK(m.matches());
-    if ((m.displacement() == NULL || CanBeImmediate(m.displacement()))) {
+    if ((m.displacement() == nullptr || CanBeImmediate(m.displacement()))) {
       return GenerateMemoryOperandInputs(m.index(), m.scale(), m.base(),
                                          m.displacement(), inputs, input_count);
     } else {
@@ -105,40 +108,39 @@
 
 
 void InstructionSelector::VisitLoad(Node* node) {
-  MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node));
-  MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node));
+  LoadRepresentation load_rep = LoadRepresentationOf(node->op());
   X64OperandGenerator g(this);
 
-  ArchOpcode opcode;
-  switch (rep) {
-    case kRepFloat32:
+  ArchOpcode opcode = kArchNop;
+  switch (load_rep.representation()) {
+    case MachineRepresentation::kFloat32:
       opcode = kX64Movss;
       break;
-    case kRepFloat64:
+    case MachineRepresentation::kFloat64:
       opcode = kX64Movsd;
       break;
-    case kRepBit:  // Fall through.
-    case kRepWord8:
-      opcode = typ == kTypeInt32 ? kX64Movsxbl : kX64Movzxbl;
+    case MachineRepresentation::kBit:  // Fall through.
+    case MachineRepresentation::kWord8:
+      opcode = load_rep.IsSigned() ? kX64Movsxbl : kX64Movzxbl;
       break;
-    case kRepWord16:
-      opcode = typ == kTypeInt32 ? kX64Movsxwl : kX64Movzxwl;
+    case MachineRepresentation::kWord16:
+      opcode = load_rep.IsSigned() ? kX64Movsxwl : kX64Movzxwl;
       break;
-    case kRepWord32:
+    case MachineRepresentation::kWord32:
       opcode = kX64Movl;
       break;
-    case kRepTagged:  // Fall through.
-    case kRepWord64:
+    case MachineRepresentation::kTagged:  // Fall through.
+    case MachineRepresentation::kWord64:
       opcode = kX64Movq;
       break;
-    default:
+    case MachineRepresentation::kNone:
       UNREACHABLE();
       return;
   }
 
-  InstructionOperand* outputs[1];
+  InstructionOperand outputs[1];
   outputs[0] = g.DefineAsRegister(node);
-  InstructionOperand* inputs[3];
+  InstructionOperand inputs[3];
   size_t input_count = 0;
   AddressingMode mode =
       g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count);
@@ -153,83 +155,118 @@
   Node* index = node->InputAt(1);
   Node* value = node->InputAt(2);
 
-  StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node);
-  MachineType rep = RepresentationOf(store_rep.machine_type());
-  if (store_rep.write_barrier_kind() == kFullWriteBarrier) {
-    DCHECK(rep == kRepTagged);
-    // TODO(dcarney): refactor RecordWrite function to take temp registers
-    //                and pass them here instead of using fixed regs
-    // TODO(dcarney): handle immediate indices.
-    InstructionOperand* temps[] = {g.TempRegister(rcx), g.TempRegister(rdx)};
-    Emit(kX64StoreWriteBarrier, NULL, g.UseFixed(base, rbx),
-         g.UseFixed(index, rcx), g.UseFixed(value, rdx), arraysize(temps),
-         temps);
-    return;
+  StoreRepresentation store_rep = StoreRepresentationOf(node->op());
+  WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind();
+  MachineRepresentation rep = store_rep.representation();
+
+  if (write_barrier_kind != kNoWriteBarrier) {
+    DCHECK_EQ(MachineRepresentation::kTagged, rep);
+    AddressingMode addressing_mode;
+    InstructionOperand inputs[3];
+    size_t input_count = 0;
+    inputs[input_count++] = g.UseUniqueRegister(base);
+    if (g.CanBeImmediate(index)) {
+      inputs[input_count++] = g.UseImmediate(index);
+      addressing_mode = kMode_MRI;
+    } else {
+      inputs[input_count++] = g.UseUniqueRegister(index);
+      addressing_mode = kMode_MR1;
+    }
+    inputs[input_count++] = (write_barrier_kind == kMapWriteBarrier)
+                                ? g.UseRegister(value)
+                                : g.UseUniqueRegister(value);
+    RecordWriteMode record_write_mode = RecordWriteMode::kValueIsAny;
+    switch (write_barrier_kind) {
+      case kNoWriteBarrier:
+        UNREACHABLE();
+        break;
+      case kMapWriteBarrier:
+        record_write_mode = RecordWriteMode::kValueIsMap;
+        break;
+      case kPointerWriteBarrier:
+        record_write_mode = RecordWriteMode::kValueIsPointer;
+        break;
+      case kFullWriteBarrier:
+        record_write_mode = RecordWriteMode::kValueIsAny;
+        break;
+    }
+    InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()};
+    size_t const temp_count = arraysize(temps);
+    InstructionCode code = kArchStoreWithWriteBarrier;
+    code |= AddressingModeField::encode(addressing_mode);
+    code |= MiscField::encode(static_cast<int>(record_write_mode));
+    Emit(code, 0, nullptr, input_count, inputs, temp_count, temps);
+  } else {
+    ArchOpcode opcode = kArchNop;
+    switch (rep) {
+      case MachineRepresentation::kFloat32:
+        opcode = kX64Movss;
+        break;
+      case MachineRepresentation::kFloat64:
+        opcode = kX64Movsd;
+        break;
+      case MachineRepresentation::kBit:  // Fall through.
+      case MachineRepresentation::kWord8:
+        opcode = kX64Movb;
+        break;
+      case MachineRepresentation::kWord16:
+        opcode = kX64Movw;
+        break;
+      case MachineRepresentation::kWord32:
+        opcode = kX64Movl;
+        break;
+      case MachineRepresentation::kTagged:  // Fall through.
+      case MachineRepresentation::kWord64:
+        opcode = kX64Movq;
+        break;
+      case MachineRepresentation::kNone:
+        UNREACHABLE();
+        return;
+    }
+    InstructionOperand inputs[4];
+    size_t input_count = 0;
+    AddressingMode addressing_mode =
+        g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count);
+    InstructionCode code =
+        opcode | AddressingModeField::encode(addressing_mode);
+    InstructionOperand value_operand =
+        g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value);
+    inputs[input_count++] = value_operand;
+    Emit(code, 0, static_cast<InstructionOperand*>(nullptr), input_count,
+         inputs);
   }
-  DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind());
-  ArchOpcode opcode;
-  switch (rep) {
-    case kRepFloat32:
-      opcode = kX64Movss;
-      break;
-    case kRepFloat64:
-      opcode = kX64Movsd;
-      break;
-    case kRepBit:  // Fall through.
-    case kRepWord8:
-      opcode = kX64Movb;
-      break;
-    case kRepWord16:
-      opcode = kX64Movw;
-      break;
-    case kRepWord32:
-      opcode = kX64Movl;
-      break;
-    case kRepTagged:  // Fall through.
-    case kRepWord64:
-      opcode = kX64Movq;
-      break;
-    default:
-      UNREACHABLE();
-      return;
-  }
-  InstructionOperand* inputs[4];
-  size_t input_count = 0;
-  AddressingMode mode =
-      g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count);
-  InstructionCode code = opcode | AddressingModeField::encode(mode);
-  InstructionOperand* value_operand =
-      g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value);
-  inputs[input_count++] = value_operand;
-  Emit(code, 0, static_cast<InstructionOperand**>(NULL), input_count, inputs);
 }
 
 
 void InstructionSelector::VisitCheckedLoad(Node* node) {
-  MachineType rep = RepresentationOf(OpParameter<MachineType>(node));
-  MachineType typ = TypeOf(OpParameter<MachineType>(node));
+  CheckedLoadRepresentation load_rep = CheckedLoadRepresentationOf(node->op());
   X64OperandGenerator g(this);
   Node* const buffer = node->InputAt(0);
   Node* const offset = node->InputAt(1);
   Node* const length = node->InputAt(2);
-  ArchOpcode opcode;
-  switch (rep) {
-    case kRepWord8:
-      opcode = typ == kTypeInt32 ? kCheckedLoadInt8 : kCheckedLoadUint8;
+  ArchOpcode opcode = kArchNop;
+  switch (load_rep.representation()) {
+    case MachineRepresentation::kWord8:
+      opcode = load_rep.IsSigned() ? kCheckedLoadInt8 : kCheckedLoadUint8;
       break;
-    case kRepWord16:
-      opcode = typ == kTypeInt32 ? kCheckedLoadInt16 : kCheckedLoadUint16;
+    case MachineRepresentation::kWord16:
+      opcode = load_rep.IsSigned() ? kCheckedLoadInt16 : kCheckedLoadUint16;
       break;
-    case kRepWord32:
+    case MachineRepresentation::kWord32:
       opcode = kCheckedLoadWord32;
       break;
-    case kRepFloat32:
+    case MachineRepresentation::kWord64:
+      opcode = kCheckedLoadWord64;
+      break;
+    case MachineRepresentation::kFloat32:
       opcode = kCheckedLoadFloat32;
       break;
-    case kRepFloat64:
+    case MachineRepresentation::kFloat64:
       opcode = kCheckedLoadFloat64;
       break;
-    default:
+    case MachineRepresentation::kBit:
+    case MachineRepresentation::kTagged:
+    case MachineRepresentation::kNone:
       UNREACHABLE();
       return;
   }
@@ -245,7 +282,7 @@
       return;
     }
   }
-  InstructionOperand* length_operand =
+  InstructionOperand length_operand =
       g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length);
   Emit(opcode, g.DefineAsRegister(node), g.UseRegister(buffer),
        g.UseRegister(offset), g.TempImmediate(0), length_operand);
@@ -253,34 +290,39 @@
 
 
 void InstructionSelector::VisitCheckedStore(Node* node) {
-  MachineType rep = RepresentationOf(OpParameter<MachineType>(node));
+  MachineRepresentation rep = CheckedStoreRepresentationOf(node->op());
   X64OperandGenerator g(this);
   Node* const buffer = node->InputAt(0);
   Node* const offset = node->InputAt(1);
   Node* const length = node->InputAt(2);
   Node* const value = node->InputAt(3);
-  ArchOpcode opcode;
+  ArchOpcode opcode = kArchNop;
   switch (rep) {
-    case kRepWord8:
+    case MachineRepresentation::kWord8:
       opcode = kCheckedStoreWord8;
       break;
-    case kRepWord16:
+    case MachineRepresentation::kWord16:
       opcode = kCheckedStoreWord16;
       break;
-    case kRepWord32:
+    case MachineRepresentation::kWord32:
       opcode = kCheckedStoreWord32;
       break;
-    case kRepFloat32:
+    case MachineRepresentation::kWord64:
+      opcode = kCheckedStoreWord64;
+      break;
+    case MachineRepresentation::kFloat32:
       opcode = kCheckedStoreFloat32;
       break;
-    case kRepFloat64:
+    case MachineRepresentation::kFloat64:
       opcode = kCheckedStoreFloat64;
       break;
-    default:
+    case MachineRepresentation::kBit:
+    case MachineRepresentation::kTagged:
+    case MachineRepresentation::kNone:
       UNREACHABLE();
       return;
   }
-  InstructionOperand* value_operand =
+  InstructionOperand value_operand =
       g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value);
   if (offset->opcode() == IrOpcode::kInt32Add && CanCover(node, offset)) {
     Int32Matcher mlength(length);
@@ -288,16 +330,16 @@
     if (mlength.HasValue() && moffset.right().HasValue() &&
         moffset.right().Value() >= 0 &&
         mlength.Value() >= moffset.right().Value()) {
-      Emit(opcode, nullptr, g.UseRegister(buffer),
+      Emit(opcode, g.NoOutput(), g.UseRegister(buffer),
            g.UseRegister(moffset.left().node()),
            g.UseImmediate(moffset.right().node()), g.UseImmediate(length),
            value_operand);
       return;
     }
   }
-  InstructionOperand* length_operand =
+  InstructionOperand length_operand =
       g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length);
-  Emit(opcode, nullptr, g.UseRegister(buffer), g.UseRegister(offset),
+  Emit(opcode, g.NoOutput(), g.UseRegister(buffer), g.UseRegister(offset),
        g.TempImmediate(0), length_operand, value_operand);
 }
 
@@ -309,9 +351,9 @@
   Int32BinopMatcher m(node);
   Node* left = m.left().node();
   Node* right = m.right().node();
-  InstructionOperand* inputs[4];
+  InstructionOperand inputs[4];
   size_t input_count = 0;
-  InstructionOperand* outputs[2];
+  InstructionOperand outputs[2];
   size_t output_count = 0;
 
   // TODO(turbofan): match complex addressing modes.
@@ -323,7 +365,7 @@
     //   mov rax, [rbp-0x10]
     //   add rax, [rbp-0x10]
     //   jo label
-    InstructionOperand* const input = g.UseRegister(left);
+    InstructionOperand const input = g.UseRegister(left);
     inputs[input_count++] = input;
     inputs[input_count++] = input;
   } else if (g.CanBeImmediate(right)) {
@@ -348,14 +390,13 @@
     outputs[output_count++] = g.DefineAsRegister(cont->result());
   }
 
-  DCHECK_NE(0, static_cast<int>(input_count));
-  DCHECK_NE(0, static_cast<int>(output_count));
+  DCHECK_NE(0u, input_count);
+  DCHECK_NE(0u, output_count);
   DCHECK_GE(arraysize(inputs), input_count);
   DCHECK_GE(arraysize(outputs), output_count);
 
-  Instruction* instr = selector->Emit(cont->Encode(opcode), output_count,
-                                      outputs, input_count, inputs);
-  if (cont->IsBranch()) instr->MarkAsControl();
+  selector->Emit(cont->Encode(opcode), output_count, outputs, input_count,
+                 inputs);
 }
 
 
@@ -368,7 +409,15 @@
 
 
 void InstructionSelector::VisitWord32And(Node* node) {
-  VisitBinop(this, node, kX64And32);
+  X64OperandGenerator g(this);
+  Uint32BinopMatcher m(node);
+  if (m.right().Is(0xff)) {
+    Emit(kX64Movzxbl, g.DefineAsRegister(node), g.Use(m.left().node()));
+  } else if (m.right().Is(0xffff)) {
+    Emit(kX64Movzxwl, g.DefineAsRegister(node), g.Use(m.left().node()));
+  } else {
+    VisitBinop(this, node, kX64And32);
+  }
 }
 
 
@@ -460,15 +509,15 @@
              Node* displacement) {
   X64OperandGenerator g(selector);
 
-  InstructionOperand* inputs[4];
+  InstructionOperand inputs[4];
   size_t input_count = 0;
   AddressingMode mode = g.GenerateMemoryOperandInputs(
       index, scale, base, displacement, inputs, &input_count);
 
-  DCHECK_NE(0, static_cast<int>(input_count));
+  DCHECK_NE(0u, input_count);
   DCHECK_GE(arraysize(inputs), input_count);
 
-  InstructionOperand* outputs[1];
+  InstructionOperand outputs[1];
   outputs[0] = g.DefineAsRegister(result);
 
   opcode = AddressingModeField::encode(mode) | opcode;
@@ -483,8 +532,8 @@
   Int32ScaleMatcher m(node, true);
   if (m.matches()) {
     Node* index = node->InputAt(0);
-    Node* base = m.power_of_two_plus_one() ? index : NULL;
-    EmitLea(this, kX64Lea32, node, index, m.scale(), base, NULL);
+    Node* base = m.power_of_two_plus_one() ? index : nullptr;
+    EmitLea(this, kX64Lea32, node, index, m.scale(), base, nullptr);
     return;
   }
   VisitWord32Shift(this, node, kX64Shl32);
@@ -549,13 +598,49 @@
 }
 
 
+void InstructionSelector::VisitWord64Clz(Node* node) {
+  X64OperandGenerator g(this);
+  Emit(kX64Lzcnt, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitWord32Clz(Node* node) {
+  X64OperandGenerator g(this);
+  Emit(kX64Lzcnt32, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitWord64Ctz(Node* node) {
+  X64OperandGenerator g(this);
+  Emit(kX64Tzcnt, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitWord32Ctz(Node* node) {
+  X64OperandGenerator g(this);
+  Emit(kX64Tzcnt32, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitWord32Popcnt(Node* node) {
+  X64OperandGenerator g(this);
+  Emit(kX64Popcnt32, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitWord64Popcnt(Node* node) {
+  X64OperandGenerator g(this);
+  Emit(kX64Popcnt, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
+}
+
+
 void InstructionSelector::VisitInt32Add(Node* node) {
   X64OperandGenerator g(this);
 
   // Try to match the Add to a leal pattern
   BaseWithIndexAndDisplacement32Matcher m(node);
   if (m.matches() &&
-      (m.displacement() == NULL || g.CanBeImmediate(m.displacement()))) {
+      (m.displacement() == nullptr || g.CanBeImmediate(m.displacement()))) {
     EmitLea(this, kX64Lea32, node, m.index(), m.scale(), m.base(),
             m.displacement());
     return;
@@ -571,6 +656,16 @@
 }
 
 
+void InstructionSelector::VisitInt64AddWithOverflow(Node* node) {
+  if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
+    FlagsContinuation cont(kOverflow, ovf);
+    VisitBinop(this, node, kX64Add, &cont);
+  }
+  FlagsContinuation cont;
+  VisitBinop(this, node, kX64Add, &cont);
+}
+
+
 void InstructionSelector::VisitInt32Sub(Node* node) {
   X64OperandGenerator g(this);
   Int32BinopMatcher m(node);
@@ -601,6 +696,16 @@
 }
 
 
+void InstructionSelector::VisitInt64SubWithOverflow(Node* node) {
+  if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
+    FlagsContinuation cont(kOverflow, ovf);
+    return VisitBinop(this, node, kX64Sub, &cont);
+  }
+  FlagsContinuation cont;
+  VisitBinop(this, node, kX64Sub, &cont);
+}
+
+
 namespace {
 
 void VisitMul(InstructionSelector* selector, Node* node, ArchOpcode opcode) {
@@ -638,7 +743,7 @@
 
 void VisitDiv(InstructionSelector* selector, Node* node, ArchOpcode opcode) {
   X64OperandGenerator g(selector);
-  InstructionOperand* temps[] = {g.TempRegister(rdx)};
+  InstructionOperand temps[] = {g.TempRegister(rdx)};
   selector->Emit(
       opcode, g.DefineAsFixed(node, rax), g.UseFixed(node->InputAt(0), rax),
       g.UseUniqueRegister(node->InputAt(1)), arraysize(temps), temps);
@@ -659,8 +764,8 @@
   Int32ScaleMatcher m(node, true);
   if (m.matches()) {
     Node* index = node->InputAt(0);
-    Node* base = m.power_of_two_plus_one() ? index : NULL;
-    EmitLea(this, kX64Lea32, node, index, m.scale(), base, NULL);
+    Node* base = m.power_of_two_plus_one() ? index : nullptr;
+    EmitLea(this, kX64Lea32, node, index, m.scale(), base, nullptr);
     return;
   }
   VisitMul(this, node, kX64Imul32);
@@ -724,7 +829,7 @@
 
 void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) {
   X64OperandGenerator g(this);
-  Emit(kSSECvtss2sd, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
+  Emit(kSSEFloat32ToFloat64, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
 }
 
 
@@ -752,6 +857,70 @@
 }
 
 
+void InstructionSelector::VisitTryTruncateFloat32ToInt64(Node* node) {
+  X64OperandGenerator g(this);
+  InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0))};
+  InstructionOperand outputs[2];
+  size_t output_count = 0;
+  outputs[output_count++] = g.DefineAsRegister(node);
+
+  Node* success_output = NodeProperties::FindProjection(node, 1);
+  if (success_output) {
+    outputs[output_count++] = g.DefineAsRegister(success_output);
+  }
+
+  Emit(kSSEFloat32ToInt64, output_count, outputs, 1, inputs);
+}
+
+
+void InstructionSelector::VisitTryTruncateFloat64ToInt64(Node* node) {
+  X64OperandGenerator g(this);
+  InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0))};
+  InstructionOperand outputs[2];
+  size_t output_count = 0;
+  outputs[output_count++] = g.DefineAsRegister(node);
+
+  Node* success_output = NodeProperties::FindProjection(node, 1);
+  if (success_output) {
+    outputs[output_count++] = g.DefineAsRegister(success_output);
+  }
+
+  Emit(kSSEFloat64ToInt64, output_count, outputs, 1, inputs);
+}
+
+
+void InstructionSelector::VisitTryTruncateFloat32ToUint64(Node* node) {
+  X64OperandGenerator g(this);
+  InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0))};
+  InstructionOperand outputs[2];
+  size_t output_count = 0;
+  outputs[output_count++] = g.DefineAsRegister(node);
+
+  Node* success_output = NodeProperties::FindProjection(node, 1);
+  if (success_output) {
+    outputs[output_count++] = g.DefineAsRegister(success_output);
+  }
+
+  Emit(kSSEFloat32ToUint64, output_count, outputs, 1, inputs);
+}
+
+
+void InstructionSelector::VisitTryTruncateFloat64ToUint64(Node* node) {
+  X64OperandGenerator g(this);
+  InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0))};
+  InstructionOperand outputs[2];
+  size_t output_count = 0;
+  outputs[output_count++] = g.DefineAsRegister(node);
+
+  Node* success_output = NodeProperties::FindProjection(node, 1);
+  if (success_output) {
+    outputs[output_count++] = g.DefineAsRegister(success_output);
+  }
+
+  Emit(kSSEFloat64ToUint64, output_count, outputs, 1, inputs);
+}
+
+
 void InstructionSelector::VisitChangeInt32ToInt64(Node* node) {
   X64OperandGenerator g(this);
   Emit(kX64Movsxlq, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
@@ -795,9 +964,62 @@
 }
 
 
+namespace {
+
+void VisitRO(InstructionSelector* selector, Node* node,
+             InstructionCode opcode) {
+  X64OperandGenerator g(selector);
+  selector->Emit(opcode, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
+}
+
+
+void VisitRR(InstructionSelector* selector, Node* node,
+             InstructionCode opcode) {
+  X64OperandGenerator g(selector);
+  selector->Emit(opcode, g.DefineAsRegister(node),
+                 g.UseRegister(node->InputAt(0)));
+}
+
+
+void VisitFloatBinop(InstructionSelector* selector, Node* node,
+                     ArchOpcode avx_opcode, ArchOpcode sse_opcode) {
+  X64OperandGenerator g(selector);
+  InstructionOperand operand0 = g.UseRegister(node->InputAt(0));
+  InstructionOperand operand1 = g.Use(node->InputAt(1));
+  if (selector->IsSupported(AVX)) {
+    selector->Emit(avx_opcode, g.DefineAsRegister(node), operand0, operand1);
+  } else {
+    selector->Emit(sse_opcode, g.DefineSameAsFirst(node), operand0, operand1);
+  }
+}
+
+
+void VisitFloatUnop(InstructionSelector* selector, Node* node, Node* input,
+                    ArchOpcode avx_opcode, ArchOpcode sse_opcode) {
+  X64OperandGenerator g(selector);
+  if (selector->IsSupported(AVX)) {
+    selector->Emit(avx_opcode, g.DefineAsRegister(node), g.Use(input));
+  } else {
+    selector->Emit(sse_opcode, g.DefineSameAsFirst(node), g.UseRegister(input));
+  }
+}
+
+}  // namespace
+
+
 void InstructionSelector::VisitTruncateFloat64ToFloat32(Node* node) {
-  X64OperandGenerator g(this);
-  Emit(kSSECvtsd2ss, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
+  VisitRO(this, node, kSSEFloat64ToFloat32);
+}
+
+
+void InstructionSelector::VisitTruncateFloat64ToInt32(Node* node) {
+  switch (TruncationModeOf(node->op())) {
+    case TruncationMode::kJavaScript:
+      return VisitRR(this, node, kArchTruncateDoubleToI);
+    case TruncationMode::kRoundToZero:
+      return VisitRO(this, node, kSSEFloat64ToInt32);
+  }
+  UNREACHABLE();
 }
 
 
@@ -824,96 +1046,200 @@
 }
 
 
-void InstructionSelector::VisitFloat64Add(Node* node) {
+void InstructionSelector::VisitRoundInt64ToFloat32(Node* node) {
   X64OperandGenerator g(this);
-  if (IsSupported(AVX)) {
-    Emit(kAVXFloat64Add, g.DefineAsRegister(node),
-         g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
-  } else {
-    Emit(kSSEFloat64Add, g.DefineSameAsFirst(node),
-         g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
+  Emit(kSSEInt64ToFloat32, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitRoundInt64ToFloat64(Node* node) {
+  X64OperandGenerator g(this);
+  Emit(kSSEInt64ToFloat64, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitRoundUint64ToFloat32(Node* node) {
+  X64OperandGenerator g(this);
+  InstructionOperand temps[] = {g.TempRegister()};
+  Emit(kSSEUint64ToFloat32, g.DefineAsRegister(node), g.Use(node->InputAt(0)),
+       arraysize(temps), temps);
+}
+
+
+void InstructionSelector::VisitRoundUint64ToFloat64(Node* node) {
+  X64OperandGenerator g(this);
+  InstructionOperand temps[] = {g.TempRegister()};
+  Emit(kSSEUint64ToFloat64, g.DefineAsRegister(node), g.Use(node->InputAt(0)),
+       arraysize(temps), temps);
+}
+
+
+void InstructionSelector::VisitBitcastFloat32ToInt32(Node* node) {
+  X64OperandGenerator g(this);
+  Emit(kX64BitcastFI, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitBitcastFloat64ToInt64(Node* node) {
+  X64OperandGenerator g(this);
+  Emit(kX64BitcastDL, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitBitcastInt32ToFloat32(Node* node) {
+  X64OperandGenerator g(this);
+  Emit(kX64BitcastIF, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitBitcastInt64ToFloat64(Node* node) {
+  X64OperandGenerator g(this);
+  Emit(kX64BitcastLD, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitFloat32Add(Node* node) {
+  VisitFloatBinop(this, node, kAVXFloat32Add, kSSEFloat32Add);
+}
+
+
+void InstructionSelector::VisitFloat32Sub(Node* node) {
+  X64OperandGenerator g(this);
+  Float32BinopMatcher m(node);
+  if (m.left().IsMinusZero()) {
+    VisitFloatUnop(this, node, m.right().node(), kAVXFloat32Neg,
+                   kSSEFloat32Neg);
+    return;
   }
+  VisitFloatBinop(this, node, kAVXFloat32Sub, kSSEFloat32Sub);
+}
+
+
+void InstructionSelector::VisitFloat32Mul(Node* node) {
+  VisitFloatBinop(this, node, kAVXFloat32Mul, kSSEFloat32Mul);
+}
+
+
+void InstructionSelector::VisitFloat32Div(Node* node) {
+  VisitFloatBinop(this, node, kAVXFloat32Div, kSSEFloat32Div);
+}
+
+
+void InstructionSelector::VisitFloat32Max(Node* node) {
+  VisitFloatBinop(this, node, kAVXFloat32Max, kSSEFloat32Max);
+}
+
+
+void InstructionSelector::VisitFloat32Min(Node* node) {
+  VisitFloatBinop(this, node, kAVXFloat32Min, kSSEFloat32Min);
+}
+
+
+void InstructionSelector::VisitFloat32Abs(Node* node) {
+  VisitFloatUnop(this, node, node->InputAt(0), kAVXFloat32Abs, kSSEFloat32Abs);
+}
+
+
+void InstructionSelector::VisitFloat32Sqrt(Node* node) {
+  VisitRO(this, node, kSSEFloat32Sqrt);
+}
+
+
+void InstructionSelector::VisitFloat64Add(Node* node) {
+  VisitFloatBinop(this, node, kAVXFloat64Add, kSSEFloat64Add);
 }
 
 
 void InstructionSelector::VisitFloat64Sub(Node* node) {
   X64OperandGenerator g(this);
-  if (IsSupported(AVX)) {
-    Emit(kAVXFloat64Sub, g.DefineAsRegister(node),
-         g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
-  } else {
-    Emit(kSSEFloat64Sub, g.DefineSameAsFirst(node),
-         g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
+  Float64BinopMatcher m(node);
+  if (m.left().IsMinusZero()) {
+    if (m.right().IsFloat64RoundDown() &&
+        CanCover(m.node(), m.right().node())) {
+      if (m.right().InputAt(0)->opcode() == IrOpcode::kFloat64Sub &&
+          CanCover(m.right().node(), m.right().InputAt(0))) {
+        Float64BinopMatcher mright0(m.right().InputAt(0));
+        if (mright0.left().IsMinusZero()) {
+          Emit(kSSEFloat64Round | MiscField::encode(kRoundUp),
+               g.DefineAsRegister(node), g.UseRegister(mright0.right().node()));
+          return;
+        }
+      }
+    }
+    VisitFloatUnop(this, node, m.right().node(), kAVXFloat64Neg,
+                   kSSEFloat64Neg);
+    return;
   }
+  VisitFloatBinop(this, node, kAVXFloat64Sub, kSSEFloat64Sub);
 }
 
 
 void InstructionSelector::VisitFloat64Mul(Node* node) {
-  X64OperandGenerator g(this);
-  if (IsSupported(AVX)) {
-    Emit(kAVXFloat64Mul, g.DefineAsRegister(node),
-         g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
-  } else {
-    Emit(kSSEFloat64Mul, g.DefineSameAsFirst(node),
-         g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
-  }
+  VisitFloatBinop(this, node, kAVXFloat64Mul, kSSEFloat64Mul);
 }
 
 
 void InstructionSelector::VisitFloat64Div(Node* node) {
-  X64OperandGenerator g(this);
-  if (IsSupported(AVX)) {
-    Emit(kAVXFloat64Div, g.DefineAsRegister(node),
-         g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
-  } else {
-    Emit(kSSEFloat64Div, g.DefineSameAsFirst(node),
-         g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
-  }
+  VisitFloatBinop(this, node, kAVXFloat64Div, kSSEFloat64Div);
 }
 
 
 void InstructionSelector::VisitFloat64Mod(Node* node) {
   X64OperandGenerator g(this);
-  InstructionOperand* temps[] = {g.TempRegister(rax)};
+  InstructionOperand temps[] = {g.TempRegister(rax)};
   Emit(kSSEFloat64Mod, g.DefineSameAsFirst(node),
        g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)), 1,
        temps);
 }
 
 
+void InstructionSelector::VisitFloat64Max(Node* node) {
+  VisitFloatBinop(this, node, kAVXFloat64Max, kSSEFloat64Max);
+}
+
+
+void InstructionSelector::VisitFloat64Min(Node* node) {
+  VisitFloatBinop(this, node, kAVXFloat64Min, kSSEFloat64Min);
+}
+
+
+void InstructionSelector::VisitFloat64Abs(Node* node) {
+  VisitFloatUnop(this, node, node->InputAt(0), kAVXFloat64Abs, kSSEFloat64Abs);
+}
+
+
 void InstructionSelector::VisitFloat64Sqrt(Node* node) {
-  X64OperandGenerator g(this);
-  Emit(kSSEFloat64Sqrt, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
+  VisitRO(this, node, kSSEFloat64Sqrt);
 }
 
 
-namespace {
-
-void VisitRRFloat64(InstructionSelector* selector, ArchOpcode opcode,
-                    Node* node) {
-  X64OperandGenerator g(selector);
-  selector->Emit(opcode, g.DefineAsRegister(node),
-                 g.UseRegister(node->InputAt(0)));
-}
-
-}  // namespace
-
-
-void InstructionSelector::VisitFloat64Floor(Node* node) {
-  DCHECK(CpuFeatures::IsSupported(SSE4_1));
-  VisitRRFloat64(this, kSSEFloat64Floor, node);
+void InstructionSelector::VisitFloat32RoundDown(Node* node) {
+  VisitRR(this, node, kSSEFloat32Round | MiscField::encode(kRoundDown));
 }
 
 
-void InstructionSelector::VisitFloat64Ceil(Node* node) {
-  DCHECK(CpuFeatures::IsSupported(SSE4_1));
-  VisitRRFloat64(this, kSSEFloat64Ceil, node);
+void InstructionSelector::VisitFloat64RoundDown(Node* node) {
+  VisitRR(this, node, kSSEFloat64Round | MiscField::encode(kRoundDown));
+}
+
+
+void InstructionSelector::VisitFloat32RoundUp(Node* node) {
+  VisitRR(this, node, kSSEFloat32Round | MiscField::encode(kRoundUp));
+}
+
+
+void InstructionSelector::VisitFloat64RoundUp(Node* node) {
+  VisitRR(this, node, kSSEFloat64Round | MiscField::encode(kRoundUp));
+}
+
+
+void InstructionSelector::VisitFloat32RoundTruncate(Node* node) {
+  VisitRR(this, node, kSSEFloat32Round | MiscField::encode(kRoundToZero));
 }
 
 
 void InstructionSelector::VisitFloat64RoundTruncate(Node* node) {
-  DCHECK(CpuFeatures::IsSupported(SSE4_1));
-  VisitRRFloat64(this, kSSEFloat64RoundTruncate, node);
+  VisitRR(this, node, kSSEFloat64Round | MiscField::encode(kRoundToZero));
 }
 
 
@@ -922,64 +1248,70 @@
 }
 
 
-void InstructionSelector::VisitCall(Node* node) {
-  X64OperandGenerator g(this);
-  const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(node);
-
-  FrameStateDescriptor* frame_state_descriptor = NULL;
-  if (descriptor->NeedsFrameState()) {
-    frame_state_descriptor = GetFrameStateDescriptor(
-        node->InputAt(static_cast<int>(descriptor->InputCount())));
-  }
-
-  CallBuffer buffer(zone(), descriptor, frame_state_descriptor);
-
-  // Compute InstructionOperands for inputs and outputs.
-  InitializeCallBuffer(node, &buffer, true, true);
-
-  // Push any stack arguments.
-  for (NodeVectorRIter input = buffer.pushed_nodes.rbegin();
-       input != buffer.pushed_nodes.rend(); input++) {
-    // TODO(titzer): handle pushing double parameters.
-    Emit(kX64Push, NULL,
-         g.CanBeImmediate(*input) ? g.UseImmediate(*input) : g.Use(*input));
-  }
-
-  // Select the appropriate opcode based on the call type.
-  InstructionCode opcode;
-  switch (descriptor->kind()) {
-    case CallDescriptor::kCallCodeObject: {
-      opcode = kArchCallCodeObject;
-      break;
-    }
-    case CallDescriptor::kCallJSFunction:
-      opcode = kArchCallJSFunction;
-      break;
-    default:
-      UNREACHABLE();
-      return;
-  }
-  opcode |= MiscField::encode(descriptor->flags());
-
-  // Emit the call instruction.
-  InstructionOperand** first_output =
-      buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL;
-  Instruction* call_instr =
-      Emit(opcode, buffer.outputs.size(), first_output,
-           buffer.instruction_args.size(), &buffer.instruction_args.front());
-  call_instr->MarkAsCall();
+void InstructionSelector::VisitFloat32RoundTiesEven(Node* node) {
+  VisitRR(this, node, kSSEFloat32Round | MiscField::encode(kRoundToNearest));
 }
 
 
+void InstructionSelector::VisitFloat64RoundTiesEven(Node* node) {
+  VisitRR(this, node, kSSEFloat64Round | MiscField::encode(kRoundToNearest));
+}
+
+
+void InstructionSelector::EmitPrepareArguments(
+    ZoneVector<PushParameter>* arguments, const CallDescriptor* descriptor,
+    Node* node) {
+  X64OperandGenerator g(this);
+
+  // Prepare for C function call.
+  if (descriptor->IsCFunctionCall()) {
+    Emit(kArchPrepareCallCFunction |
+             MiscField::encode(static_cast<int>(descriptor->CParameterCount())),
+         0, nullptr, 0, nullptr);
+
+    // Poke any stack arguments.
+    for (size_t n = 0; n < arguments->size(); ++n) {
+      PushParameter input = (*arguments)[n];
+      if (input.node()) {
+        int slot = static_cast<int>(n);
+        InstructionOperand value = g.CanBeImmediate(input.node())
+                                       ? g.UseImmediate(input.node())
+                                       : g.UseRegister(input.node());
+        Emit(kX64Poke | MiscField::encode(slot), g.NoOutput(), value);
+      }
+    }
+  } else {
+    // Push any stack arguments.
+    for (PushParameter input : base::Reversed(*arguments)) {
+      // TODO(titzer): X64Push cannot handle stack->stack double moves
+      // because there is no way to encode fixed double slots.
+      InstructionOperand value =
+          g.CanBeImmediate(input.node())
+              ? g.UseImmediate(input.node())
+              : IsSupported(ATOM) ||
+                        sequence()->IsFloat(GetVirtualRegister(input.node()))
+                    ? g.UseRegister(input.node())
+                    : g.Use(input.node());
+      Emit(kX64Push, g.NoOutput(), value);
+    }
+  }
+}
+
+
+bool InstructionSelector::IsTailCallAddressImmediate() { return true; }
+
+
+namespace {
+
 // Shared routine for multiple compare operations.
-static void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
-                         InstructionOperand* left, InstructionOperand* right,
-                         FlagsContinuation* cont) {
+void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
+                  InstructionOperand left, InstructionOperand right,
+                  FlagsContinuation* cont) {
   X64OperandGenerator g(selector);
   opcode = cont->Encode(opcode);
   if (cont->IsBranch()) {
-    selector->Emit(opcode, NULL, left, right, g.Label(cont->true_block()),
-                   g.Label(cont->false_block()))->MarkAsControl();
+    selector->Emit(opcode, g.NoOutput(), left, right,
+                   g.Label(cont->true_block()), g.Label(cont->false_block()));
   } else {
     DCHECK(cont->IsSet());
     selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right);
@@ -988,9 +1320,9 @@
 
 
 // Shared routine for multiple compare operations.
-static void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
-                         Node* left, Node* right, FlagsContinuation* cont,
-                         bool commutative) {
+void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
+                  Node* left, Node* right, FlagsContinuation* cont,
+                  bool commutative) {
   X64OperandGenerator g(selector);
   if (commutative && g.CanBeBetterLeftOperand(right)) {
     std::swap(left, right);
@@ -1000,8 +1332,8 @@
 
 
 // Shared routine for multiple word compare operations.
-static void VisitWordCompare(InstructionSelector* selector, Node* node,
-                             InstructionCode opcode, FlagsContinuation* cont) {
+void VisitWordCompare(InstructionSelector* selector, Node* node,
+                      InstructionCode opcode, FlagsContinuation* cont) {
   X64OperandGenerator g(selector);
   Node* const left = node->InputAt(0);
   Node* const right = node->InputAt(1);
@@ -1019,22 +1351,65 @@
 }
 
 
+// Shared routine for 64-bit word comparison operations.
+void VisitWord64Compare(InstructionSelector* selector, Node* node,
+                        FlagsContinuation* cont) {
+  X64OperandGenerator g(selector);
+  Int64BinopMatcher m(node);
+  if (m.left().IsLoad() && m.right().IsLoadStackPointer()) {
+    LoadMatcher<ExternalReferenceMatcher> mleft(m.left().node());
+    ExternalReference js_stack_limit =
+        ExternalReference::address_of_stack_limit(selector->isolate());
+    if (mleft.object().Is(js_stack_limit) && mleft.index().Is(0)) {
+      // Compare(Load(js_stack_limit), LoadStackPointer)
+      if (!node->op()->HasProperty(Operator::kCommutative)) cont->Commute();
+      InstructionCode opcode = cont->Encode(kX64StackCheck);
+      if (cont->IsBranch()) {
+        selector->Emit(opcode, g.NoOutput(), g.Label(cont->true_block()),
+                       g.Label(cont->false_block()));
+      } else {
+        DCHECK(cont->IsSet());
+        selector->Emit(opcode, g.DefineAsRegister(cont->result()));
+      }
+      return;
+    }
+  }
+  VisitWordCompare(selector, node, kX64Cmp, cont);
+}
+
+
 // Shared routine for comparison with zero.
-static void VisitCompareZero(InstructionSelector* selector, Node* node,
-                             InstructionCode opcode, FlagsContinuation* cont) {
+void VisitCompareZero(InstructionSelector* selector, Node* node,
+                      InstructionCode opcode, FlagsContinuation* cont) {
   X64OperandGenerator g(selector);
   VisitCompare(selector, opcode, g.Use(node), g.TempImmediate(0), cont);
 }
 
 
-// Shared routine for multiple float64 compare operations.
-static void VisitFloat64Compare(InstructionSelector* selector, Node* node,
-                                FlagsContinuation* cont) {
-  VisitCompare(selector, kSSEFloat64Cmp, node->InputAt(0), node->InputAt(1),
-               cont, node->op()->HasProperty(Operator::kCommutative));
+// Shared routine for multiple float32 compare operations (inputs commuted).
+void VisitFloat32Compare(InstructionSelector* selector, Node* node,
+                         FlagsContinuation* cont) {
+  Node* const left = node->InputAt(0);
+  Node* const right = node->InputAt(1);
+  InstructionCode const opcode =
+      selector->IsSupported(AVX) ? kAVXFloat32Cmp : kSSEFloat32Cmp;
+  VisitCompare(selector, opcode, right, left, cont, false);
 }
 
 
+// Shared routine for multiple float64 compare operations (inputs commuted).
+void VisitFloat64Compare(InstructionSelector* selector, Node* node,
+                         FlagsContinuation* cont) {
+  Node* const left = node->InputAt(0);
+  Node* const right = node->InputAt(1);
+  InstructionCode const opcode =
+      selector->IsSupported(AVX) ? kAVXFloat64Cmp : kSSEFloat64Cmp;
+  VisitCompare(selector, opcode, right, left, cont, false);
+}
+
+}  // namespace
+
+
 void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
                                       BasicBlock* fbranch) {
   X64OperandGenerator g(this);
@@ -1044,25 +1419,12 @@
   FlagsContinuation cont(kNotEqual, tbranch, fbranch);
 
   // Try to combine with comparisons against 0 by simply inverting the branch.
-  while (CanCover(user, value)) {
-    if (value->opcode() == IrOpcode::kWord32Equal) {
-      Int32BinopMatcher m(value);
-      if (m.right().Is(0)) {
-        user = value;
-        value = m.left().node();
-        cont.Negate();
-      } else {
-        break;
-      }
-    } else if (value->opcode() == IrOpcode::kWord64Equal) {
-      Int64BinopMatcher m(value);
-      if (m.right().Is(0)) {
-        user = value;
-        value = m.left().node();
-        cont.Negate();
-      } else {
-        break;
-      }
+  while (CanCover(user, value) && value->opcode() == IrOpcode::kWord32Equal) {
+    Int32BinopMatcher m(value);
+    if (m.right().Is(0)) {
+      user = value;
+      value = m.left().node();
+      cont.Negate();
     } else {
       break;
     }
@@ -1086,39 +1448,69 @@
       case IrOpcode::kUint32LessThanOrEqual:
         cont.OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
         return VisitWordCompare(this, value, kX64Cmp32, &cont);
-      case IrOpcode::kWord64Equal:
+      case IrOpcode::kWord64Equal: {
         cont.OverwriteAndNegateIfEqual(kEqual);
-        return VisitWordCompare(this, value, kX64Cmp, &cont);
+        Int64BinopMatcher m(value);
+        if (m.right().Is(0)) {
+          // Try to combine the branch with a comparison.
+          Node* const user = m.node();
+          Node* const value = m.left().node();
+          if (CanCover(user, value)) {
+            switch (value->opcode()) {
+              case IrOpcode::kInt64Sub:
+                return VisitWord64Compare(this, value, &cont);
+              case IrOpcode::kWord64And:
+                return VisitWordCompare(this, value, kX64Test, &cont);
+              default:
+                break;
+            }
+          }
+          return VisitCompareZero(this, value, kX64Cmp, &cont);
+        }
+        return VisitWord64Compare(this, value, &cont);
+      }
       case IrOpcode::kInt64LessThan:
         cont.OverwriteAndNegateIfEqual(kSignedLessThan);
-        return VisitWordCompare(this, value, kX64Cmp, &cont);
+        return VisitWord64Compare(this, value, &cont);
       case IrOpcode::kInt64LessThanOrEqual:
         cont.OverwriteAndNegateIfEqual(kSignedLessThanOrEqual);
-        return VisitWordCompare(this, value, kX64Cmp, &cont);
+        return VisitWord64Compare(this, value, &cont);
       case IrOpcode::kUint64LessThan:
         cont.OverwriteAndNegateIfEqual(kUnsignedLessThan);
-        return VisitWordCompare(this, value, kX64Cmp, &cont);
+        return VisitWord64Compare(this, value, &cont);
+      case IrOpcode::kUint64LessThanOrEqual:
+        cont.OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
+        return VisitWord64Compare(this, value, &cont);
+      case IrOpcode::kFloat32Equal:
+        cont.OverwriteAndNegateIfEqual(kUnorderedEqual);
+        return VisitFloat32Compare(this, value, &cont);
+      case IrOpcode::kFloat32LessThan:
+        cont.OverwriteAndNegateIfEqual(kUnsignedGreaterThan);
+        return VisitFloat32Compare(this, value, &cont);
+      case IrOpcode::kFloat32LessThanOrEqual:
+        cont.OverwriteAndNegateIfEqual(kUnsignedGreaterThanOrEqual);
+        return VisitFloat32Compare(this, value, &cont);
       case IrOpcode::kFloat64Equal:
         cont.OverwriteAndNegateIfEqual(kUnorderedEqual);
         return VisitFloat64Compare(this, value, &cont);
       case IrOpcode::kFloat64LessThan:
-        cont.OverwriteAndNegateIfEqual(kUnorderedLessThan);
+        cont.OverwriteAndNegateIfEqual(kUnsignedGreaterThan);
         return VisitFloat64Compare(this, value, &cont);
       case IrOpcode::kFloat64LessThanOrEqual:
-        cont.OverwriteAndNegateIfEqual(kUnorderedLessThanOrEqual);
+        cont.OverwriteAndNegateIfEqual(kUnsignedGreaterThanOrEqual);
         return VisitFloat64Compare(this, value, &cont);
       case IrOpcode::kProjection:
         // Check if this is the overflow output projection of an
         // <Operation>WithOverflow node.
-        if (OpParameter<size_t>(value) == 1u) {
+        if (ProjectionIndexOf(value->op()) == 1u) {
           // We cannot combine the <Operation>WithOverflow with this branch
           // unless the 0th projection (the use of the actual value of the
-          // <Operation> is either NULL, which means there's no use of the
+          // <Operation> is either nullptr, which means there's no use of the
           // actual value, or was already defined, which means it is scheduled
           // *AFTER* this branch).
-          Node* node = value->InputAt(0);
-          Node* result = node->FindProjection(0);
-          if (result == NULL || IsDefined(result)) {
+          Node* const node = value->InputAt(0);
+          Node* const result = NodeProperties::FindProjection(node, 0);
+          if (result == nullptr || IsDefined(result)) {
             switch (node->opcode()) {
               case IrOpcode::kInt32AddWithOverflow:
                 cont.OverwriteAndNegateIfEqual(kOverflow);
@@ -1126,6 +1518,12 @@
               case IrOpcode::kInt32SubWithOverflow:
                 cont.OverwriteAndNegateIfEqual(kOverflow);
                 return VisitBinop(this, node, kX64Sub32, &cont);
+              case IrOpcode::kInt64AddWithOverflow:
+                cont.OverwriteAndNegateIfEqual(kOverflow);
+                return VisitBinop(this, node, kX64Add, &cont);
+              case IrOpcode::kInt64SubWithOverflow:
+                cont.OverwriteAndNegateIfEqual(kOverflow);
+                return VisitBinop(this, node, kX64Sub, &cont);
               default:
                 break;
             }
@@ -1135,7 +1533,7 @@
       case IrOpcode::kInt32Sub:
         return VisitWordCompare(this, value, kX64Cmp32, &cont);
       case IrOpcode::kInt64Sub:
-        return VisitWordCompare(this, value, kX64Cmp, &cont);
+        return VisitWord64Compare(this, value, &cont);
       case IrOpcode::kWord32And:
         return VisitWordCompare(this, value, kX64Test32, &cont);
       case IrOpcode::kWord64And:
@@ -1150,6 +1548,37 @@
 }
 
 
+void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) {
+  X64OperandGenerator g(this);
+  InstructionOperand value_operand = g.UseRegister(node->InputAt(0));
+
+  // Emit either ArchTableSwitch or ArchLookupSwitch.
+  size_t table_space_cost = 4 + sw.value_range;
+  size_t table_time_cost = 3;
+  size_t lookup_space_cost = 3 + 2 * sw.case_count;
+  size_t lookup_time_cost = sw.case_count;
+  if (sw.case_count > 4 &&
+      table_space_cost + 3 * table_time_cost <=
+          lookup_space_cost + 3 * lookup_time_cost &&
+      sw.min_value > std::numeric_limits<int32_t>::min()) {
+    InstructionOperand index_operand = g.TempRegister();
+    if (sw.min_value) {
+      // The leal automatically zero extends, so result is a valid 64-bit index.
+      Emit(kX64Lea32 | AddressingModeField::encode(kMode_MRI), index_operand,
+           value_operand, g.TempImmediate(-sw.min_value));
+    } else {
+      // Zero extend, because we use it as 64-bit index into the jump table.
+      Emit(kX64Movl, index_operand, value_operand);
+    }
+    // Generate a table lookup.
+    return EmitTableSwitch(sw, index_operand);
+  }
+
+  // Generate a sequence of conditional jumps.
+  return EmitLookupSwitch(sw, value_operand);
+}
+
+
 void InstructionSelector::VisitWord32Equal(Node* const node) {
   Node* user = node;
   FlagsContinuation cont(kEqual, node);
@@ -1211,43 +1640,29 @@
 
 
 void InstructionSelector::VisitWord64Equal(Node* const node) {
-  Node* user = node;
   FlagsContinuation cont(kEqual, node);
-  Int64BinopMatcher m(user);
+  Int64BinopMatcher m(node);
   if (m.right().Is(0)) {
-    Node* value = m.left().node();
-
-    // Try to combine with comparisons against 0 by simply inverting the branch.
-    while (CanCover(user, value) && value->opcode() == IrOpcode::kWord64Equal) {
-      Int64BinopMatcher m(value);
-      if (m.right().Is(0)) {
-        user = value;
-        value = m.left().node();
-        cont.Negate();
-      } else {
-        break;
-      }
-    }
-
-    // Try to combine the branch with a comparison.
+    // Try to combine the equality check with a comparison.
+    Node* const user = m.node();
+    Node* const value = m.left().node();
     if (CanCover(user, value)) {
       switch (value->opcode()) {
         case IrOpcode::kInt64Sub:
-          return VisitWordCompare(this, value, kX64Cmp, &cont);
+          return VisitWord64Compare(this, value, &cont);
         case IrOpcode::kWord64And:
           return VisitWordCompare(this, value, kX64Test, &cont);
         default:
           break;
       }
     }
-    return VisitCompareZero(this, value, kX64Cmp, &cont);
   }
-  VisitWordCompare(this, node, kX64Cmp, &cont);
+  VisitWord64Compare(this, node, &cont);
 }
 
 
 void InstructionSelector::VisitInt32AddWithOverflow(Node* node) {
-  if (Node* ovf = node->FindProjection(1)) {
+  if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
     FlagsContinuation cont(kOverflow, ovf);
     VisitBinop(this, node, kX64Add32, &cont);
   }
@@ -1257,7 +1672,7 @@
 
 
 void InstructionSelector::VisitInt32SubWithOverflow(Node* node) {
-  if (Node* ovf = node->FindProjection(1)) {
+  if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
     FlagsContinuation cont(kOverflow, ovf);
     return VisitBinop(this, node, kX64Sub32, &cont);
   }
@@ -1268,19 +1683,43 @@
 
 void InstructionSelector::VisitInt64LessThan(Node* node) {
   FlagsContinuation cont(kSignedLessThan, node);
-  VisitWordCompare(this, node, kX64Cmp, &cont);
+  VisitWord64Compare(this, node, &cont);
 }
 
 
 void InstructionSelector::VisitInt64LessThanOrEqual(Node* node) {
   FlagsContinuation cont(kSignedLessThanOrEqual, node);
-  VisitWordCompare(this, node, kX64Cmp, &cont);
+  VisitWord64Compare(this, node, &cont);
 }
 
 
 void InstructionSelector::VisitUint64LessThan(Node* node) {
   FlagsContinuation cont(kUnsignedLessThan, node);
-  VisitWordCompare(this, node, kX64Cmp, &cont);
+  VisitWord64Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitUint64LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kUnsignedLessThanOrEqual, node);
+  VisitWord64Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitFloat32Equal(Node* node) {
+  FlagsContinuation cont(kUnorderedEqual, node);
+  VisitFloat32Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitFloat32LessThan(Node* node) {
+  FlagsContinuation cont(kUnsignedGreaterThan, node);
+  VisitFloat32Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitFloat32LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kUnsignedGreaterThanOrEqual, node);
+  VisitFloat32Compare(this, node, &cont);
 }
 
 
@@ -1291,27 +1730,79 @@
 
 
 void InstructionSelector::VisitFloat64LessThan(Node* node) {
-  FlagsContinuation cont(kUnorderedLessThan, node);
+  FlagsContinuation cont(kUnsignedGreaterThan, node);
   VisitFloat64Compare(this, node, &cont);
 }
 
 
 void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
-  FlagsContinuation cont(kUnorderedLessThanOrEqual, node);
+  FlagsContinuation cont(kUnsignedGreaterThanOrEqual, node);
   VisitFloat64Compare(this, node, &cont);
 }
 
 
+void InstructionSelector::VisitFloat64ExtractLowWord32(Node* node) {
+  X64OperandGenerator g(this);
+  Emit(kSSEFloat64ExtractLowWord32, g.DefineAsRegister(node),
+       g.Use(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitFloat64ExtractHighWord32(Node* node) {
+  X64OperandGenerator g(this);
+  Emit(kSSEFloat64ExtractHighWord32, g.DefineAsRegister(node),
+       g.Use(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitFloat64InsertLowWord32(Node* node) {
+  X64OperandGenerator g(this);
+  Node* left = node->InputAt(0);
+  Node* right = node->InputAt(1);
+  Float64Matcher mleft(left);
+  if (mleft.HasValue() && (bit_cast<uint64_t>(mleft.Value()) >> 32) == 0u) {
+    Emit(kSSEFloat64LoadLowWord32, g.DefineAsRegister(node), g.Use(right));
+    return;
+  }
+  Emit(kSSEFloat64InsertLowWord32, g.DefineSameAsFirst(node),
+       g.UseRegister(left), g.Use(right));
+}
+
+
+void InstructionSelector::VisitFloat64InsertHighWord32(Node* node) {
+  X64OperandGenerator g(this);
+  Node* left = node->InputAt(0);
+  Node* right = node->InputAt(1);
+  Emit(kSSEFloat64InsertHighWord32, g.DefineSameAsFirst(node),
+       g.UseRegister(left), g.Use(right));
+}
+
+
 // static
 MachineOperatorBuilder::Flags
 InstructionSelector::SupportedMachineOperatorFlags() {
-  if (CpuFeatures::IsSupported(SSE4_1)) {
-    return MachineOperatorBuilder::kFloat64Floor |
-           MachineOperatorBuilder::kFloat64Ceil |
-           MachineOperatorBuilder::kFloat64RoundTruncate |
-           MachineOperatorBuilder::kWord32ShiftIsSafe;
+  MachineOperatorBuilder::Flags flags =
+      MachineOperatorBuilder::kFloat32Max |
+      MachineOperatorBuilder::kFloat32Min |
+      MachineOperatorBuilder::kFloat64Max |
+      MachineOperatorBuilder::kFloat64Min |
+      MachineOperatorBuilder::kWord32ShiftIsSafe |
+      MachineOperatorBuilder::kWord32Ctz | MachineOperatorBuilder::kWord64Ctz;
+  if (CpuFeatures::IsSupported(POPCNT)) {
+    flags |= MachineOperatorBuilder::kWord32Popcnt |
+             MachineOperatorBuilder::kWord64Popcnt;
   }
-  return MachineOperatorBuilder::kNoFlags;
+  if (CpuFeatures::IsSupported(SSE4_1)) {
+    flags |= MachineOperatorBuilder::kFloat32RoundDown |
+             MachineOperatorBuilder::kFloat64RoundDown |
+             MachineOperatorBuilder::kFloat32RoundUp |
+             MachineOperatorBuilder::kFloat64RoundUp |
+             MachineOperatorBuilder::kFloat32RoundTruncate |
+             MachineOperatorBuilder::kFloat64RoundTruncate |
+             MachineOperatorBuilder::kFloat32RoundTiesEven |
+             MachineOperatorBuilder::kFloat64RoundTiesEven;
+  }
+  return flags;
 }
 
 }  // namespace compiler
diff --git a/src/compiler/x64/linkage-x64.cc b/src/compiler/x64/linkage-x64.cc
deleted file mode 100644
index 0b76cc7..0000000
--- a/src/compiler/x64/linkage-x64.cc
+++ /dev/null
@@ -1,81 +0,0 @@
-// 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/v8.h"
-
-#include "src/assembler.h"
-#include "src/code-stubs.h"
-#include "src/compiler/linkage.h"
-#include "src/compiler/linkage-impl.h"
-#include "src/zone.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-#ifdef _WIN64
-const bool kWin64 = true;
-#else
-const bool kWin64 = false;
-#endif
-
-struct X64LinkageHelperTraits {
-  static Register ReturnValueReg() { return rax; }
-  static Register ReturnValue2Reg() { return rdx; }
-  static Register JSCallFunctionReg() { return rdi; }
-  static Register ContextReg() { return rsi; }
-  static Register RuntimeCallFunctionReg() { return rbx; }
-  static Register RuntimeCallArgCountReg() { return rax; }
-  static RegList CCalleeSaveRegisters() {
-    if (kWin64) {
-      return rbx.bit() | rdi.bit() | rsi.bit() | r12.bit() | r13.bit() |
-             r14.bit() | r15.bit();
-    } else {
-      return rbx.bit() | r12.bit() | r13.bit() | r14.bit() | r15.bit();
-    }
-  }
-  static Register CRegisterParameter(int i) {
-    if (kWin64) {
-      static Register register_parameters[] = {rcx, rdx, r8, r9};
-      return register_parameters[i];
-    } else {
-      static Register register_parameters[] = {rdi, rsi, rdx, rcx, r8, r9};
-      return register_parameters[i];
-    }
-  }
-  static int CRegisterParametersLength() { return kWin64 ? 4 : 6; }
-};
-
-typedef LinkageHelper<X64LinkageHelperTraits> LH;
-
-CallDescriptor* Linkage::GetJSCallDescriptor(int parameter_count, Zone* zone,
-                                             CallDescriptor::Flags flags) {
-  return LH::GetJSCallDescriptor(zone, parameter_count, flags);
-}
-
-
-CallDescriptor* Linkage::GetRuntimeCallDescriptor(
-    Runtime::FunctionId function, int parameter_count,
-    Operator::Properties properties, Zone* zone) {
-  return LH::GetRuntimeCallDescriptor(zone, function, parameter_count,
-                                      properties);
-}
-
-
-CallDescriptor* Linkage::GetStubCallDescriptor(
-    const CallInterfaceDescriptor& descriptor, int stack_parameter_count,
-    CallDescriptor::Flags flags, Operator::Properties properties, Zone* zone) {
-  return LH::GetStubCallDescriptor(zone, descriptor, stack_parameter_count,
-                                   flags, properties);
-}
-
-
-CallDescriptor* Linkage::GetSimplifiedCDescriptor(Zone* zone,
-                                                  MachineSignature* sig) {
-  return LH::GetSimplifiedCDescriptor(zone, sig);
-}
-
-}  // namespace compiler
-}  // namespace internal
-}  // namespace v8
diff --git a/src/compiler/x87/OWNERS b/src/compiler/x87/OWNERS
new file mode 100644
index 0000000..61245ae
--- /dev/null
+++ b/src/compiler/x87/OWNERS
@@ -0,0 +1,2 @@
+weiliang.lin@intel.com
+chunyang.dai@intel.com
diff --git a/src/compiler/x87/code-generator-x87.cc b/src/compiler/x87/code-generator-x87.cc
new file mode 100644
index 0000000..a7b7246
--- /dev/null
+++ b/src/compiler/x87/code-generator-x87.cc
@@ -0,0 +1,2138 @@
+// Copyright 2013 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/code-generator.h"
+
+#include "src/ast/scopes.h"
+#include "src/compiler/code-generator-impl.h"
+#include "src/compiler/gap-resolver.h"
+#include "src/compiler/node-matchers.h"
+#include "src/compiler/osr.h"
+#include "src/x87/assembler-x87.h"
+#include "src/x87/frames-x87.h"
+#include "src/x87/macro-assembler-x87.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+#define __ masm()->
+
+
+// Adds X87 specific methods for decoding operands.
+class X87OperandConverter : public InstructionOperandConverter {
+ public:
+  X87OperandConverter(CodeGenerator* gen, Instruction* instr)
+      : InstructionOperandConverter(gen, instr) {}
+
+  Operand InputOperand(size_t index, int extra = 0) {
+    return ToOperand(instr_->InputAt(index), extra);
+  }
+
+  Immediate InputImmediate(size_t index) {
+    return ToImmediate(instr_->InputAt(index));
+  }
+
+  Operand OutputOperand() { return ToOperand(instr_->Output()); }
+
+  Operand ToOperand(InstructionOperand* op, int extra = 0) {
+    if (op->IsRegister()) {
+      DCHECK(extra == 0);
+      return Operand(ToRegister(op));
+    }
+    DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot());
+    FrameOffset offset = frame_access_state()->GetFrameOffset(
+        AllocatedOperand::cast(op)->index());
+    return Operand(offset.from_stack_pointer() ? esp : ebp,
+                   offset.offset() + extra);
+  }
+
+  Operand ToMaterializableOperand(int materializable_offset) {
+    FrameOffset offset = frame_access_state()->GetFrameOffset(
+        Frame::FPOffsetToSlot(materializable_offset));
+    return Operand(offset.from_stack_pointer() ? esp : ebp, offset.offset());
+  }
+
+  Operand HighOperand(InstructionOperand* op) {
+    DCHECK(op->IsDoubleStackSlot());
+    return ToOperand(op, kPointerSize);
+  }
+
+  Immediate ToImmediate(InstructionOperand* operand) {
+    Constant constant = ToConstant(operand);
+    switch (constant.type()) {
+      case Constant::kInt32:
+        return Immediate(constant.ToInt32());
+      case Constant::kFloat32:
+        return Immediate(
+            isolate()->factory()->NewNumber(constant.ToFloat32(), TENURED));
+      case Constant::kFloat64:
+        return Immediate(
+            isolate()->factory()->NewNumber(constant.ToFloat64(), TENURED));
+      case Constant::kExternalReference:
+        return Immediate(constant.ToExternalReference());
+      case Constant::kHeapObject:
+        return Immediate(constant.ToHeapObject());
+      case Constant::kInt64:
+        break;
+      case Constant::kRpoNumber:
+        return Immediate::CodeRelativeOffset(ToLabel(operand));
+    }
+    UNREACHABLE();
+    return Immediate(-1);
+  }
+
+  static size_t NextOffset(size_t* offset) {
+    size_t i = *offset;
+    (*offset)++;
+    return i;
+  }
+
+  static ScaleFactor ScaleFor(AddressingMode one, AddressingMode mode) {
+    STATIC_ASSERT(0 == static_cast<int>(times_1));
+    STATIC_ASSERT(1 == static_cast<int>(times_2));
+    STATIC_ASSERT(2 == static_cast<int>(times_4));
+    STATIC_ASSERT(3 == static_cast<int>(times_8));
+    int scale = static_cast<int>(mode - one);
+    DCHECK(scale >= 0 && scale < 4);
+    return static_cast<ScaleFactor>(scale);
+  }
+
+  Operand MemoryOperand(size_t* offset) {
+    AddressingMode mode = AddressingModeField::decode(instr_->opcode());
+    switch (mode) {
+      case kMode_MR: {
+        Register base = InputRegister(NextOffset(offset));
+        int32_t disp = 0;
+        return Operand(base, disp);
+      }
+      case kMode_MRI: {
+        Register base = InputRegister(NextOffset(offset));
+        int32_t disp = InputInt32(NextOffset(offset));
+        return Operand(base, disp);
+      }
+      case kMode_MR1:
+      case kMode_MR2:
+      case kMode_MR4:
+      case kMode_MR8: {
+        Register base = InputRegister(NextOffset(offset));
+        Register index = InputRegister(NextOffset(offset));
+        ScaleFactor scale = ScaleFor(kMode_MR1, mode);
+        int32_t disp = 0;
+        return Operand(base, index, scale, disp);
+      }
+      case kMode_MR1I:
+      case kMode_MR2I:
+      case kMode_MR4I:
+      case kMode_MR8I: {
+        Register base = InputRegister(NextOffset(offset));
+        Register index = InputRegister(NextOffset(offset));
+        ScaleFactor scale = ScaleFor(kMode_MR1I, mode);
+        int32_t disp = InputInt32(NextOffset(offset));
+        return Operand(base, index, scale, disp);
+      }
+      case kMode_M1:
+      case kMode_M2:
+      case kMode_M4:
+      case kMode_M8: {
+        Register index = InputRegister(NextOffset(offset));
+        ScaleFactor scale = ScaleFor(kMode_M1, mode);
+        int32_t disp = 0;
+        return Operand(index, scale, disp);
+      }
+      case kMode_M1I:
+      case kMode_M2I:
+      case kMode_M4I:
+      case kMode_M8I: {
+        Register index = InputRegister(NextOffset(offset));
+        ScaleFactor scale = ScaleFor(kMode_M1I, mode);
+        int32_t disp = InputInt32(NextOffset(offset));
+        return Operand(index, scale, disp);
+      }
+      case kMode_MI: {
+        int32_t disp = InputInt32(NextOffset(offset));
+        return Operand(Immediate(disp));
+      }
+      case kMode_None:
+        UNREACHABLE();
+        return Operand(no_reg, 0);
+    }
+    UNREACHABLE();
+    return Operand(no_reg, 0);
+  }
+
+  Operand MemoryOperand(size_t first_input = 0) {
+    return MemoryOperand(&first_input);
+  }
+};
+
+
+namespace {
+
+bool HasImmediateInput(Instruction* instr, size_t index) {
+  return instr->InputAt(index)->IsImmediate();
+}
+
+
+class OutOfLineLoadInteger final : public OutOfLineCode {
+ public:
+  OutOfLineLoadInteger(CodeGenerator* gen, Register result)
+      : OutOfLineCode(gen), result_(result) {}
+
+  void Generate() final { __ xor_(result_, result_); }
+
+ private:
+  Register const result_;
+};
+
+
+class OutOfLineLoadFloat final : public OutOfLineCode {
+ public:
+  OutOfLineLoadFloat(CodeGenerator* gen, X87Register result)
+      : OutOfLineCode(gen), result_(result) {}
+
+  void Generate() final {
+    DCHECK(result_.code() == 0);
+    USE(result_);
+    if (FLAG_debug_code && FLAG_enable_slow_asserts) {
+      __ VerifyX87StackDepth(1);
+    }
+    __ fstp(0);
+    __ push(Immediate(0xffffffff));
+    __ push(Immediate(0x7fffffff));
+    __ fld_d(MemOperand(esp, 0));
+    __ lea(esp, Operand(esp, kDoubleSize));
+  }
+
+ private:
+  X87Register const result_;
+};
+
+
+class OutOfLineTruncateDoubleToI final : public OutOfLineCode {
+ public:
+  OutOfLineTruncateDoubleToI(CodeGenerator* gen, Register result,
+                             X87Register input)
+      : OutOfLineCode(gen), result_(result), input_(input) {}
+
+  void Generate() final {
+    UNIMPLEMENTED();
+    USE(result_);
+    USE(input_);
+  }
+
+ private:
+  Register const result_;
+  X87Register const input_;
+};
+
+
+class OutOfLineRecordWrite final : public OutOfLineCode {
+ public:
+  OutOfLineRecordWrite(CodeGenerator* gen, Register object, Operand operand,
+                       Register value, Register scratch0, Register scratch1,
+                       RecordWriteMode mode)
+      : OutOfLineCode(gen),
+        object_(object),
+        operand_(operand),
+        value_(value),
+        scratch0_(scratch0),
+        scratch1_(scratch1),
+        mode_(mode) {}
+
+  void Generate() final {
+    if (mode_ > RecordWriteMode::kValueIsPointer) {
+      __ JumpIfSmi(value_, exit());
+    }
+    if (mode_ > RecordWriteMode::kValueIsMap) {
+      __ CheckPageFlag(value_, scratch0_,
+                       MemoryChunk::kPointersToHereAreInterestingMask, zero,
+                       exit());
+    }
+    SaveFPRegsMode const save_fp_mode =
+        frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs;
+    RecordWriteStub stub(isolate(), object_, scratch0_, scratch1_,
+                         EMIT_REMEMBERED_SET, save_fp_mode);
+    __ lea(scratch1_, operand_);
+    __ CallStub(&stub);
+  }
+
+ private:
+  Register const object_;
+  Operand const operand_;
+  Register const value_;
+  Register const scratch0_;
+  Register const scratch1_;
+  RecordWriteMode const mode_;
+};
+
+}  // namespace
+
+
+#define ASSEMBLE_CHECKED_LOAD_FLOAT(asm_instr)                          \
+  do {                                                                  \
+    auto result = i.OutputDoubleRegister();                             \
+    auto offset = i.InputRegister(0);                                   \
+    DCHECK(result.code() == 0);                                         \
+    if (instr->InputAt(1)->IsRegister()) {                              \
+      __ cmp(offset, i.InputRegister(1));                               \
+    } else {                                                            \
+      __ cmp(offset, i.InputImmediate(1));                              \
+    }                                                                   \
+    OutOfLineCode* ool = new (zone()) OutOfLineLoadFloat(this, result); \
+    __ j(above_equal, ool->entry());                                    \
+    __ fstp(0);                                                         \
+    __ asm_instr(i.MemoryOperand(2));                                   \
+    __ bind(ool->exit());                                               \
+  } while (false)
+
+
+#define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr)                          \
+  do {                                                                    \
+    auto result = i.OutputRegister();                                     \
+    auto offset = i.InputRegister(0);                                     \
+    if (instr->InputAt(1)->IsRegister()) {                                \
+      __ cmp(offset, i.InputRegister(1));                                 \
+    } else {                                                              \
+      __ cmp(offset, i.InputImmediate(1));                                \
+    }                                                                     \
+    OutOfLineCode* ool = new (zone()) OutOfLineLoadInteger(this, result); \
+    __ j(above_equal, ool->entry());                                      \
+    __ asm_instr(result, i.MemoryOperand(2));                             \
+    __ bind(ool->exit());                                                 \
+  } while (false)
+
+
+#define ASSEMBLE_CHECKED_STORE_FLOAT(asm_instr)   \
+  do {                                            \
+    auto offset = i.InputRegister(0);             \
+    if (instr->InputAt(1)->IsRegister()) {        \
+      __ cmp(offset, i.InputRegister(1));         \
+    } else {                                      \
+      __ cmp(offset, i.InputImmediate(1));        \
+    }                                             \
+    Label done;                                   \
+    DCHECK(i.InputDoubleRegister(2).code() == 0); \
+    __ j(above_equal, &done, Label::kNear);       \
+    __ asm_instr(i.MemoryOperand(3));             \
+    __ bind(&done);                               \
+  } while (false)
+
+
+#define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr)            \
+  do {                                                       \
+    auto offset = i.InputRegister(0);                        \
+    if (instr->InputAt(1)->IsRegister()) {                   \
+      __ cmp(offset, i.InputRegister(1));                    \
+    } else {                                                 \
+      __ cmp(offset, i.InputImmediate(1));                   \
+    }                                                        \
+    Label done;                                              \
+    __ j(above_equal, &done, Label::kNear);                  \
+    if (instr->InputAt(2)->IsRegister()) {                   \
+      __ asm_instr(i.MemoryOperand(3), i.InputRegister(2));  \
+    } else {                                                 \
+      __ asm_instr(i.MemoryOperand(3), i.InputImmediate(2)); \
+    }                                                        \
+    __ bind(&done);                                          \
+  } while (false)
+
+
+void CodeGenerator::AssembleDeconstructActivationRecord(int stack_param_delta) {
+  int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta);
+  if (sp_slot_delta > 0) {
+    __ add(esp, Immediate(sp_slot_delta * kPointerSize));
+  }
+  frame_access_state()->SetFrameAccessToDefault();
+}
+
+
+void CodeGenerator::AssemblePrepareTailCall(int stack_param_delta) {
+  int sp_slot_delta = TailCallFrameStackSlotDelta(stack_param_delta);
+  if (sp_slot_delta < 0) {
+    __ sub(esp, Immediate(-sp_slot_delta * kPointerSize));
+    frame_access_state()->IncreaseSPDelta(-sp_slot_delta);
+  }
+  if (frame()->needs_frame()) {
+    __ mov(ebp, MemOperand(ebp, 0));
+  }
+  frame_access_state()->SetFrameAccessToSP();
+}
+
+
+// Assembles an instruction after register allocation, producing machine code.
+void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
+  X87OperandConverter i(this, instr);
+
+  switch (ArchOpcodeField::decode(instr->opcode())) {
+    case kArchCallCodeObject: {
+      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
+        __ VerifyX87StackDepth(1);
+      }
+      __ fstp(0);
+      EnsureSpaceForLazyDeopt();
+      if (HasImmediateInput(instr, 0)) {
+        Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0));
+        __ call(code, RelocInfo::CODE_TARGET);
+      } else {
+        Register reg = i.InputRegister(0);
+        __ add(reg, Immediate(Code::kHeaderSize - kHeapObjectTag));
+        __ call(reg);
+      }
+      RecordCallPosition(instr);
+      bool double_result =
+          instr->HasOutput() && instr->Output()->IsDoubleRegister();
+      if (double_result) {
+        __ lea(esp, Operand(esp, -kDoubleSize));
+        __ fstp_d(Operand(esp, 0));
+      }
+      __ fninit();
+      if (double_result) {
+        __ fld_d(Operand(esp, 0));
+        __ lea(esp, Operand(esp, kDoubleSize));
+      } else {
+        __ fld1();
+      }
+      frame_access_state()->ClearSPDelta();
+      break;
+    }
+    case kArchTailCallCodeObject: {
+      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
+        __ VerifyX87StackDepth(1);
+      }
+      __ fstp(0);
+      int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
+      AssembleDeconstructActivationRecord(stack_param_delta);
+      if (HasImmediateInput(instr, 0)) {
+        Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0));
+        __ jmp(code, RelocInfo::CODE_TARGET);
+      } else {
+        Register reg = i.InputRegister(0);
+        __ add(reg, Immediate(Code::kHeaderSize - kHeapObjectTag));
+        __ jmp(reg);
+      }
+      frame_access_state()->ClearSPDelta();
+      break;
+    }
+    case kArchCallJSFunction: {
+      EnsureSpaceForLazyDeopt();
+      Register func = i.InputRegister(0);
+      if (FLAG_debug_code) {
+        // Check the function's context matches the context argument.
+        __ cmp(esi, FieldOperand(func, JSFunction::kContextOffset));
+        __ Assert(equal, kWrongFunctionContext);
+      }
+      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
+        __ VerifyX87StackDepth(1);
+      }
+      __ fstp(0);
+      __ call(FieldOperand(func, JSFunction::kCodeEntryOffset));
+      RecordCallPosition(instr);
+      bool double_result =
+          instr->HasOutput() && instr->Output()->IsDoubleRegister();
+      if (double_result) {
+        __ lea(esp, Operand(esp, -kDoubleSize));
+        __ fstp_d(Operand(esp, 0));
+      }
+      __ fninit();
+      if (double_result) {
+        __ fld_d(Operand(esp, 0));
+        __ lea(esp, Operand(esp, kDoubleSize));
+      } else {
+        __ fld1();
+      }
+      frame_access_state()->ClearSPDelta();
+      break;
+    }
+    case kArchTailCallJSFunction: {
+      Register func = i.InputRegister(0);
+      if (FLAG_debug_code) {
+        // Check the function's context matches the context argument.
+        __ cmp(esi, FieldOperand(func, JSFunction::kContextOffset));
+        __ Assert(equal, kWrongFunctionContext);
+      }
+      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
+        __ VerifyX87StackDepth(1);
+      }
+      __ fstp(0);
+      int stack_param_delta = i.InputInt32(instr->InputCount() - 1);
+      AssembleDeconstructActivationRecord(stack_param_delta);
+      __ jmp(FieldOperand(func, JSFunction::kCodeEntryOffset));
+      frame_access_state()->ClearSPDelta();
+      break;
+    }
+    case kArchLazyBailout: {
+      EnsureSpaceForLazyDeopt();
+      RecordCallPosition(instr);
+      // Lazy Bailout entry, need to re-initialize FPU state.
+      __ fninit();
+      __ fld1();
+      break;
+    }
+    case kArchPrepareCallCFunction: {
+      // Frame alignment requires using FP-relative frame addressing.
+      frame_access_state()->SetFrameAccessToFP();
+      int const num_parameters = MiscField::decode(instr->opcode());
+      __ PrepareCallCFunction(num_parameters, i.TempRegister(0));
+      break;
+    }
+    case kArchPrepareTailCall:
+      AssemblePrepareTailCall(i.InputInt32(instr->InputCount() - 1));
+      break;
+    case kArchCallCFunction: {
+      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
+        __ VerifyX87StackDepth(1);
+      }
+      __ fstp(0);
+      int const num_parameters = MiscField::decode(instr->opcode());
+      if (HasImmediateInput(instr, 0)) {
+        ExternalReference ref = i.InputExternalReference(0);
+        __ CallCFunction(ref, num_parameters);
+      } else {
+        Register func = i.InputRegister(0);
+        __ CallCFunction(func, num_parameters);
+      }
+      bool double_result =
+          instr->HasOutput() && instr->Output()->IsDoubleRegister();
+      if (double_result) {
+        __ lea(esp, Operand(esp, -kDoubleSize));
+        __ fstp_d(Operand(esp, 0));
+      }
+      __ fninit();
+      if (double_result) {
+        __ fld_d(Operand(esp, 0));
+        __ lea(esp, Operand(esp, kDoubleSize));
+      } else {
+        __ fld1();
+      }
+      frame_access_state()->SetFrameAccessToDefault();
+      frame_access_state()->ClearSPDelta();
+      break;
+    }
+    case kArchJmp:
+      AssembleArchJump(i.InputRpo(0));
+      break;
+    case kArchLookupSwitch:
+      AssembleArchLookupSwitch(instr);
+      break;
+    case kArchTableSwitch:
+      AssembleArchTableSwitch(instr);
+      break;
+    case kArchNop:
+    case kArchThrowTerminator:
+      // don't emit code for nops.
+      break;
+    case kArchDeoptimize: {
+      int deopt_state_id =
+          BuildTranslation(instr, -1, 0, OutputFrameStateCombine::Ignore());
+      int double_register_param_count = 0;
+      int x87_layout = 0;
+      for (size_t i = 0; i < instr->InputCount(); i++) {
+        if (instr->InputAt(i)->IsDoubleRegister()) {
+          double_register_param_count++;
+        }
+      }
+      // Currently we use only one X87 register. If double_register_param_count
+      // is bigger than 1, it means duplicated double register is added to input
+      // of this instruction.
+      if (double_register_param_count > 0) {
+        x87_layout = (0 << 3) | 1;
+      }
+      // The layout of x87 register stack is loaded on the top of FPU register
+      // stack for deoptimization.
+      __ push(Immediate(x87_layout));
+      __ fild_s(MemOperand(esp, 0));
+      __ lea(esp, Operand(esp, kPointerSize));
+
+      Deoptimizer::BailoutType bailout_type =
+          Deoptimizer::BailoutType(MiscField::decode(instr->opcode()));
+      AssembleDeoptimizerCall(deopt_state_id, bailout_type);
+      break;
+    }
+    case kArchRet:
+      AssembleReturn();
+      break;
+    case kArchFramePointer:
+      __ mov(i.OutputRegister(), ebp);
+      break;
+    case kArchStackPointer:
+      __ mov(i.OutputRegister(), esp);
+      break;
+    case kArchTruncateDoubleToI: {
+      if (!instr->InputAt(0)->IsDoubleRegister()) {
+        __ fld_d(i.InputOperand(0));
+      }
+      __ TruncateX87TOSToI(i.OutputRegister());
+      if (!instr->InputAt(0)->IsDoubleRegister()) {
+        __ fstp(0);
+      }
+      break;
+    }
+    case kArchStoreWithWriteBarrier: {
+      RecordWriteMode mode =
+          static_cast<RecordWriteMode>(MiscField::decode(instr->opcode()));
+      Register object = i.InputRegister(0);
+      size_t index = 0;
+      Operand operand = i.MemoryOperand(&index);
+      Register value = i.InputRegister(index);
+      Register scratch0 = i.TempRegister(0);
+      Register scratch1 = i.TempRegister(1);
+      auto ool = new (zone()) OutOfLineRecordWrite(this, object, operand, value,
+                                                   scratch0, scratch1, mode);
+      __ mov(operand, value);
+      __ CheckPageFlag(object, scratch0,
+                       MemoryChunk::kPointersFromHereAreInterestingMask,
+                       not_zero, ool->entry());
+      __ bind(ool->exit());
+      break;
+    }
+    case kX87Add:
+      if (HasImmediateInput(instr, 1)) {
+        __ add(i.InputOperand(0), i.InputImmediate(1));
+      } else {
+        __ add(i.InputRegister(0), i.InputOperand(1));
+      }
+      break;
+    case kX87And:
+      if (HasImmediateInput(instr, 1)) {
+        __ and_(i.InputOperand(0), i.InputImmediate(1));
+      } else {
+        __ and_(i.InputRegister(0), i.InputOperand(1));
+      }
+      break;
+    case kX87Cmp:
+      if (HasImmediateInput(instr, 1)) {
+        __ cmp(i.InputOperand(0), i.InputImmediate(1));
+      } else {
+        __ cmp(i.InputRegister(0), i.InputOperand(1));
+      }
+      break;
+    case kX87Test:
+      if (HasImmediateInput(instr, 1)) {
+        __ test(i.InputOperand(0), i.InputImmediate(1));
+      } else {
+        __ test(i.InputRegister(0), i.InputOperand(1));
+      }
+      break;
+    case kX87Imul:
+      if (HasImmediateInput(instr, 1)) {
+        __ imul(i.OutputRegister(), i.InputOperand(0), i.InputInt32(1));
+      } else {
+        __ imul(i.OutputRegister(), i.InputOperand(1));
+      }
+      break;
+    case kX87ImulHigh:
+      __ imul(i.InputRegister(1));
+      break;
+    case kX87UmulHigh:
+      __ mul(i.InputRegister(1));
+      break;
+    case kX87Idiv:
+      __ cdq();
+      __ idiv(i.InputOperand(1));
+      break;
+    case kX87Udiv:
+      __ Move(edx, Immediate(0));
+      __ div(i.InputOperand(1));
+      break;
+    case kX87Not:
+      __ not_(i.OutputOperand());
+      break;
+    case kX87Neg:
+      __ neg(i.OutputOperand());
+      break;
+    case kX87Or:
+      if (HasImmediateInput(instr, 1)) {
+        __ or_(i.InputOperand(0), i.InputImmediate(1));
+      } else {
+        __ or_(i.InputRegister(0), i.InputOperand(1));
+      }
+      break;
+    case kX87Xor:
+      if (HasImmediateInput(instr, 1)) {
+        __ xor_(i.InputOperand(0), i.InputImmediate(1));
+      } else {
+        __ xor_(i.InputRegister(0), i.InputOperand(1));
+      }
+      break;
+    case kX87Sub:
+      if (HasImmediateInput(instr, 1)) {
+        __ sub(i.InputOperand(0), i.InputImmediate(1));
+      } else {
+        __ sub(i.InputRegister(0), i.InputOperand(1));
+      }
+      break;
+    case kX87Shl:
+      if (HasImmediateInput(instr, 1)) {
+        __ shl(i.OutputOperand(), i.InputInt5(1));
+      } else {
+        __ shl_cl(i.OutputOperand());
+      }
+      break;
+    case kX87Shr:
+      if (HasImmediateInput(instr, 1)) {
+        __ shr(i.OutputOperand(), i.InputInt5(1));
+      } else {
+        __ shr_cl(i.OutputOperand());
+      }
+      break;
+    case kX87Sar:
+      if (HasImmediateInput(instr, 1)) {
+        __ sar(i.OutputOperand(), i.InputInt5(1));
+      } else {
+        __ sar_cl(i.OutputOperand());
+      }
+      break;
+    case kX87Ror:
+      if (HasImmediateInput(instr, 1)) {
+        __ ror(i.OutputOperand(), i.InputInt5(1));
+      } else {
+        __ ror_cl(i.OutputOperand());
+      }
+      break;
+    case kX87Lzcnt:
+      __ Lzcnt(i.OutputRegister(), i.InputOperand(0));
+      break;
+    case kX87Popcnt:
+      __ Popcnt(i.OutputRegister(), i.InputOperand(0));
+      break;
+    case kX87LoadFloat64Constant: {
+      InstructionOperand* source = instr->InputAt(0);
+      InstructionOperand* destination = instr->Output();
+      DCHECK(source->IsConstant());
+      X87OperandConverter g(this, nullptr);
+      Constant src_constant = g.ToConstant(source);
+
+      DCHECK_EQ(Constant::kFloat64, src_constant.type());
+      uint64_t src = bit_cast<uint64_t>(src_constant.ToFloat64());
+      uint32_t lower = static_cast<uint32_t>(src);
+      uint32_t upper = static_cast<uint32_t>(src >> 32);
+      if (destination->IsDoubleRegister()) {
+        __ sub(esp, Immediate(kDoubleSize));
+        __ mov(MemOperand(esp, 0), Immediate(lower));
+        __ mov(MemOperand(esp, kInt32Size), Immediate(upper));
+        __ fstp(0);
+        __ fld_d(MemOperand(esp, 0));
+        __ add(esp, Immediate(kDoubleSize));
+      } else {
+        UNREACHABLE();
+      }
+      break;
+    }
+    case kX87Float32Cmp: {
+      __ fld_s(MemOperand(esp, kFloatSize));
+      __ fld_s(MemOperand(esp, 0));
+      __ FCmp();
+      __ lea(esp, Operand(esp, 2 * kFloatSize));
+      break;
+    }
+    case kX87Float32Add: {
+      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
+        __ VerifyX87StackDepth(1);
+      }
+      __ X87SetFPUCW(0x027F);
+      __ fstp(0);
+      __ fld_s(MemOperand(esp, 0));
+      __ fld_s(MemOperand(esp, kFloatSize));
+      __ faddp();
+      // Clear stack.
+      __ lea(esp, Operand(esp, 2 * kFloatSize));
+      // Restore the default value of control word.
+      __ X87SetFPUCW(0x037F);
+      break;
+    }
+    case kX87Float32Sub: {
+      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
+        __ VerifyX87StackDepth(1);
+      }
+      __ X87SetFPUCW(0x027F);
+      __ fstp(0);
+      __ fld_s(MemOperand(esp, kFloatSize));
+      __ fld_s(MemOperand(esp, 0));
+      __ fsubp();
+      // Clear stack.
+      __ lea(esp, Operand(esp, 2 * kFloatSize));
+      // Restore the default value of control word.
+      __ X87SetFPUCW(0x037F);
+      break;
+    }
+    case kX87Float32Mul: {
+      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
+        __ VerifyX87StackDepth(1);
+      }
+      __ X87SetFPUCW(0x027F);
+      __ fstp(0);
+      __ fld_s(MemOperand(esp, kFloatSize));
+      __ fld_s(MemOperand(esp, 0));
+      __ fmulp();
+      // Clear stack.
+      __ lea(esp, Operand(esp, 2 * kFloatSize));
+      // Restore the default value of control word.
+      __ X87SetFPUCW(0x037F);
+      break;
+    }
+    case kX87Float32Div: {
+      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
+        __ VerifyX87StackDepth(1);
+      }
+      __ X87SetFPUCW(0x027F);
+      __ fstp(0);
+      __ fld_s(MemOperand(esp, kFloatSize));
+      __ fld_s(MemOperand(esp, 0));
+      __ fdivp();
+      // Clear stack.
+      __ lea(esp, Operand(esp, 2 * kFloatSize));
+      // Restore the default value of control word.
+      __ X87SetFPUCW(0x037F);
+      break;
+    }
+    case kX87Float32Max: {
+      Label check_nan_left, check_zero, return_left, return_right;
+      Condition condition = below;
+      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
+        __ VerifyX87StackDepth(1);
+      }
+      __ fstp(0);
+      __ fld_s(MemOperand(esp, kFloatSize));
+      __ fld_s(MemOperand(esp, 0));
+      __ fld(1);
+      __ fld(1);
+      __ FCmp();
+
+      // At least one NaN.
+      // Return the second operands if one of the two operands is NaN
+      __ j(parity_even, &return_right, Label::kNear);
+      __ j(equal, &check_zero, Label::kNear);            // left == right.
+      __ j(condition, &return_left, Label::kNear);
+      __ jmp(&return_right, Label::kNear);
+
+      __ bind(&check_zero);
+      __ fld(0);
+      __ fldz();
+      __ FCmp();
+      __ j(not_equal, &return_left, Label::kNear);  // left == right != 0.
+
+      __ fadd(1);
+      __ jmp(&return_left, Label::kNear);
+
+      __ bind(&return_right);
+      __ fxch();
+
+      __ bind(&return_left);
+      __ fstp(0);
+      __ lea(esp, Operand(esp, 2 * kFloatSize));
+      break;
+    }
+    case kX87Float32Min: {
+      Label check_nan_left, check_zero, return_left, return_right;
+      Condition condition = above;
+      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
+        __ VerifyX87StackDepth(1);
+      }
+      __ fstp(0);
+      __ fld_s(MemOperand(esp, kFloatSize));
+      __ fld_s(MemOperand(esp, 0));
+      __ fld(1);
+      __ fld(1);
+      __ FCmp();
+      // At least one NaN.
+      // Return the second operands if one of the two operands is NaN
+      __ j(parity_even, &return_right, Label::kNear);
+      __ j(equal, &check_zero, Label::kNear);            // left == right.
+      __ j(condition, &return_left, Label::kNear);
+      __ jmp(&return_right, Label::kNear);
+
+      __ bind(&check_zero);
+      __ fld(0);
+      __ fldz();
+      __ FCmp();
+      __ j(not_equal, &return_left, Label::kNear);  // left == right != 0.
+      // At this point, both left and right are either 0 or -0.
+      // Push st0 and st1 to stack, then pop them to temp registers and OR them,
+      // load it to left.
+      __ push(eax);
+      __ fld(1);
+      __ fld(1);
+      __ sub(esp, Immediate(2 * kPointerSize));
+      __ fstp_s(MemOperand(esp, 0));
+      __ fstp_s(MemOperand(esp, kPointerSize));
+      __ pop(eax);
+      __ xor_(MemOperand(esp, 0), eax);
+      __ fstp(0);
+      __ fld_s(MemOperand(esp, 0));
+      __ pop(eax);  // restore esp
+      __ pop(eax);  // restore esp
+      __ jmp(&return_left, Label::kNear);
+
+
+      __ bind(&return_right);
+      __ fxch();
+
+      __ bind(&return_left);
+      __ fstp(0);
+      __ lea(esp, Operand(esp, 2 * kFloatSize));
+      break;
+    }
+    case kX87Float32Sqrt: {
+      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
+        __ VerifyX87StackDepth(1);
+      }
+      __ fstp(0);
+      __ fld_s(MemOperand(esp, 0));
+      __ fsqrt();
+      __ lea(esp, Operand(esp, kFloatSize));
+      break;
+    }
+    case kX87Float32Abs: {
+      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
+        __ VerifyX87StackDepth(1);
+      }
+      __ fstp(0);
+      __ fld_s(MemOperand(esp, 0));
+      __ fabs();
+      __ lea(esp, Operand(esp, kFloatSize));
+      break;
+    }
+    case kX87Float32Round: {
+      RoundingMode mode =
+          static_cast<RoundingMode>(MiscField::decode(instr->opcode()));
+      // Set the correct round mode in x87 control register
+      __ X87SetRC((mode << 10));
+
+      if (!instr->InputAt(0)->IsDoubleRegister()) {
+        InstructionOperand* input = instr->InputAt(0);
+        USE(input);
+        DCHECK(input->IsDoubleStackSlot());
+        if (FLAG_debug_code && FLAG_enable_slow_asserts) {
+          __ VerifyX87StackDepth(1);
+        }
+        __ fstp(0);
+        __ fld_s(i.InputOperand(0));
+      }
+      __ frndint();
+      __ X87SetRC(0x0000);
+      break;
+    }
+    case kX87Float64Add: {
+      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
+        __ VerifyX87StackDepth(1);
+      }
+      __ X87SetFPUCW(0x027F);
+      __ fstp(0);
+      __ fld_d(MemOperand(esp, 0));
+      __ fld_d(MemOperand(esp, kDoubleSize));
+      __ faddp();
+      // Clear stack.
+      __ lea(esp, Operand(esp, 2 * kDoubleSize));
+      // Restore the default value of control word.
+      __ X87SetFPUCW(0x037F);
+      break;
+    }
+    case kX87Float64Sub: {
+      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
+        __ VerifyX87StackDepth(1);
+      }
+      __ X87SetFPUCW(0x027F);
+      __ fstp(0);
+      __ fld_d(MemOperand(esp, kDoubleSize));
+      __ fsub_d(MemOperand(esp, 0));
+      // Clear stack.
+      __ lea(esp, Operand(esp, 2 * kDoubleSize));
+      // Restore the default value of control word.
+      __ X87SetFPUCW(0x037F);
+      break;
+    }
+    case kX87Float64Mul: {
+      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
+        __ VerifyX87StackDepth(1);
+      }
+      __ X87SetFPUCW(0x027F);
+      __ fstp(0);
+      __ fld_d(MemOperand(esp, kDoubleSize));
+      __ fmul_d(MemOperand(esp, 0));
+      // Clear stack.
+      __ lea(esp, Operand(esp, 2 * kDoubleSize));
+      // Restore the default value of control word.
+      __ X87SetFPUCW(0x037F);
+      break;
+    }
+    case kX87Float64Div: {
+      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
+        __ VerifyX87StackDepth(1);
+      }
+      __ X87SetFPUCW(0x027F);
+      __ fstp(0);
+      __ fld_d(MemOperand(esp, kDoubleSize));
+      __ fdiv_d(MemOperand(esp, 0));
+      // Clear stack.
+      __ lea(esp, Operand(esp, 2 * kDoubleSize));
+      // Restore the default value of control word.
+      __ X87SetFPUCW(0x037F);
+      break;
+    }
+    case kX87Float64Mod: {
+      FrameScope frame_scope(&masm_, StackFrame::MANUAL);
+      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
+        __ VerifyX87StackDepth(1);
+      }
+      __ mov(eax, esp);
+      __ PrepareCallCFunction(4, eax);
+      __ fstp(0);
+      __ fld_d(MemOperand(eax, 0));
+      __ fstp_d(Operand(esp, 1 * kDoubleSize));
+      __ fld_d(MemOperand(eax, kDoubleSize));
+      __ fstp_d(Operand(esp, 0));
+      __ CallCFunction(ExternalReference::mod_two_doubles_operation(isolate()),
+                       4);
+      __ lea(esp, Operand(esp, 2 * kDoubleSize));
+      break;
+    }
+    case kX87Float64Max: {
+      Label check_zero, return_left, return_right;
+      Condition condition = below;
+      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
+        __ VerifyX87StackDepth(1);
+      }
+      __ fstp(0);
+      __ fld_d(MemOperand(esp, kDoubleSize));
+      __ fld_d(MemOperand(esp, 0));
+      __ fld(1);
+      __ fld(1);
+      __ FCmp();
+      __ j(parity_even, &return_right,
+           Label::kNear);  // At least one NaN, Return right.
+      __ j(equal, &check_zero, Label::kNear);  // left == right.
+      __ j(condition, &return_left, Label::kNear);
+      __ jmp(&return_right, Label::kNear);
+
+      __ bind(&check_zero);
+      __ fld(0);
+      __ fldz();
+      __ FCmp();
+      __ j(not_equal, &return_left, Label::kNear);  // left == right != 0.
+
+      __ bind(&return_right);
+      __ fxch();
+
+      __ bind(&return_left);
+      __ fstp(0);
+      __ lea(esp, Operand(esp, 2 * kDoubleSize));
+      break;
+    }
+    case kX87Float64Min: {
+      Label check_zero, return_left, return_right;
+      Condition condition = above;
+      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
+        __ VerifyX87StackDepth(1);
+      }
+      __ fstp(0);
+      __ fld_d(MemOperand(esp, kDoubleSize));
+      __ fld_d(MemOperand(esp, 0));
+      __ fld(1);
+      __ fld(1);
+      __ FCmp();
+      __ j(parity_even, &return_right,
+           Label::kNear);  // At least one NaN, return right value.
+      __ j(equal, &check_zero, Label::kNear);  // left == right.
+      __ j(condition, &return_left, Label::kNear);
+      __ jmp(&return_right, Label::kNear);
+
+      __ bind(&check_zero);
+      __ fld(0);
+      __ fldz();
+      __ FCmp();
+      __ j(not_equal, &return_left, Label::kNear);  // left == right != 0.
+
+      __ bind(&return_right);
+      __ fxch();
+
+      __ bind(&return_left);
+      __ fstp(0);
+      __ lea(esp, Operand(esp, 2 * kDoubleSize));
+      break;
+    }
+    case kX87Float64Abs: {
+      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
+        __ VerifyX87StackDepth(1);
+      }
+      __ fstp(0);
+      __ fld_d(MemOperand(esp, 0));
+      __ fabs();
+      __ lea(esp, Operand(esp, kDoubleSize));
+      break;
+    }
+    case kX87Int32ToFloat64: {
+      InstructionOperand* input = instr->InputAt(0);
+      DCHECK(input->IsRegister() || input->IsStackSlot());
+      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
+        __ VerifyX87StackDepth(1);
+      }
+      __ fstp(0);
+      if (input->IsRegister()) {
+        Register input_reg = i.InputRegister(0);
+        __ push(input_reg);
+        __ fild_s(Operand(esp, 0));
+        __ pop(input_reg);
+      } else {
+        __ fild_s(i.InputOperand(0));
+      }
+      break;
+    }
+    case kX87Float32ToFloat64: {
+      InstructionOperand* input = instr->InputAt(0);
+      if (input->IsDoubleRegister()) {
+        __ sub(esp, Immediate(kDoubleSize));
+        __ fstp_d(MemOperand(esp, 0));
+        __ fld_d(MemOperand(esp, 0));
+        __ add(esp, Immediate(kDoubleSize));
+      } else {
+        DCHECK(input->IsDoubleStackSlot());
+        if (FLAG_debug_code && FLAG_enable_slow_asserts) {
+          __ VerifyX87StackDepth(1);
+        }
+        __ fstp(0);
+        __ fld_s(i.InputOperand(0));
+      }
+      break;
+    }
+    case kX87Uint32ToFloat64: {
+      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
+        __ VerifyX87StackDepth(1);
+      }
+      __ fstp(0);
+      __ LoadUint32NoSSE2(i.InputRegister(0));
+      break;
+    }
+    case kX87Float64ToInt32: {
+      if (!instr->InputAt(0)->IsDoubleRegister()) {
+        __ fld_d(i.InputOperand(0));
+      }
+      __ TruncateX87TOSToI(i.OutputRegister(0));
+      if (!instr->InputAt(0)->IsDoubleRegister()) {
+        __ fstp(0);
+      }
+      break;
+    }
+    case kX87Float64ToFloat32: {
+      InstructionOperand* input = instr->InputAt(0);
+      if (input->IsDoubleRegister()) {
+        __ sub(esp, Immediate(kDoubleSize));
+        __ fstp_s(MemOperand(esp, 0));
+        __ fld_s(MemOperand(esp, 0));
+        __ add(esp, Immediate(kDoubleSize));
+      } else {
+        DCHECK(input->IsDoubleStackSlot());
+        if (FLAG_debug_code && FLAG_enable_slow_asserts) {
+          __ VerifyX87StackDepth(1);
+        }
+        __ fstp(0);
+        __ fld_d(i.InputOperand(0));
+        __ sub(esp, Immediate(kDoubleSize));
+        __ fstp_s(MemOperand(esp, 0));
+        __ fld_s(MemOperand(esp, 0));
+        __ add(esp, Immediate(kDoubleSize));
+      }
+      break;
+    }
+    case kX87Float64ToUint32: {
+      __ push_imm32(-2147483648);
+      if (!instr->InputAt(0)->IsDoubleRegister()) {
+        __ fld_d(i.InputOperand(0));
+      }
+      __ fild_s(Operand(esp, 0));
+      __ fadd(1);
+      __ fstp(0);
+      __ TruncateX87TOSToI(i.OutputRegister(0));
+      __ add(esp, Immediate(kInt32Size));
+      __ add(i.OutputRegister(), Immediate(0x80000000));
+      if (!instr->InputAt(0)->IsDoubleRegister()) {
+        __ fstp(0);
+      }
+      break;
+    }
+    case kX87Float64ExtractHighWord32: {
+      if (instr->InputAt(0)->IsDoubleRegister()) {
+        __ sub(esp, Immediate(kDoubleSize));
+        __ fst_d(MemOperand(esp, 0));
+        __ mov(i.OutputRegister(), MemOperand(esp, kDoubleSize / 2));
+        __ add(esp, Immediate(kDoubleSize));
+      } else {
+        InstructionOperand* input = instr->InputAt(0);
+        USE(input);
+        DCHECK(input->IsDoubleStackSlot());
+        __ mov(i.OutputRegister(), i.InputOperand(0, kDoubleSize / 2));
+      }
+      break;
+    }
+    case kX87Float64ExtractLowWord32: {
+      if (instr->InputAt(0)->IsDoubleRegister()) {
+        __ sub(esp, Immediate(kDoubleSize));
+        __ fst_d(MemOperand(esp, 0));
+        __ mov(i.OutputRegister(), MemOperand(esp, 0));
+        __ add(esp, Immediate(kDoubleSize));
+      } else {
+        InstructionOperand* input = instr->InputAt(0);
+        USE(input);
+        DCHECK(input->IsDoubleStackSlot());
+        __ mov(i.OutputRegister(), i.InputOperand(0));
+      }
+      break;
+    }
+    case kX87Float64InsertHighWord32: {
+      __ sub(esp, Immediate(kDoubleSize));
+      __ fstp_d(MemOperand(esp, 0));
+      __ mov(MemOperand(esp, kDoubleSize / 2), i.InputRegister(1));
+      __ fld_d(MemOperand(esp, 0));
+      __ add(esp, Immediate(kDoubleSize));
+      break;
+    }
+    case kX87Float64InsertLowWord32: {
+      __ sub(esp, Immediate(kDoubleSize));
+      __ fstp_d(MemOperand(esp, 0));
+      __ mov(MemOperand(esp, 0), i.InputRegister(1));
+      __ fld_d(MemOperand(esp, 0));
+      __ add(esp, Immediate(kDoubleSize));
+      break;
+    }
+    case kX87Float64Sqrt: {
+      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
+        __ VerifyX87StackDepth(1);
+      }
+      __ X87SetFPUCW(0x027F);
+      __ fstp(0);
+      __ fld_d(MemOperand(esp, 0));
+      __ fsqrt();
+      __ lea(esp, Operand(esp, kDoubleSize));
+      __ X87SetFPUCW(0x037F);
+      break;
+    }
+    case kX87Float64Round: {
+      RoundingMode mode =
+          static_cast<RoundingMode>(MiscField::decode(instr->opcode()));
+      // Set the correct round mode in x87 control register
+      __ X87SetRC((mode << 10));
+
+      if (!instr->InputAt(0)->IsDoubleRegister()) {
+        InstructionOperand* input = instr->InputAt(0);
+        USE(input);
+        DCHECK(input->IsDoubleStackSlot());
+        if (FLAG_debug_code && FLAG_enable_slow_asserts) {
+          __ VerifyX87StackDepth(1);
+        }
+        __ fstp(0);
+        __ fld_d(i.InputOperand(0));
+      }
+      __ frndint();
+      __ X87SetRC(0x0000);
+      break;
+    }
+    case kX87Float64Cmp: {
+      __ fld_d(MemOperand(esp, kDoubleSize));
+      __ fld_d(MemOperand(esp, 0));
+      __ FCmp();
+      __ lea(esp, Operand(esp, 2 * kDoubleSize));
+      break;
+    }
+    case kX87Movsxbl:
+      __ movsx_b(i.OutputRegister(), i.MemoryOperand());
+      break;
+    case kX87Movzxbl:
+      __ movzx_b(i.OutputRegister(), i.MemoryOperand());
+      break;
+    case kX87Movb: {
+      size_t index = 0;
+      Operand operand = i.MemoryOperand(&index);
+      if (HasImmediateInput(instr, index)) {
+        __ mov_b(operand, i.InputInt8(index));
+      } else {
+        __ mov_b(operand, i.InputRegister(index));
+      }
+      break;
+    }
+    case kX87Movsxwl:
+      __ movsx_w(i.OutputRegister(), i.MemoryOperand());
+      break;
+    case kX87Movzxwl:
+      __ movzx_w(i.OutputRegister(), i.MemoryOperand());
+      break;
+    case kX87Movw: {
+      size_t index = 0;
+      Operand operand = i.MemoryOperand(&index);
+      if (HasImmediateInput(instr, index)) {
+        __ mov_w(operand, i.InputInt16(index));
+      } else {
+        __ mov_w(operand, i.InputRegister(index));
+      }
+      break;
+    }
+    case kX87Movl:
+      if (instr->HasOutput()) {
+        __ mov(i.OutputRegister(), i.MemoryOperand());
+      } else {
+        size_t index = 0;
+        Operand operand = i.MemoryOperand(&index);
+        if (HasImmediateInput(instr, index)) {
+          __ mov(operand, i.InputImmediate(index));
+        } else {
+          __ mov(operand, i.InputRegister(index));
+        }
+      }
+      break;
+    case kX87Movsd: {
+      if (instr->HasOutput()) {
+        X87Register output = i.OutputDoubleRegister();
+        USE(output);
+        DCHECK(output.code() == 0);
+        if (FLAG_debug_code && FLAG_enable_slow_asserts) {
+          __ VerifyX87StackDepth(1);
+        }
+        __ fstp(0);
+        __ fld_d(i.MemoryOperand());
+      } else {
+        size_t index = 0;
+        Operand operand = i.MemoryOperand(&index);
+        __ fst_d(operand);
+      }
+      break;
+    }
+    case kX87Movss: {
+      if (instr->HasOutput()) {
+        X87Register output = i.OutputDoubleRegister();
+        USE(output);
+        DCHECK(output.code() == 0);
+        if (FLAG_debug_code && FLAG_enable_slow_asserts) {
+          __ VerifyX87StackDepth(1);
+        }
+        __ fstp(0);
+        __ fld_s(i.MemoryOperand());
+      } else {
+        size_t index = 0;
+        Operand operand = i.MemoryOperand(&index);
+        __ fst_s(operand);
+      }
+      break;
+    }
+    case kX87BitcastFI: {
+      __ mov(i.OutputRegister(), MemOperand(esp, 0));
+      __ lea(esp, Operand(esp, kFloatSize));
+      break;
+    }
+    case kX87BitcastIF: {
+      if (FLAG_debug_code && FLAG_enable_slow_asserts) {
+        __ VerifyX87StackDepth(1);
+      }
+      __ fstp(0);
+      if (instr->InputAt(0)->IsRegister()) {
+        __ lea(esp, Operand(esp, -kFloatSize));
+        __ mov(MemOperand(esp, 0), i.InputRegister(0));
+        __ fld_s(MemOperand(esp, 0));
+        __ lea(esp, Operand(esp, kFloatSize));
+      } else {
+        __ fld_s(i.InputOperand(0));
+      }
+      break;
+    }
+    case kX87Lea: {
+      AddressingMode mode = AddressingModeField::decode(instr->opcode());
+      // Shorten "leal" to "addl", "subl" or "shll" if the register allocation
+      // and addressing mode just happens to work out. The "addl"/"subl" forms
+      // in these cases are faster based on measurements.
+      if (mode == kMode_MI) {
+        __ Move(i.OutputRegister(), Immediate(i.InputInt32(0)));
+      } else if (i.InputRegister(0).is(i.OutputRegister())) {
+        if (mode == kMode_MRI) {
+          int32_t constant_summand = i.InputInt32(1);
+          if (constant_summand > 0) {
+            __ add(i.OutputRegister(), Immediate(constant_summand));
+          } else if (constant_summand < 0) {
+            __ sub(i.OutputRegister(), Immediate(-constant_summand));
+          }
+        } else if (mode == kMode_MR1) {
+          if (i.InputRegister(1).is(i.OutputRegister())) {
+            __ shl(i.OutputRegister(), 1);
+          } else {
+            __ lea(i.OutputRegister(), i.MemoryOperand());
+          }
+        } else if (mode == kMode_M2) {
+          __ shl(i.OutputRegister(), 1);
+        } else if (mode == kMode_M4) {
+          __ shl(i.OutputRegister(), 2);
+        } else if (mode == kMode_M8) {
+          __ shl(i.OutputRegister(), 3);
+        } else {
+          __ lea(i.OutputRegister(), i.MemoryOperand());
+        }
+      } else {
+        __ lea(i.OutputRegister(), i.MemoryOperand());
+      }
+      break;
+    }
+    case kX87Push:
+      if (instr->InputAt(0)->IsDoubleRegister()) {
+        auto allocated = AllocatedOperand::cast(*instr->InputAt(0));
+        if (allocated.representation() == MachineRepresentation::kFloat32) {
+          __ sub(esp, Immediate(kDoubleSize));
+          __ fst_s(Operand(esp, 0));
+        } else {
+          DCHECK(allocated.representation() == MachineRepresentation::kFloat64);
+          __ sub(esp, Immediate(kDoubleSize));
+          __ fst_d(Operand(esp, 0));
+        }
+        frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize);
+      } else if (instr->InputAt(0)->IsDoubleStackSlot()) {
+        auto allocated = AllocatedOperand::cast(*instr->InputAt(0));
+        if (allocated.representation() == MachineRepresentation::kFloat32) {
+          __ sub(esp, Immediate(kDoubleSize));
+          __ fld_s(i.InputOperand(0));
+          __ fstp_s(MemOperand(esp, 0));
+        } else {
+          DCHECK(allocated.representation() == MachineRepresentation::kFloat64);
+          __ sub(esp, Immediate(kDoubleSize));
+          __ fld_d(i.InputOperand(0));
+          __ fstp_d(MemOperand(esp, 0));
+        }
+        frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize);
+      } else if (HasImmediateInput(instr, 0)) {
+        __ push(i.InputImmediate(0));
+        frame_access_state()->IncreaseSPDelta(1);
+      } else {
+        __ push(i.InputOperand(0));
+        frame_access_state()->IncreaseSPDelta(1);
+      }
+      break;
+    case kX87Poke: {
+      int const slot = MiscField::decode(instr->opcode());
+      if (HasImmediateInput(instr, 0)) {
+        __ mov(Operand(esp, slot * kPointerSize), i.InputImmediate(0));
+      } else {
+        __ mov(Operand(esp, slot * kPointerSize), i.InputRegister(0));
+      }
+      break;
+    }
+    case kX87PushFloat32:
+      __ lea(esp, Operand(esp, -kFloatSize));
+      if (instr->InputAt(0)->IsDoubleStackSlot()) {
+        __ fld_s(i.InputOperand(0));
+        __ fstp_s(MemOperand(esp, 0));
+      } else if (instr->InputAt(0)->IsDoubleRegister()) {
+        __ fst_s(MemOperand(esp, 0));
+      } else {
+        UNREACHABLE();
+      }
+      break;
+    case kX87PushFloat64:
+      __ lea(esp, Operand(esp, -kDoubleSize));
+      if (instr->InputAt(0)->IsDoubleStackSlot()) {
+        __ fld_d(i.InputOperand(0));
+        __ fstp_d(MemOperand(esp, 0));
+      } else if (instr->InputAt(0)->IsDoubleRegister()) {
+        __ fst_d(MemOperand(esp, 0));
+      } else {
+        UNREACHABLE();
+      }
+      break;
+    case kCheckedLoadInt8:
+      ASSEMBLE_CHECKED_LOAD_INTEGER(movsx_b);
+      break;
+    case kCheckedLoadUint8:
+      ASSEMBLE_CHECKED_LOAD_INTEGER(movzx_b);
+      break;
+    case kCheckedLoadInt16:
+      ASSEMBLE_CHECKED_LOAD_INTEGER(movsx_w);
+      break;
+    case kCheckedLoadUint16:
+      ASSEMBLE_CHECKED_LOAD_INTEGER(movzx_w);
+      break;
+    case kCheckedLoadWord32:
+      ASSEMBLE_CHECKED_LOAD_INTEGER(mov);
+      break;
+    case kCheckedLoadFloat32:
+      ASSEMBLE_CHECKED_LOAD_FLOAT(fld_s);
+      break;
+    case kCheckedLoadFloat64:
+      ASSEMBLE_CHECKED_LOAD_FLOAT(fld_d);
+      break;
+    case kCheckedStoreWord8:
+      ASSEMBLE_CHECKED_STORE_INTEGER(mov_b);
+      break;
+    case kCheckedStoreWord16:
+      ASSEMBLE_CHECKED_STORE_INTEGER(mov_w);
+      break;
+    case kCheckedStoreWord32:
+      ASSEMBLE_CHECKED_STORE_INTEGER(mov);
+      break;
+    case kCheckedStoreFloat32:
+      ASSEMBLE_CHECKED_STORE_FLOAT(fst_s);
+      break;
+    case kCheckedStoreFloat64:
+      ASSEMBLE_CHECKED_STORE_FLOAT(fst_d);
+      break;
+    case kX87StackCheck: {
+      ExternalReference const stack_limit =
+          ExternalReference::address_of_stack_limit(isolate());
+      __ cmp(esp, Operand::StaticVariable(stack_limit));
+      break;
+    }
+    case kCheckedLoadWord64:
+    case kCheckedStoreWord64:
+      UNREACHABLE();  // currently unsupported checked int64 load/store.
+      break;
+  }
+}  // NOLINT(readability/fn_size)
+
+
+// Assembles a branch after an instruction.
+void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) {
+  X87OperandConverter i(this, instr);
+  Label::Distance flabel_distance =
+      branch->fallthru ? Label::kNear : Label::kFar;
+  Label* tlabel = branch->true_label;
+  Label* flabel = branch->false_label;
+  switch (branch->condition) {
+    case kUnorderedEqual:
+      __ j(parity_even, flabel, flabel_distance);
+    // Fall through.
+    case kEqual:
+      __ j(equal, tlabel);
+      break;
+    case kUnorderedNotEqual:
+      __ j(parity_even, tlabel);
+    // Fall through.
+    case kNotEqual:
+      __ j(not_equal, tlabel);
+      break;
+    case kSignedLessThan:
+      __ j(less, tlabel);
+      break;
+    case kSignedGreaterThanOrEqual:
+      __ j(greater_equal, tlabel);
+      break;
+    case kSignedLessThanOrEqual:
+      __ j(less_equal, tlabel);
+      break;
+    case kSignedGreaterThan:
+      __ j(greater, tlabel);
+      break;
+    case kUnsignedLessThan:
+      __ j(below, tlabel);
+      break;
+    case kUnsignedGreaterThanOrEqual:
+      __ j(above_equal, tlabel);
+      break;
+    case kUnsignedLessThanOrEqual:
+      __ j(below_equal, tlabel);
+      break;
+    case kUnsignedGreaterThan:
+      __ j(above, tlabel);
+      break;
+    case kOverflow:
+      __ j(overflow, tlabel);
+      break;
+    case kNotOverflow:
+      __ j(no_overflow, tlabel);
+      break;
+    default:
+      UNREACHABLE();
+      break;
+  }
+  // Add a jump if not falling through to the next block.
+  if (!branch->fallthru) __ jmp(flabel);
+}
+
+
+void CodeGenerator::AssembleArchJump(RpoNumber target) {
+  if (!IsNextInAssemblyOrder(target)) __ jmp(GetLabel(target));
+}
+
+
+// Assembles boolean materializations after an instruction.
+void CodeGenerator::AssembleArchBoolean(Instruction* instr,
+                                        FlagsCondition condition) {
+  X87OperandConverter i(this, instr);
+  Label done;
+
+  // Materialize a full 32-bit 1 or 0 value. The result register is always the
+  // last output of the instruction.
+  Label check;
+  DCHECK_NE(0u, instr->OutputCount());
+  Register reg = i.OutputRegister(instr->OutputCount() - 1);
+  Condition cc = no_condition;
+  switch (condition) {
+    case kUnorderedEqual:
+      __ j(parity_odd, &check, Label::kNear);
+      __ Move(reg, Immediate(0));
+      __ jmp(&done, Label::kNear);
+    // Fall through.
+    case kEqual:
+      cc = equal;
+      break;
+    case kUnorderedNotEqual:
+      __ j(parity_odd, &check, Label::kNear);
+      __ mov(reg, Immediate(1));
+      __ jmp(&done, Label::kNear);
+    // Fall through.
+    case kNotEqual:
+      cc = not_equal;
+      break;
+    case kSignedLessThan:
+      cc = less;
+      break;
+    case kSignedGreaterThanOrEqual:
+      cc = greater_equal;
+      break;
+    case kSignedLessThanOrEqual:
+      cc = less_equal;
+      break;
+    case kSignedGreaterThan:
+      cc = greater;
+      break;
+    case kUnsignedLessThan:
+      cc = below;
+      break;
+    case kUnsignedGreaterThanOrEqual:
+      cc = above_equal;
+      break;
+    case kUnsignedLessThanOrEqual:
+      cc = below_equal;
+      break;
+    case kUnsignedGreaterThan:
+      cc = above;
+      break;
+    case kOverflow:
+      cc = overflow;
+      break;
+    case kNotOverflow:
+      cc = no_overflow;
+      break;
+    default:
+      UNREACHABLE();
+      break;
+  }
+  __ bind(&check);
+  if (reg.is_byte_register()) {
+    // setcc for byte registers (al, bl, cl, dl).
+    __ setcc(cc, reg);
+    __ movzx_b(reg, reg);
+  } else {
+    // Emit a branch to set a register to either 1 or 0.
+    Label set;
+    __ j(cc, &set, Label::kNear);
+    __ Move(reg, Immediate(0));
+    __ jmp(&done, Label::kNear);
+    __ bind(&set);
+    __ mov(reg, Immediate(1));
+  }
+  __ bind(&done);
+}
+
+
+void CodeGenerator::AssembleArchLookupSwitch(Instruction* instr) {
+  X87OperandConverter i(this, instr);
+  Register input = i.InputRegister(0);
+  for (size_t index = 2; index < instr->InputCount(); index += 2) {
+    __ cmp(input, Immediate(i.InputInt32(index + 0)));
+    __ j(equal, GetLabel(i.InputRpo(index + 1)));
+  }
+  AssembleArchJump(i.InputRpo(1));
+}
+
+
+void CodeGenerator::AssembleArchTableSwitch(Instruction* instr) {
+  X87OperandConverter i(this, instr);
+  Register input = i.InputRegister(0);
+  size_t const case_count = instr->InputCount() - 2;
+  Label** cases = zone()->NewArray<Label*>(case_count);
+  for (size_t index = 0; index < case_count; ++index) {
+    cases[index] = GetLabel(i.InputRpo(index + 2));
+  }
+  Label* const table = AddJumpTable(cases, case_count);
+  __ cmp(input, Immediate(case_count));
+  __ j(above_equal, GetLabel(i.InputRpo(1)));
+  __ jmp(Operand::JumpTable(input, times_4, table));
+}
+
+
+void CodeGenerator::AssembleDeoptimizerCall(
+    int deoptimization_id, Deoptimizer::BailoutType bailout_type) {
+  Address deopt_entry = Deoptimizer::GetDeoptimizationEntry(
+      isolate(), deoptimization_id, bailout_type);
+  __ call(deopt_entry, RelocInfo::RUNTIME_ENTRY);
+}
+
+
+// The calling convention for JSFunctions on X87 passes arguments on the
+// stack and the JSFunction and context in EDI and ESI, respectively, thus
+// the steps of the call look as follows:
+
+// --{ before the call instruction }--------------------------------------------
+//                                                         |  caller frame |
+//                                                         ^ esp           ^ ebp
+
+// --{ push arguments and setup ESI, EDI }--------------------------------------
+//                                       | args + receiver |  caller frame |
+//                                       ^ esp                             ^ ebp
+//                 [edi = JSFunction, esi = context]
+
+// --{ call [edi + kCodeEntryOffset] }------------------------------------------
+//                                 | RET | args + receiver |  caller frame |
+//                                 ^ esp                                   ^ ebp
+
+// =={ prologue of called function }============================================
+// --{ push ebp }---------------------------------------------------------------
+//                            | FP | RET | args + receiver |  caller frame |
+//                            ^ esp                                        ^ ebp
+
+// --{ mov ebp, esp }-----------------------------------------------------------
+//                            | FP | RET | args + receiver |  caller frame |
+//                            ^ ebp,esp
+
+// --{ push esi }---------------------------------------------------------------
+//                      | CTX | FP | RET | args + receiver |  caller frame |
+//                      ^esp  ^ ebp
+
+// --{ push edi }---------------------------------------------------------------
+//                | FNC | CTX | FP | RET | args + receiver |  caller frame |
+//                ^esp        ^ ebp
+
+// --{ subi esp, #N }-----------------------------------------------------------
+// | callee frame | FNC | CTX | FP | RET | args + receiver |  caller frame |
+// ^esp                       ^ ebp
+
+// =={ body of called function }================================================
+
+// =={ epilogue of called function }============================================
+// --{ mov esp, ebp }-----------------------------------------------------------
+//                            | FP | RET | args + receiver |  caller frame |
+//                            ^ esp,ebp
+
+// --{ pop ebp }-----------------------------------------------------------
+// |                               | RET | args + receiver |  caller frame |
+//                                 ^ esp                                   ^ ebp
+
+// --{ ret #A+1 }-----------------------------------------------------------
+// |                                                       |  caller frame |
+//                                                         ^ esp           ^ ebp
+
+
+// Runtime function calls are accomplished by doing a stub call to the
+// CEntryStub (a real code object). On X87 passes arguments on the
+// stack, the number of arguments in EAX, the address of the runtime function
+// in EBX, and the context in ESI.
+
+// --{ before the call instruction }--------------------------------------------
+//                                                         |  caller frame |
+//                                                         ^ esp           ^ ebp
+
+// --{ push arguments and setup EAX, EBX, and ESI }-----------------------------
+//                                       | args + receiver |  caller frame |
+//                                       ^ esp                             ^ ebp
+//              [eax = #args, ebx = runtime function, esi = context]
+
+// --{ call #CEntryStub }-------------------------------------------------------
+//                                 | RET | args + receiver |  caller frame |
+//                                 ^ esp                                   ^ ebp
+
+// =={ body of runtime function }===============================================
+
+// --{ runtime returns }--------------------------------------------------------
+//                                                         |  caller frame |
+//                                                         ^ esp           ^ ebp
+
+// Other custom linkages (e.g. for calling directly into and out of C++) may
+// need to save callee-saved registers on the stack, which is done in the
+// function prologue of generated code.
+
+// --{ before the call instruction }--------------------------------------------
+//                                                         |  caller frame |
+//                                                         ^ esp           ^ ebp
+
+// --{ set up arguments in registers on stack }---------------------------------
+//                                                  | args |  caller frame |
+//                                                  ^ esp                  ^ ebp
+//                  [r0 = arg0, r1 = arg1, ...]
+
+// --{ call code }--------------------------------------------------------------
+//                                            | RET | args |  caller frame |
+//                                            ^ esp                        ^ ebp
+
+// =={ prologue of called function }============================================
+// --{ push ebp }---------------------------------------------------------------
+//                                       | FP | RET | args |  caller frame |
+//                                       ^ esp                             ^ ebp
+
+// --{ mov ebp, esp }-----------------------------------------------------------
+//                                       | FP | RET | args |  caller frame |
+//                                       ^ ebp,esp
+
+// --{ save registers }---------------------------------------------------------
+//                                | regs | FP | RET | args |  caller frame |
+//                                ^ esp  ^ ebp
+
+// --{ subi esp, #N }-----------------------------------------------------------
+//                 | callee frame | regs | FP | RET | args |  caller frame |
+//                 ^esp                  ^ ebp
+
+// =={ body of called function }================================================
+
+// =={ epilogue of called function }============================================
+// --{ restore registers }------------------------------------------------------
+//                                | regs | FP | RET | args |  caller frame |
+//                                ^ esp  ^ ebp
+
+// --{ mov esp, ebp }-----------------------------------------------------------
+//                                       | FP | RET | args |  caller frame |
+//                                       ^ esp,ebp
+
+// --{ pop ebp }----------------------------------------------------------------
+//                                            | RET | args |  caller frame |
+//                                            ^ esp                        ^ ebp
+
+
+void CodeGenerator::AssemblePrologue() {
+  CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
+  if (descriptor->IsCFunctionCall()) {
+    // Assemble a prologue similar the to cdecl calling convention.
+    __ push(ebp);
+    __ mov(ebp, esp);
+  } else if (descriptor->IsJSFunctionCall()) {
+    // TODO(turbofan): this prologue is redundant with OSR, but needed for
+    // code aging.
+    __ Prologue(this->info()->GeneratePreagedPrologue());
+  } else if (frame()->needs_frame()) {
+    __ StubPrologue();
+  } else {
+    frame()->SetElidedFrameSizeInSlots(kPCOnStackSize / kPointerSize);
+  }
+  frame_access_state()->SetFrameAccessToDefault();
+
+  int stack_shrink_slots = frame()->GetSpillSlotCount();
+  if (info()->is_osr()) {
+    // TurboFan OSR-compiled functions cannot be entered directly.
+    __ Abort(kShouldNotDirectlyEnterOsrFunction);
+
+    // Unoptimized code jumps directly to this entrypoint while the unoptimized
+    // frame is still on the stack. Optimized code uses OSR values directly from
+    // the unoptimized frame. Thus, all that needs to be done is to allocate the
+    // remaining stack slots.
+    if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --");
+    osr_pc_offset_ = __ pc_offset();
+    // TODO(titzer): cannot address target function == local #-1
+    __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
+    stack_shrink_slots -= OsrHelper(info()).UnoptimizedFrameSlots();
+  }
+
+  const RegList saves = descriptor->CalleeSavedRegisters();
+  if (stack_shrink_slots > 0) {
+    __ sub(esp, Immediate(stack_shrink_slots * kPointerSize));
+  }
+
+  if (saves != 0) {  // Save callee-saved registers.
+    DCHECK(!info()->is_osr());
+    int pushed = 0;
+    for (int i = Register::kNumRegisters - 1; i >= 0; i--) {
+      if (!((1 << i) & saves)) continue;
+      __ push(Register::from_code(i));
+      ++pushed;
+    }
+    frame()->AllocateSavedCalleeRegisterSlots(pushed);
+  }
+
+  // Initailize FPU state.
+  __ fninit();
+  __ fld1();
+}
+
+
+void CodeGenerator::AssembleReturn() {
+  CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
+
+  // Clear the FPU stack only if there is no return value in the stack.
+  if (FLAG_debug_code && FLAG_enable_slow_asserts) {
+    __ VerifyX87StackDepth(1);
+  }
+  bool clear_stack = true;
+  for (int i = 0; i < descriptor->ReturnCount(); i++) {
+    MachineRepresentation rep = descriptor->GetReturnType(i).representation();
+    LinkageLocation loc = descriptor->GetReturnLocation(i);
+    if (IsFloatingPoint(rep) && loc == LinkageLocation::ForRegister(0)) {
+      clear_stack = false;
+      break;
+    }
+  }
+  if (clear_stack) __ fstp(0);
+
+  int pop_count = static_cast<int>(descriptor->StackParameterCount());
+  const RegList saves = descriptor->CalleeSavedRegisters();
+  // Restore registers.
+  if (saves != 0) {
+    for (int i = 0; i < Register::kNumRegisters; i++) {
+      if (!((1 << i) & saves)) continue;
+      __ pop(Register::from_code(i));
+    }
+  }
+
+  if (descriptor->IsCFunctionCall()) {
+    __ mov(esp, ebp);  // Move stack pointer back to frame pointer.
+    __ pop(ebp);       // Pop caller's frame pointer.
+  } else if (frame()->needs_frame()) {
+    // Canonicalize JSFunction return sites for now.
+    if (return_label_.is_bound()) {
+      __ jmp(&return_label_);
+      return;
+    } else {
+      __ bind(&return_label_);
+      __ mov(esp, ebp);  // Move stack pointer back to frame pointer.
+      __ pop(ebp);       // Pop caller's frame pointer.
+    }
+  }
+  if (pop_count == 0) {
+    __ ret(0);
+  } else {
+    __ Ret(pop_count * kPointerSize, ebx);
+  }
+}
+
+
+void CodeGenerator::AssembleMove(InstructionOperand* source,
+                                 InstructionOperand* destination) {
+  X87OperandConverter g(this, nullptr);
+  // Dispatch on the source and destination operand kinds.  Not all
+  // combinations are possible.
+  if (source->IsRegister()) {
+    DCHECK(destination->IsRegister() || destination->IsStackSlot());
+    Register src = g.ToRegister(source);
+    Operand dst = g.ToOperand(destination);
+    __ mov(dst, src);
+  } else if (source->IsStackSlot()) {
+    DCHECK(destination->IsRegister() || destination->IsStackSlot());
+    Operand src = g.ToOperand(source);
+    if (destination->IsRegister()) {
+      Register dst = g.ToRegister(destination);
+      __ mov(dst, src);
+    } else {
+      Operand dst = g.ToOperand(destination);
+      __ push(src);
+      __ pop(dst);
+    }
+  } else if (source->IsConstant()) {
+    Constant src_constant = g.ToConstant(source);
+    if (src_constant.type() == Constant::kHeapObject) {
+      Handle<HeapObject> src = src_constant.ToHeapObject();
+      int offset;
+      if (IsMaterializableFromFrame(src, &offset)) {
+        if (destination->IsRegister()) {
+          Register dst = g.ToRegister(destination);
+          __ mov(dst, g.ToMaterializableOperand(offset));
+        } else {
+          DCHECK(destination->IsStackSlot());
+          Operand dst = g.ToOperand(destination);
+          __ push(g.ToMaterializableOperand(offset));
+          __ pop(dst);
+        }
+      } else if (destination->IsRegister()) {
+        Register dst = g.ToRegister(destination);
+        __ LoadHeapObject(dst, src);
+      } else {
+        DCHECK(destination->IsStackSlot());
+        Operand dst = g.ToOperand(destination);
+        AllowDeferredHandleDereference embedding_raw_address;
+        if (isolate()->heap()->InNewSpace(*src)) {
+          __ PushHeapObject(src);
+          __ pop(dst);
+        } else {
+          __ mov(dst, src);
+        }
+      }
+    } else if (destination->IsRegister()) {
+      Register dst = g.ToRegister(destination);
+      __ Move(dst, g.ToImmediate(source));
+    } else if (destination->IsStackSlot()) {
+      Operand dst = g.ToOperand(destination);
+      __ Move(dst, g.ToImmediate(source));
+    } else if (src_constant.type() == Constant::kFloat32) {
+      // TODO(turbofan): Can we do better here?
+      uint32_t src = bit_cast<uint32_t>(src_constant.ToFloat32());
+      if (destination->IsDoubleRegister()) {
+        __ sub(esp, Immediate(kInt32Size));
+        __ mov(MemOperand(esp, 0), Immediate(src));
+        // always only push one value into the x87 stack.
+        __ fstp(0);
+        __ fld_s(MemOperand(esp, 0));
+        __ add(esp, Immediate(kInt32Size));
+      } else {
+        DCHECK(destination->IsDoubleStackSlot());
+        Operand dst = g.ToOperand(destination);
+        __ Move(dst, Immediate(src));
+      }
+    } else {
+      DCHECK_EQ(Constant::kFloat64, src_constant.type());
+      uint64_t src = bit_cast<uint64_t>(src_constant.ToFloat64());
+      uint32_t lower = static_cast<uint32_t>(src);
+      uint32_t upper = static_cast<uint32_t>(src >> 32);
+      if (destination->IsDoubleRegister()) {
+        __ sub(esp, Immediate(kDoubleSize));
+        __ mov(MemOperand(esp, 0), Immediate(lower));
+        __ mov(MemOperand(esp, kInt32Size), Immediate(upper));
+        // always only push one value into the x87 stack.
+        __ fstp(0);
+        __ fld_d(MemOperand(esp, 0));
+        __ add(esp, Immediate(kDoubleSize));
+      } else {
+        DCHECK(destination->IsDoubleStackSlot());
+        Operand dst0 = g.ToOperand(destination);
+        Operand dst1 = g.HighOperand(destination);
+        __ Move(dst0, Immediate(lower));
+        __ Move(dst1, Immediate(upper));
+      }
+    }
+  } else if (source->IsDoubleRegister()) {
+    DCHECK(destination->IsDoubleStackSlot());
+    Operand dst = g.ToOperand(destination);
+    auto allocated = AllocatedOperand::cast(*source);
+    switch (allocated.representation()) {
+      case MachineRepresentation::kFloat32:
+        __ fst_s(dst);
+        break;
+      case MachineRepresentation::kFloat64:
+        __ fst_d(dst);
+        break;
+      default:
+        UNREACHABLE();
+    }
+  } else if (source->IsDoubleStackSlot()) {
+    DCHECK(destination->IsDoubleRegister() || destination->IsDoubleStackSlot());
+    Operand src = g.ToOperand(source);
+    auto allocated = AllocatedOperand::cast(*source);
+    if (destination->IsDoubleRegister()) {
+      // always only push one value into the x87 stack.
+      __ fstp(0);
+      switch (allocated.representation()) {
+        case MachineRepresentation::kFloat32:
+          __ fld_s(src);
+          break;
+        case MachineRepresentation::kFloat64:
+          __ fld_d(src);
+          break;
+        default:
+          UNREACHABLE();
+      }
+    } else {
+      Operand dst = g.ToOperand(destination);
+      switch (allocated.representation()) {
+        case MachineRepresentation::kFloat32:
+          __ fld_s(src);
+          __ fstp_s(dst);
+          break;
+        case MachineRepresentation::kFloat64:
+          __ fld_d(src);
+          __ fstp_d(dst);
+          break;
+        default:
+          UNREACHABLE();
+      }
+    }
+  } else {
+    UNREACHABLE();
+  }
+}
+
+
+void CodeGenerator::AssembleSwap(InstructionOperand* source,
+                                 InstructionOperand* destination) {
+  X87OperandConverter g(this, nullptr);
+  // Dispatch on the source and destination operand kinds.  Not all
+  // combinations are possible.
+  if (source->IsRegister() && destination->IsRegister()) {
+    // Register-register.
+    Register src = g.ToRegister(source);
+    Register dst = g.ToRegister(destination);
+    __ xchg(dst, src);
+  } else if (source->IsRegister() && destination->IsStackSlot()) {
+    // Register-memory.
+    __ xchg(g.ToRegister(source), g.ToOperand(destination));
+  } else if (source->IsStackSlot() && destination->IsStackSlot()) {
+    // Memory-memory.
+    Operand dst1 = g.ToOperand(destination);
+    __ push(dst1);
+    frame_access_state()->IncreaseSPDelta(1);
+    Operand src1 = g.ToOperand(source);
+    __ push(src1);
+    Operand dst2 = g.ToOperand(destination);
+    __ pop(dst2);
+    frame_access_state()->IncreaseSPDelta(-1);
+    Operand src2 = g.ToOperand(source);
+    __ pop(src2);
+  } else if (source->IsDoubleRegister() && destination->IsDoubleRegister()) {
+    UNREACHABLE();
+  } else if (source->IsDoubleRegister() && destination->IsDoubleStackSlot()) {
+    auto allocated = AllocatedOperand::cast(*source);
+    switch (allocated.representation()) {
+      case MachineRepresentation::kFloat32:
+        __ fld_s(g.ToOperand(destination));
+        __ fxch();
+        __ fstp_s(g.ToOperand(destination));
+        break;
+      case MachineRepresentation::kFloat64:
+        __ fld_d(g.ToOperand(destination));
+        __ fxch();
+        __ fstp_d(g.ToOperand(destination));
+        break;
+      default:
+        UNREACHABLE();
+    }
+  } else if (source->IsDoubleStackSlot() && destination->IsDoubleStackSlot()) {
+    auto allocated = AllocatedOperand::cast(*source);
+    switch (allocated.representation()) {
+      case MachineRepresentation::kFloat32:
+        __ fld_s(g.ToOperand(source));
+        __ fld_s(g.ToOperand(destination));
+        __ fstp_s(g.ToOperand(source));
+        __ fstp_s(g.ToOperand(destination));
+        break;
+      case MachineRepresentation::kFloat64:
+        __ fld_d(g.ToOperand(source));
+        __ fld_d(g.ToOperand(destination));
+        __ fstp_d(g.ToOperand(source));
+        __ fstp_d(g.ToOperand(destination));
+        break;
+      default:
+        UNREACHABLE();
+    }
+  } else {
+    // No other combinations are possible.
+    UNREACHABLE();
+  }
+}
+
+
+void CodeGenerator::AssembleJumpTable(Label** targets, size_t target_count) {
+  for (size_t index = 0; index < target_count; ++index) {
+    __ dd(targets[index]);
+  }
+}
+
+
+void CodeGenerator::AddNopForSmiCodeInlining() { __ nop(); }
+
+
+void CodeGenerator::EnsureSpaceForLazyDeopt() {
+  if (!info()->ShouldEnsureSpaceForLazyDeopt()) {
+    return;
+  }
+
+  int space_needed = Deoptimizer::patch_size();
+  // Ensure that we have enough space after the previous lazy-bailout
+  // instruction for patching the code here.
+  int current_pc = masm()->pc_offset();
+  if (current_pc < last_lazy_deopt_pc_ + space_needed) {
+    int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc;
+    __ Nop(padding_size);
+  }
+}
+
+#undef __
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/x87/instruction-codes-x87.h b/src/compiler/x87/instruction-codes-x87.h
new file mode 100644
index 0000000..b498d9c
--- /dev/null
+++ b/src/compiler/x87/instruction-codes-x87.h
@@ -0,0 +1,125 @@
+// 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.
+
+#ifndef V8_COMPILER_X87_INSTRUCTION_CODES_X87_H_
+#define V8_COMPILER_X87_INSTRUCTION_CODES_X87_H_
+
+#include "src/compiler/instruction.h"
+#include "src/compiler/instruction-codes.h"
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+// X87-specific opcodes that specify which assembly sequence to emit.
+// Most opcodes specify a single instruction.
+#define TARGET_ARCH_OPCODE_LIST(V) \
+  V(X87Add)                        \
+  V(X87And)                        \
+  V(X87Cmp)                        \
+  V(X87Test)                       \
+  V(X87Or)                         \
+  V(X87Xor)                        \
+  V(X87Sub)                        \
+  V(X87Imul)                       \
+  V(X87ImulHigh)                   \
+  V(X87UmulHigh)                   \
+  V(X87Idiv)                       \
+  V(X87Udiv)                       \
+  V(X87Not)                        \
+  V(X87Neg)                        \
+  V(X87Shl)                        \
+  V(X87Shr)                        \
+  V(X87Sar)                        \
+  V(X87Ror)                        \
+  V(X87Lzcnt)                      \
+  V(X87Popcnt)                     \
+  V(X87Float32Cmp)                 \
+  V(X87Float32Add)                 \
+  V(X87Float32Sub)                 \
+  V(X87Float32Mul)                 \
+  V(X87Float32Div)                 \
+  V(X87Float32Max)                 \
+  V(X87Float32Min)                 \
+  V(X87Float32Abs)                 \
+  V(X87Float32Sqrt)                \
+  V(X87Float32Round)               \
+  V(X87LoadFloat64Constant)        \
+  V(X87Float64Add)                 \
+  V(X87Float64Sub)                 \
+  V(X87Float64Mul)                 \
+  V(X87Float64Div)                 \
+  V(X87Float64Mod)                 \
+  V(X87Float64Max)                 \
+  V(X87Float64Min)                 \
+  V(X87Float64Abs)                 \
+  V(X87Int32ToFloat64)             \
+  V(X87Float32ToFloat64)           \
+  V(X87Uint32ToFloat64)            \
+  V(X87Float64ToInt32)             \
+  V(X87Float64ToFloat32)           \
+  V(X87Float64ToUint32)            \
+  V(X87Float64ExtractHighWord32)   \
+  V(X87Float64ExtractLowWord32)    \
+  V(X87Float64InsertHighWord32)    \
+  V(X87Float64InsertLowWord32)     \
+  V(X87Float64Sqrt)                \
+  V(X87Float64Round)               \
+  V(X87Float64Cmp)                 \
+  V(X87Movsxbl)                    \
+  V(X87Movzxbl)                    \
+  V(X87Movb)                       \
+  V(X87Movsxwl)                    \
+  V(X87Movzxwl)                    \
+  V(X87Movw)                       \
+  V(X87Movl)                       \
+  V(X87Movss)                      \
+  V(X87Movsd)                      \
+  V(X87Lea)                        \
+  V(X87BitcastFI)                  \
+  V(X87BitcastIF)                  \
+  V(X87Push)                       \
+  V(X87PushFloat64)                \
+  V(X87PushFloat32)                \
+  V(X87Poke)                       \
+  V(X87StackCheck)
+
+
+// Addressing modes represent the "shape" of inputs to an instruction.
+// Many instructions support multiple addressing modes. Addressing modes
+// are encoded into the InstructionCode of the instruction and tell the
+// code generator after register allocation which assembler method to call.
+//
+// We use the following local notation for addressing modes:
+//
+// M = memory operand
+// R = base register
+// N = index register * N for N in {1, 2, 4, 8}
+// I = immediate displacement (int32_t)
+
+#define TARGET_ADDRESSING_MODE_LIST(V) \
+  V(MR)   /* [%r1            ] */      \
+  V(MRI)  /* [%r1         + K] */      \
+  V(MR1)  /* [%r1 + %r2*1    ] */      \
+  V(MR2)  /* [%r1 + %r2*2    ] */      \
+  V(MR4)  /* [%r1 + %r2*4    ] */      \
+  V(MR8)  /* [%r1 + %r2*8    ] */      \
+  V(MR1I) /* [%r1 + %r2*1 + K] */      \
+  V(MR2I) /* [%r1 + %r2*2 + K] */      \
+  V(MR4I) /* [%r1 + %r2*3 + K] */      \
+  V(MR8I) /* [%r1 + %r2*4 + K] */      \
+  V(M1)   /* [      %r2*1    ] */      \
+  V(M2)   /* [      %r2*2    ] */      \
+  V(M4)   /* [      %r2*4    ] */      \
+  V(M8)   /* [      %r2*8    ] */      \
+  V(M1I)  /* [      %r2*1 + K] */      \
+  V(M2I)  /* [      %r2*2 + K] */      \
+  V(M4I)  /* [      %r2*4 + K] */      \
+  V(M8I)  /* [      %r2*8 + K] */      \
+  V(MI)   /* [              K] */
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_X87_INSTRUCTION_CODES_X87_H_
diff --git a/src/compiler/x87/instruction-scheduler-x87.cc b/src/compiler/x87/instruction-scheduler-x87.cc
new file mode 100644
index 0000000..af86a87
--- /dev/null
+++ b/src/compiler/x87/instruction-scheduler-x87.cc
@@ -0,0 +1,26 @@
+// Copyright 2015 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/instruction-scheduler.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+bool InstructionScheduler::SchedulerSupported() { return false; }
+
+
+int InstructionScheduler::GetTargetInstructionFlags(
+    const Instruction* instr) const {
+  UNIMPLEMENTED();
+}
+
+
+int InstructionScheduler::GetInstructionLatency(const Instruction* instr) {
+  UNIMPLEMENTED();
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/x87/instruction-selector-x87.cc b/src/compiler/x87/instruction-selector-x87.cc
new file mode 100644
index 0000000..cff4aaf
--- /dev/null
+++ b/src/compiler/x87/instruction-selector-x87.cc
@@ -0,0 +1,1345 @@
+// 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/base/adapters.h"
+#include "src/compiler/instruction-selector-impl.h"
+#include "src/compiler/node-matchers.h"
+#include "src/compiler/node-properties.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+// Adds X87-specific methods for generating operands.
+class X87OperandGenerator final : public OperandGenerator {
+ public:
+  explicit X87OperandGenerator(InstructionSelector* selector)
+      : OperandGenerator(selector) {}
+
+  InstructionOperand UseByteRegister(Node* node) {
+    // TODO(titzer): encode byte register use constraints.
+    return UseFixed(node, edx);
+  }
+
+  InstructionOperand DefineAsByteRegister(Node* node) {
+    // TODO(titzer): encode byte register def constraints.
+    return DefineAsRegister(node);
+  }
+
+  InstructionOperand CreateImmediate(int imm) {
+    return sequence()->AddImmediate(Constant(imm));
+  }
+
+  bool CanBeImmediate(Node* node) {
+    switch (node->opcode()) {
+      case IrOpcode::kInt32Constant:
+      case IrOpcode::kNumberConstant:
+      case IrOpcode::kExternalConstant:
+        return true;
+      case IrOpcode::kHeapConstant: {
+        // Constants in new space cannot be used as immediates in V8 because
+        // the GC does not scan code objects when collecting the new generation.
+        Handle<HeapObject> value = OpParameter<Handle<HeapObject>>(node);
+        Isolate* isolate = value->GetIsolate();
+        return !isolate->heap()->InNewSpace(*value);
+      }
+      default:
+        return false;
+    }
+  }
+
+  AddressingMode GenerateMemoryOperandInputs(Node* index, int scale, Node* base,
+                                             Node* displacement_node,
+                                             InstructionOperand inputs[],
+                                             size_t* input_count) {
+    AddressingMode mode = kMode_MRI;
+    int32_t displacement = (displacement_node == nullptr)
+                               ? 0
+                               : OpParameter<int32_t>(displacement_node);
+    if (base != nullptr) {
+      if (base->opcode() == IrOpcode::kInt32Constant) {
+        displacement += OpParameter<int32_t>(base);
+        base = nullptr;
+      }
+    }
+    if (base != nullptr) {
+      inputs[(*input_count)++] = UseRegister(base);
+      if (index != nullptr) {
+        DCHECK(scale >= 0 && scale <= 3);
+        inputs[(*input_count)++] = UseRegister(index);
+        if (displacement != 0) {
+          inputs[(*input_count)++] = TempImmediate(displacement);
+          static const AddressingMode kMRnI_modes[] = {kMode_MR1I, kMode_MR2I,
+                                                       kMode_MR4I, kMode_MR8I};
+          mode = kMRnI_modes[scale];
+        } else {
+          static const AddressingMode kMRn_modes[] = {kMode_MR1, kMode_MR2,
+                                                      kMode_MR4, kMode_MR8};
+          mode = kMRn_modes[scale];
+        }
+      } else {
+        if (displacement == 0) {
+          mode = kMode_MR;
+        } else {
+          inputs[(*input_count)++] = TempImmediate(displacement);
+          mode = kMode_MRI;
+        }
+      }
+    } else {
+      DCHECK(scale >= 0 && scale <= 3);
+      if (index != nullptr) {
+        inputs[(*input_count)++] = UseRegister(index);
+        if (displacement != 0) {
+          inputs[(*input_count)++] = TempImmediate(displacement);
+          static const AddressingMode kMnI_modes[] = {kMode_MRI, kMode_M2I,
+                                                      kMode_M4I, kMode_M8I};
+          mode = kMnI_modes[scale];
+        } else {
+          static const AddressingMode kMn_modes[] = {kMode_MR, kMode_M2,
+                                                     kMode_M4, kMode_M8};
+          mode = kMn_modes[scale];
+        }
+      } else {
+        inputs[(*input_count)++] = TempImmediate(displacement);
+        return kMode_MI;
+      }
+    }
+    return mode;
+  }
+
+  AddressingMode GetEffectiveAddressMemoryOperand(Node* node,
+                                                  InstructionOperand inputs[],
+                                                  size_t* input_count) {
+    BaseWithIndexAndDisplacement32Matcher m(node, true);
+    DCHECK(m.matches());
+    if ((m.displacement() == nullptr || CanBeImmediate(m.displacement()))) {
+      return GenerateMemoryOperandInputs(m.index(), m.scale(), m.base(),
+                                         m.displacement(), inputs, input_count);
+    } else {
+      inputs[(*input_count)++] = UseRegister(node->InputAt(0));
+      inputs[(*input_count)++] = UseRegister(node->InputAt(1));
+      return kMode_MR1;
+    }
+  }
+
+  bool CanBeBetterLeftOperand(Node* node) const {
+    return !selector()->IsLive(node);
+  }
+};
+
+
+void InstructionSelector::VisitLoad(Node* node) {
+  LoadRepresentation load_rep = LoadRepresentationOf(node->op());
+
+  ArchOpcode opcode = kArchNop;
+  switch (load_rep.representation()) {
+    case MachineRepresentation::kFloat32:
+      opcode = kX87Movss;
+      break;
+    case MachineRepresentation::kFloat64:
+      opcode = kX87Movsd;
+      break;
+    case MachineRepresentation::kBit:  // Fall through.
+    case MachineRepresentation::kWord8:
+      opcode = load_rep.IsSigned() ? kX87Movsxbl : kX87Movzxbl;
+      break;
+    case MachineRepresentation::kWord16:
+      opcode = load_rep.IsSigned() ? kX87Movsxwl : kX87Movzxwl;
+      break;
+    case MachineRepresentation::kTagged:  // Fall through.
+    case MachineRepresentation::kWord32:
+      opcode = kX87Movl;
+      break;
+    case MachineRepresentation::kWord64:  // Fall through.
+    case MachineRepresentation::kNone:
+      UNREACHABLE();
+      return;
+  }
+
+  X87OperandGenerator g(this);
+  InstructionOperand outputs[1];
+  outputs[0] = g.DefineAsRegister(node);
+  InstructionOperand inputs[3];
+  size_t input_count = 0;
+  AddressingMode mode =
+      g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count);
+  InstructionCode code = opcode | AddressingModeField::encode(mode);
+  Emit(code, 1, outputs, input_count, inputs);
+}
+
+
+void InstructionSelector::VisitStore(Node* node) {
+  X87OperandGenerator g(this);
+  Node* base = node->InputAt(0);
+  Node* index = node->InputAt(1);
+  Node* value = node->InputAt(2);
+
+  StoreRepresentation store_rep = StoreRepresentationOf(node->op());
+  WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind();
+  MachineRepresentation rep = store_rep.representation();
+
+  if (write_barrier_kind != kNoWriteBarrier) {
+    DCHECK_EQ(MachineRepresentation::kTagged, rep);
+    AddressingMode addressing_mode;
+    InstructionOperand inputs[3];
+    size_t input_count = 0;
+    inputs[input_count++] = g.UseUniqueRegister(base);
+    if (g.CanBeImmediate(index)) {
+      inputs[input_count++] = g.UseImmediate(index);
+      addressing_mode = kMode_MRI;
+    } else {
+      inputs[input_count++] = g.UseUniqueRegister(index);
+      addressing_mode = kMode_MR1;
+    }
+    inputs[input_count++] = (write_barrier_kind == kMapWriteBarrier)
+                                ? g.UseRegister(value)
+                                : g.UseUniqueRegister(value);
+    RecordWriteMode record_write_mode = RecordWriteMode::kValueIsAny;
+    switch (write_barrier_kind) {
+      case kNoWriteBarrier:
+        UNREACHABLE();
+        break;
+      case kMapWriteBarrier:
+        record_write_mode = RecordWriteMode::kValueIsMap;
+        break;
+      case kPointerWriteBarrier:
+        record_write_mode = RecordWriteMode::kValueIsPointer;
+        break;
+      case kFullWriteBarrier:
+        record_write_mode = RecordWriteMode::kValueIsAny;
+        break;
+    }
+    InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()};
+    size_t const temp_count = arraysize(temps);
+    InstructionCode code = kArchStoreWithWriteBarrier;
+    code |= AddressingModeField::encode(addressing_mode);
+    code |= MiscField::encode(static_cast<int>(record_write_mode));
+    Emit(code, 0, nullptr, input_count, inputs, temp_count, temps);
+  } else {
+    ArchOpcode opcode = kArchNop;
+    switch (rep) {
+      case MachineRepresentation::kFloat32:
+        opcode = kX87Movss;
+        break;
+      case MachineRepresentation::kFloat64:
+        opcode = kX87Movsd;
+        break;
+      case MachineRepresentation::kBit:  // Fall through.
+      case MachineRepresentation::kWord8:
+        opcode = kX87Movb;
+        break;
+      case MachineRepresentation::kWord16:
+        opcode = kX87Movw;
+        break;
+      case MachineRepresentation::kTagged:  // Fall through.
+      case MachineRepresentation::kWord32:
+        opcode = kX87Movl;
+        break;
+      case MachineRepresentation::kWord64:  // Fall through.
+      case MachineRepresentation::kNone:
+        UNREACHABLE();
+        return;
+    }
+
+    InstructionOperand val;
+    if (g.CanBeImmediate(value)) {
+      val = g.UseImmediate(value);
+    } else if (rep == MachineRepresentation::kWord8 ||
+               rep == MachineRepresentation::kBit) {
+      val = g.UseByteRegister(value);
+    } else {
+      val = g.UseRegister(value);
+    }
+
+    InstructionOperand inputs[4];
+    size_t input_count = 0;
+    AddressingMode addressing_mode =
+        g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count);
+    InstructionCode code =
+        opcode | AddressingModeField::encode(addressing_mode);
+    inputs[input_count++] = val;
+    Emit(code, 0, static_cast<InstructionOperand*>(nullptr), input_count,
+         inputs);
+  }
+}
+
+
+void InstructionSelector::VisitCheckedLoad(Node* node) {
+  CheckedLoadRepresentation load_rep = CheckedLoadRepresentationOf(node->op());
+  X87OperandGenerator g(this);
+  Node* const buffer = node->InputAt(0);
+  Node* const offset = node->InputAt(1);
+  Node* const length = node->InputAt(2);
+  ArchOpcode opcode = kArchNop;
+  switch (load_rep.representation()) {
+    case MachineRepresentation::kWord8:
+      opcode = load_rep.IsSigned() ? kCheckedLoadInt8 : kCheckedLoadUint8;
+      break;
+    case MachineRepresentation::kWord16:
+      opcode = load_rep.IsSigned() ? kCheckedLoadInt16 : kCheckedLoadUint16;
+      break;
+    case MachineRepresentation::kWord32:
+      opcode = kCheckedLoadWord32;
+      break;
+    case MachineRepresentation::kFloat32:
+      opcode = kCheckedLoadFloat32;
+      break;
+    case MachineRepresentation::kFloat64:
+      opcode = kCheckedLoadFloat64;
+      break;
+    case MachineRepresentation::kBit:     // Fall through.
+    case MachineRepresentation::kTagged:  // Fall through.
+    case MachineRepresentation::kWord64:  // Fall through.
+    case MachineRepresentation::kNone:
+      UNREACHABLE();
+      return;
+  }
+  InstructionOperand offset_operand = g.UseRegister(offset);
+  InstructionOperand length_operand =
+      g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length);
+  if (g.CanBeImmediate(buffer)) {
+    Emit(opcode | AddressingModeField::encode(kMode_MRI),
+         g.DefineAsRegister(node), offset_operand, length_operand,
+         offset_operand, g.UseImmediate(buffer));
+  } else {
+    Emit(opcode | AddressingModeField::encode(kMode_MR1),
+         g.DefineAsRegister(node), offset_operand, length_operand,
+         g.UseRegister(buffer), offset_operand);
+  }
+}
+
+
+void InstructionSelector::VisitCheckedStore(Node* node) {
+  MachineRepresentation rep = CheckedStoreRepresentationOf(node->op());
+  X87OperandGenerator g(this);
+  Node* const buffer = node->InputAt(0);
+  Node* const offset = node->InputAt(1);
+  Node* const length = node->InputAt(2);
+  Node* const value = node->InputAt(3);
+  ArchOpcode opcode = kArchNop;
+  switch (rep) {
+    case MachineRepresentation::kWord8:
+      opcode = kCheckedStoreWord8;
+      break;
+    case MachineRepresentation::kWord16:
+      opcode = kCheckedStoreWord16;
+      break;
+    case MachineRepresentation::kWord32:
+      opcode = kCheckedStoreWord32;
+      break;
+    case MachineRepresentation::kFloat32:
+      opcode = kCheckedStoreFloat32;
+      break;
+    case MachineRepresentation::kFloat64:
+      opcode = kCheckedStoreFloat64;
+      break;
+    case MachineRepresentation::kBit:     // Fall through.
+    case MachineRepresentation::kTagged:  // Fall through.
+    case MachineRepresentation::kWord64:  // Fall through.
+    case MachineRepresentation::kNone:
+      UNREACHABLE();
+      return;
+  }
+  InstructionOperand value_operand =
+      g.CanBeImmediate(value) ? g.UseImmediate(value)
+                              : ((rep == MachineRepresentation::kWord8 ||
+                                  rep == MachineRepresentation::kBit)
+                                     ? g.UseByteRegister(value)
+                                     : g.UseRegister(value));
+  InstructionOperand offset_operand = g.UseRegister(offset);
+  InstructionOperand length_operand =
+      g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length);
+  if (g.CanBeImmediate(buffer)) {
+    Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
+         offset_operand, length_operand, value_operand, offset_operand,
+         g.UseImmediate(buffer));
+  } else {
+    Emit(opcode | AddressingModeField::encode(kMode_MR1), g.NoOutput(),
+         offset_operand, length_operand, value_operand, g.UseRegister(buffer),
+         offset_operand);
+  }
+}
+
+
+// Shared routine for multiple binary operations.
+static void VisitBinop(InstructionSelector* selector, Node* node,
+                       InstructionCode opcode, FlagsContinuation* cont) {
+  X87OperandGenerator g(selector);
+  Int32BinopMatcher m(node);
+  Node* left = m.left().node();
+  Node* right = m.right().node();
+  InstructionOperand inputs[4];
+  size_t input_count = 0;
+  InstructionOperand outputs[2];
+  size_t output_count = 0;
+
+  // TODO(turbofan): match complex addressing modes.
+  if (left == right) {
+    // If both inputs refer to the same operand, enforce allocating a register
+    // for both of them to ensure that we don't end up generating code like
+    // this:
+    //
+    //   mov eax, [ebp-0x10]
+    //   add eax, [ebp-0x10]
+    //   jo label
+    InstructionOperand const input = g.UseRegister(left);
+    inputs[input_count++] = input;
+    inputs[input_count++] = input;
+  } else if (g.CanBeImmediate(right)) {
+    inputs[input_count++] = g.UseRegister(left);
+    inputs[input_count++] = g.UseImmediate(right);
+  } else {
+    if (node->op()->HasProperty(Operator::kCommutative) &&
+        g.CanBeBetterLeftOperand(right)) {
+      std::swap(left, right);
+    }
+    inputs[input_count++] = g.UseRegister(left);
+    inputs[input_count++] = g.Use(right);
+  }
+
+  if (cont->IsBranch()) {
+    inputs[input_count++] = g.Label(cont->true_block());
+    inputs[input_count++] = g.Label(cont->false_block());
+  }
+
+  outputs[output_count++] = g.DefineSameAsFirst(node);
+  if (cont->IsSet()) {
+    outputs[output_count++] = g.DefineAsRegister(cont->result());
+  }
+
+  DCHECK_NE(0u, input_count);
+  DCHECK_NE(0u, output_count);
+  DCHECK_GE(arraysize(inputs), input_count);
+  DCHECK_GE(arraysize(outputs), output_count);
+
+  selector->Emit(cont->Encode(opcode), output_count, outputs, input_count,
+                 inputs);
+}
+
+
+// Shared routine for multiple binary operations.
+static void VisitBinop(InstructionSelector* selector, Node* node,
+                       InstructionCode opcode) {
+  FlagsContinuation cont;
+  VisitBinop(selector, node, opcode, &cont);
+}
+
+
+void InstructionSelector::VisitWord32And(Node* node) {
+  VisitBinop(this, node, kX87And);
+}
+
+
+void InstructionSelector::VisitWord32Or(Node* node) {
+  VisitBinop(this, node, kX87Or);
+}
+
+
+void InstructionSelector::VisitWord32Xor(Node* node) {
+  X87OperandGenerator g(this);
+  Int32BinopMatcher m(node);
+  if (m.right().Is(-1)) {
+    Emit(kX87Not, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()));
+  } else {
+    VisitBinop(this, node, kX87Xor);
+  }
+}
+
+
+// Shared routine for multiple shift operations.
+static inline void VisitShift(InstructionSelector* selector, Node* node,
+                              ArchOpcode opcode) {
+  X87OperandGenerator g(selector);
+  Node* left = node->InputAt(0);
+  Node* right = node->InputAt(1);
+
+  if (g.CanBeImmediate(right)) {
+    selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left),
+                   g.UseImmediate(right));
+  } else {
+    selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left),
+                   g.UseFixed(right, ecx));
+  }
+}
+
+
+namespace {
+
+void VisitMulHigh(InstructionSelector* selector, Node* node,
+                  ArchOpcode opcode) {
+  X87OperandGenerator g(selector);
+  selector->Emit(opcode, g.DefineAsFixed(node, edx),
+                 g.UseFixed(node->InputAt(0), eax),
+                 g.UseUniqueRegister(node->InputAt(1)));
+}
+
+
+void VisitDiv(InstructionSelector* selector, Node* node, ArchOpcode opcode) {
+  X87OperandGenerator g(selector);
+  InstructionOperand temps[] = {g.TempRegister(edx)};
+  selector->Emit(opcode, g.DefineAsFixed(node, eax),
+                 g.UseFixed(node->InputAt(0), eax),
+                 g.UseUnique(node->InputAt(1)), arraysize(temps), temps);
+}
+
+
+void VisitMod(InstructionSelector* selector, Node* node, ArchOpcode opcode) {
+  X87OperandGenerator g(selector);
+  selector->Emit(opcode, g.DefineAsFixed(node, edx),
+                 g.UseFixed(node->InputAt(0), eax),
+                 g.UseUnique(node->InputAt(1)));
+}
+
+void EmitLea(InstructionSelector* selector, Node* result, Node* index,
+             int scale, Node* base, Node* displacement) {
+  X87OperandGenerator g(selector);
+  InstructionOperand inputs[4];
+  size_t input_count = 0;
+  AddressingMode mode = g.GenerateMemoryOperandInputs(
+      index, scale, base, displacement, inputs, &input_count);
+
+  DCHECK_NE(0u, input_count);
+  DCHECK_GE(arraysize(inputs), input_count);
+
+  InstructionOperand outputs[1];
+  outputs[0] = g.DefineAsRegister(result);
+
+  InstructionCode opcode = AddressingModeField::encode(mode) | kX87Lea;
+
+  selector->Emit(opcode, 1, outputs, input_count, inputs);
+}
+
+}  // namespace
+
+
+void InstructionSelector::VisitWord32Shl(Node* node) {
+  Int32ScaleMatcher m(node, true);
+  if (m.matches()) {
+    Node* index = node->InputAt(0);
+    Node* base = m.power_of_two_plus_one() ? index : nullptr;
+    EmitLea(this, node, index, m.scale(), base, nullptr);
+    return;
+  }
+  VisitShift(this, node, kX87Shl);
+}
+
+
+void InstructionSelector::VisitWord32Shr(Node* node) {
+  VisitShift(this, node, kX87Shr);
+}
+
+
+void InstructionSelector::VisitWord32Sar(Node* node) {
+  VisitShift(this, node, kX87Sar);
+}
+
+
+void InstructionSelector::VisitWord32Ror(Node* node) {
+  VisitShift(this, node, kX87Ror);
+}
+
+
+void InstructionSelector::VisitWord32Clz(Node* node) {
+  X87OperandGenerator g(this);
+  Emit(kX87Lzcnt, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitWord32Ctz(Node* node) { UNREACHABLE(); }
+
+
+void InstructionSelector::VisitWord32Popcnt(Node* node) {
+  X87OperandGenerator g(this);
+  Emit(kX87Popcnt, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitInt32Add(Node* node) {
+  X87OperandGenerator g(this);
+
+  // Try to match the Add to a lea pattern
+  BaseWithIndexAndDisplacement32Matcher m(node);
+  if (m.matches() &&
+      (m.displacement() == nullptr || g.CanBeImmediate(m.displacement()))) {
+    InstructionOperand inputs[4];
+    size_t input_count = 0;
+    AddressingMode mode = g.GenerateMemoryOperandInputs(
+        m.index(), m.scale(), m.base(), m.displacement(), inputs, &input_count);
+
+    DCHECK_NE(0u, input_count);
+    DCHECK_GE(arraysize(inputs), input_count);
+
+    InstructionOperand outputs[1];
+    outputs[0] = g.DefineAsRegister(node);
+
+    InstructionCode opcode = AddressingModeField::encode(mode) | kX87Lea;
+    Emit(opcode, 1, outputs, input_count, inputs);
+    return;
+  }
+
+  // No lea pattern match, use add
+  VisitBinop(this, node, kX87Add);
+}
+
+
+void InstructionSelector::VisitInt32Sub(Node* node) {
+  X87OperandGenerator g(this);
+  Int32BinopMatcher m(node);
+  if (m.left().Is(0)) {
+    Emit(kX87Neg, g.DefineSameAsFirst(node), g.Use(m.right().node()));
+  } else {
+    VisitBinop(this, node, kX87Sub);
+  }
+}
+
+
+void InstructionSelector::VisitInt32Mul(Node* node) {
+  Int32ScaleMatcher m(node, true);
+  if (m.matches()) {
+    Node* index = node->InputAt(0);
+    Node* base = m.power_of_two_plus_one() ? index : nullptr;
+    EmitLea(this, node, index, m.scale(), base, nullptr);
+    return;
+  }
+  X87OperandGenerator g(this);
+  Node* left = node->InputAt(0);
+  Node* right = node->InputAt(1);
+  if (g.CanBeImmediate(right)) {
+    Emit(kX87Imul, g.DefineAsRegister(node), g.Use(left),
+         g.UseImmediate(right));
+  } else {
+    if (g.CanBeBetterLeftOperand(right)) {
+      std::swap(left, right);
+    }
+    Emit(kX87Imul, g.DefineSameAsFirst(node), g.UseRegister(left),
+         g.Use(right));
+  }
+}
+
+
+void InstructionSelector::VisitInt32MulHigh(Node* node) {
+  VisitMulHigh(this, node, kX87ImulHigh);
+}
+
+
+void InstructionSelector::VisitUint32MulHigh(Node* node) {
+  VisitMulHigh(this, node, kX87UmulHigh);
+}
+
+
+void InstructionSelector::VisitInt32Div(Node* node) {
+  VisitDiv(this, node, kX87Idiv);
+}
+
+
+void InstructionSelector::VisitUint32Div(Node* node) {
+  VisitDiv(this, node, kX87Udiv);
+}
+
+
+void InstructionSelector::VisitInt32Mod(Node* node) {
+  VisitMod(this, node, kX87Idiv);
+}
+
+
+void InstructionSelector::VisitUint32Mod(Node* node) {
+  VisitMod(this, node, kX87Udiv);
+}
+
+
+void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) {
+  X87OperandGenerator g(this);
+  Emit(kX87Float32ToFloat64, g.DefineAsFixed(node, stX_0),
+       g.Use(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) {
+  X87OperandGenerator g(this);
+  Emit(kX87Int32ToFloat64, g.DefineAsFixed(node, stX_0),
+       g.Use(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitChangeUint32ToFloat64(Node* node) {
+  X87OperandGenerator g(this);
+  Emit(kX87Uint32ToFloat64, g.DefineAsFixed(node, stX_0),
+       g.UseRegister(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitChangeFloat64ToInt32(Node* node) {
+  X87OperandGenerator g(this);
+  Emit(kX87Float64ToInt32, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitChangeFloat64ToUint32(Node* node) {
+  X87OperandGenerator g(this);
+  Emit(kX87Float64ToUint32, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitTruncateFloat64ToFloat32(Node* node) {
+  X87OperandGenerator g(this);
+  Emit(kX87Float64ToFloat32, g.DefineAsFixed(node, stX_0),
+       g.Use(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitTruncateFloat64ToInt32(Node* node) {
+  X87OperandGenerator g(this);
+
+  switch (TruncationModeOf(node->op())) {
+    case TruncationMode::kJavaScript:
+      Emit(kArchTruncateDoubleToI, g.DefineAsRegister(node),
+           g.Use(node->InputAt(0)));
+      return;
+    case TruncationMode::kRoundToZero:
+      Emit(kX87Float64ToInt32, g.DefineAsRegister(node),
+           g.Use(node->InputAt(0)));
+      return;
+  }
+  UNREACHABLE();
+}
+
+
+void InstructionSelector::VisitBitcastFloat32ToInt32(Node* node) {
+  X87OperandGenerator g(this);
+  Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(0)));
+  Emit(kX87BitcastFI, g.DefineAsRegister(node), 0, nullptr);
+}
+
+
+void InstructionSelector::VisitBitcastInt32ToFloat32(Node* node) {
+  X87OperandGenerator g(this);
+  Emit(kX87BitcastIF, g.DefineAsFixed(node, stX_0), g.Use(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitFloat32Add(Node* node) {
+  X87OperandGenerator g(this);
+  Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(0)));
+  Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(1)));
+  Emit(kX87Float32Add, g.DefineAsFixed(node, stX_0), 0, nullptr);
+}
+
+
+void InstructionSelector::VisitFloat64Add(Node* node) {
+  X87OperandGenerator g(this);
+  Emit(kX87PushFloat64, g.NoOutput(), g.Use(node->InputAt(0)));
+  Emit(kX87PushFloat64, g.NoOutput(), g.Use(node->InputAt(1)));
+  Emit(kX87Float64Add, g.DefineAsFixed(node, stX_0), 0, nullptr);
+}
+
+
+void InstructionSelector::VisitFloat32Sub(Node* node) {
+  X87OperandGenerator g(this);
+  Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(0)));
+  Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(1)));
+  Emit(kX87Float32Sub, g.DefineAsFixed(node, stX_0), 0, nullptr);
+}
+
+
+void InstructionSelector::VisitFloat64Sub(Node* node) {
+  X87OperandGenerator g(this);
+  Emit(kX87PushFloat64, g.NoOutput(), g.Use(node->InputAt(0)));
+  Emit(kX87PushFloat64, g.NoOutput(), g.Use(node->InputAt(1)));
+  Emit(kX87Float64Sub, g.DefineAsFixed(node, stX_0), 0, nullptr);
+}
+
+
+void InstructionSelector::VisitFloat32Mul(Node* node) {
+  X87OperandGenerator g(this);
+  Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(0)));
+  Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(1)));
+  Emit(kX87Float32Mul, g.DefineAsFixed(node, stX_0), 0, nullptr);
+}
+
+
+void InstructionSelector::VisitFloat64Mul(Node* node) {
+  X87OperandGenerator g(this);
+  Emit(kX87PushFloat64, g.NoOutput(), g.Use(node->InputAt(0)));
+  Emit(kX87PushFloat64, g.NoOutput(), g.Use(node->InputAt(1)));
+  Emit(kX87Float64Mul, g.DefineAsFixed(node, stX_0), 0, nullptr);
+}
+
+
+void InstructionSelector::VisitFloat32Div(Node* node) {
+  X87OperandGenerator g(this);
+  Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(0)));
+  Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(1)));
+  Emit(kX87Float32Div, g.DefineAsFixed(node, stX_0), 0, nullptr);
+}
+
+
+void InstructionSelector::VisitFloat64Div(Node* node) {
+  X87OperandGenerator g(this);
+  Emit(kX87PushFloat64, g.NoOutput(), g.Use(node->InputAt(0)));
+  Emit(kX87PushFloat64, g.NoOutput(), g.Use(node->InputAt(1)));
+  Emit(kX87Float64Div, g.DefineAsFixed(node, stX_0), 0, nullptr);
+}
+
+
+void InstructionSelector::VisitFloat64Mod(Node* node) {
+  X87OperandGenerator g(this);
+  InstructionOperand temps[] = {g.TempRegister(eax)};
+  Emit(kX87PushFloat64, g.NoOutput(), g.Use(node->InputAt(0)));
+  Emit(kX87PushFloat64, g.NoOutput(), g.Use(node->InputAt(1)));
+  Emit(kX87Float64Mod, g.DefineAsFixed(node, stX_0), 1, temps)->MarkAsCall();
+}
+
+
+void InstructionSelector::VisitFloat32Max(Node* node) {
+  X87OperandGenerator g(this);
+  Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(0)));
+  Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(1)));
+  Emit(kX87Float32Max, g.DefineAsFixed(node, stX_0), 0, nullptr);
+}
+
+
+void InstructionSelector::VisitFloat64Max(Node* node) {
+  X87OperandGenerator g(this);
+  Emit(kX87PushFloat64, g.NoOutput(), g.Use(node->InputAt(0)));
+  Emit(kX87PushFloat64, g.NoOutput(), g.Use(node->InputAt(1)));
+  Emit(kX87Float64Max, g.DefineAsFixed(node, stX_0), 0, nullptr);
+}
+
+
+void InstructionSelector::VisitFloat32Min(Node* node) {
+  X87OperandGenerator g(this);
+  Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(0)));
+  Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(1)));
+  Emit(kX87Float32Min, g.DefineAsFixed(node, stX_0), 0, nullptr);
+}
+
+
+void InstructionSelector::VisitFloat64Min(Node* node) {
+  X87OperandGenerator g(this);
+  Emit(kX87PushFloat64, g.NoOutput(), g.Use(node->InputAt(0)));
+  Emit(kX87PushFloat64, g.NoOutput(), g.Use(node->InputAt(1)));
+  Emit(kX87Float64Min, g.DefineAsFixed(node, stX_0), 0, nullptr);
+}
+
+
+void InstructionSelector::VisitFloat32Abs(Node* node) {
+  X87OperandGenerator g(this);
+  Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(0)));
+  Emit(kX87Float32Abs, g.DefineAsFixed(node, stX_0), 0, nullptr);
+}
+
+
+void InstructionSelector::VisitFloat64Abs(Node* node) {
+  X87OperandGenerator g(this);
+  Emit(kX87PushFloat64, g.NoOutput(), g.Use(node->InputAt(0)));
+  Emit(kX87Float64Abs, g.DefineAsFixed(node, stX_0), 0, nullptr);
+}
+
+
+void InstructionSelector::VisitFloat32Sqrt(Node* node) {
+  X87OperandGenerator g(this);
+  Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(0)));
+  Emit(kX87Float32Sqrt, g.DefineAsFixed(node, stX_0), 0, nullptr);
+}
+
+
+void InstructionSelector::VisitFloat64Sqrt(Node* node) {
+  X87OperandGenerator g(this);
+  Emit(kX87PushFloat64, g.NoOutput(), g.Use(node->InputAt(0)));
+  Emit(kX87Float64Sqrt, g.DefineAsFixed(node, stX_0), 0, nullptr);
+}
+
+
+void InstructionSelector::VisitFloat32RoundDown(Node* node) {
+  X87OperandGenerator g(this);
+  Emit(kX87Float32Round | MiscField::encode(kRoundDown),
+       g.UseFixed(node, stX_0), g.Use(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitFloat64RoundDown(Node* node) {
+  X87OperandGenerator g(this);
+  Emit(kX87Float64Round | MiscField::encode(kRoundDown),
+       g.UseFixed(node, stX_0), g.Use(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitFloat32RoundUp(Node* node) {
+  X87OperandGenerator g(this);
+  Emit(kX87Float32Round | MiscField::encode(kRoundUp), g.UseFixed(node, stX_0),
+       g.Use(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitFloat64RoundUp(Node* node) {
+  X87OperandGenerator g(this);
+  Emit(kX87Float64Round | MiscField::encode(kRoundUp), g.UseFixed(node, stX_0),
+       g.Use(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitFloat32RoundTruncate(Node* node) {
+  X87OperandGenerator g(this);
+  Emit(kX87Float32Round | MiscField::encode(kRoundToZero),
+       g.UseFixed(node, stX_0), g.Use(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitFloat64RoundTruncate(Node* node) {
+  X87OperandGenerator g(this);
+  Emit(kX87Float64Round | MiscField::encode(kRoundToZero),
+       g.UseFixed(node, stX_0), g.Use(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) {
+  UNREACHABLE();
+}
+
+
+void InstructionSelector::VisitFloat32RoundTiesEven(Node* node) {
+  X87OperandGenerator g(this);
+  Emit(kX87Float32Round | MiscField::encode(kRoundToNearest),
+       g.UseFixed(node, stX_0), g.Use(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitFloat64RoundTiesEven(Node* node) {
+  X87OperandGenerator g(this);
+  Emit(kX87Float64Round | MiscField::encode(kRoundToNearest),
+       g.UseFixed(node, stX_0), g.Use(node->InputAt(0)));
+}
+
+
+void InstructionSelector::EmitPrepareArguments(
+    ZoneVector<PushParameter>* arguments, const CallDescriptor* descriptor,
+    Node* node) {
+  X87OperandGenerator g(this);
+
+  // Prepare for C function call.
+  if (descriptor->IsCFunctionCall()) {
+    InstructionOperand temps[] = {g.TempRegister()};
+    size_t const temp_count = arraysize(temps);
+    Emit(kArchPrepareCallCFunction |
+             MiscField::encode(static_cast<int>(descriptor->CParameterCount())),
+         0, nullptr, 0, nullptr, temp_count, temps);
+
+    // Poke any stack arguments.
+    for (size_t n = 0; n < arguments->size(); ++n) {
+      PushParameter input = (*arguments)[n];
+      if (input.node()) {
+        int const slot = static_cast<int>(n);
+        InstructionOperand value = g.CanBeImmediate(input.node())
+                                       ? g.UseImmediate(input.node())
+                                       : g.UseRegister(input.node());
+        Emit(kX87Poke | MiscField::encode(slot), g.NoOutput(), value);
+      }
+    }
+  } else {
+    // Push any stack arguments.
+    for (PushParameter input : base::Reversed(*arguments)) {
+      // TODO(titzer): handle pushing double parameters.
+      if (input.node() == nullptr) continue;
+      InstructionOperand value =
+          g.CanBeImmediate(input.node())
+              ? g.UseImmediate(input.node())
+              : IsSupported(ATOM) ||
+                        sequence()->IsFloat(GetVirtualRegister(input.node()))
+                    ? g.UseRegister(input.node())
+                    : g.Use(input.node());
+      Emit(kX87Push, g.NoOutput(), value);
+    }
+  }
+}
+
+
+bool InstructionSelector::IsTailCallAddressImmediate() { return true; }
+
+
+namespace {
+
+// Shared routine for multiple compare operations.
+void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
+                  InstructionOperand left, InstructionOperand right,
+                  FlagsContinuation* cont) {
+  X87OperandGenerator g(selector);
+  if (cont->IsBranch()) {
+    selector->Emit(cont->Encode(opcode), g.NoOutput(), left, right,
+                   g.Label(cont->true_block()), g.Label(cont->false_block()));
+  } else {
+    DCHECK(cont->IsSet());
+    selector->Emit(cont->Encode(opcode), g.DefineAsByteRegister(cont->result()),
+                   left, right);
+  }
+}
+
+
+// Shared routine for multiple compare operations.
+void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
+                  Node* left, Node* right, FlagsContinuation* cont,
+                  bool commutative) {
+  X87OperandGenerator g(selector);
+  if (commutative && g.CanBeBetterLeftOperand(right)) {
+    std::swap(left, right);
+  }
+  VisitCompare(selector, opcode, g.UseRegister(left), g.Use(right), cont);
+}
+
+
+// Shared routine for multiple float32 compare operations (inputs commuted).
+void VisitFloat32Compare(InstructionSelector* selector, Node* node,
+                         FlagsContinuation* cont) {
+  X87OperandGenerator g(selector);
+  selector->Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(0)));
+  selector->Emit(kX87PushFloat32, g.NoOutput(), g.Use(node->InputAt(1)));
+  if (cont->IsBranch()) {
+    selector->Emit(cont->Encode(kX87Float32Cmp), g.NoOutput(),
+                   g.Label(cont->true_block()), g.Label(cont->false_block()));
+  } else {
+    DCHECK(cont->IsSet());
+    selector->Emit(cont->Encode(kX87Float32Cmp),
+                   g.DefineAsByteRegister(cont->result()));
+  }
+}
+
+
+// Shared routine for multiple float64 compare operations (inputs commuted).
+void VisitFloat64Compare(InstructionSelector* selector, Node* node,
+                         FlagsContinuation* cont) {
+  X87OperandGenerator g(selector);
+  selector->Emit(kX87PushFloat64, g.NoOutput(), g.Use(node->InputAt(0)));
+  selector->Emit(kX87PushFloat64, g.NoOutput(), g.Use(node->InputAt(1)));
+  if (cont->IsBranch()) {
+    selector->Emit(cont->Encode(kX87Float64Cmp), g.NoOutput(),
+                   g.Label(cont->true_block()), g.Label(cont->false_block()));
+  } else {
+    DCHECK(cont->IsSet());
+    selector->Emit(cont->Encode(kX87Float64Cmp),
+                   g.DefineAsByteRegister(cont->result()));
+  }
+}
+
+
+// Shared routine for multiple word compare operations.
+void VisitWordCompare(InstructionSelector* selector, Node* node,
+                      InstructionCode opcode, FlagsContinuation* cont) {
+  X87OperandGenerator g(selector);
+  Node* const left = node->InputAt(0);
+  Node* const right = node->InputAt(1);
+
+  // Match immediates on left or right side of comparison.
+  if (g.CanBeImmediate(right)) {
+    VisitCompare(selector, opcode, g.Use(left), g.UseImmediate(right), cont);
+  } else if (g.CanBeImmediate(left)) {
+    if (!node->op()->HasProperty(Operator::kCommutative)) cont->Commute();
+    VisitCompare(selector, opcode, g.Use(right), g.UseImmediate(left), cont);
+  } else {
+    VisitCompare(selector, opcode, left, right, cont,
+                 node->op()->HasProperty(Operator::kCommutative));
+  }
+}
+
+
+void VisitWordCompare(InstructionSelector* selector, Node* node,
+                      FlagsContinuation* cont) {
+  X87OperandGenerator g(selector);
+  Int32BinopMatcher m(node);
+  if (m.left().IsLoad() && m.right().IsLoadStackPointer()) {
+    LoadMatcher<ExternalReferenceMatcher> mleft(m.left().node());
+    ExternalReference js_stack_limit =
+        ExternalReference::address_of_stack_limit(selector->isolate());
+    if (mleft.object().Is(js_stack_limit) && mleft.index().Is(0)) {
+      // Compare(Load(js_stack_limit), LoadStackPointer)
+      if (!node->op()->HasProperty(Operator::kCommutative)) cont->Commute();
+      InstructionCode opcode = cont->Encode(kX87StackCheck);
+      if (cont->IsBranch()) {
+        selector->Emit(opcode, g.NoOutput(), g.Label(cont->true_block()),
+                       g.Label(cont->false_block()));
+      } else {
+        DCHECK(cont->IsSet());
+        selector->Emit(opcode, g.DefineAsRegister(cont->result()));
+      }
+      return;
+    }
+  }
+  VisitWordCompare(selector, node, kX87Cmp, cont);
+}
+
+
+// Shared routine for word comparison with zero.
+void VisitWordCompareZero(InstructionSelector* selector, Node* user,
+                          Node* value, FlagsContinuation* cont) {
+  // Try to combine the branch with a comparison.
+  while (selector->CanCover(user, value)) {
+    switch (value->opcode()) {
+      case IrOpcode::kWord32Equal: {
+        // Try to combine with comparisons against 0 by simply inverting the
+        // continuation.
+        Int32BinopMatcher m(value);
+        if (m.right().Is(0)) {
+          user = value;
+          value = m.left().node();
+          cont->Negate();
+          continue;
+        }
+        cont->OverwriteAndNegateIfEqual(kEqual);
+        return VisitWordCompare(selector, value, cont);
+      }
+      case IrOpcode::kInt32LessThan:
+        cont->OverwriteAndNegateIfEqual(kSignedLessThan);
+        return VisitWordCompare(selector, value, cont);
+      case IrOpcode::kInt32LessThanOrEqual:
+        cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual);
+        return VisitWordCompare(selector, value, cont);
+      case IrOpcode::kUint32LessThan:
+        cont->OverwriteAndNegateIfEqual(kUnsignedLessThan);
+        return VisitWordCompare(selector, value, cont);
+      case IrOpcode::kUint32LessThanOrEqual:
+        cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
+        return VisitWordCompare(selector, value, cont);
+      case IrOpcode::kFloat32Equal:
+        cont->OverwriteAndNegateIfEqual(kUnorderedEqual);
+        return VisitFloat32Compare(selector, value, cont);
+      case IrOpcode::kFloat32LessThan:
+        cont->OverwriteAndNegateIfEqual(kUnsignedGreaterThan);
+        return VisitFloat32Compare(selector, value, cont);
+      case IrOpcode::kFloat32LessThanOrEqual:
+        cont->OverwriteAndNegateIfEqual(kUnsignedGreaterThanOrEqual);
+        return VisitFloat32Compare(selector, value, cont);
+      case IrOpcode::kFloat64Equal:
+        cont->OverwriteAndNegateIfEqual(kUnorderedEqual);
+        return VisitFloat64Compare(selector, value, cont);
+      case IrOpcode::kFloat64LessThan:
+        cont->OverwriteAndNegateIfEqual(kUnsignedGreaterThan);
+        return VisitFloat64Compare(selector, value, cont);
+      case IrOpcode::kFloat64LessThanOrEqual:
+        cont->OverwriteAndNegateIfEqual(kUnsignedGreaterThanOrEqual);
+        return VisitFloat64Compare(selector, value, cont);
+      case IrOpcode::kProjection:
+        // Check if this is the overflow output projection of an
+        // <Operation>WithOverflow node.
+        if (ProjectionIndexOf(value->op()) == 1u) {
+          // We cannot combine the <Operation>WithOverflow with this branch
+          // unless the 0th projection (the use of the actual value of the
+          // <Operation> is either nullptr, which means there's no use of the
+          // actual value, or was already defined, which means it is scheduled
+          // *AFTER* this branch).
+          Node* const node = value->InputAt(0);
+          Node* const result = NodeProperties::FindProjection(node, 0);
+          if (result == nullptr || selector->IsDefined(result)) {
+            switch (node->opcode()) {
+              case IrOpcode::kInt32AddWithOverflow:
+                cont->OverwriteAndNegateIfEqual(kOverflow);
+                return VisitBinop(selector, node, kX87Add, cont);
+              case IrOpcode::kInt32SubWithOverflow:
+                cont->OverwriteAndNegateIfEqual(kOverflow);
+                return VisitBinop(selector, node, kX87Sub, cont);
+              default:
+                break;
+            }
+          }
+        }
+        break;
+      case IrOpcode::kInt32Sub:
+        return VisitWordCompare(selector, value, cont);
+      case IrOpcode::kWord32And:
+        return VisitWordCompare(selector, value, kX87Test, cont);
+      default:
+        break;
+    }
+    break;
+  }
+
+  // Continuation could not be combined with a compare, emit compare against 0.
+  X87OperandGenerator g(selector);
+  VisitCompare(selector, kX87Cmp, g.Use(value), g.TempImmediate(0), cont);
+}
+
+}  // namespace
+
+
+void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
+                                      BasicBlock* fbranch) {
+  FlagsContinuation cont(kNotEqual, tbranch, fbranch);
+  VisitWordCompareZero(this, branch, branch->InputAt(0), &cont);
+}
+
+
+void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) {
+  X87OperandGenerator g(this);
+  InstructionOperand value_operand = g.UseRegister(node->InputAt(0));
+
+  // Emit either ArchTableSwitch or ArchLookupSwitch.
+  size_t table_space_cost = 4 + sw.value_range;
+  size_t table_time_cost = 3;
+  size_t lookup_space_cost = 3 + 2 * sw.case_count;
+  size_t lookup_time_cost = sw.case_count;
+  if (sw.case_count > 4 &&
+      table_space_cost + 3 * table_time_cost <=
+          lookup_space_cost + 3 * lookup_time_cost &&
+      sw.min_value > std::numeric_limits<int32_t>::min()) {
+    InstructionOperand index_operand = value_operand;
+    if (sw.min_value) {
+      index_operand = g.TempRegister();
+      Emit(kX87Lea | AddressingModeField::encode(kMode_MRI), index_operand,
+           value_operand, g.TempImmediate(-sw.min_value));
+    }
+    // Generate a table lookup.
+    return EmitTableSwitch(sw, index_operand);
+  }
+
+  // Generate a sequence of conditional jumps.
+  return EmitLookupSwitch(sw, value_operand);
+}
+
+
+void InstructionSelector::VisitWord32Equal(Node* const node) {
+  FlagsContinuation cont(kEqual, node);
+  Int32BinopMatcher m(node);
+  if (m.right().Is(0)) {
+    return VisitWordCompareZero(this, m.node(), m.left().node(), &cont);
+  }
+  VisitWordCompare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitInt32LessThan(Node* node) {
+  FlagsContinuation cont(kSignedLessThan, node);
+  VisitWordCompare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitInt32LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kSignedLessThanOrEqual, node);
+  VisitWordCompare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitUint32LessThan(Node* node) {
+  FlagsContinuation cont(kUnsignedLessThan, node);
+  VisitWordCompare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitUint32LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kUnsignedLessThanOrEqual, node);
+  VisitWordCompare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitInt32AddWithOverflow(Node* node) {
+  if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
+    FlagsContinuation cont(kOverflow, ovf);
+    return VisitBinop(this, node, kX87Add, &cont);
+  }
+  FlagsContinuation cont;
+  VisitBinop(this, node, kX87Add, &cont);
+}
+
+
+void InstructionSelector::VisitInt32SubWithOverflow(Node* node) {
+  if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
+    FlagsContinuation cont(kOverflow, ovf);
+    return VisitBinop(this, node, kX87Sub, &cont);
+  }
+  FlagsContinuation cont;
+  VisitBinop(this, node, kX87Sub, &cont);
+}
+
+
+void InstructionSelector::VisitFloat32Equal(Node* node) {
+  FlagsContinuation cont(kUnorderedEqual, node);
+  VisitFloat32Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitFloat32LessThan(Node* node) {
+  FlagsContinuation cont(kUnsignedGreaterThan, node);
+  VisitFloat32Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitFloat32LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kUnsignedGreaterThanOrEqual, node);
+  VisitFloat32Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitFloat64Equal(Node* node) {
+  FlagsContinuation cont(kUnorderedEqual, node);
+  VisitFloat64Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitFloat64LessThan(Node* node) {
+  FlagsContinuation cont(kUnsignedGreaterThan, node);
+  VisitFloat64Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kUnsignedGreaterThanOrEqual, node);
+  VisitFloat64Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitFloat64ExtractLowWord32(Node* node) {
+  X87OperandGenerator g(this);
+  Emit(kX87Float64ExtractLowWord32, g.DefineAsRegister(node),
+       g.Use(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitFloat64ExtractHighWord32(Node* node) {
+  X87OperandGenerator g(this);
+  Emit(kX87Float64ExtractHighWord32, g.DefineAsRegister(node),
+       g.Use(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitFloat64InsertLowWord32(Node* node) {
+  X87OperandGenerator g(this);
+  Node* left = node->InputAt(0);
+  Node* right = node->InputAt(1);
+  Emit(kX87Float64InsertLowWord32, g.UseFixed(node, stX_0), g.UseRegister(left),
+       g.UseRegister(right));
+}
+
+
+void InstructionSelector::VisitFloat64InsertHighWord32(Node* node) {
+  X87OperandGenerator g(this);
+  Node* left = node->InputAt(0);
+  Node* right = node->InputAt(1);
+  Emit(kX87Float64InsertHighWord32, g.UseFixed(node, stX_0),
+       g.UseRegister(left), g.UseRegister(right));
+}
+
+
+// static
+MachineOperatorBuilder::Flags
+InstructionSelector::SupportedMachineOperatorFlags() {
+  MachineOperatorBuilder::Flags flags =
+      MachineOperatorBuilder::kFloat32Max |
+      MachineOperatorBuilder::kFloat32Min |
+      MachineOperatorBuilder::kFloat64Max |
+      MachineOperatorBuilder::kFloat64Min |
+      MachineOperatorBuilder::kWord32ShiftIsSafe;
+  if (CpuFeatures::IsSupported(POPCNT)) {
+    flags |= MachineOperatorBuilder::kWord32Popcnt;
+  }
+
+  flags |= MachineOperatorBuilder::kFloat32RoundDown |
+           MachineOperatorBuilder::kFloat64RoundDown |
+           MachineOperatorBuilder::kFloat32RoundUp |
+           MachineOperatorBuilder::kFloat64RoundUp |
+           MachineOperatorBuilder::kFloat32RoundTruncate |
+           MachineOperatorBuilder::kFloat64RoundTruncate |
+           MachineOperatorBuilder::kFloat32RoundTiesEven |
+           MachineOperatorBuilder::kFloat64RoundTiesEven;
+  return flags;
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/zone-pool.cc b/src/compiler/zone-pool.cc
index 179988d..2006a79 100644
--- a/src/compiler/zone-pool.cc
+++ b/src/compiler/zone-pool.cc
@@ -65,8 +65,7 @@
 }
 
 
-ZonePool::ZonePool(Isolate* isolate)
-    : isolate_(isolate), max_allocated_bytes_(0), total_deleted_bytes_(0) {}
+ZonePool::ZonePool() : max_allocated_bytes_(0), total_deleted_bytes_(0) {}
 
 
 ZonePool::~ZonePool() {
@@ -104,10 +103,10 @@
     zone = unused_.back();
     unused_.pop_back();
   } else {
-    zone = new Zone(isolate_);
+    zone = new Zone();
   }
   used_.push_back(zone);
-  DCHECK_EQ(0, zone->allocation_size());
+  DCHECK_EQ(0u, zone->allocation_size());
   return zone;
 }
 
@@ -130,7 +129,7 @@
     delete zone;
   } else {
     zone->DeleteAll();
-    DCHECK_EQ(0, zone->allocation_size());
+    DCHECK_EQ(0u, zone->allocation_size());
     unused_.push_back(zone);
   }
 }
diff --git a/src/compiler/zone-pool.h b/src/compiler/zone-pool.h
index 8b43265..aaf9daa 100644
--- a/src/compiler/zone-pool.h
+++ b/src/compiler/zone-pool.h
@@ -9,26 +9,27 @@
 #include <set>
 #include <vector>
 
-#include "src/v8.h"
+#include "src/zone.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
-class ZonePool FINAL {
+class ZonePool final {
  public:
-  class Scope FINAL {
+  class Scope final {
    public:
-    explicit Scope(ZonePool* zone_pool) : zone_pool_(zone_pool), zone_(NULL) {}
+    explicit Scope(ZonePool* zone_pool)
+        : zone_pool_(zone_pool), zone_(nullptr) {}
     ~Scope() { Destroy(); }
 
     Zone* zone() {
-      if (zone_ == NULL) zone_ = zone_pool_->NewEmptyZone();
+      if (zone_ == nullptr) zone_ = zone_pool_->NewEmptyZone();
       return zone_;
     }
     void Destroy() {
-      if (zone_ != NULL) zone_pool_->ReturnZone(zone_);
-      zone_ = NULL;
+      if (zone_ != nullptr) zone_pool_->ReturnZone(zone_);
+      zone_ = nullptr;
     }
 
    private:
@@ -37,7 +38,7 @@
     DISALLOW_COPY_AND_ASSIGN(Scope);
   };
 
-  class StatsScope FINAL {
+  class StatsScope final {
    public:
     explicit StatsScope(ZonePool* zone_pool);
     ~StatsScope();
@@ -60,7 +61,7 @@
     DISALLOW_COPY_AND_ASSIGN(StatsScope);
   };
 
-  explicit ZonePool(Isolate* isolate);
+  ZonePool();
   ~ZonePool();
 
   size_t GetMaxAllocatedBytes();
@@ -76,7 +77,6 @@
   typedef std::vector<Zone*> Used;
   typedef std::vector<StatsScope*> Stats;
 
-  Isolate* const isolate_;
   Unused unused_;
   Used used_;
   Stats stats_;
