Home | History | Annotate | Download | only in compiler
      1 // Copyright 2014 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "src/code-factory.h"
      6 #include "src/compilation-dependencies.h"
      7 #include "src/compiler/access-builder.h"
      8 #include "src/compiler/js-graph.h"
      9 #include "src/compiler/js-typed-lowering.h"
     10 #include "src/compiler/linkage.h"
     11 #include "src/compiler/node-matchers.h"
     12 #include "src/compiler/node-properties.h"
     13 #include "src/compiler/operator-properties.h"
     14 #include "src/type-cache.h"
     15 #include "src/types.h"
     16 
     17 namespace v8 {
     18 namespace internal {
     19 namespace compiler {
     20 
     21 // A helper class to simplify the process of reducing a single binop node with a
     22 // JSOperator. This class manages the rewriting of context, control, and effect
     23 // dependencies during lowering of a binop and contains numerous helper
     24 // functions for matching the types of inputs to an operation.
     25 class JSBinopReduction final {
     26  public:
     27   JSBinopReduction(JSTypedLowering* lowering, Node* node)
     28       : lowering_(lowering), node_(node) {}
     29 
     30   BinaryOperationHints::Hint GetNumberBinaryOperationFeedback() {
     31     if (!(lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) ||
     32         !(lowering_->flags() & JSTypedLowering::kTypeFeedbackEnabled)) {
     33       return BinaryOperationHints::kAny;
     34     }
     35     DCHECK_NE(0, node_->op()->ControlOutputCount());
     36     DCHECK_EQ(1, node_->op()->EffectOutputCount());
     37     DCHECK_EQ(2, OperatorProperties::GetFrameStateInputCount(node_->op()));
     38     BinaryOperationHints hints = BinaryOperationHintsOf(node_->op());
     39     BinaryOperationHints::Hint combined = hints.combined();
     40     if (combined == BinaryOperationHints::kSignedSmall ||
     41         combined == BinaryOperationHints::kSigned32 ||
     42         combined == BinaryOperationHints::kNumberOrUndefined) {
     43       return combined;
     44     }
     45     return BinaryOperationHints::kAny;
     46   }
     47 
     48   CompareOperationHints::Hint GetNumberCompareOperationFeedback() {
     49     if (!(lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) ||
     50         !(lowering_->flags() & JSTypedLowering::kTypeFeedbackEnabled)) {
     51       return CompareOperationHints::kAny;
     52     }
     53     DCHECK_NE(0, node_->op()->ControlOutputCount());
     54     DCHECK_EQ(1, node_->op()->EffectOutputCount());
     55     DCHECK_EQ(2, OperatorProperties::GetFrameStateInputCount(node_->op()));
     56     CompareOperationHints hints = CompareOperationHintsOf(node_->op());
     57     CompareOperationHints::Hint combined = hints.combined();
     58     if (combined == CompareOperationHints::kSignedSmall ||
     59         combined == CompareOperationHints::kNumber) {
     60       return combined;
     61     }
     62     return CompareOperationHints::kAny;
     63   }
     64 
     65   void ConvertInputsToNumber(Node* frame_state) {
     66     // To convert the inputs to numbers, we have to provide frame states
     67     // for lazy bailouts in the ToNumber conversions.
     68     // We use a little hack here: we take the frame state before the binary
     69     // operation and use it to construct the frame states for the conversion
     70     // so that after the deoptimization, the binary operation IC gets
     71     // already converted values from full code. This way we are sure that we
     72     // will not re-do any of the side effects.
     73 
     74     Node* left_input = nullptr;
     75     Node* right_input = nullptr;
     76     bool left_is_primitive = left_type()->Is(Type::PlainPrimitive());
     77     bool right_is_primitive = right_type()->Is(Type::PlainPrimitive());
     78     bool handles_exception = NodeProperties::IsExceptionalCall(node_);
     79 
     80     if (!left_is_primitive && !right_is_primitive && handles_exception) {
     81       ConvertBothInputsToNumber(&left_input, &right_input, frame_state);
     82     } else {
     83       left_input = left_is_primitive
     84                        ? ConvertPlainPrimitiveToNumber(left())
     85                        : ConvertSingleInputToNumber(
     86                              left(), CreateFrameStateForLeftInput(frame_state));
     87       right_input = right_is_primitive
     88                         ? ConvertPlainPrimitiveToNumber(right())
     89                         : ConvertSingleInputToNumber(
     90                               right(), CreateFrameStateForRightInput(
     91                                            frame_state, left_input));
     92     }
     93 
     94     node_->ReplaceInput(0, left_input);
     95     node_->ReplaceInput(1, right_input);
     96   }
     97 
     98   void ConvertInputsToUI32(Signedness left_signedness,
     99                            Signedness right_signedness) {
    100     node_->ReplaceInput(0, ConvertToUI32(left(), left_signedness));
    101     node_->ReplaceInput(1, ConvertToUI32(right(), right_signedness));
    102   }
    103 
    104   void SwapInputs() {
    105     Node* l = left();
    106     Node* r = right();
    107     node_->ReplaceInput(0, r);
    108     node_->ReplaceInput(1, l);
    109   }
    110 
    111   // Remove all effect and control inputs and outputs to this node and change
    112   // to the pure operator {op}, possibly inserting a boolean inversion.
    113   Reduction ChangeToPureOperator(const Operator* op, bool invert = false,
    114                                  Type* type = Type::Any()) {
    115     DCHECK_EQ(0, op->EffectInputCount());
    116     DCHECK_EQ(false, OperatorProperties::HasContextInput(op));
    117     DCHECK_EQ(0, op->ControlInputCount());
    118     DCHECK_EQ(2, op->ValueInputCount());
    119 
    120     // Remove the effects from the node, and update its effect/control usages.
    121     if (node_->op()->EffectInputCount() > 0) {
    122       lowering_->RelaxEffectsAndControls(node_);
    123     }
    124     // Remove the inputs corresponding to context, effect, and control.
    125     NodeProperties::RemoveNonValueInputs(node_);
    126     // Finally, update the operator to the new one.
    127     NodeProperties::ChangeOp(node_, op);
    128 
    129     // TODO(jarin): Replace the explicit typing hack with a call to some method
    130     // that encapsulates changing the operator and re-typing.
    131     Type* node_type = NodeProperties::GetType(node_);
    132     NodeProperties::SetType(node_, Type::Intersect(node_type, type, zone()));
    133 
    134     if (invert) {
    135       // Insert an boolean not to invert the value.
    136       Node* value = graph()->NewNode(simplified()->BooleanNot(), node_);
    137       node_->ReplaceUses(value);
    138       // Note: ReplaceUses() smashes all uses, so smash it back here.
    139       value->ReplaceInput(0, node_);
    140       return lowering_->Replace(value);
    141     }
    142     return lowering_->Changed(node_);
    143   }
    144 
    145   Reduction ChangeToSpeculativeOperator(const Operator* op, Type* upper_bound) {
    146     DCHECK_EQ(1, op->EffectInputCount());
    147     DCHECK_EQ(1, op->EffectOutputCount());
    148     DCHECK_EQ(false, OperatorProperties::HasContextInput(op));
    149     DCHECK_EQ(1, op->ControlInputCount());
    150     DCHECK_EQ(0, op->ControlOutputCount());
    151     DCHECK_EQ(0, OperatorProperties::GetFrameStateInputCount(op));
    152     DCHECK_EQ(2, op->ValueInputCount());
    153 
    154     DCHECK_EQ(1, node_->op()->EffectInputCount());
    155     DCHECK_EQ(1, node_->op()->EffectOutputCount());
    156     DCHECK_EQ(1, node_->op()->ControlInputCount());
    157     DCHECK_LT(1, node_->op()->ControlOutputCount());
    158     DCHECK_EQ(2, OperatorProperties::GetFrameStateInputCount(node_->op()));
    159     DCHECK_EQ(2, node_->op()->ValueInputCount());
    160 
    161     // Reconnect the control output to bypass the IfSuccess node and
    162     // possibly disconnect from the IfException node.
    163     for (Edge edge : node_->use_edges()) {
    164       Node* const user = edge.from();
    165       DCHECK(!user->IsDead());
    166       if (NodeProperties::IsControlEdge(edge)) {
    167         if (user->opcode() == IrOpcode::kIfSuccess) {
    168           user->ReplaceUses(NodeProperties::GetControlInput(node_));
    169           user->Kill();
    170         } else {
    171           DCHECK_EQ(user->opcode(), IrOpcode::kIfException);
    172           edge.UpdateTo(jsgraph()->Dead());
    173         }
    174       }
    175     }
    176 
    177     // Remove both bailout frame states and the context.
    178     node_->RemoveInput(NodeProperties::FirstFrameStateIndex(node_) + 1);
    179     node_->RemoveInput(NodeProperties::FirstFrameStateIndex(node_));
    180     node_->RemoveInput(NodeProperties::FirstContextIndex(node_));
    181 
    182     NodeProperties::ChangeOp(node_, op);
    183 
    184     // Update the type to number.
    185     Type* node_type = NodeProperties::GetType(node_);
    186     NodeProperties::SetType(node_,
    187                             Type::Intersect(node_type, upper_bound, zone()));
    188 
    189     return lowering_->Changed(node_);
    190   }
    191 
    192   Reduction ChangeToPureOperator(const Operator* op, Type* type) {
    193     return ChangeToPureOperator(op, false, type);
    194   }
    195 
    196   bool LeftInputIs(Type* t) { return left_type()->Is(t); }
    197 
    198   bool RightInputIs(Type* t) { return right_type()->Is(t); }
    199 
    200   bool OneInputIs(Type* t) { return LeftInputIs(t) || RightInputIs(t); }
    201 
    202   bool BothInputsAre(Type* t) { return LeftInputIs(t) && RightInputIs(t); }
    203 
    204   bool OneInputCannotBe(Type* t) {
    205     return !left_type()->Maybe(t) || !right_type()->Maybe(t);
    206   }
    207 
    208   bool NeitherInputCanBe(Type* t) {
    209     return !left_type()->Maybe(t) && !right_type()->Maybe(t);
    210   }
    211 
    212   Node* effect() { return NodeProperties::GetEffectInput(node_); }
    213   Node* control() { return NodeProperties::GetControlInput(node_); }
    214   Node* context() { return NodeProperties::GetContextInput(node_); }
    215   Node* left() { return NodeProperties::GetValueInput(node_, 0); }
    216   Node* right() { return NodeProperties::GetValueInput(node_, 1); }
    217   Type* left_type() { return NodeProperties::GetType(node_->InputAt(0)); }
    218   Type* right_type() { return NodeProperties::GetType(node_->InputAt(1)); }
    219 
    220   SimplifiedOperatorBuilder* simplified() { return lowering_->simplified(); }
    221   Graph* graph() const { return lowering_->graph(); }
    222   JSGraph* jsgraph() { return lowering_->jsgraph(); }
    223   JSOperatorBuilder* javascript() { return lowering_->javascript(); }
    224   MachineOperatorBuilder* machine() { return lowering_->machine(); }
    225   CommonOperatorBuilder* common() { return jsgraph()->common(); }
    226   Zone* zone() const { return graph()->zone(); }
    227 
    228  private:
    229   JSTypedLowering* lowering_;  // The containing lowering instance.
    230   Node* node_;                 // The original node.
    231 
    232   Node* CreateFrameStateForLeftInput(Node* frame_state) {
    233     FrameStateInfo state_info = OpParameter<FrameStateInfo>(frame_state);
    234 
    235     if (state_info.bailout_id() == BailoutId::None()) {
    236       // Dummy frame state => just leave it as is.
    237       return frame_state;
    238     }
    239 
    240     // If the frame state is already the right one, just return it.
    241     if (state_info.state_combine().kind() == OutputFrameStateCombine::kPokeAt &&
    242         state_info.state_combine().GetOffsetToPokeAt() == 1) {
    243       return frame_state;
    244     }
    245 
    246     // Here, we smash the result of the conversion into the slot just below
    247     // the stack top. This is the slot that full code uses to store the
    248     // left operand.
    249     const Operator* op = jsgraph()->common()->FrameState(
    250         state_info.bailout_id(), OutputFrameStateCombine::PokeAt(1),
    251         state_info.function_info());
    252 
    253     return graph()->NewNode(op,
    254                             frame_state->InputAt(kFrameStateParametersInput),
    255                             frame_state->InputAt(kFrameStateLocalsInput),
    256                             frame_state->InputAt(kFrameStateStackInput),
    257                             frame_state->InputAt(kFrameStateContextInput),
    258                             frame_state->InputAt(kFrameStateFunctionInput),
    259                             frame_state->InputAt(kFrameStateOuterStateInput));
    260   }
    261 
    262   Node* CreateFrameStateForRightInput(Node* frame_state, Node* converted_left) {
    263     FrameStateInfo state_info = OpParameter<FrameStateInfo>(frame_state);
    264 
    265     if (state_info.bailout_id() == BailoutId::None()) {
    266       // Dummy frame state => just leave it as is.
    267       return frame_state;
    268     }
    269 
    270     // Create a frame state that stores the result of the operation to the
    271     // top of the stack (i.e., the slot used for the right operand).
    272     const Operator* op = jsgraph()->common()->FrameState(
    273         state_info.bailout_id(), OutputFrameStateCombine::PokeAt(0),
    274         state_info.function_info());
    275 
    276     // Change the left operand {converted_left} on the expression stack.
    277     Node* stack = frame_state->InputAt(2);
    278     DCHECK_EQ(stack->opcode(), IrOpcode::kStateValues);
    279     DCHECK_GE(stack->InputCount(), 2);
    280 
    281     // TODO(jarin) Allocate in a local zone or a reusable buffer.
    282     NodeVector new_values(stack->InputCount(), zone());
    283     for (int i = 0; i < stack->InputCount(); i++) {
    284       if (i == stack->InputCount() - 2) {
    285         new_values[i] = converted_left;
    286       } else {
    287         new_values[i] = stack->InputAt(i);
    288       }
    289     }
    290     Node* new_stack =
    291         graph()->NewNode(stack->op(), stack->InputCount(), &new_values.front());
    292 
    293     return graph()->NewNode(
    294         op, frame_state->InputAt(kFrameStateParametersInput),
    295         frame_state->InputAt(kFrameStateLocalsInput), new_stack,
    296         frame_state->InputAt(kFrameStateContextInput),
    297         frame_state->InputAt(kFrameStateFunctionInput),
    298         frame_state->InputAt(kFrameStateOuterStateInput));
    299   }
    300 
    301   Node* ConvertPlainPrimitiveToNumber(Node* node) {
    302     DCHECK(NodeProperties::GetType(node)->Is(Type::PlainPrimitive()));
    303     // Avoid inserting too many eager ToNumber() operations.
    304     Reduction const reduction = lowering_->ReduceJSToNumberInput(node);
    305     if (reduction.Changed()) return reduction.replacement();
    306     if (NodeProperties::GetType(node)->Is(Type::Number())) {
    307       return node;
    308     }
    309     return graph()->NewNode(simplified()->PlainPrimitiveToNumber(), node);
    310   }
    311 
    312   Node* ConvertSingleInputToNumber(Node* node, Node* frame_state) {
    313     DCHECK(!NodeProperties::GetType(node)->Is(Type::PlainPrimitive()));
    314     Node* const n = graph()->NewNode(javascript()->ToNumber(), node, context(),
    315                                      frame_state, effect(), control());
    316     Node* const if_success = graph()->NewNode(common()->IfSuccess(), n);
    317     NodeProperties::ReplaceControlInput(node_, if_success);
    318     NodeProperties::ReplaceUses(node_, node_, node_, node_, n);
    319     update_effect(n);
    320     return n;
    321   }
    322 
    323   void ConvertBothInputsToNumber(Node** left_result, Node** right_result,
    324                                  Node* frame_state) {
    325     Node* projections[2];
    326 
    327     // Find {IfSuccess} and {IfException} continuations of the operation.
    328     NodeProperties::CollectControlProjections(node_, projections, 2);
    329     IfExceptionHint hint = OpParameter<IfExceptionHint>(projections[1]);
    330     Node* if_exception = projections[1];
    331     Node* if_success = projections[0];
    332 
    333     // Insert two ToNumber() operations that both potentially throw.
    334     Node* left_state = CreateFrameStateForLeftInput(frame_state);
    335     Node* left_conv =
    336         graph()->NewNode(javascript()->ToNumber(), left(), context(),
    337                          left_state, effect(), control());
    338     Node* left_success = graph()->NewNode(common()->IfSuccess(), left_conv);
    339     Node* right_state = CreateFrameStateForRightInput(frame_state, left_conv);
    340     Node* right_conv =
    341         graph()->NewNode(javascript()->ToNumber(), right(), context(),
    342                          right_state, left_conv, left_success);
    343     Node* left_exception =
    344         graph()->NewNode(common()->IfException(hint), left_conv, left_conv);
    345     Node* right_exception =
    346         graph()->NewNode(common()->IfException(hint), right_conv, right_conv);
    347     NodeProperties::ReplaceControlInput(if_success, right_conv);
    348     update_effect(right_conv);
    349 
    350     // Wire conversions to existing {IfException} continuation.
    351     Node* exception_merge = if_exception;
    352     Node* exception_value =
    353         graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
    354                          left_exception, right_exception, exception_merge);
    355     Node* exception_effect =
    356         graph()->NewNode(common()->EffectPhi(2), left_exception,
    357                          right_exception, exception_merge);
    358     for (Edge edge : exception_merge->use_edges()) {
    359       if (NodeProperties::IsEffectEdge(edge)) edge.UpdateTo(exception_effect);
    360       if (NodeProperties::IsValueEdge(edge)) edge.UpdateTo(exception_value);
    361     }
    362     NodeProperties::RemoveType(exception_merge);
    363     exception_merge->ReplaceInput(0, left_exception);
    364     exception_merge->ReplaceInput(1, right_exception);
    365     NodeProperties::ChangeOp(exception_merge, common()->Merge(2));
    366 
    367     *left_result = left_conv;
    368     *right_result = right_conv;
    369   }
    370 
    371   Node* ConvertToUI32(Node* node, Signedness signedness) {
    372     // Avoid introducing too many eager NumberToXXnt32() operations.
    373     Type* type = NodeProperties::GetType(node);
    374     if (signedness == kSigned) {
    375       if (!type->Is(Type::Signed32())) {
    376         node = graph()->NewNode(simplified()->NumberToInt32(), node);
    377       }
    378     } else {
    379       DCHECK_EQ(kUnsigned, signedness);
    380       if (!type->Is(Type::Unsigned32())) {
    381         node = graph()->NewNode(simplified()->NumberToUint32(), node);
    382       }
    383     }
    384     return node;
    385   }
    386 
    387   void update_effect(Node* effect) {
    388     NodeProperties::ReplaceEffectInput(node_, effect);
    389   }
    390 };
    391 
    392 
    393 // TODO(turbofan): js-typed-lowering improvements possible
    394 // - immediately put in type bounds for all new nodes
    395 // - relax effects from generic but not-side-effecting operations
    396 
    397 
    398 JSTypedLowering::JSTypedLowering(Editor* editor,
    399                                  CompilationDependencies* dependencies,
    400                                  Flags flags, JSGraph* jsgraph, Zone* zone)
    401     : AdvancedReducer(editor),
    402       dependencies_(dependencies),
    403       flags_(flags),
    404       jsgraph_(jsgraph),
    405       true_type_(Type::Constant(factory()->true_value(), graph()->zone())),
    406       false_type_(Type::Constant(factory()->false_value(), graph()->zone())),
    407       the_hole_type_(
    408           Type::Constant(factory()->the_hole_value(), graph()->zone())),
    409       type_cache_(TypeCache::Get()) {
    410   for (size_t k = 0; k < arraysize(shifted_int32_ranges_); ++k) {
    411     double min = kMinInt / (1 << k);
    412     double max = kMaxInt / (1 << k);
    413     shifted_int32_ranges_[k] = Type::Range(min, max, graph()->zone());
    414   }
    415 }
    416 
    417 
    418 Reduction JSTypedLowering::ReduceJSAdd(Node* node) {
    419   if (flags() & kDisableBinaryOpReduction) return NoChange();
    420 
    421   JSBinopReduction r(this, node);
    422 
    423   BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback();
    424   if (feedback == BinaryOperationHints::kNumberOrUndefined &&
    425       r.BothInputsAre(Type::PlainPrimitive()) &&
    426       r.NeitherInputCanBe(Type::StringOrReceiver())) {
    427     // JSAdd(x:-string, y:-string) => NumberAdd(ToNumber(x), ToNumber(y))
    428     Node* frame_state = NodeProperties::GetFrameStateInput(node, 1);
    429     r.ConvertInputsToNumber(frame_state);
    430     return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number());
    431   }
    432   if (feedback != BinaryOperationHints::kAny) {
    433     // Lower to the optimistic number binop.
    434     return r.ChangeToSpeculativeOperator(
    435         simplified()->SpeculativeNumberAdd(feedback), Type::Number());
    436   }
    437   if (r.BothInputsAre(Type::Number())) {
    438     // JSAdd(x:number, y:number) => NumberAdd(x, y)
    439     Node* frame_state = NodeProperties::GetFrameStateInput(node, 1);
    440     r.ConvertInputsToNumber(frame_state);
    441     return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number());
    442   }
    443   if (r.NeitherInputCanBe(Type::StringOrReceiver())) {
    444     // JSAdd(x:-string, y:-string) => NumberAdd(ToNumber(x), ToNumber(y))
    445     Node* frame_state = NodeProperties::GetFrameStateInput(node, 1);
    446     r.ConvertInputsToNumber(frame_state);
    447     return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number());
    448   }
    449   if (r.OneInputIs(Type::String())) {
    450     StringAddFlags flags = STRING_ADD_CHECK_NONE;
    451     if (!r.LeftInputIs(Type::String())) {
    452       flags = STRING_ADD_CONVERT_LEFT;
    453     } else if (!r.RightInputIs(Type::String())) {
    454       flags = STRING_ADD_CONVERT_RIGHT;
    455     }
    456     // JSAdd(x:string, y) => CallStub[StringAdd](x, y)
    457     // JSAdd(x, y:string) => CallStub[StringAdd](x, y)
    458     Callable const callable =
    459         CodeFactory::StringAdd(isolate(), flags, NOT_TENURED);
    460     CallDescriptor const* const desc = Linkage::GetStubCallDescriptor(
    461         isolate(), graph()->zone(), callable.descriptor(), 0,
    462         CallDescriptor::kNeedsFrameState, node->op()->properties());
    463     DCHECK_EQ(2, OperatorProperties::GetFrameStateInputCount(node->op()));
    464     node->RemoveInput(NodeProperties::FirstFrameStateIndex(node) + 1);
    465     node->InsertInput(graph()->zone(), 0,
    466                       jsgraph()->HeapConstant(callable.code()));
    467     NodeProperties::ChangeOp(node, common()->Call(desc));
    468     return Changed(node);
    469   }
    470   return NoChange();
    471 }
    472 
    473 
    474 Reduction JSTypedLowering::ReduceJSModulus(Node* node) {
    475   if (flags() & kDisableBinaryOpReduction) return NoChange();
    476   JSBinopReduction r(this, node);
    477   if (r.BothInputsAre(Type::Number())) {
    478     // JSModulus(x:number, x:number) => NumberModulus(x, y)
    479     return r.ChangeToPureOperator(simplified()->NumberModulus(),
    480                                   Type::Number());
    481   }
    482   BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback();
    483   if (feedback != BinaryOperationHints::kAny) {
    484     return r.ChangeToSpeculativeOperator(
    485         simplified()->SpeculativeNumberModulus(feedback), Type::Number());
    486   }
    487   return NoChange();
    488 }
    489 
    490 Reduction JSTypedLowering::ReduceJSSubtract(Node* node) {
    491   if (flags() & kDisableBinaryOpReduction) return NoChange();
    492   JSBinopReduction r(this, node);
    493   BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback();
    494   if (feedback == BinaryOperationHints::kNumberOrUndefined &&
    495       r.BothInputsAre(Type::PlainPrimitive())) {
    496     // JSSubtract(x:plain-primitive, y:plain-primitive)
    497     //   => NumberSubtract(ToNumber(x), ToNumber(y))
    498     Node* frame_state = NodeProperties::GetFrameStateInput(node, 1);
    499     r.ConvertInputsToNumber(frame_state);
    500     return r.ChangeToPureOperator(simplified()->NumberSubtract(),
    501                                   Type::Number());
    502   }
    503   if (feedback != BinaryOperationHints::kAny) {
    504     // Lower to the optimistic number binop.
    505     return r.ChangeToSpeculativeOperator(
    506         simplified()->SpeculativeNumberSubtract(feedback), Type::Number());
    507   }
    508   Node* frame_state = NodeProperties::GetFrameStateInput(node, 1);
    509   r.ConvertInputsToNumber(frame_state);
    510   return r.ChangeToPureOperator(simplified()->NumberSubtract(), Type::Number());
    511 }
    512 
    513 Reduction JSTypedLowering::ReduceJSMultiply(Node* node) {
    514   if (flags() & kDisableBinaryOpReduction) return NoChange();
    515   JSBinopReduction r(this, node);
    516 
    517   BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback();
    518   if (feedback != BinaryOperationHints::kAny) {
    519     return r.ChangeToSpeculativeOperator(
    520         simplified()->SpeculativeNumberMultiply(feedback), Type::Number());
    521   }
    522 
    523   Node* frame_state = NodeProperties::GetFrameStateInput(node, 1);
    524   r.ConvertInputsToNumber(frame_state);
    525   return r.ChangeToPureOperator(simplified()->NumberMultiply(), Type::Number());
    526 }
    527 
    528 Reduction JSTypedLowering::ReduceJSDivide(Node* node) {
    529   if (flags() & kDisableBinaryOpReduction) return NoChange();
    530   JSBinopReduction r(this, node);
    531   BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback();
    532   if (feedback != BinaryOperationHints::kAny) {
    533     return r.ChangeToSpeculativeOperator(
    534         simplified()->SpeculativeNumberDivide(feedback), Type::Number());
    535   }
    536   Node* frame_state = NodeProperties::GetFrameStateInput(node, 1);
    537   r.ConvertInputsToNumber(frame_state);
    538   return r.ChangeToPureOperator(simplified()->NumberDivide(), Type::Number());
    539 }
    540 
    541 
    542 Reduction JSTypedLowering::ReduceInt32Binop(Node* node, const Operator* intOp) {
    543   if (flags() & kDisableBinaryOpReduction) return NoChange();
    544 
    545   JSBinopReduction r(this, node);
    546   Node* frame_state = NodeProperties::GetFrameStateInput(node, 1);
    547   r.ConvertInputsToNumber(frame_state);
    548   r.ConvertInputsToUI32(kSigned, kSigned);
    549   return r.ChangeToPureOperator(intOp, Type::Integral32());
    550 }
    551 
    552 
    553 Reduction JSTypedLowering::ReduceUI32Shift(Node* node,
    554                                            Signedness left_signedness,
    555                                            const Operator* shift_op) {
    556   if (flags() & kDisableBinaryOpReduction) return NoChange();
    557 
    558   JSBinopReduction r(this, node);
    559   Node* frame_state = NodeProperties::GetFrameStateInput(node, 1);
    560   r.ConvertInputsToNumber(frame_state);
    561   r.ConvertInputsToUI32(left_signedness, kUnsigned);
    562   return r.ChangeToPureOperator(shift_op);
    563 }
    564 
    565 
    566 Reduction JSTypedLowering::ReduceJSComparison(Node* node) {
    567   if (flags() & kDisableBinaryOpReduction) return NoChange();
    568 
    569   JSBinopReduction r(this, node);
    570   if (r.BothInputsAre(Type::String())) {
    571     // If both inputs are definitely strings, perform a string comparison.
    572     const Operator* stringOp;
    573     switch (node->opcode()) {
    574       case IrOpcode::kJSLessThan:
    575         stringOp = simplified()->StringLessThan();
    576         break;
    577       case IrOpcode::kJSGreaterThan:
    578         stringOp = simplified()->StringLessThan();
    579         r.SwapInputs();  // a > b => b < a
    580         break;
    581       case IrOpcode::kJSLessThanOrEqual:
    582         stringOp = simplified()->StringLessThanOrEqual();
    583         break;
    584       case IrOpcode::kJSGreaterThanOrEqual:
    585         stringOp = simplified()->StringLessThanOrEqual();
    586         r.SwapInputs();  // a >= b => b <= a
    587         break;
    588       default:
    589         return NoChange();
    590     }
    591     r.ChangeToPureOperator(stringOp);
    592     return Changed(node);
    593   }
    594 
    595   CompareOperationHints::Hint hint = r.GetNumberCompareOperationFeedback();
    596   if (hint != CompareOperationHints::kAny ||
    597       r.OneInputCannotBe(Type::StringOrReceiver())) {
    598     const Operator* less_than;
    599     const Operator* less_than_or_equal;
    600     if (r.BothInputsAre(Type::Unsigned32())) {
    601       less_than = machine()->Uint32LessThan();
    602       less_than_or_equal = machine()->Uint32LessThanOrEqual();
    603     } else if (r.BothInputsAre(Type::Signed32())) {
    604       less_than = machine()->Int32LessThan();
    605       less_than_or_equal = machine()->Int32LessThanOrEqual();
    606     } else if (hint != CompareOperationHints::kAny) {
    607       less_than = simplified()->SpeculativeNumberLessThan(hint);
    608       less_than_or_equal = simplified()->SpeculativeNumberLessThanOrEqual(hint);
    609     } else {
    610       // TODO(turbofan): mixed signed/unsigned int32 comparisons.
    611       Node* frame_state = NodeProperties::GetFrameStateInput(node, 1);
    612       r.ConvertInputsToNumber(frame_state);
    613       less_than = simplified()->NumberLessThan();
    614       less_than_or_equal = simplified()->NumberLessThanOrEqual();
    615     }
    616     const Operator* comparison;
    617     switch (node->opcode()) {
    618       case IrOpcode::kJSLessThan:
    619         comparison = less_than;
    620         break;
    621       case IrOpcode::kJSGreaterThan:
    622         comparison = less_than;
    623         r.SwapInputs();  // a > b => b < a
    624         break;
    625       case IrOpcode::kJSLessThanOrEqual:
    626         comparison = less_than_or_equal;
    627         break;
    628       case IrOpcode::kJSGreaterThanOrEqual:
    629         comparison = less_than_or_equal;
    630         r.SwapInputs();  // a >= b => b <= a
    631         break;
    632       default:
    633         return NoChange();
    634     }
    635     if (comparison->EffectInputCount() > 0) {
    636       return r.ChangeToSpeculativeOperator(comparison, Type::Boolean());
    637     } else {
    638       return r.ChangeToPureOperator(comparison);
    639     }
    640   }
    641   // TODO(turbofan): relax/remove effects of this operator in other cases.
    642   return NoChange();  // Keep a generic comparison.
    643 }
    644 
    645 Reduction JSTypedLowering::ReduceJSEqualTypeOf(Node* node, bool invert) {
    646   HeapObjectBinopMatcher m(node);
    647   if (m.left().IsJSTypeOf() && m.right().HasValue() &&
    648       m.right().Value()->IsString()) {
    649     Node* replacement;
    650     Node* input = m.left().InputAt(0);
    651     Handle<String> value = Handle<String>::cast(m.right().Value());
    652     if (String::Equals(value, factory()->boolean_string())) {
    653       replacement = graph()->NewNode(
    654           common()->Select(MachineRepresentation::kTagged),
    655           graph()->NewNode(simplified()->ReferenceEqual(Type::Any()), input,
    656                            jsgraph()->TrueConstant()),
    657           jsgraph()->TrueConstant(),
    658           graph()->NewNode(simplified()->ReferenceEqual(Type::Any()), input,
    659                            jsgraph()->FalseConstant()));
    660     } else if (String::Equals(value, factory()->function_string())) {
    661       replacement = graph()->NewNode(simplified()->ObjectIsCallable(), input);
    662     } else if (String::Equals(value, factory()->number_string())) {
    663       replacement = graph()->NewNode(simplified()->ObjectIsNumber(), input);
    664     } else if (String::Equals(value, factory()->string_string())) {
    665       replacement = graph()->NewNode(simplified()->ObjectIsString(), input);
    666     } else if (String::Equals(value, factory()->undefined_string())) {
    667       replacement = graph()->NewNode(
    668           common()->Select(MachineRepresentation::kTagged),
    669           graph()->NewNode(simplified()->ReferenceEqual(Type::Any()), input,
    670                            jsgraph()->NullConstant()),
    671           jsgraph()->FalseConstant(),
    672           graph()->NewNode(simplified()->ObjectIsUndetectable(), input));
    673     } else {
    674       return NoChange();
    675     }
    676     if (invert) {
    677       replacement = graph()->NewNode(simplified()->BooleanNot(), replacement);
    678     }
    679     return Replace(replacement);
    680   }
    681   return NoChange();
    682 }
    683 
    684 Reduction JSTypedLowering::ReduceJSEqual(Node* node, bool invert) {
    685   if (flags() & kDisableBinaryOpReduction) return NoChange();
    686 
    687   Reduction const reduction = ReduceJSEqualTypeOf(node, invert);
    688   if (reduction.Changed()) {
    689     ReplaceWithValue(node, reduction.replacement());
    690     return reduction;
    691   }
    692 
    693   JSBinopReduction r(this, node);
    694 
    695   if (r.BothInputsAre(Type::Number())) {
    696     return r.ChangeToPureOperator(simplified()->NumberEqual(), invert);
    697   }
    698   if (r.BothInputsAre(Type::String())) {
    699     return r.ChangeToPureOperator(simplified()->StringEqual(), invert);
    700   }
    701   if (r.BothInputsAre(Type::Boolean())) {
    702     return r.ChangeToPureOperator(simplified()->ReferenceEqual(Type::Boolean()),
    703                                   invert);
    704   }
    705   if (r.BothInputsAre(Type::Receiver())) {
    706     return r.ChangeToPureOperator(
    707         simplified()->ReferenceEqual(Type::Receiver()), invert);
    708   }
    709   if (r.OneInputIs(Type::Undetectable())) {
    710     RelaxEffectsAndControls(node);
    711     node->RemoveInput(r.LeftInputIs(Type::Undetectable()) ? 0 : 1);
    712     node->TrimInputCount(1);
    713     NodeProperties::ChangeOp(node, simplified()->ObjectIsUndetectable());
    714     if (invert) {
    715       // Insert an boolean not to invert the value.
    716       Node* value = graph()->NewNode(simplified()->BooleanNot(), node);
    717       node->ReplaceUses(value);
    718       // Note: ReplaceUses() smashes all uses, so smash it back here.
    719       value->ReplaceInput(0, node);
    720       return Replace(value);
    721     }
    722     return Changed(node);
    723   }
    724   return NoChange();
    725 }
    726 
    727 
    728 Reduction JSTypedLowering::ReduceJSStrictEqual(Node* node, bool invert) {
    729   if (flags() & kDisableBinaryOpReduction) return NoChange();
    730 
    731   JSBinopReduction r(this, node);
    732   if (r.left() == r.right()) {
    733     // x === x is always true if x != NaN
    734     if (!r.left_type()->Maybe(Type::NaN())) {
    735       Node* replacement = jsgraph()->BooleanConstant(!invert);
    736       ReplaceWithValue(node, replacement);
    737       return Replace(replacement);
    738     }
    739   }
    740   if (r.OneInputCannotBe(Type::NumberOrSimdOrString())) {
    741     // For values with canonical representation (i.e. neither String, nor
    742     // Simd128Value nor Number) an empty type intersection means the values
    743     // cannot be strictly equal.
    744     if (!r.left_type()->Maybe(r.right_type())) {
    745       Node* replacement = jsgraph()->BooleanConstant(invert);
    746       ReplaceWithValue(node, replacement);
    747       return Replace(replacement);
    748     }
    749   }
    750   Reduction const reduction = ReduceJSEqualTypeOf(node, invert);
    751   if (reduction.Changed()) {
    752     return reduction;
    753   }
    754   if (r.OneInputIs(the_hole_type_)) {
    755     return r.ChangeToPureOperator(simplified()->ReferenceEqual(the_hole_type_),
    756                                   invert);
    757   }
    758   if (r.OneInputIs(Type::Undefined())) {
    759     return r.ChangeToPureOperator(
    760         simplified()->ReferenceEqual(Type::Undefined()), invert);
    761   }
    762   if (r.OneInputIs(Type::Null())) {
    763     return r.ChangeToPureOperator(simplified()->ReferenceEqual(Type::Null()),
    764                                   invert);
    765   }
    766   if (r.OneInputIs(Type::Boolean())) {
    767     return r.ChangeToPureOperator(simplified()->ReferenceEqual(Type::Boolean()),
    768                                   invert);
    769   }
    770   if (r.OneInputIs(Type::Object())) {
    771     return r.ChangeToPureOperator(simplified()->ReferenceEqual(Type::Object()),
    772                                   invert);
    773   }
    774   if (r.OneInputIs(Type::Receiver())) {
    775     return r.ChangeToPureOperator(
    776         simplified()->ReferenceEqual(Type::Receiver()), invert);
    777   }
    778   if (r.BothInputsAre(Type::Unique())) {
    779     return r.ChangeToPureOperator(simplified()->ReferenceEqual(Type::Unique()),
    780                                   invert);
    781   }
    782   if (r.BothInputsAre(Type::String())) {
    783     return r.ChangeToPureOperator(simplified()->StringEqual(), invert);
    784   }
    785   if (r.BothInputsAre(Type::Number())) {
    786     return r.ChangeToPureOperator(simplified()->NumberEqual(), invert);
    787   }
    788   // TODO(turbofan): js-typed-lowering of StrictEqual(mixed types)
    789   return NoChange();
    790 }
    791 
    792 
    793 Reduction JSTypedLowering::ReduceJSToBoolean(Node* node) {
    794   Node* const input = node->InputAt(0);
    795   Type* const input_type = NodeProperties::GetType(input);
    796   if (input_type->Is(Type::Boolean())) {
    797     // JSToBoolean(x:boolean) => x
    798     return Replace(input);
    799   } else if (input_type->Is(Type::OrderedNumber())) {
    800     // JSToBoolean(x:ordered-number) => BooleanNot(NumberEqual(x,#0))
    801     RelaxEffectsAndControls(node);
    802     node->ReplaceInput(0, graph()->NewNode(simplified()->NumberEqual(), input,
    803                                            jsgraph()->ZeroConstant()));
    804     node->TrimInputCount(1);
    805     NodeProperties::ChangeOp(node, simplified()->BooleanNot());
    806     return Changed(node);
    807   } else if (input_type->Is(Type::String())) {
    808     // JSToBoolean(x:string) => NumberLessThan(#0,x.length)
    809     FieldAccess const access = AccessBuilder::ForStringLength();
    810     Node* length = graph()->NewNode(simplified()->LoadField(access), input,
    811                                     graph()->start(), graph()->start());
    812     ReplaceWithValue(node, node, length);
    813     node->ReplaceInput(0, jsgraph()->ZeroConstant());
    814     node->ReplaceInput(1, length);
    815     NodeProperties::ChangeOp(node, simplified()->NumberLessThan());
    816     return Changed(node);
    817   }
    818   return NoChange();
    819 }
    820 
    821 Reduction JSTypedLowering::ReduceJSToInteger(Node* node) {
    822   Node* const input = NodeProperties::GetValueInput(node, 0);
    823   Type* const input_type = NodeProperties::GetType(input);
    824   if (input_type->Is(type_cache_.kIntegerOrMinusZero)) {
    825     // JSToInteger(x:integer) => x
    826     ReplaceWithValue(node, input);
    827     return Replace(input);
    828   }
    829   return NoChange();
    830 }
    831 
    832 Reduction JSTypedLowering::ReduceJSToLength(Node* node) {
    833   Node* input = NodeProperties::GetValueInput(node, 0);
    834   Type* input_type = NodeProperties::GetType(input);
    835   if (input_type->Is(type_cache_.kIntegerOrMinusZero)) {
    836     if (input_type->Max() <= 0.0) {
    837       input = jsgraph()->ZeroConstant();
    838     } else if (input_type->Min() >= kMaxSafeInteger) {
    839       input = jsgraph()->Constant(kMaxSafeInteger);
    840     } else {
    841       if (input_type->Min() <= 0.0) {
    842         input = graph()->NewNode(
    843             common()->Select(MachineRepresentation::kTagged),
    844             graph()->NewNode(simplified()->NumberLessThanOrEqual(), input,
    845                              jsgraph()->ZeroConstant()),
    846             jsgraph()->ZeroConstant(), input);
    847         input_type = Type::Range(0.0, input_type->Max(), graph()->zone());
    848         NodeProperties::SetType(input, input_type);
    849       }
    850       if (input_type->Max() > kMaxSafeInteger) {
    851         input = graph()->NewNode(
    852             common()->Select(MachineRepresentation::kTagged),
    853             graph()->NewNode(simplified()->NumberLessThanOrEqual(),
    854                              jsgraph()->Constant(kMaxSafeInteger), input),
    855             jsgraph()->Constant(kMaxSafeInteger), input);
    856         input_type =
    857             Type::Range(input_type->Min(), kMaxSafeInteger, graph()->zone());
    858         NodeProperties::SetType(input, input_type);
    859       }
    860     }
    861     ReplaceWithValue(node, input);
    862     return Replace(input);
    863   }
    864   return NoChange();
    865 }
    866 
    867 Reduction JSTypedLowering::ReduceJSToNumberInput(Node* input) {
    868   // Try constant-folding of JSToNumber with constant inputs.
    869   Type* input_type = NodeProperties::GetType(input);
    870   if (input_type->IsConstant()) {
    871     Handle<Object> input_value = input_type->AsConstant()->Value();
    872     if (input_value->IsString()) {
    873       return Replace(jsgraph()->Constant(
    874           String::ToNumber(Handle<String>::cast(input_value))));
    875     } else if (input_value->IsOddball()) {
    876       return Replace(jsgraph()->Constant(
    877           Oddball::ToNumber(Handle<Oddball>::cast(input_value))));
    878     }
    879   }
    880   if (input_type->Is(Type::Number())) {
    881     // JSToNumber(x:number) => x
    882     return Changed(input);
    883   }
    884   if (input_type->Is(Type::Undefined())) {
    885     // JSToNumber(undefined) => #NaN
    886     return Replace(jsgraph()->NaNConstant());
    887   }
    888   if (input_type->Is(Type::Null())) {
    889     // JSToNumber(null) => #0
    890     return Replace(jsgraph()->ZeroConstant());
    891   }
    892   if (input_type->Is(Type::Boolean())) {
    893     // JSToNumber(x:boolean) => BooleanToNumber(x)
    894     return Replace(graph()->NewNode(simplified()->BooleanToNumber(), input));
    895   }
    896   if (input_type->Is(Type::String())) {
    897     // JSToNumber(x:string) => StringToNumber(x)
    898     return Replace(graph()->NewNode(simplified()->StringToNumber(), input));
    899   }
    900   return NoChange();
    901 }
    902 
    903 
    904 Reduction JSTypedLowering::ReduceJSToNumber(Node* node) {
    905   // Try to reduce the input first.
    906   Node* const input = node->InputAt(0);
    907   Reduction reduction = ReduceJSToNumberInput(input);
    908   if (reduction.Changed()) {
    909     ReplaceWithValue(node, reduction.replacement());
    910     return reduction;
    911   }
    912   Type* const input_type = NodeProperties::GetType(input);
    913   if (input_type->Is(Type::PlainPrimitive())) {
    914     RelaxEffectsAndControls(node);
    915     node->TrimInputCount(1);
    916     NodeProperties::ChangeOp(node, simplified()->PlainPrimitiveToNumber());
    917     return Changed(node);
    918   }
    919   return NoChange();
    920 }
    921 
    922 
    923 Reduction JSTypedLowering::ReduceJSToStringInput(Node* input) {
    924   if (input->opcode() == IrOpcode::kJSToString) {
    925     // Recursively try to reduce the input first.
    926     Reduction result = ReduceJSToString(input);
    927     if (result.Changed()) return result;
    928     return Changed(input);  // JSToString(JSToString(x)) => JSToString(x)
    929   }
    930   Type* input_type = NodeProperties::GetType(input);
    931   if (input_type->Is(Type::String())) {
    932     return Changed(input);  // JSToString(x:string) => x
    933   }
    934   if (input_type->Is(Type::Boolean())) {
    935     return Replace(graph()->NewNode(
    936         common()->Select(MachineRepresentation::kTagged), input,
    937         jsgraph()->HeapConstant(factory()->true_string()),
    938         jsgraph()->HeapConstant(factory()->false_string())));
    939   }
    940   if (input_type->Is(Type::Undefined())) {
    941     return Replace(jsgraph()->HeapConstant(factory()->undefined_string()));
    942   }
    943   if (input_type->Is(Type::Null())) {
    944     return Replace(jsgraph()->HeapConstant(factory()->null_string()));
    945   }
    946   // TODO(turbofan): js-typed-lowering of ToString(x:number)
    947   return NoChange();
    948 }
    949 
    950 
    951 Reduction JSTypedLowering::ReduceJSToString(Node* node) {
    952   // Try to reduce the input first.
    953   Node* const input = node->InputAt(0);
    954   Reduction reduction = ReduceJSToStringInput(input);
    955   if (reduction.Changed()) {
    956     ReplaceWithValue(node, reduction.replacement());
    957     return reduction;
    958   }
    959   return NoChange();
    960 }
    961 
    962 
    963 Reduction JSTypedLowering::ReduceJSToObject(Node* node) {
    964   DCHECK_EQ(IrOpcode::kJSToObject, node->opcode());
    965   Node* receiver = NodeProperties::GetValueInput(node, 0);
    966   Type* receiver_type = NodeProperties::GetType(receiver);
    967   Node* context = NodeProperties::GetContextInput(node);
    968   Node* frame_state = NodeProperties::GetFrameStateInput(node, 0);
    969   Node* effect = NodeProperties::GetEffectInput(node);
    970   Node* control = NodeProperties::GetControlInput(node);
    971   if (!receiver_type->Is(Type::Receiver())) {
    972     // TODO(bmeurer/mstarzinger): Add support for lowering inside try blocks.
    973     if (receiver_type->Maybe(Type::NullOrUndefined()) &&
    974         NodeProperties::IsExceptionalCall(node)) {
    975       // ToObject throws for null or undefined inputs.
    976       return NoChange();
    977     }
    978 
    979     // Check whether {receiver} is a Smi.
    980     Node* check0 = graph()->NewNode(simplified()->ObjectIsSmi(), receiver);
    981     Node* branch0 =
    982         graph()->NewNode(common()->Branch(BranchHint::kFalse), check0, control);
    983     Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
    984     Node* etrue0 = effect;
    985 
    986     Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
    987     Node* efalse0 = effect;
    988 
    989     // Determine the instance type of {receiver}.
    990     Node* receiver_map = efalse0 =
    991         graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
    992                          receiver, efalse0, if_false0);
    993     Node* receiver_instance_type = efalse0 = graph()->NewNode(
    994         simplified()->LoadField(AccessBuilder::ForMapInstanceType()),
    995         receiver_map, efalse0, if_false0);
    996 
    997     // Check whether {receiver} is a spec object.
    998     STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
    999     Node* check1 =
   1000         graph()->NewNode(machine()->Uint32LessThanOrEqual(),
   1001                          jsgraph()->Uint32Constant(FIRST_JS_RECEIVER_TYPE),
   1002                          receiver_instance_type);
   1003     Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kTrue),
   1004                                      check1, if_false0);
   1005     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
   1006     Node* etrue1 = efalse0;
   1007 
   1008     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
   1009     Node* efalse1 = efalse0;
   1010 
   1011     // Convert {receiver} using the ToObjectStub.
   1012     Node* if_convert =
   1013         graph()->NewNode(common()->Merge(2), if_true0, if_false1);
   1014     Node* econvert =
   1015         graph()->NewNode(common()->EffectPhi(2), etrue0, efalse1, if_convert);
   1016     Node* rconvert;
   1017     {
   1018       Callable callable = CodeFactory::ToObject(isolate());
   1019       CallDescriptor const* const desc = Linkage::GetStubCallDescriptor(
   1020           isolate(), graph()->zone(), callable.descriptor(), 0,
   1021           CallDescriptor::kNeedsFrameState, node->op()->properties());
   1022       rconvert = econvert = graph()->NewNode(
   1023           common()->Call(desc), jsgraph()->HeapConstant(callable.code()),
   1024           receiver, context, frame_state, econvert, if_convert);
   1025     }
   1026 
   1027     // The {receiver} is already a spec object.
   1028     Node* if_done = if_true1;
   1029     Node* edone = etrue1;
   1030     Node* rdone = receiver;
   1031 
   1032     control = graph()->NewNode(common()->Merge(2), if_convert, if_done);
   1033     effect = graph()->NewNode(common()->EffectPhi(2), econvert, edone, control);
   1034     receiver =
   1035         graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
   1036                          rconvert, rdone, control);
   1037   }
   1038   ReplaceWithValue(node, receiver, effect, control);
   1039   return Changed(receiver);
   1040 }
   1041 
   1042 
   1043 Reduction JSTypedLowering::ReduceJSLoadNamed(Node* node) {
   1044   DCHECK_EQ(IrOpcode::kJSLoadNamed, node->opcode());
   1045   Node* receiver = NodeProperties::GetValueInput(node, 0);
   1046   Type* receiver_type = NodeProperties::GetType(receiver);
   1047   Node* effect = NodeProperties::GetEffectInput(node);
   1048   Node* control = NodeProperties::GetControlInput(node);
   1049   Handle<Name> name = NamedAccessOf(node->op()).name();
   1050   // Optimize "length" property of strings.
   1051   if (name.is_identical_to(factory()->length_string()) &&
   1052       receiver_type->Is(Type::String())) {
   1053     Node* value = effect = graph()->NewNode(
   1054         simplified()->LoadField(AccessBuilder::ForStringLength()), receiver,
   1055         effect, control);
   1056     ReplaceWithValue(node, value, effect);
   1057     return Replace(value);
   1058   }
   1059   return NoChange();
   1060 }
   1061 
   1062 
   1063 Reduction JSTypedLowering::ReduceJSLoadProperty(Node* node) {
   1064   Node* key = NodeProperties::GetValueInput(node, 1);
   1065   Node* base = NodeProperties::GetValueInput(node, 0);
   1066   Type* key_type = NodeProperties::GetType(key);
   1067   HeapObjectMatcher mbase(base);
   1068   if (mbase.HasValue() && mbase.Value()->IsJSTypedArray()) {
   1069     Handle<JSTypedArray> const array =
   1070         Handle<JSTypedArray>::cast(mbase.Value());
   1071     if (!array->GetBuffer()->was_neutered()) {
   1072       array->GetBuffer()->set_is_neuterable(false);
   1073       BufferAccess const access(array->type());
   1074       size_t const k =
   1075           ElementSizeLog2Of(access.machine_type().representation());
   1076       double const byte_length = array->byte_length()->Number();
   1077       CHECK_LT(k, arraysize(shifted_int32_ranges_));
   1078       if (key_type->Is(shifted_int32_ranges_[k]) && byte_length <= kMaxInt) {
   1079         // JSLoadProperty(typed-array, int32)
   1080         Handle<FixedTypedArrayBase> elements =
   1081             Handle<FixedTypedArrayBase>::cast(handle(array->elements()));
   1082         Node* buffer = jsgraph()->PointerConstant(elements->external_pointer());
   1083         Node* length = jsgraph()->Constant(byte_length);
   1084         Node* effect = NodeProperties::GetEffectInput(node);
   1085         Node* control = NodeProperties::GetControlInput(node);
   1086         // Check if we can avoid the bounds check.
   1087         if (key_type->Min() >= 0 && key_type->Max() < array->length_value()) {
   1088           Node* load = graph()->NewNode(
   1089               simplified()->LoadElement(
   1090                   AccessBuilder::ForTypedArrayElement(array->type(), true)),
   1091               buffer, key, effect, control);
   1092           ReplaceWithValue(node, load, load);
   1093           return Replace(load);
   1094         }
   1095         // Compute byte offset.
   1096         Node* offset = Word32Shl(key, static_cast<int>(k));
   1097         Node* load = graph()->NewNode(simplified()->LoadBuffer(access), buffer,
   1098                                       offset, length, effect, control);
   1099         ReplaceWithValue(node, load, load);
   1100         return Replace(load);
   1101       }
   1102     }
   1103   }
   1104   return NoChange();
   1105 }
   1106 
   1107 
   1108 Reduction JSTypedLowering::ReduceJSStoreProperty(Node* node) {
   1109   Node* key = NodeProperties::GetValueInput(node, 1);
   1110   Node* base = NodeProperties::GetValueInput(node, 0);
   1111   Node* value = NodeProperties::GetValueInput(node, 2);
   1112   Type* key_type = NodeProperties::GetType(key);
   1113   Type* value_type = NodeProperties::GetType(value);
   1114   HeapObjectMatcher mbase(base);
   1115   if (mbase.HasValue() && mbase.Value()->IsJSTypedArray()) {
   1116     Handle<JSTypedArray> const array =
   1117         Handle<JSTypedArray>::cast(mbase.Value());
   1118     if (!array->GetBuffer()->was_neutered()) {
   1119       array->GetBuffer()->set_is_neuterable(false);
   1120       BufferAccess const access(array->type());
   1121       size_t const k =
   1122           ElementSizeLog2Of(access.machine_type().representation());
   1123       double const byte_length = array->byte_length()->Number();
   1124       CHECK_LT(k, arraysize(shifted_int32_ranges_));
   1125       if (access.external_array_type() != kExternalUint8ClampedArray &&
   1126           key_type->Is(shifted_int32_ranges_[k]) && byte_length <= kMaxInt) {
   1127         // JSLoadProperty(typed-array, int32)
   1128         Handle<FixedTypedArrayBase> elements =
   1129             Handle<FixedTypedArrayBase>::cast(handle(array->elements()));
   1130         Node* buffer = jsgraph()->PointerConstant(elements->external_pointer());
   1131         Node* length = jsgraph()->Constant(byte_length);
   1132         Node* context = NodeProperties::GetContextInput(node);
   1133         Node* effect = NodeProperties::GetEffectInput(node);
   1134         Node* control = NodeProperties::GetControlInput(node);
   1135         // Convert to a number first.
   1136         if (!value_type->Is(Type::Number())) {
   1137           Reduction number_reduction = ReduceJSToNumberInput(value);
   1138           if (number_reduction.Changed()) {
   1139             value = number_reduction.replacement();
   1140           } else {
   1141             Node* frame_state_for_to_number =
   1142                 NodeProperties::FindFrameStateBefore(node);
   1143             value = effect =
   1144                 graph()->NewNode(javascript()->ToNumber(), value, context,
   1145                                  frame_state_for_to_number, effect, control);
   1146           }
   1147         }
   1148         // Check if we can avoid the bounds check.
   1149         if (key_type->Min() >= 0 && key_type->Max() < array->length_value()) {
   1150           RelaxControls(node);
   1151           node->ReplaceInput(0, buffer);
   1152           DCHECK_EQ(key, node->InputAt(1));
   1153           node->ReplaceInput(2, value);
   1154           node->ReplaceInput(3, effect);
   1155           node->ReplaceInput(4, control);
   1156           node->TrimInputCount(5);
   1157           NodeProperties::ChangeOp(
   1158               node,
   1159               simplified()->StoreElement(
   1160                   AccessBuilder::ForTypedArrayElement(array->type(), true)));
   1161           return Changed(node);
   1162         }
   1163         // Compute byte offset.
   1164         Node* offset = Word32Shl(key, static_cast<int>(k));
   1165         // Turn into a StoreBuffer operation.
   1166         RelaxControls(node);
   1167         node->ReplaceInput(0, buffer);
   1168         node->ReplaceInput(1, offset);
   1169         node->ReplaceInput(2, length);
   1170         node->ReplaceInput(3, value);
   1171         node->ReplaceInput(4, effect);
   1172         node->ReplaceInput(5, control);
   1173         node->TrimInputCount(6);
   1174         NodeProperties::ChangeOp(node, simplified()->StoreBuffer(access));
   1175         return Changed(node);
   1176       }
   1177     }
   1178   }
   1179   return NoChange();
   1180 }
   1181 
   1182 
   1183 Reduction JSTypedLowering::ReduceJSInstanceOf(Node* node) {
   1184   DCHECK_EQ(IrOpcode::kJSInstanceOf, node->opcode());
   1185   Node* const context = NodeProperties::GetContextInput(node);
   1186   Node* const frame_state = NodeProperties::GetFrameStateInput(node, 0);
   1187 
   1188   // If deoptimization is disabled, we cannot optimize.
   1189   if (!(flags() & kDeoptimizationEnabled)) return NoChange();
   1190 
   1191   // If we are in a try block, don't optimize since the runtime call
   1192   // in the proxy case can throw.
   1193   if (NodeProperties::IsExceptionalCall(node)) return NoChange();
   1194 
   1195   JSBinopReduction r(this, node);
   1196   Node* effect = r.effect();
   1197   Node* control = r.control();
   1198 
   1199   if (!r.right_type()->IsConstant() ||
   1200       !r.right_type()->AsConstant()->Value()->IsJSFunction()) {
   1201     return NoChange();
   1202   }
   1203 
   1204   Handle<JSFunction> function =
   1205       Handle<JSFunction>::cast(r.right_type()->AsConstant()->Value());
   1206   Handle<SharedFunctionInfo> shared(function->shared(), isolate());
   1207 
   1208   // Make sure the prototype of {function} is the %FunctionPrototype%, and it
   1209   // already has a meaningful initial map (i.e. we constructed at least one
   1210   // instance using the constructor {function}).
   1211   if (function->map()->prototype() != function->native_context()->closure() ||
   1212       function->map()->has_non_instance_prototype() ||
   1213       !function->has_initial_map()) {
   1214     return NoChange();
   1215   }
   1216 
   1217   // We can only use the fast case if @@hasInstance was not used so far.
   1218   if (!isolate()->IsHasInstanceLookupChainIntact()) return NoChange();
   1219   dependencies()->AssumePropertyCell(factory()->has_instance_protector());
   1220 
   1221   Handle<Map> initial_map(function->initial_map(), isolate());
   1222   dependencies()->AssumeInitialMapCantChange(initial_map);
   1223   Node* prototype =
   1224       jsgraph()->Constant(handle(initial_map->prototype(), isolate()));
   1225 
   1226   // If the left hand side is an object, no smi check is needed.
   1227   Node* is_smi = graph()->NewNode(simplified()->ObjectIsSmi(), r.left());
   1228   Node* branch_is_smi =
   1229       graph()->NewNode(common()->Branch(BranchHint::kFalse), is_smi, control);
   1230   Node* if_is_smi = graph()->NewNode(common()->IfTrue(), branch_is_smi);
   1231   Node* e_is_smi = effect;
   1232   control = graph()->NewNode(common()->IfFalse(), branch_is_smi);
   1233 
   1234   Node* object_map = effect =
   1235       graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
   1236                        r.left(), effect, control);
   1237 
   1238   // Loop through the {object}s prototype chain looking for the {prototype}.
   1239   Node* loop = control = graph()->NewNode(common()->Loop(2), control, control);
   1240 
   1241   Node* loop_effect = effect =
   1242       graph()->NewNode(common()->EffectPhi(2), effect, effect, loop);
   1243 
   1244   Node* loop_object_map =
   1245       graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
   1246                        object_map, r.left(), loop);
   1247 
   1248   // Check if the lhs needs access checks.
   1249   Node* map_bit_field = effect =
   1250       graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMapBitField()),
   1251                        loop_object_map, loop_effect, control);
   1252   int is_access_check_needed_bit = 1 << Map::kIsAccessCheckNeeded;
   1253   Node* is_access_check_needed_num =
   1254       graph()->NewNode(simplified()->NumberBitwiseAnd(), map_bit_field,
   1255                        jsgraph()->Uint32Constant(is_access_check_needed_bit));
   1256   Node* is_access_check_needed =
   1257       graph()->NewNode(machine()->Word32Equal(), is_access_check_needed_num,
   1258                        jsgraph()->Uint32Constant(is_access_check_needed_bit));
   1259 
   1260   Node* branch_is_access_check_needed = graph()->NewNode(
   1261       common()->Branch(BranchHint::kFalse), is_access_check_needed, control);
   1262   Node* if_is_access_check_needed =
   1263       graph()->NewNode(common()->IfTrue(), branch_is_access_check_needed);
   1264   Node* e_is_access_check_needed = effect;
   1265 
   1266   control =
   1267       graph()->NewNode(common()->IfFalse(), branch_is_access_check_needed);
   1268 
   1269   // Check if the lhs is a proxy.
   1270   Node* map_instance_type = effect = graph()->NewNode(
   1271       simplified()->LoadField(AccessBuilder::ForMapInstanceType()),
   1272       loop_object_map, loop_effect, control);
   1273   Node* is_proxy = graph()->NewNode(machine()->Word32Equal(), map_instance_type,
   1274                                     jsgraph()->Uint32Constant(JS_PROXY_TYPE));
   1275   Node* branch_is_proxy =
   1276       graph()->NewNode(common()->Branch(BranchHint::kFalse), is_proxy, control);
   1277   Node* if_is_proxy = graph()->NewNode(common()->IfTrue(), branch_is_proxy);
   1278   Node* e_is_proxy = effect;
   1279 
   1280 
   1281   Node* runtime_has_in_proto_chain = control = graph()->NewNode(
   1282       common()->Merge(2), if_is_access_check_needed, if_is_proxy);
   1283   effect = graph()->NewNode(common()->EffectPhi(2), e_is_access_check_needed,
   1284                             e_is_proxy, control);
   1285 
   1286   // If we need an access check or the object is a Proxy, make a runtime call
   1287   // to finish the lowering.
   1288   Node* bool_result_runtime_has_in_proto_chain_case = graph()->NewNode(
   1289       javascript()->CallRuntime(Runtime::kHasInPrototypeChain), r.left(),
   1290       prototype, context, frame_state, effect, control);
   1291 
   1292   control = graph()->NewNode(common()->IfFalse(), branch_is_proxy);
   1293 
   1294   Node* object_prototype = effect = graph()->NewNode(
   1295       simplified()->LoadField(AccessBuilder::ForMapPrototype()),
   1296       loop_object_map, loop_effect, control);
   1297 
   1298   // If not, check if object prototype is the null prototype.
   1299   Node* null_proto =
   1300       graph()->NewNode(simplified()->ReferenceEqual(r.right_type()),
   1301                        object_prototype, jsgraph()->NullConstant());
   1302   Node* branch_null_proto = graph()->NewNode(
   1303       common()->Branch(BranchHint::kFalse), null_proto, control);
   1304   Node* if_null_proto = graph()->NewNode(common()->IfTrue(), branch_null_proto);
   1305   Node* e_null_proto = effect;
   1306 
   1307   control = graph()->NewNode(common()->IfFalse(), branch_null_proto);
   1308 
   1309   // Check if object prototype is equal to function prototype.
   1310   Node* eq_proto =
   1311       graph()->NewNode(simplified()->ReferenceEqual(r.right_type()),
   1312                        object_prototype, prototype);
   1313   Node* branch_eq_proto =
   1314       graph()->NewNode(common()->Branch(BranchHint::kFalse), eq_proto, control);
   1315   Node* if_eq_proto = graph()->NewNode(common()->IfTrue(), branch_eq_proto);
   1316   Node* e_eq_proto = effect;
   1317 
   1318   control = graph()->NewNode(common()->IfFalse(), branch_eq_proto);
   1319 
   1320   Node* load_object_map = effect =
   1321       graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
   1322                        object_prototype, effect, control);
   1323   // Close the loop.
   1324   loop_effect->ReplaceInput(1, effect);
   1325   loop_object_map->ReplaceInput(1, load_object_map);
   1326   loop->ReplaceInput(1, control);
   1327 
   1328   control = graph()->NewNode(common()->Merge(3), runtime_has_in_proto_chain,
   1329                              if_eq_proto, if_null_proto);
   1330   effect = graph()->NewNode(common()->EffectPhi(3),
   1331                             bool_result_runtime_has_in_proto_chain_case,
   1332                             e_eq_proto, e_null_proto, control);
   1333 
   1334   Node* result = graph()->NewNode(
   1335       common()->Phi(MachineRepresentation::kTagged, 3),
   1336       bool_result_runtime_has_in_proto_chain_case, jsgraph()->TrueConstant(),
   1337       jsgraph()->FalseConstant(), control);
   1338 
   1339   DCHECK_NOT_NULL(e_is_smi);
   1340   control = graph()->NewNode(common()->Merge(2), if_is_smi, control);
   1341   effect =
   1342       graph()->NewNode(common()->EffectPhi(2), e_is_smi, effect, control);
   1343   result = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
   1344                             jsgraph()->FalseConstant(), result, control);
   1345 
   1346   ReplaceWithValue(node, result, effect, control);
   1347   return Changed(result);
   1348 }
   1349 
   1350 
   1351 Reduction JSTypedLowering::ReduceJSLoadContext(Node* node) {
   1352   DCHECK_EQ(IrOpcode::kJSLoadContext, node->opcode());
   1353   ContextAccess const& access = ContextAccessOf(node->op());
   1354   Node* effect = NodeProperties::GetEffectInput(node);
   1355   Node* control = graph()->start();
   1356   for (size_t i = 0; i < access.depth(); ++i) {
   1357     Node* previous = effect = graph()->NewNode(
   1358         simplified()->LoadField(
   1359             AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX)),
   1360         NodeProperties::GetValueInput(node, 0), effect, control);
   1361     node->ReplaceInput(0, previous);
   1362   }
   1363   node->ReplaceInput(1, effect);
   1364   node->ReplaceInput(2, control);
   1365   NodeProperties::ChangeOp(
   1366       node,
   1367       simplified()->LoadField(AccessBuilder::ForContextSlot(access.index())));
   1368   return Changed(node);
   1369 }
   1370 
   1371 
   1372 Reduction JSTypedLowering::ReduceJSStoreContext(Node* node) {
   1373   DCHECK_EQ(IrOpcode::kJSStoreContext, node->opcode());
   1374   ContextAccess const& access = ContextAccessOf(node->op());
   1375   Node* effect = NodeProperties::GetEffectInput(node);
   1376   Node* control = graph()->start();
   1377   for (size_t i = 0; i < access.depth(); ++i) {
   1378     Node* previous = effect = graph()->NewNode(
   1379         simplified()->LoadField(
   1380             AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX)),
   1381         NodeProperties::GetValueInput(node, 0), effect, control);
   1382     node->ReplaceInput(0, previous);
   1383   }
   1384   node->RemoveInput(2);
   1385   node->ReplaceInput(2, effect);
   1386   NodeProperties::ChangeOp(
   1387       node,
   1388       simplified()->StoreField(AccessBuilder::ForContextSlot(access.index())));
   1389   return Changed(node);
   1390 }
   1391 
   1392 
   1393 Reduction JSTypedLowering::ReduceJSConvertReceiver(Node* node) {
   1394   DCHECK_EQ(IrOpcode::kJSConvertReceiver, node->opcode());
   1395   ConvertReceiverMode mode = ConvertReceiverModeOf(node->op());
   1396   Node* receiver = NodeProperties::GetValueInput(node, 0);
   1397   Type* receiver_type = NodeProperties::GetType(receiver);
   1398   Node* context = NodeProperties::GetContextInput(node);
   1399   Type* context_type = NodeProperties::GetType(context);
   1400   Node* frame_state = NodeProperties::GetFrameStateInput(node, 0);
   1401   Node* effect = NodeProperties::GetEffectInput(node);
   1402   Node* control = NodeProperties::GetControlInput(node);
   1403   if (!receiver_type->Is(Type::Receiver())) {
   1404     if (receiver_type->Is(Type::NullOrUndefined()) ||
   1405         mode == ConvertReceiverMode::kNullOrUndefined) {
   1406       if (context_type->IsConstant()) {
   1407         Handle<JSObject> global_proxy(
   1408             Handle<Context>::cast(context_type->AsConstant()->Value())
   1409                 ->global_proxy(),
   1410             isolate());
   1411         receiver = jsgraph()->Constant(global_proxy);
   1412       } else {
   1413         Node* native_context = effect = graph()->NewNode(
   1414             javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true),
   1415             context, context, effect);
   1416         receiver = effect = graph()->NewNode(
   1417             javascript()->LoadContext(0, Context::GLOBAL_PROXY_INDEX, true),
   1418             native_context, native_context, effect);
   1419       }
   1420     } else if (!receiver_type->Maybe(Type::NullOrUndefined()) ||
   1421                mode == ConvertReceiverMode::kNotNullOrUndefined) {
   1422       receiver = effect =
   1423           graph()->NewNode(javascript()->ToObject(), receiver, context,
   1424                            frame_state, effect, control);
   1425     } else {
   1426       // Check {receiver} for undefined.
   1427       Node* check0 =
   1428           graph()->NewNode(simplified()->ReferenceEqual(receiver_type),
   1429                            receiver, jsgraph()->UndefinedConstant());
   1430       Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
   1431                                        check0, control);
   1432       Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
   1433       Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
   1434 
   1435       // Check {receiver} for null.
   1436       Node* check1 =
   1437           graph()->NewNode(simplified()->ReferenceEqual(receiver_type),
   1438                            receiver, jsgraph()->NullConstant());
   1439       Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
   1440                                        check1, if_false0);
   1441       Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
   1442       Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
   1443 
   1444       // Convert {receiver} using ToObject.
   1445       Node* if_convert = if_false1;
   1446       Node* econvert = effect;
   1447       Node* rconvert;
   1448       {
   1449         rconvert = econvert =
   1450             graph()->NewNode(javascript()->ToObject(), receiver, context,
   1451                              frame_state, econvert, if_convert);
   1452       }
   1453 
   1454       // Replace {receiver} with global proxy of {context}.
   1455       Node* if_global =
   1456           graph()->NewNode(common()->Merge(2), if_true0, if_true1);
   1457       Node* eglobal = effect;
   1458       Node* rglobal;
   1459       {
   1460         if (context_type->IsConstant()) {
   1461           Handle<JSObject> global_proxy(
   1462               Handle<Context>::cast(context_type->AsConstant()->Value())
   1463                   ->global_proxy(),
   1464               isolate());
   1465           rglobal = jsgraph()->Constant(global_proxy);
   1466         } else {
   1467           Node* native_context = eglobal = graph()->NewNode(
   1468               javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true),
   1469               context, context, eglobal);
   1470           rglobal = eglobal = graph()->NewNode(
   1471               javascript()->LoadContext(0, Context::GLOBAL_PROXY_INDEX, true),
   1472               native_context, native_context, eglobal);
   1473         }
   1474       }
   1475 
   1476       control = graph()->NewNode(common()->Merge(2), if_convert, if_global);
   1477       effect =
   1478           graph()->NewNode(common()->EffectPhi(2), econvert, eglobal, control);
   1479       receiver =
   1480           graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
   1481                            rconvert, rglobal, control);
   1482     }
   1483   }
   1484   ReplaceWithValue(node, receiver, effect, control);
   1485   return Changed(receiver);
   1486 }
   1487 
   1488 
   1489 Reduction JSTypedLowering::ReduceJSCallConstruct(Node* node) {
   1490   DCHECK_EQ(IrOpcode::kJSCallConstruct, node->opcode());
   1491   CallConstructParameters const& p = CallConstructParametersOf(node->op());
   1492   DCHECK_LE(2u, p.arity());
   1493   int const arity = static_cast<int>(p.arity() - 2);
   1494   Node* target = NodeProperties::GetValueInput(node, 0);
   1495   Type* target_type = NodeProperties::GetType(target);
   1496   Node* new_target = NodeProperties::GetValueInput(node, arity + 1);
   1497 
   1498   // Check if {target} is a known JSFunction.
   1499   if (target_type->IsConstant() &&
   1500       target_type->AsConstant()->Value()->IsJSFunction()) {
   1501     Handle<JSFunction> function =
   1502         Handle<JSFunction>::cast(target_type->AsConstant()->Value());
   1503     Handle<SharedFunctionInfo> shared(function->shared(), isolate());
   1504 
   1505     // Patch {node} to an indirect call via the {function}s construct stub.
   1506     Callable callable(handle(shared->construct_stub(), isolate()),
   1507                       ConstructStubDescriptor(isolate()));
   1508     node->RemoveInput(arity + 1);
   1509     node->InsertInput(graph()->zone(), 0,
   1510                       jsgraph()->HeapConstant(callable.code()));
   1511     node->InsertInput(graph()->zone(), 2, new_target);
   1512     node->InsertInput(graph()->zone(), 3, jsgraph()->Int32Constant(arity));
   1513     node->InsertInput(graph()->zone(), 4, jsgraph()->UndefinedConstant());
   1514     node->InsertInput(graph()->zone(), 5, jsgraph()->UndefinedConstant());
   1515     NodeProperties::ChangeOp(
   1516         node, common()->Call(Linkage::GetStubCallDescriptor(
   1517                   isolate(), graph()->zone(), callable.descriptor(), 1 + arity,
   1518                   CallDescriptor::kNeedsFrameState)));
   1519     return Changed(node);
   1520   }
   1521 
   1522   // Check if {target} is a JSFunction.
   1523   if (target_type->Is(Type::Function())) {
   1524     // Patch {node} to an indirect call via the ConstructFunction builtin.
   1525     Callable callable = CodeFactory::ConstructFunction(isolate());
   1526     node->RemoveInput(arity + 1);
   1527     node->InsertInput(graph()->zone(), 0,
   1528                       jsgraph()->HeapConstant(callable.code()));
   1529     node->InsertInput(graph()->zone(), 2, new_target);
   1530     node->InsertInput(graph()->zone(), 3, jsgraph()->Int32Constant(arity));
   1531     node->InsertInput(graph()->zone(), 4, jsgraph()->UndefinedConstant());
   1532     NodeProperties::ChangeOp(
   1533         node, common()->Call(Linkage::GetStubCallDescriptor(
   1534                   isolate(), graph()->zone(), callable.descriptor(), 1 + arity,
   1535                   CallDescriptor::kNeedsFrameState)));
   1536     return Changed(node);
   1537   }
   1538 
   1539   return NoChange();
   1540 }
   1541 
   1542 
   1543 Reduction JSTypedLowering::ReduceJSCallFunction(Node* node) {
   1544   DCHECK_EQ(IrOpcode::kJSCallFunction, node->opcode());
   1545   CallFunctionParameters const& p = CallFunctionParametersOf(node->op());
   1546   int const arity = static_cast<int>(p.arity() - 2);
   1547   ConvertReceiverMode convert_mode = p.convert_mode();
   1548   Node* target = NodeProperties::GetValueInput(node, 0);
   1549   Type* target_type = NodeProperties::GetType(target);
   1550   Node* receiver = NodeProperties::GetValueInput(node, 1);
   1551   Type* receiver_type = NodeProperties::GetType(receiver);
   1552   Node* effect = NodeProperties::GetEffectInput(node);
   1553   Node* control = NodeProperties::GetControlInput(node);
   1554   Node* frame_state = NodeProperties::FindFrameStateBefore(node);
   1555 
   1556   // Try to infer receiver {convert_mode} from {receiver} type.
   1557   if (receiver_type->Is(Type::NullOrUndefined())) {
   1558     convert_mode = ConvertReceiverMode::kNullOrUndefined;
   1559   } else if (!receiver_type->Maybe(Type::NullOrUndefined())) {
   1560     convert_mode = ConvertReceiverMode::kNotNullOrUndefined;
   1561   }
   1562 
   1563   // Check if {target} is a known JSFunction.
   1564   if (target_type->IsConstant() &&
   1565       target_type->AsConstant()->Value()->IsJSFunction()) {
   1566     Handle<JSFunction> function =
   1567         Handle<JSFunction>::cast(target_type->AsConstant()->Value());
   1568     Handle<SharedFunctionInfo> shared(function->shared(), isolate());
   1569 
   1570     // Class constructors are callable, but [[Call]] will raise an exception.
   1571     // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList ).
   1572     if (IsClassConstructor(shared->kind())) return NoChange();
   1573 
   1574     // Load the context from the {target}.
   1575     Node* context = effect = graph()->NewNode(
   1576         simplified()->LoadField(AccessBuilder::ForJSFunctionContext()), target,
   1577         effect, control);
   1578     NodeProperties::ReplaceContextInput(node, context);
   1579 
   1580     // Check if we need to convert the {receiver}.
   1581     if (is_sloppy(shared->language_mode()) && !shared->native() &&
   1582         !receiver_type->Is(Type::Receiver())) {
   1583       receiver = effect =
   1584           graph()->NewNode(javascript()->ConvertReceiver(convert_mode),
   1585                            receiver, context, frame_state, effect, control);
   1586       NodeProperties::ReplaceValueInput(node, receiver, 1);
   1587     }
   1588 
   1589     // Update the effect dependency for the {node}.
   1590     NodeProperties::ReplaceEffectInput(node, effect);
   1591 
   1592     // Compute flags for the call.
   1593     CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState;
   1594     if (p.tail_call_mode() == TailCallMode::kAllow) {
   1595       flags |= CallDescriptor::kSupportsTailCalls;
   1596     }
   1597 
   1598     Node* new_target = jsgraph()->UndefinedConstant();
   1599     Node* argument_count = jsgraph()->Int32Constant(arity);
   1600     if (shared->internal_formal_parameter_count() == arity ||
   1601         shared->internal_formal_parameter_count() ==
   1602             SharedFunctionInfo::kDontAdaptArgumentsSentinel) {
   1603       // Patch {node} to a direct call.
   1604       node->InsertInput(graph()->zone(), arity + 2, new_target);
   1605       node->InsertInput(graph()->zone(), arity + 3, argument_count);
   1606       NodeProperties::ChangeOp(node,
   1607                                common()->Call(Linkage::GetJSCallDescriptor(
   1608                                    graph()->zone(), false, 1 + arity, flags)));
   1609     } else {
   1610       // Patch {node} to an indirect call via the ArgumentsAdaptorTrampoline.
   1611       Callable callable = CodeFactory::ArgumentAdaptor(isolate());
   1612       node->InsertInput(graph()->zone(), 0,
   1613                         jsgraph()->HeapConstant(callable.code()));
   1614       node->InsertInput(graph()->zone(), 2, new_target);
   1615       node->InsertInput(graph()->zone(), 3, argument_count);
   1616       node->InsertInput(
   1617           graph()->zone(), 4,
   1618           jsgraph()->Int32Constant(shared->internal_formal_parameter_count()));
   1619       NodeProperties::ChangeOp(
   1620           node, common()->Call(Linkage::GetStubCallDescriptor(
   1621                     isolate(), graph()->zone(), callable.descriptor(),
   1622                     1 + arity, flags)));
   1623     }
   1624     return Changed(node);
   1625   }
   1626 
   1627   // Check if {target} is a JSFunction.
   1628   if (target_type->Is(Type::Function())) {
   1629     // Compute flags for the call.
   1630     CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState;
   1631     if (p.tail_call_mode() == TailCallMode::kAllow) {
   1632       flags |= CallDescriptor::kSupportsTailCalls;
   1633     }
   1634 
   1635     // Patch {node} to an indirect call via the CallFunction builtin.
   1636     Callable callable = CodeFactory::CallFunction(isolate(), convert_mode);
   1637     node->InsertInput(graph()->zone(), 0,
   1638                       jsgraph()->HeapConstant(callable.code()));
   1639     node->InsertInput(graph()->zone(), 2, jsgraph()->Int32Constant(arity));
   1640     NodeProperties::ChangeOp(
   1641         node, common()->Call(Linkage::GetStubCallDescriptor(
   1642                   isolate(), graph()->zone(), callable.descriptor(), 1 + arity,
   1643                   flags)));
   1644     return Changed(node);
   1645   }
   1646 
   1647   // Maybe we did at least learn something about the {receiver}.
   1648   if (p.convert_mode() != convert_mode) {
   1649     NodeProperties::ChangeOp(
   1650         node, javascript()->CallFunction(p.arity(), p.feedback(), convert_mode,
   1651                                          p.tail_call_mode()));
   1652     return Changed(node);
   1653   }
   1654 
   1655   return NoChange();
   1656 }
   1657 
   1658 
   1659 Reduction JSTypedLowering::ReduceJSForInDone(Node* node) {
   1660   DCHECK_EQ(IrOpcode::kJSForInDone, node->opcode());
   1661   node->TrimInputCount(2);
   1662   NodeProperties::ChangeOp(node, machine()->Word32Equal());
   1663   return Changed(node);
   1664 }
   1665 
   1666 
   1667 Reduction JSTypedLowering::ReduceJSForInNext(Node* node) {
   1668   DCHECK_EQ(IrOpcode::kJSForInNext, node->opcode());
   1669   Node* receiver = NodeProperties::GetValueInput(node, 0);
   1670   Node* cache_array = NodeProperties::GetValueInput(node, 1);
   1671   Node* cache_type = NodeProperties::GetValueInput(node, 2);
   1672   Node* index = NodeProperties::GetValueInput(node, 3);
   1673   Node* context = NodeProperties::GetContextInput(node);
   1674   Node* frame_state = NodeProperties::GetFrameStateInput(node, 0);
   1675   Node* effect = NodeProperties::GetEffectInput(node);
   1676   Node* control = NodeProperties::GetControlInput(node);
   1677 
   1678   // Load the next {key} from the {cache_array}.
   1679   Node* key = effect = graph()->NewNode(
   1680       simplified()->LoadElement(AccessBuilder::ForFixedArrayElement()),
   1681       cache_array, index, effect, control);
   1682 
   1683   // Load the map of the {receiver}.
   1684   Node* receiver_map = effect =
   1685       graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
   1686                        receiver, effect, control);
   1687 
   1688   // Check if the expected map still matches that of the {receiver}.
   1689   Node* check0 = graph()->NewNode(simplified()->ReferenceEqual(Type::Any()),
   1690                                   receiver_map, cache_type);
   1691   Node* branch0 =
   1692       graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
   1693 
   1694   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
   1695   Node* etrue0;
   1696   Node* vtrue0;
   1697   {
   1698     // Don't need filtering since expected map still matches that of the
   1699     // {receiver}.
   1700     etrue0 = effect;
   1701     vtrue0 = key;
   1702   }
   1703 
   1704   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
   1705   Node* efalse0;
   1706   Node* vfalse0;
   1707   {
   1708     // Filter the {key} to check if it's still a valid property of the
   1709     // {receiver} (does the ToName conversion implicitly).
   1710     vfalse0 = efalse0 = graph()->NewNode(
   1711         javascript()->CallRuntime(Runtime::kForInFilter), receiver, key,
   1712         context, frame_state, effect, if_false0);
   1713     if_false0 = graph()->NewNode(common()->IfSuccess(), vfalse0);
   1714   }
   1715 
   1716   control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
   1717   effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
   1718   ReplaceWithValue(node, node, effect, control);
   1719   node->ReplaceInput(0, vtrue0);
   1720   node->ReplaceInput(1, vfalse0);
   1721   node->ReplaceInput(2, control);
   1722   node->TrimInputCount(3);
   1723   NodeProperties::ChangeOp(node,
   1724                            common()->Phi(MachineRepresentation::kTagged, 2));
   1725   return Changed(node);
   1726 }
   1727 
   1728 
   1729 Reduction JSTypedLowering::ReduceJSForInStep(Node* node) {
   1730   DCHECK_EQ(IrOpcode::kJSForInStep, node->opcode());
   1731   node->ReplaceInput(1, jsgraph()->Int32Constant(1));
   1732   NodeProperties::ChangeOp(node, machine()->Int32Add());
   1733   return Changed(node);
   1734 }
   1735 
   1736 Reduction JSTypedLowering::ReduceJSGeneratorStore(Node* node) {
   1737   DCHECK_EQ(IrOpcode::kJSGeneratorStore, node->opcode());
   1738   Node* generator = NodeProperties::GetValueInput(node, 0);
   1739   Node* continuation = NodeProperties::GetValueInput(node, 1);
   1740   Node* offset = NodeProperties::GetValueInput(node, 2);
   1741   Node* context = NodeProperties::GetContextInput(node);
   1742   Node* effect = NodeProperties::GetEffectInput(node);
   1743   Node* control = NodeProperties::GetControlInput(node);
   1744   int register_count = OpParameter<int>(node);
   1745 
   1746   FieldAccess array_field = AccessBuilder::ForJSGeneratorObjectOperandStack();
   1747   FieldAccess context_field = AccessBuilder::ForJSGeneratorObjectContext();
   1748   FieldAccess continuation_field =
   1749       AccessBuilder::ForJSGeneratorObjectContinuation();
   1750   FieldAccess input_or_debug_pos_field =
   1751       AccessBuilder::ForJSGeneratorObjectInputOrDebugPos();
   1752 
   1753   Node* array = effect = graph()->NewNode(simplified()->LoadField(array_field),
   1754                                           generator, effect, control);
   1755 
   1756   for (int i = 0; i < register_count; ++i) {
   1757     Node* value = NodeProperties::GetValueInput(node, 3 + i);
   1758     effect = graph()->NewNode(
   1759         simplified()->StoreField(AccessBuilder::ForFixedArraySlot(i)), array,
   1760         value, effect, control);
   1761   }
   1762 
   1763   effect = graph()->NewNode(simplified()->StoreField(context_field), generator,
   1764                             context, effect, control);
   1765   effect = graph()->NewNode(simplified()->StoreField(continuation_field),
   1766                             generator, continuation, effect, control);
   1767   effect = graph()->NewNode(simplified()->StoreField(input_or_debug_pos_field),
   1768                             generator, offset, effect, control);
   1769 
   1770   ReplaceWithValue(node, effect, effect, control);
   1771   return Changed(effect);
   1772 }
   1773 
   1774 Reduction JSTypedLowering::ReduceJSGeneratorRestoreContinuation(Node* node) {
   1775   DCHECK_EQ(IrOpcode::kJSGeneratorRestoreContinuation, node->opcode());
   1776   Node* generator = NodeProperties::GetValueInput(node, 0);
   1777   Node* effect = NodeProperties::GetEffectInput(node);
   1778   Node* control = NodeProperties::GetControlInput(node);
   1779 
   1780   FieldAccess continuation_field =
   1781       AccessBuilder::ForJSGeneratorObjectContinuation();
   1782 
   1783   Node* continuation = effect = graph()->NewNode(
   1784       simplified()->LoadField(continuation_field), generator, effect, control);
   1785   Node* executing = jsgraph()->Constant(JSGeneratorObject::kGeneratorExecuting);
   1786   effect = graph()->NewNode(simplified()->StoreField(continuation_field),
   1787                             generator, executing, effect, control);
   1788 
   1789   ReplaceWithValue(node, continuation, effect, control);
   1790   return Changed(continuation);
   1791 }
   1792 
   1793 Reduction JSTypedLowering::ReduceJSGeneratorRestoreRegister(Node* node) {
   1794   DCHECK_EQ(IrOpcode::kJSGeneratorRestoreRegister, node->opcode());
   1795   Node* generator = NodeProperties::GetValueInput(node, 0);
   1796   Node* effect = NodeProperties::GetEffectInput(node);
   1797   Node* control = NodeProperties::GetControlInput(node);
   1798   int index = OpParameter<int>(node);
   1799 
   1800   FieldAccess array_field = AccessBuilder::ForJSGeneratorObjectOperandStack();
   1801   FieldAccess element_field = AccessBuilder::ForFixedArraySlot(index);
   1802 
   1803   Node* array = effect = graph()->NewNode(simplified()->LoadField(array_field),
   1804                                           generator, effect, control);
   1805   Node* element = effect = graph()->NewNode(
   1806       simplified()->LoadField(element_field), array, effect, control);
   1807   Node* stale = jsgraph()->StaleRegisterConstant();
   1808   effect = graph()->NewNode(simplified()->StoreField(element_field), array,
   1809                             stale, effect, control);
   1810 
   1811   ReplaceWithValue(node, element, effect, control);
   1812   return Changed(element);
   1813 }
   1814 
   1815 Reduction JSTypedLowering::ReduceSelect(Node* node) {
   1816   DCHECK_EQ(IrOpcode::kSelect, node->opcode());
   1817   Node* const condition = NodeProperties::GetValueInput(node, 0);
   1818   Type* const condition_type = NodeProperties::GetType(condition);
   1819   Node* const vtrue = NodeProperties::GetValueInput(node, 1);
   1820   Type* const vtrue_type = NodeProperties::GetType(vtrue);
   1821   Node* const vfalse = NodeProperties::GetValueInput(node, 2);
   1822   Type* const vfalse_type = NodeProperties::GetType(vfalse);
   1823   if (condition_type->Is(true_type_)) {
   1824     // Select(condition:true, vtrue, vfalse) => vtrue
   1825     return Replace(vtrue);
   1826   }
   1827   if (condition_type->Is(false_type_)) {
   1828     // Select(condition:false, vtrue, vfalse) => vfalse
   1829     return Replace(vfalse);
   1830   }
   1831   if (vtrue_type->Is(true_type_) && vfalse_type->Is(false_type_)) {
   1832     // Select(condition, vtrue:true, vfalse:false) => condition
   1833     return Replace(condition);
   1834   }
   1835   if (vtrue_type->Is(false_type_) && vfalse_type->Is(true_type_)) {
   1836     // Select(condition, vtrue:false, vfalse:true) => BooleanNot(condition)
   1837     node->TrimInputCount(1);
   1838     NodeProperties::ChangeOp(node, simplified()->BooleanNot());
   1839     return Changed(node);
   1840   }
   1841   return NoChange();
   1842 }
   1843 
   1844 
   1845 Reduction JSTypedLowering::Reduce(Node* node) {
   1846   // Check if the output type is a singleton.  In that case we already know the
   1847   // result value and can simply replace the node if it's eliminable.
   1848   if (!NodeProperties::IsConstant(node) && NodeProperties::IsTyped(node) &&
   1849       node->op()->HasProperty(Operator::kEliminatable)) {
   1850     // We can only constant-fold nodes here, that are known to not cause any
   1851     // side-effect, may it be a JavaScript observable side-effect or a possible
   1852     // eager deoptimization exit (i.e. {node} has an operator that doesn't have
   1853     // the Operator::kNoDeopt property).
   1854     Type* upper = NodeProperties::GetType(node);
   1855     if (upper->IsInhabited()) {
   1856       if (upper->IsConstant()) {
   1857         Node* replacement = jsgraph()->Constant(upper->AsConstant()->Value());
   1858         ReplaceWithValue(node, replacement);
   1859         return Changed(replacement);
   1860       } else if (upper->Is(Type::MinusZero())) {
   1861         Node* replacement = jsgraph()->Constant(factory()->minus_zero_value());
   1862         ReplaceWithValue(node, replacement);
   1863         return Changed(replacement);
   1864       } else if (upper->Is(Type::NaN())) {
   1865         Node* replacement = jsgraph()->NaNConstant();
   1866         ReplaceWithValue(node, replacement);
   1867         return Changed(replacement);
   1868       } else if (upper->Is(Type::Null())) {
   1869         Node* replacement = jsgraph()->NullConstant();
   1870         ReplaceWithValue(node, replacement);
   1871         return Changed(replacement);
   1872       } else if (upper->Is(Type::PlainNumber()) &&
   1873                  upper->Min() == upper->Max()) {
   1874         Node* replacement = jsgraph()->Constant(upper->Min());
   1875         ReplaceWithValue(node, replacement);
   1876         return Changed(replacement);
   1877       } else if (upper->Is(Type::Undefined())) {
   1878         Node* replacement = jsgraph()->UndefinedConstant();
   1879         ReplaceWithValue(node, replacement);
   1880         return Changed(replacement);
   1881       }
   1882     }
   1883   }
   1884   switch (node->opcode()) {
   1885     case IrOpcode::kJSEqual:
   1886       return ReduceJSEqual(node, false);
   1887     case IrOpcode::kJSNotEqual:
   1888       return ReduceJSEqual(node, true);
   1889     case IrOpcode::kJSStrictEqual:
   1890       return ReduceJSStrictEqual(node, false);
   1891     case IrOpcode::kJSStrictNotEqual:
   1892       return ReduceJSStrictEqual(node, true);
   1893     case IrOpcode::kJSLessThan:         // fall through
   1894     case IrOpcode::kJSGreaterThan:      // fall through
   1895     case IrOpcode::kJSLessThanOrEqual:  // fall through
   1896     case IrOpcode::kJSGreaterThanOrEqual:
   1897       return ReduceJSComparison(node);
   1898     case IrOpcode::kJSBitwiseOr:
   1899       return ReduceInt32Binop(node, simplified()->NumberBitwiseOr());
   1900     case IrOpcode::kJSBitwiseXor:
   1901       return ReduceInt32Binop(node, simplified()->NumberBitwiseXor());
   1902     case IrOpcode::kJSBitwiseAnd:
   1903       return ReduceInt32Binop(node, simplified()->NumberBitwiseAnd());
   1904     case IrOpcode::kJSShiftLeft:
   1905       return ReduceUI32Shift(node, kSigned, simplified()->NumberShiftLeft());
   1906     case IrOpcode::kJSShiftRight:
   1907       return ReduceUI32Shift(node, kSigned, simplified()->NumberShiftRight());
   1908     case IrOpcode::kJSShiftRightLogical:
   1909       return ReduceUI32Shift(node, kUnsigned,
   1910                              simplified()->NumberShiftRightLogical());
   1911     case IrOpcode::kJSAdd:
   1912       return ReduceJSAdd(node);
   1913     case IrOpcode::kJSSubtract:
   1914       return ReduceJSSubtract(node);
   1915     case IrOpcode::kJSMultiply:
   1916       return ReduceJSMultiply(node);
   1917     case IrOpcode::kJSDivide:
   1918       return ReduceJSDivide(node);
   1919     case IrOpcode::kJSModulus:
   1920       return ReduceJSModulus(node);
   1921     case IrOpcode::kJSToBoolean:
   1922       return ReduceJSToBoolean(node);
   1923     case IrOpcode::kJSToInteger:
   1924       return ReduceJSToInteger(node);
   1925     case IrOpcode::kJSToLength:
   1926       return ReduceJSToLength(node);
   1927     case IrOpcode::kJSToNumber:
   1928       return ReduceJSToNumber(node);
   1929     case IrOpcode::kJSToString:
   1930       return ReduceJSToString(node);
   1931     case IrOpcode::kJSToObject:
   1932       return ReduceJSToObject(node);
   1933     case IrOpcode::kJSLoadNamed:
   1934       return ReduceJSLoadNamed(node);
   1935     case IrOpcode::kJSLoadProperty:
   1936       return ReduceJSLoadProperty(node);
   1937     case IrOpcode::kJSStoreProperty:
   1938       return ReduceJSStoreProperty(node);
   1939     case IrOpcode::kJSInstanceOf:
   1940       return ReduceJSInstanceOf(node);
   1941     case IrOpcode::kJSLoadContext:
   1942       return ReduceJSLoadContext(node);
   1943     case IrOpcode::kJSStoreContext:
   1944       return ReduceJSStoreContext(node);
   1945     case IrOpcode::kJSConvertReceiver:
   1946       return ReduceJSConvertReceiver(node);
   1947     case IrOpcode::kJSCallConstruct:
   1948       return ReduceJSCallConstruct(node);
   1949     case IrOpcode::kJSCallFunction:
   1950       return ReduceJSCallFunction(node);
   1951     case IrOpcode::kJSForInDone:
   1952       return ReduceJSForInDone(node);
   1953     case IrOpcode::kJSForInNext:
   1954       return ReduceJSForInNext(node);
   1955     case IrOpcode::kJSForInStep:
   1956       return ReduceJSForInStep(node);
   1957     case IrOpcode::kJSGeneratorStore:
   1958       return ReduceJSGeneratorStore(node);
   1959     case IrOpcode::kJSGeneratorRestoreContinuation:
   1960       return ReduceJSGeneratorRestoreContinuation(node);
   1961     case IrOpcode::kJSGeneratorRestoreRegister:
   1962       return ReduceJSGeneratorRestoreRegister(node);
   1963     case IrOpcode::kSelect:
   1964       return ReduceSelect(node);
   1965     default:
   1966       break;
   1967   }
   1968   return NoChange();
   1969 }
   1970 
   1971 
   1972 Node* JSTypedLowering::Word32Shl(Node* const lhs, int32_t const rhs) {
   1973   if (rhs == 0) return lhs;
   1974   return graph()->NewNode(machine()->Word32Shl(), lhs,
   1975                           jsgraph()->Int32Constant(rhs));
   1976 }
   1977 
   1978 Node* JSTypedLowering::EmptyFrameState() {
   1979   return graph()->NewNode(
   1980       common()->FrameState(BailoutId::None(), OutputFrameStateCombine::Ignore(),
   1981                            nullptr),
   1982       jsgraph()->EmptyStateValues(), jsgraph()->EmptyStateValues(),
   1983       jsgraph()->EmptyStateValues(), jsgraph()->NoContextConstant(),
   1984       jsgraph()->UndefinedConstant(), graph()->start());
   1985 }
   1986 
   1987 Factory* JSTypedLowering::factory() const { return jsgraph()->factory(); }
   1988 
   1989 
   1990 Graph* JSTypedLowering::graph() const { return jsgraph()->graph(); }
   1991 
   1992 
   1993 Isolate* JSTypedLowering::isolate() const { return jsgraph()->isolate(); }
   1994 
   1995 
   1996 JSOperatorBuilder* JSTypedLowering::javascript() const {
   1997   return jsgraph()->javascript();
   1998 }
   1999 
   2000 
   2001 CommonOperatorBuilder* JSTypedLowering::common() const {
   2002   return jsgraph()->common();
   2003 }
   2004 
   2005 
   2006 SimplifiedOperatorBuilder* JSTypedLowering::simplified() const {
   2007   return jsgraph()->simplified();
   2008 }
   2009 
   2010 
   2011 MachineOperatorBuilder* JSTypedLowering::machine() const {
   2012   return jsgraph()->machine();
   2013 }
   2014 
   2015 
   2016 CompilationDependencies* JSTypedLowering::dependencies() const {
   2017   return dependencies_;
   2018 }
   2019 
   2020 }  // namespace compiler
   2021 }  // namespace internal
   2022 }  // namespace v8
   2023