diff --git a/src/compiler/effect-control-linearizer.cc b/src/compiler/effect-control-linearizer.cc
new file mode 100644
index 0000000..716723b
--- /dev/null
+++ b/src/compiler/effect-control-linearizer.cc
@@ -0,0 +1,983 @@
+// 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/effect-control-linearizer.h"
+
+#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-properties.h"
+#include "src/compiler/node.h"
+#include "src/compiler/schedule.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+EffectControlLinearizer::EffectControlLinearizer(JSGraph* js_graph,
+                                                 Schedule* schedule,
+                                                 Zone* temp_zone)
+    : js_graph_(js_graph), schedule_(schedule), temp_zone_(temp_zone) {}
+
+Graph* EffectControlLinearizer::graph() const { return js_graph_->graph(); }
+CommonOperatorBuilder* EffectControlLinearizer::common() const {
+  return js_graph_->common();
+}
+SimplifiedOperatorBuilder* EffectControlLinearizer::simplified() const {
+  return js_graph_->simplified();
+}
+MachineOperatorBuilder* EffectControlLinearizer::machine() const {
+  return js_graph_->machine();
+}
+
+namespace {
+
+struct BlockEffectControlData {
+  Node* current_effect = nullptr;  // New effect.
+  Node* current_control = nullptr;  // New control.
+};
+
+// Effect phis that need to be updated after the first pass.
+struct PendingEffectPhi {
+  Node* effect_phi;
+  BasicBlock* block;
+
+  PendingEffectPhi(Node* effect_phi, BasicBlock* block)
+      : effect_phi(effect_phi), block(block) {}
+};
+
+void UpdateEffectPhi(Node* node, BasicBlock* block,
+                     ZoneVector<BlockEffectControlData>* block_effects) {
+  // Update all inputs to an effect phi with the effects from the given
+  // block->effect map.
+  DCHECK_EQ(IrOpcode::kEffectPhi, node->opcode());
+  DCHECK_EQ(node->op()->EffectInputCount(), block->PredecessorCount());
+  for (int i = 0; i < node->op()->EffectInputCount(); i++) {
+    Node* input = node->InputAt(i);
+    BasicBlock* predecessor = block->PredecessorAt(static_cast<size_t>(i));
+    Node* input_effect =
+        (*block_effects)[predecessor->rpo_number()].current_effect;
+    if (input != input_effect) {
+      node->ReplaceInput(i, input_effect);
+    }
+  }
+}
+
+void UpdateBlockControl(BasicBlock* block,
+                        ZoneVector<BlockEffectControlData>* block_effects) {
+  Node* control = block->NodeAt(0);
+  DCHECK(NodeProperties::IsControl(control));
+
+  // Do not rewire the end node.
+  if (control->opcode() == IrOpcode::kEnd) return;
+
+  // Update all inputs to the given control node with the correct control.
+  DCHECK_EQ(control->op()->ControlInputCount(), block->PredecessorCount());
+  for (int i = 0; i < control->op()->ControlInputCount(); i++) {
+    Node* input = NodeProperties::GetControlInput(control, i);
+    BasicBlock* predecessor = block->PredecessorAt(static_cast<size_t>(i));
+    Node* input_control =
+        (*block_effects)[predecessor->rpo_number()].current_control;
+    if (input != input_control) {
+      NodeProperties::ReplaceControlInput(control, input_control, i);
+    }
+  }
+}
+
+bool HasIncomingBackEdges(BasicBlock* block) {
+  for (BasicBlock* pred : block->predecessors()) {
+    if (pred->rpo_number() >= block->rpo_number()) {
+      return true;
+    }
+  }
+  return false;
+}
+
+void RemoveRegionNode(Node* node) {
+  DCHECK(IrOpcode::kFinishRegion == node->opcode() ||
+         IrOpcode::kBeginRegion == node->opcode());
+  // Update the value/context uses to the value input of the finish node and
+  // the effect uses to the effect input.
+  for (Edge edge : node->use_edges()) {
+    DCHECK(!edge.from()->IsDead());
+    if (NodeProperties::IsEffectEdge(edge)) {
+      edge.UpdateTo(NodeProperties::GetEffectInput(node));
+    } else {
+      DCHECK(!NodeProperties::IsControlEdge(edge));
+      DCHECK(!NodeProperties::IsFrameStateEdge(edge));
+      edge.UpdateTo(node->InputAt(0));
+    }
+  }
+  node->Kill();
+}
+
+}  // namespace
+
+void EffectControlLinearizer::Run() {
+  ZoneVector<BlockEffectControlData> block_effects(temp_zone());
+  ZoneVector<PendingEffectPhi> pending_effect_phis(temp_zone());
+  ZoneVector<BasicBlock*> pending_block_controls(temp_zone());
+  block_effects.resize(schedule()->RpoBlockCount());
+  NodeVector inputs_buffer(temp_zone());
+
+  for (BasicBlock* block : *(schedule()->rpo_order())) {
+    size_t instr = 0;
+
+    // The control node should be the first.
+    Node* control = block->NodeAt(instr);
+    DCHECK(NodeProperties::IsControl(control));
+    // Update the control inputs.
+    if (HasIncomingBackEdges(block)) {
+      // If there are back edges, we need to update later because we have not
+      // computed the control yet. This should only happen for loops.
+      DCHECK_EQ(IrOpcode::kLoop, control->opcode());
+      pending_block_controls.push_back(block);
+    } else {
+      // If there are no back edges, we can update now.
+      UpdateBlockControl(block, &block_effects);
+    }
+    instr++;
+
+    // Iterate over the phis and update the effect phis.
+    Node* effect = nullptr;
+    Node* terminate = nullptr;
+    for (; instr < block->NodeCount(); instr++) {
+      Node* node = block->NodeAt(instr);
+      // Only go through the phis and effect phis.
+      if (node->opcode() == IrOpcode::kEffectPhi) {
+        // There should be at most one effect phi in a block.
+        DCHECK_NULL(effect);
+        // IfException blocks should not have effect phis.
+        DCHECK_NE(IrOpcode::kIfException, control->opcode());
+        effect = node;
+
+        // Make sure we update the inputs to the incoming blocks' effects.
+        if (HasIncomingBackEdges(block)) {
+          // In case of loops, we do not update the effect phi immediately
+          // because the back predecessor has not been handled yet. We just
+          // record the effect phi for later processing.
+          pending_effect_phis.push_back(PendingEffectPhi(node, block));
+        } else {
+          UpdateEffectPhi(node, block, &block_effects);
+        }
+      } else if (node->opcode() == IrOpcode::kPhi) {
+        // Just skip phis.
+      } else if (node->opcode() == IrOpcode::kTerminate) {
+        DCHECK(terminate == nullptr);
+        terminate = node;
+      } else {
+        break;
+      }
+    }
+
+    if (effect == nullptr) {
+      // There was no effect phi.
+      DCHECK(!HasIncomingBackEdges(block));
+      if (block == schedule()->start()) {
+        // Start block => effect is start.
+        DCHECK_EQ(graph()->start(), control);
+        effect = graph()->start();
+      } else if (control->opcode() == IrOpcode::kEnd) {
+        // End block is just a dummy, no effect needed.
+        DCHECK_EQ(BasicBlock::kNone, block->control());
+        DCHECK_EQ(1u, block->size());
+        effect = nullptr;
+      } else {
+        // If all the predecessors have the same effect, we can use it
+        // as our current effect.
+        int rpo_number = block->PredecessorAt(0)->rpo_number();
+        effect = block_effects[rpo_number].current_effect;
+        for (size_t i = 1; i < block->PredecessorCount(); i++) {
+          int rpo_number = block->PredecessorAt(i)->rpo_number();
+          if (block_effects[rpo_number].current_effect != effect) {
+            effect = nullptr;
+            break;
+          }
+        }
+        if (effect == nullptr) {
+          DCHECK_NE(IrOpcode::kIfException, control->opcode());
+          // The input blocks do not have the same effect. We have
+          // to create an effect phi node.
+          inputs_buffer.clear();
+          inputs_buffer.resize(block->PredecessorCount(), graph()->start());
+          inputs_buffer.push_back(control);
+          effect = graph()->NewNode(
+              common()->EffectPhi(static_cast<int>(block->PredecessorCount())),
+              static_cast<int>(inputs_buffer.size()), &(inputs_buffer.front()));
+          // Let us update the effect phi node later.
+          pending_effect_phis.push_back(PendingEffectPhi(effect, block));
+        } else if (control->opcode() == IrOpcode::kIfException) {
+          // The IfException is connected into the effect chain, so we need
+          // to update the effect here.
+          NodeProperties::ReplaceEffectInput(control, effect);
+          effect = control;
+        }
+      }
+    }
+
+    // Fixup the Terminate node.
+    if (terminate != nullptr) {
+      NodeProperties::ReplaceEffectInput(terminate, effect);
+    }
+
+    // Process the ordinary instructions.
+    for (; instr < block->NodeCount(); instr++) {
+      Node* node = block->NodeAt(instr);
+      ProcessNode(node, &effect, &control);
+    }
+
+    switch (block->control()) {
+      case BasicBlock::kGoto:
+      case BasicBlock::kNone:
+        break;
+
+      case BasicBlock::kCall:
+      case BasicBlock::kTailCall:
+      case BasicBlock::kBranch:
+      case BasicBlock::kSwitch:
+      case BasicBlock::kReturn:
+      case BasicBlock::kDeoptimize:
+      case BasicBlock::kThrow:
+        ProcessNode(block->control_input(), &effect, &control);
+        break;
+    }
+
+    // Store the effect for later use.
+    block_effects[block->rpo_number()].current_effect = effect;
+    block_effects[block->rpo_number()].current_control = control;
+  }
+
+  // Update the incoming edges of the effect phis that could not be processed
+  // during the first pass (because they could have incoming back edges).
+  for (const PendingEffectPhi& pending_effect_phi : pending_effect_phis) {
+    UpdateEffectPhi(pending_effect_phi.effect_phi, pending_effect_phi.block,
+                    &block_effects);
+  }
+  for (BasicBlock* pending_block_control : pending_block_controls) {
+    UpdateBlockControl(pending_block_control, &block_effects);
+  }
+}
+
+namespace {
+
+void TryScheduleCallIfSuccess(Node* node, Node** control) {
+  // Schedule the call's IfSuccess node if there is no exception use.
+  if (!NodeProperties::IsExceptionalCall(node)) {
+    for (Edge edge : node->use_edges()) {
+      if (NodeProperties::IsControlEdge(edge) &&
+          edge.from()->opcode() == IrOpcode::kIfSuccess) {
+        *control = edge.from();
+      }
+    }
+  }
+}
+
+}  // namespace
+
+void EffectControlLinearizer::ProcessNode(Node* node, Node** effect,
+                                          Node** control) {
+  // If the node needs to be wired into the effect/control chain, do this
+  // here.
+  if (TryWireInStateEffect(node, effect, control)) {
+    return;
+  }
+
+  // Remove the end markers of 'atomic' allocation region because the
+  // region should be wired-in now.
+  if (node->opcode() == IrOpcode::kFinishRegion ||
+      node->opcode() == IrOpcode::kBeginRegion) {
+    // Update the value uses to the value input of the finish node and
+    // the effect uses to the effect input.
+    return RemoveRegionNode(node);
+  }
+
+  // Special treatment for CheckPoint nodes.
+  // TODO(epertoso): Pickup the current frame state.
+  if (node->opcode() == IrOpcode::kCheckPoint) {
+    // Unlink the check point; effect uses will be updated to the incoming
+    // effect that is passed.
+    node->Kill();
+    return;
+  }
+
+  if (node->opcode() == IrOpcode::kIfSuccess) {
+    // We always schedule IfSuccess with its call, so skip it here.
+    DCHECK_EQ(IrOpcode::kCall, node->InputAt(0)->opcode());
+    // The IfSuccess node should not belong to an exceptional call node
+    // because such IfSuccess nodes should only start a basic block (and
+    // basic block start nodes are not handled in the ProcessNode method).
+    DCHECK(!NodeProperties::IsExceptionalCall(node->InputAt(0)));
+    return;
+  }
+
+  // If the node takes an effect, replace with the current one.
+  if (node->op()->EffectInputCount() > 0) {
+    DCHECK_EQ(1, node->op()->EffectInputCount());
+    Node* input_effect = NodeProperties::GetEffectInput(node);
+
+    if (input_effect != *effect) {
+      NodeProperties::ReplaceEffectInput(node, *effect);
+    }
+
+    // If the node produces an effect, update our current effect. (However,
+    // ignore new effect chains started with ValueEffect.)
+    if (node->op()->EffectOutputCount() > 0) {
+      DCHECK_EQ(1, node->op()->EffectOutputCount());
+      *effect = node;
+    }
+  } else {
+    // New effect chain is only started with a Start or ValueEffect node.
+    DCHECK(node->op()->EffectOutputCount() == 0 ||
+           node->opcode() == IrOpcode::kStart);
+  }
+
+  // Rewire control inputs.
+  for (int i = 0; i < node->op()->ControlInputCount(); i++) {
+    NodeProperties::ReplaceControlInput(node, *control, i);
+  }
+  // Update the current control and wire IfSuccess right after calls.
+  if (node->op()->ControlOutputCount() > 0) {
+    *control = node;
+    if (node->opcode() == IrOpcode::kCall) {
+      // Schedule the call's IfSuccess node (if there is no exception use).
+      TryScheduleCallIfSuccess(node, control);
+    }
+  }
+}
+
+bool EffectControlLinearizer::TryWireInStateEffect(Node* node, Node** effect,
+                                                   Node** control) {
+  ValueEffectControl state(nullptr, nullptr, nullptr);
+  switch (node->opcode()) {
+    case IrOpcode::kTypeGuard:
+      state = LowerTypeGuard(node, *effect, *control);
+      break;
+    case IrOpcode::kChangeBitToTagged:
+      state = LowerChangeBitToTagged(node, *effect, *control);
+      break;
+    case IrOpcode::kChangeInt31ToTaggedSigned:
+      state = LowerChangeInt31ToTaggedSigned(node, *effect, *control);
+      break;
+    case IrOpcode::kChangeInt32ToTagged:
+      state = LowerChangeInt32ToTagged(node, *effect, *control);
+      break;
+    case IrOpcode::kChangeUint32ToTagged:
+      state = LowerChangeUint32ToTagged(node, *effect, *control);
+      break;
+    case IrOpcode::kChangeFloat64ToTagged:
+      state = LowerChangeFloat64ToTagged(node, *effect, *control);
+      break;
+    case IrOpcode::kChangeTaggedSignedToInt32:
+      state = LowerChangeTaggedSignedToInt32(node, *effect, *control);
+      break;
+    case IrOpcode::kChangeTaggedToBit:
+      state = LowerChangeTaggedToBit(node, *effect, *control);
+      break;
+    case IrOpcode::kChangeTaggedToInt32:
+      state = LowerChangeTaggedToInt32(node, *effect, *control);
+      break;
+    case IrOpcode::kChangeTaggedToUint32:
+      state = LowerChangeTaggedToUint32(node, *effect, *control);
+      break;
+    case IrOpcode::kChangeTaggedToFloat64:
+      state = LowerChangeTaggedToFloat64(node, *effect, *control);
+      break;
+    case IrOpcode::kTruncateTaggedToWord32:
+      state = LowerTruncateTaggedToWord32(node, *effect, *control);
+      break;
+    case IrOpcode::kObjectIsCallable:
+      state = LowerObjectIsCallable(node, *effect, *control);
+      break;
+    case IrOpcode::kObjectIsNumber:
+      state = LowerObjectIsNumber(node, *effect, *control);
+      break;
+    case IrOpcode::kObjectIsReceiver:
+      state = LowerObjectIsReceiver(node, *effect, *control);
+      break;
+    case IrOpcode::kObjectIsSmi:
+      state = LowerObjectIsSmi(node, *effect, *control);
+      break;
+    case IrOpcode::kObjectIsString:
+      state = LowerObjectIsString(node, *effect, *control);
+      break;
+    case IrOpcode::kObjectIsUndetectable:
+      state = LowerObjectIsUndetectable(node, *effect, *control);
+      break;
+    default:
+      return false;
+  }
+  NodeProperties::ReplaceUses(node, state.value);
+  *effect = state.effect;
+  *control = state.control;
+  return true;
+}
+
+EffectControlLinearizer::ValueEffectControl
+EffectControlLinearizer::LowerTypeGuard(Node* node, Node* effect,
+                                        Node* control) {
+  Node* value = node->InputAt(0);
+  return ValueEffectControl(value, effect, control);
+}
+
+EffectControlLinearizer::ValueEffectControl
+EffectControlLinearizer::LowerChangeFloat64ToTagged(Node* node, Node* effect,
+                                                    Node* control) {
+  Node* value = node->InputAt(0);
+
+  Node* value32 = graph()->NewNode(machine()->RoundFloat64ToInt32(), value);
+  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);
+
+  // Check if {value} is -0.
+  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()) {
+    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}.
+  ValueEffectControl box = AllocateHeapNumberWithValue(value, effect, if_box);
+
+  control = graph()->NewNode(common()->Merge(2), if_smi, box.control);
+  value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
+                           vsmi, box.value, control);
+  effect =
+      graph()->NewNode(common()->EffectPhi(2), effect, box.effect, control);
+  return ValueEffectControl(value, effect, control);
+}
+
+EffectControlLinearizer::ValueEffectControl
+EffectControlLinearizer::LowerChangeBitToTagged(Node* node, Node* effect,
+                                                Node* control) {
+  Node* value = node->InputAt(0);
+
+  Node* branch = graph()->NewNode(common()->Branch(), value, control);
+
+  Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
+  Node* vtrue = jsgraph()->TrueConstant();
+
+  Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+  Node* vfalse = jsgraph()->FalseConstant();
+
+  control = graph()->NewNode(common()->Merge(2), if_true, if_false);
+  value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
+                           vtrue, vfalse, control);
+
+  return ValueEffectControl(value, effect, control);
+}
+
+EffectControlLinearizer::ValueEffectControl
+EffectControlLinearizer::LowerChangeInt31ToTaggedSigned(Node* node,
+                                                        Node* effect,
+                                                        Node* control) {
+  Node* value = node->InputAt(0);
+  value = ChangeInt32ToSmi(value);
+  return ValueEffectControl(value, effect, control);
+}
+
+EffectControlLinearizer::ValueEffectControl
+EffectControlLinearizer::LowerChangeInt32ToTagged(Node* node, Node* effect,
+                                                  Node* control) {
+  Node* value = node->InputAt(0);
+
+  if (machine()->Is64()) {
+    return ValueEffectControl(ChangeInt32ToSmi(value), effect, control);
+  }
+
+  Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(), value, value);
+
+  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);
+  ValueEffectControl alloc =
+      AllocateHeapNumberWithValue(ChangeInt32ToFloat64(value), effect, 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), alloc.control, if_false);
+  Node* phi = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
+                               alloc.value, vfalse, merge);
+  Node* ephi =
+      graph()->NewNode(common()->EffectPhi(2), alloc.effect, effect, merge);
+
+  return ValueEffectControl(phi, ephi, merge);
+}
+
+EffectControlLinearizer::ValueEffectControl
+EffectControlLinearizer::LowerChangeUint32ToTagged(Node* node, Node* effect,
+                                                   Node* control) {
+  Node* value = node->InputAt(0);
+
+  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);
+  ValueEffectControl alloc = AllocateHeapNumberWithValue(
+      ChangeUint32ToFloat64(value), effect, if_false);
+
+  Node* merge = graph()->NewNode(common()->Merge(2), if_true, alloc.control);
+  Node* phi = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
+                               vtrue, alloc.value, merge);
+  Node* ephi =
+      graph()->NewNode(common()->EffectPhi(2), effect, alloc.effect, merge);
+
+  return ValueEffectControl(phi, ephi, merge);
+}
+
+EffectControlLinearizer::ValueEffectControl
+EffectControlLinearizer::LowerChangeTaggedSignedToInt32(Node* node,
+                                                        Node* effect,
+                                                        Node* control) {
+  Node* value = node->InputAt(0);
+  value = ChangeSmiToInt32(value);
+  return ValueEffectControl(value, effect, control);
+}
+
+EffectControlLinearizer::ValueEffectControl
+EffectControlLinearizer::LowerChangeTaggedToBit(Node* node, Node* effect,
+                                                Node* control) {
+  Node* value = node->InputAt(0);
+  value = graph()->NewNode(machine()->WordEqual(), value,
+                           jsgraph()->TrueConstant());
+  return ValueEffectControl(value, effect, control);
+}
+
+EffectControlLinearizer::ValueEffectControl
+EffectControlLinearizer::LowerChangeTaggedToInt32(Node* node, Node* effect,
+                                                  Node* control) {
+  Node* value = node->InputAt(0);
+
+  Node* check = ObjectIsSmi(value);
+  Node* branch =
+      graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
+
+  Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
+  Node* etrue = effect;
+  Node* vtrue = ChangeSmiToInt32(value);
+
+  Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+  Node* efalse = effect;
+  Node* vfalse;
+  {
+    STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset);
+    vfalse = efalse = graph()->NewNode(
+        simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value,
+        efalse, if_false);
+    vfalse = graph()->NewNode(machine()->ChangeFloat64ToInt32(), vfalse);
+  }
+
+  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::kWord32, 2),
+                           vtrue, vfalse, control);
+
+  return ValueEffectControl(value, effect, control);
+}
+
+EffectControlLinearizer::ValueEffectControl
+EffectControlLinearizer::LowerChangeTaggedToUint32(Node* node, Node* effect,
+                                                   Node* control) {
+  Node* value = node->InputAt(0);
+
+  Node* check = ObjectIsSmi(value);
+  Node* branch =
+      graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
+
+  Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
+  Node* etrue = effect;
+  Node* vtrue = ChangeSmiToInt32(value);
+
+  Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+  Node* efalse = effect;
+  Node* vfalse;
+  {
+    STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset);
+    vfalse = efalse = graph()->NewNode(
+        simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value,
+        efalse, if_false);
+    vfalse = graph()->NewNode(machine()->ChangeFloat64ToUint32(), vfalse);
+  }
+
+  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::kWord32, 2),
+                           vtrue, vfalse, control);
+
+  return ValueEffectControl(value, effect, control);
+}
+
+EffectControlLinearizer::ValueEffectControl
+EffectControlLinearizer::LowerChangeTaggedToFloat64(Node* node, Node* effect,
+                                                    Node* control) {
+  Node* value = node->InputAt(0);
+
+  Node* check = ObjectIsSmi(value);
+  Node* branch =
+      graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
+
+  Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
+  Node* etrue = effect;
+  Node* vtrue;
+  {
+    vtrue = ChangeSmiToInt32(value);
+    vtrue = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue);
+  }
+
+  Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+  Node* efalse = effect;
+  Node* vfalse;
+  {
+    STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset);
+    vfalse = efalse = graph()->NewNode(
+        simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value,
+        efalse, if_false);
+  }
+
+  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::kFloat64, 2),
+                           vtrue, vfalse, control);
+
+  return ValueEffectControl(value, effect, control);
+}
+
+EffectControlLinearizer::ValueEffectControl
+EffectControlLinearizer::LowerTruncateTaggedToWord32(Node* node, Node* effect,
+                                                     Node* control) {
+  Node* value = node->InputAt(0);
+
+  Node* check = ObjectIsSmi(value);
+  Node* branch =
+      graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
+
+  Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
+  Node* etrue = effect;
+  Node* vtrue = ChangeSmiToInt32(value);
+
+  Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+  Node* efalse = effect;
+  Node* vfalse;
+  {
+    STATIC_ASSERT(HeapNumber::kValueOffset == Oddball::kToNumberRawOffset);
+    vfalse = efalse = graph()->NewNode(
+        simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), value,
+        efalse, if_false);
+    vfalse = graph()->NewNode(machine()->TruncateFloat64ToWord32(), vfalse);
+  }
+
+  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::kWord32, 2),
+                           vtrue, vfalse, control);
+
+  return ValueEffectControl(value, effect, control);
+}
+
+EffectControlLinearizer::ValueEffectControl
+EffectControlLinearizer::LowerObjectIsCallable(Node* node, Node* effect,
+                                               Node* control) {
+  Node* value = node->InputAt(0);
+
+  Node* check = ObjectIsSmi(value);
+  Node* branch =
+      graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control);
+
+  Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
+  Node* etrue = effect;
+  Node* vtrue = jsgraph()->Int32Constant(0);
+
+  Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+  Node* efalse = effect;
+  Node* vfalse;
+  {
+    Node* value_map = efalse =
+        graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
+                         value, efalse, if_false);
+    Node* value_bit_field = efalse = graph()->NewNode(
+        simplified()->LoadField(AccessBuilder::ForMapBitField()), value_map,
+        efalse, if_false);
+    vfalse = graph()->NewNode(
+        machine()->Word32Equal(),
+        jsgraph()->Int32Constant(1 << Map::kIsCallable),
+        graph()->NewNode(
+            machine()->Word32And(), value_bit_field,
+            jsgraph()->Int32Constant((1 << Map::kIsCallable) |
+                                     (1 << Map::kIsUndetectable))));
+  }
+
+  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::kBit, 2), vtrue,
+                           vfalse, control);
+
+  return ValueEffectControl(value, effect, control);
+}
+
+EffectControlLinearizer::ValueEffectControl
+EffectControlLinearizer::LowerObjectIsNumber(Node* node, Node* effect,
+                                             Node* control) {
+  Node* value = node->InputAt(0);
+
+  Node* check = ObjectIsSmi(value);
+  Node* branch = graph()->NewNode(common()->Branch(), check, control);
+
+  Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
+  Node* etrue = effect;
+  Node* vtrue = jsgraph()->Int32Constant(1);
+
+  Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+  Node* efalse = effect;
+  Node* vfalse;
+  {
+    Node* value_map = efalse =
+        graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
+                         value, efalse, if_false);
+    vfalse = graph()->NewNode(machine()->WordEqual(), value_map,
+                              jsgraph()->HeapNumberMapConstant());
+  }
+
+  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::kBit, 2), vtrue,
+                           vfalse, control);
+
+  return ValueEffectControl(value, effect, control);
+}
+
+EffectControlLinearizer::ValueEffectControl
+EffectControlLinearizer::LowerObjectIsReceiver(Node* node, Node* effect,
+                                               Node* control) {
+  Node* value = node->InputAt(0);
+
+  Node* check = ObjectIsSmi(value);
+  Node* branch =
+      graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control);
+
+  Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
+  Node* etrue = effect;
+  Node* vtrue = jsgraph()->Int32Constant(0);
+
+  Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+  Node* efalse = effect;
+  Node* vfalse;
+  {
+    STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE);
+    Node* value_map = efalse =
+        graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
+                         value, efalse, if_false);
+    Node* value_instance_type = efalse = graph()->NewNode(
+        simplified()->LoadField(AccessBuilder::ForMapInstanceType()), value_map,
+        efalse, if_false);
+    vfalse = graph()->NewNode(machine()->Uint32LessThanOrEqual(),
+                              jsgraph()->Uint32Constant(FIRST_JS_RECEIVER_TYPE),
+                              value_instance_type);
+  }
+
+  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::kBit, 2), vtrue,
+                           vfalse, control);
+
+  return ValueEffectControl(value, effect, control);
+}
+
+EffectControlLinearizer::ValueEffectControl
+EffectControlLinearizer::LowerObjectIsSmi(Node* node, Node* effect,
+                                          Node* control) {
+  Node* value = node->InputAt(0);
+  value = ObjectIsSmi(value);
+  return ValueEffectControl(value, effect, control);
+}
+
+EffectControlLinearizer::ValueEffectControl
+EffectControlLinearizer::LowerObjectIsString(Node* node, Node* effect,
+                                             Node* control) {
+  Node* value = node->InputAt(0);
+
+  Node* check = ObjectIsSmi(value);
+  Node* branch =
+      graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control);
+
+  Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
+  Node* etrue = effect;
+  Node* vtrue = jsgraph()->Int32Constant(0);
+
+  Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+  Node* efalse = effect;
+  Node* vfalse;
+  {
+    Node* value_map = efalse =
+        graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
+                         value, efalse, if_false);
+    Node* value_instance_type = efalse = graph()->NewNode(
+        simplified()->LoadField(AccessBuilder::ForMapInstanceType()), value_map,
+        efalse, if_false);
+    vfalse = graph()->NewNode(machine()->Uint32LessThan(), value_instance_type,
+                              jsgraph()->Uint32Constant(FIRST_NONSTRING_TYPE));
+  }
+
+  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::kBit, 2), vtrue,
+                           vfalse, control);
+
+  return ValueEffectControl(value, effect, control);
+}
+
+EffectControlLinearizer::ValueEffectControl
+EffectControlLinearizer::LowerObjectIsUndetectable(Node* node, Node* effect,
+                                                   Node* control) {
+  Node* value = node->InputAt(0);
+
+  Node* check = ObjectIsSmi(value);
+  Node* branch =
+      graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control);
+
+  Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
+  Node* etrue = effect;
+  Node* vtrue = jsgraph()->Int32Constant(0);
+
+  Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+  Node* efalse = effect;
+  Node* vfalse;
+  {
+    Node* value_map = efalse =
+        graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
+                         value, efalse, if_false);
+    Node* value_bit_field = efalse = graph()->NewNode(
+        simplified()->LoadField(AccessBuilder::ForMapBitField()), value_map,
+        efalse, if_false);
+    vfalse = graph()->NewNode(
+        machine()->Word32Equal(),
+        graph()->NewNode(
+            machine()->Word32Equal(), jsgraph()->Int32Constant(0),
+            graph()->NewNode(
+                machine()->Word32And(), value_bit_field,
+                jsgraph()->Int32Constant(1 << Map::kIsUndetectable))),
+        jsgraph()->Int32Constant(0));
+  }
+
+  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::kBit, 2), vtrue,
+                           vfalse, control);
+
+  return ValueEffectControl(value, effect, control);
+}
+
+EffectControlLinearizer::ValueEffectControl
+EffectControlLinearizer::AllocateHeapNumberWithValue(Node* value, Node* effect,
+                                                     Node* control) {
+  Node* result = effect = graph()->NewNode(
+      simplified()->Allocate(NOT_TENURED),
+      jsgraph()->Int32Constant(HeapNumber::kSize), effect, control);
+  effect = graph()->NewNode(simplified()->StoreField(AccessBuilder::ForMap()),
+                            result, jsgraph()->HeapNumberMapConstant(), effect,
+                            control);
+  effect = graph()->NewNode(
+      simplified()->StoreField(AccessBuilder::ForHeapNumberValue()), result,
+      value, effect, control);
+  return ValueEffectControl(result, effect, control);
+}
+
+Node* EffectControlLinearizer::ChangeInt32ToSmi(Node* value) {
+  if (machine()->Is64()) {
+    value = graph()->NewNode(machine()->ChangeInt32ToInt64(), value);
+  }
+  return graph()->NewNode(machine()->WordShl(), value, SmiShiftBitsConstant());
+}
+
+Node* EffectControlLinearizer::ChangeUint32ToSmi(Node* value) {
+  if (machine()->Is64()) {
+    value = graph()->NewNode(machine()->ChangeUint32ToUint64(), value);
+  }
+  return graph()->NewNode(machine()->WordShl(), value, SmiShiftBitsConstant());
+}
+
+Node* EffectControlLinearizer::ChangeInt32ToFloat64(Node* value) {
+  return graph()->NewNode(machine()->ChangeInt32ToFloat64(), value);
+}
+
+Node* EffectControlLinearizer::ChangeUint32ToFloat64(Node* value) {
+  return graph()->NewNode(machine()->ChangeUint32ToFloat64(), value);
+}
+
+Node* EffectControlLinearizer::ChangeSmiToInt32(Node* value) {
+  value = graph()->NewNode(machine()->WordSar(), value, SmiShiftBitsConstant());
+  if (machine()->Is64()) {
+    value = graph()->NewNode(machine()->TruncateInt64ToInt32(), value);
+  }
+  return value;
+}
+
+Node* EffectControlLinearizer::ObjectIsSmi(Node* value) {
+  return graph()->NewNode(
+      machine()->WordEqual(),
+      graph()->NewNode(machine()->WordAnd(), value,
+                       jsgraph()->IntPtrConstant(kSmiTagMask)),
+      jsgraph()->IntPtrConstant(kSmiTag));
+}
+
+Node* EffectControlLinearizer::SmiMaxValueConstant() {
+  return jsgraph()->Int32Constant(Smi::kMaxValue);
+}
+
+Node* EffectControlLinearizer::SmiShiftBitsConstant() {
+  return jsgraph()->IntPtrConstant(kSmiShiftSize + kSmiTagSize);
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
