LCOV - code coverage report
Current view: top level - src/compiler - js-typed-lowering.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 888 928 95.7 %
Date: 2017-04-26 Functions: 68 76 89.5 %

          Line data    Source code
       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/compiler/js-typed-lowering.h"
       6             : 
       7             : #include "src/ast/modules.h"
       8             : #include "src/builtins/builtins-utils.h"
       9             : #include "src/code-factory.h"
      10             : #include "src/compilation-dependencies.h"
      11             : #include "src/compiler/access-builder.h"
      12             : #include "src/compiler/js-graph.h"
      13             : #include "src/compiler/linkage.h"
      14             : #include "src/compiler/node-matchers.h"
      15             : #include "src/compiler/node-properties.h"
      16             : #include "src/compiler/operator-properties.h"
      17             : #include "src/compiler/type-cache.h"
      18             : #include "src/compiler/types.h"
      19             : #include "src/objects-inl.h"
      20             : 
      21             : namespace v8 {
      22             : namespace internal {
      23             : namespace compiler {
      24             : 
      25             : // A helper class to simplify the process of reducing a single binop node with a
      26             : // JSOperator. This class manages the rewriting of context, control, and effect
      27             : // dependencies during lowering of a binop and contains numerous helper
      28             : // functions for matching the types of inputs to an operation.
      29             : class JSBinopReduction final {
      30             :  public:
      31             :   JSBinopReduction(JSTypedLowering* lowering, Node* node)
      32      864134 :       : lowering_(lowering), node_(node) {}
      33             : 
      34      150734 :   bool GetCompareNumberOperationHint(NumberOperationHint* hint) {
      35      301468 :     if (lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) {
      36             :       DCHECK_EQ(1, node_->op()->EffectOutputCount());
      37      150734 :       switch (CompareOperationHintOf(node_->op())) {
      38             :         case CompareOperationHint::kSignedSmall:
      39        8960 :           *hint = NumberOperationHint::kSignedSmall;
      40        8960 :           return true;
      41             :         case CompareOperationHint::kNumber:
      42        7101 :           *hint = NumberOperationHint::kNumber;
      43        7101 :           return true;
      44             :         case CompareOperationHint::kNumberOrOddball:
      45           0 :           *hint = NumberOperationHint::kNumberOrOddball;
      46           0 :           return true;
      47             :         case CompareOperationHint::kAny:
      48             :         case CompareOperationHint::kNone:
      49             :         case CompareOperationHint::kString:
      50             :         case CompareOperationHint::kReceiver:
      51             :         case CompareOperationHint::kInternalizedString:
      52             :           break;
      53             :       }
      54             :     }
      55             :     return false;
      56             :   }
      57             : 
      58      232785 :   bool IsInternalizedStringCompareOperation() {
      59      465570 :     if (lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) {
      60             :       DCHECK_EQ(1, node_->op()->EffectOutputCount());
      61      230321 :       return (CompareOperationHintOf(node_->op()) ==
      62      234577 :               CompareOperationHint::kInternalizedString) &&
      63      234577 :              BothInputsMaybe(Type::InternalizedString());
      64             :     }
      65             :     return false;
      66             :   }
      67             : 
      68      135953 :   bool IsReceiverCompareOperation() {
      69      271906 :     if (lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) {
      70             :       DCHECK_EQ(1, node_->op()->EffectOutputCount());
      71      135938 :       return (CompareOperationHintOf(node_->op()) ==
      72      136325 :               CompareOperationHint::kReceiver) &&
      73      136325 :              BothInputsMaybe(Type::Receiver());
      74             :     }
      75             :     return false;
      76             :   }
      77             : 
      78      157869 :   bool IsStringCompareOperation() {
      79      315738 :     if (lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) {
      80             :       DCHECK_EQ(1, node_->op()->EffectOutputCount());
      81      157839 :       return (CompareOperationHintOf(node_->op()) ==
      82      158401 :               CompareOperationHint::kString) &&
      83      158401 :              BothInputsMaybe(Type::String());
      84             :     }
      85             :     return false;
      86             :   }
      87             : 
      88             :   // Check if a string addition will definitely result in creating a ConsString,
      89             :   // i.e. if the combined length of the resulting string exceeds the ConsString
      90             :   // minimum length.
      91       74259 :   bool ShouldCreateConsString() {
      92             :     DCHECK_EQ(IrOpcode::kJSAdd, node_->opcode());
      93             :     DCHECK(OneInputIs(Type::String()));
      94      194013 :     if (BothInputsAre(Type::String()) ||
      95       90990 :         ((lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) &&
      96       45495 :          BinaryOperationHintOf(node_->op()) == BinaryOperationHint::kString)) {
      97       31773 :       HeapObjectBinopMatcher m(node_);
      98       56497 :       if (m.right().HasValue() && m.right().Value()->IsString()) {
      99             :         Handle<String> right_string = Handle<String>::cast(m.right().Value());
     100       24724 :         if (right_string->length() >= ConsString::kMinLength) return true;
     101             :       }
     102       30282 :       if (m.left().HasValue() && m.left().Value()->IsString()) {
     103             :         Handle<String> left_string = Handle<String>::cast(m.left().Value());
     104        1601 :         if (left_string->length() >= ConsString::kMinLength) {
     105             :           // The invariant for ConsString requires the left hand side to be
     106             :           // a sequential or external string if the right hand side is the
     107             :           // empty string. Since we don't know anything about the right hand
     108             :           // side here, we must ensure that the left hand side satisfy the
     109             :           // constraints independent of the right hand side.
     110         353 :           return left_string->IsSeqString() || left_string->IsExternalString();
     111             :         }
     112             :       }
     113             :     }
     114             :     return false;
     115             :   }
     116             : 
     117             :   // Inserts a CheckReceiver for the left input.
     118        1662 :   void CheckLeftInputToReceiver() {
     119             :     Node* left_input = graph()->NewNode(simplified()->CheckReceiver(), left(),
     120         277 :                                         effect(), control());
     121         277 :     node_->ReplaceInput(0, left_input);
     122             :     update_effect(left_input);
     123         277 :   }
     124             : 
     125             :   // Checks that both inputs are Receiver, and if we don't know
     126             :   // statically that one side is already a Receiver, insert a
     127             :   // CheckReceiver node.
     128        1584 :   void CheckInputsToReceiver() {
     129         204 :     if (!left_type()->Is(Type::Receiver())) {
     130          94 :       CheckLeftInputToReceiver();
     131             :     }
     132         204 :     if (!right_type()->Is(Type::Receiver())) {
     133             :       Node* right_input = graph()->NewNode(simplified()->CheckReceiver(),
     134         196 :                                            right(), effect(), control());
     135         196 :       node_->ReplaceInput(1, right_input);
     136             :       update_effect(right_input);
     137             :     }
     138         204 :   }
     139             : 
     140             :   // Checks that both inputs are String, and if we don't know
     141             :   // statically that one side is already a String, insert a
     142             :   // CheckString node.
     143        4868 :   void CheckInputsToString() {
     144         562 :     if (!left_type()->Is(Type::String())) {
     145             :       Node* left_input = graph()->NewNode(simplified()->CheckString(), left(),
     146         562 :                                           effect(), control());
     147         562 :       node_->ReplaceInput(0, left_input);
     148             :       update_effect(left_input);
     149             :     }
     150         562 :     if (!right_type()->Is(Type::String())) {
     151             :       Node* right_input = graph()->NewNode(simplified()->CheckString(), right(),
     152          62 :                                            effect(), control());
     153          62 :       node_->ReplaceInput(1, right_input);
     154             :       update_effect(right_input);
     155             :     }
     156         562 :   }
     157             : 
     158             :   // Checks that both inputs are InternalizedString, and if we don't know
     159             :   // statically that one side is already an InternalizedString, insert a
     160             :   // CheckInternalizedString node.
     161       34900 :   void CheckInputsToInternalizedString() {
     162        4256 :     if (!left_type()->Is(Type::UniqueName())) {
     163             :       Node* left_input = graph()->NewNode(
     164        4256 :           simplified()->CheckInternalizedString(), left(), effect(), control());
     165        4256 :       node_->ReplaceInput(0, left_input);
     166             :       update_effect(left_input);
     167             :     }
     168        4256 :     if (!right_type()->Is(Type::UniqueName())) {
     169             :       Node* right_input =
     170             :           graph()->NewNode(simplified()->CheckInternalizedString(), right(),
     171         142 :                            effect(), control());
     172         142 :       node_->ReplaceInput(1, right_input);
     173             :       update_effect(right_input);
     174             :     }
     175        4256 :   }
     176             : 
     177     1091903 :   void ConvertInputsToNumber() {
     178             :     // To convert the inputs to numbers, we have to provide frame states
     179             :     // for lazy bailouts in the ToNumber conversions.
     180             :     // We use a little hack here: we take the frame state before the binary
     181             :     // operation and use it to construct the frame states for the conversion
     182             :     // so that after the deoptimization, the binary operation IC gets
     183             :     // already converted values from full code. This way we are sure that we
     184             :     // will not re-do any of the side effects.
     185             : 
     186      217842 :     Node* left_input = nullptr;
     187      217842 :     Node* right_input = nullptr;
     188             :     bool left_is_primitive = left_type()->Is(Type::PlainPrimitive());
     189             :     bool right_is_primitive = right_type()->Is(Type::PlainPrimitive());
     190      217842 :     bool handles_exception = NodeProperties::IsExceptionalCall(node_);
     191             : 
     192      217842 :     if (!left_is_primitive && !right_is_primitive && handles_exception) {
     193           0 :       ConvertBothInputsToNumber(&left_input, &right_input);
     194             :     } else {
     195             :       left_input = left_is_primitive
     196             :                        ? ConvertPlainPrimitiveToNumber(left())
     197             :                        : ConvertSingleInputToNumber(
     198      435684 :                              left(), CreateFrameStateForLeftInput());
     199             :       right_input =
     200             :           right_is_primitive
     201             :               ? ConvertPlainPrimitiveToNumber(right())
     202             :               : ConvertSingleInputToNumber(
     203      435684 :                     right(), CreateFrameStateForRightInput(left_input));
     204             :     }
     205             : 
     206      217842 :     node_->ReplaceInput(0, left_input);
     207      217842 :     node_->ReplaceInput(1, right_input);
     208      217842 :   }
     209             : 
     210       69195 :   void ConvertInputsToUI32(Signedness left_signedness,
     211      138390 :                            Signedness right_signedness) {
     212       69195 :     node_->ReplaceInput(0, ConvertToUI32(left(), left_signedness));
     213       69195 :     node_->ReplaceInput(1, ConvertToUI32(right(), right_signedness));
     214       69195 :   }
     215             : 
     216       11680 :   void SwapInputs() {
     217             :     Node* l = left();
     218             :     Node* r = right();
     219        5840 :     node_->ReplaceInput(0, r);
     220        5840 :     node_->ReplaceInput(1, l);
     221        5840 :   }
     222             : 
     223             :   // Remove all effect and control inputs and outputs to this node and change
     224             :   // to the pure operator {op}.
     225      333773 :   Reduction ChangeToPureOperator(const Operator* op, Type* type = Type::Any()) {
     226             :     DCHECK_EQ(0, op->EffectInputCount());
     227             :     DCHECK_EQ(false, OperatorProperties::HasContextInput(op));
     228             :     DCHECK_EQ(0, op->ControlInputCount());
     229             :     DCHECK_EQ(2, op->ValueInputCount());
     230             : 
     231             :     // Remove the effects from the node, and update its effect/control usages.
     232      667546 :     if (node_->op()->EffectInputCount() > 0) {
     233      333773 :       lowering_->RelaxEffectsAndControls(node_);
     234             :     }
     235             :     // Remove the inputs corresponding to context, effect, and control.
     236      333773 :     NodeProperties::RemoveNonValueInputs(node_);
     237             :     // Finally, update the operator to the new one.
     238      333773 :     NodeProperties::ChangeOp(node_, op);
     239             : 
     240             :     // TODO(jarin): Replace the explicit typing hack with a call to some method
     241             :     // that encapsulates changing the operator and re-typing.
     242      333773 :     Type* node_type = NodeProperties::GetType(node_);
     243      333773 :     NodeProperties::SetType(node_, Type::Intersect(node_type, type, zone()));
     244             : 
     245      333773 :     return lowering_->Changed(node_);
     246             :   }
     247             : 
     248       16061 :   Reduction ChangeToSpeculativeOperator(const Operator* op, Type* upper_bound) {
     249             :     DCHECK_EQ(1, op->EffectInputCount());
     250             :     DCHECK_EQ(1, op->EffectOutputCount());
     251             :     DCHECK_EQ(false, OperatorProperties::HasContextInput(op));
     252             :     DCHECK_EQ(1, op->ControlInputCount());
     253             :     DCHECK_EQ(0, op->ControlOutputCount());
     254             :     DCHECK_EQ(0, OperatorProperties::GetFrameStateInputCount(op));
     255             :     DCHECK_EQ(2, op->ValueInputCount());
     256             : 
     257             :     DCHECK_EQ(1, node_->op()->EffectInputCount());
     258             :     DCHECK_EQ(1, node_->op()->EffectOutputCount());
     259             :     DCHECK_EQ(1, node_->op()->ControlInputCount());
     260             :     DCHECK_EQ(2, node_->op()->ValueInputCount());
     261             : 
     262             :     // Reconnect the control output to bypass the IfSuccess node and
     263             :     // possibly disconnect from the IfException node.
     264       32122 :     lowering_->RelaxControls(node_);
     265             : 
     266             :     // Remove the frame state and the context.
     267       32122 :     if (OperatorProperties::HasFrameStateInput(node_->op())) {
     268           0 :       node_->RemoveInput(NodeProperties::FirstFrameStateIndex(node_));
     269             :     }
     270       32122 :     node_->RemoveInput(NodeProperties::FirstContextIndex(node_));
     271             : 
     272       16061 :     NodeProperties::ChangeOp(node_, op);
     273             : 
     274             :     // Update the type to number.
     275       16061 :     Type* node_type = NodeProperties::GetType(node_);
     276             :     NodeProperties::SetType(node_,
     277       16061 :                             Type::Intersect(node_type, upper_bound, zone()));
     278             : 
     279       16061 :     return lowering_->Changed(node_);
     280             :   }
     281             : 
     282      230698 :   const Operator* NumberOp() {
     283      230698 :     switch (node_->opcode()) {
     284             :       case IrOpcode::kJSAdd:
     285           0 :         return simplified()->NumberAdd();
     286             :       case IrOpcode::kJSSubtract:
     287       22714 :         return simplified()->NumberSubtract();
     288             :       case IrOpcode::kJSMultiply:
     289       11806 :         return simplified()->NumberMultiply();
     290             :       case IrOpcode::kJSDivide:
     291        8164 :         return simplified()->NumberDivide();
     292             :       case IrOpcode::kJSModulus:
     293        3470 :         return simplified()->NumberModulus();
     294             :       case IrOpcode::kJSBitwiseAnd:
     295        6055 :         return simplified()->NumberBitwiseAnd();
     296             :       case IrOpcode::kJSBitwiseOr:
     297       28044 :         return simplified()->NumberBitwiseOr();
     298             :       case IrOpcode::kJSBitwiseXor:
     299        6393 :         return simplified()->NumberBitwiseXor();
     300             :       case IrOpcode::kJSShiftLeft:
     301        6543 :         return simplified()->NumberShiftLeft();
     302             :       case IrOpcode::kJSShiftRight:
     303       13643 :         return simplified()->NumberShiftRight();
     304             :       case IrOpcode::kJSShiftRightLogical:
     305        8517 :         return simplified()->NumberShiftRightLogical();
     306             :       default:
     307             :         break;
     308             :     }
     309           0 :     UNREACHABLE();
     310             :     return nullptr;
     311             :   }
     312             : 
     313       55730 :   const Operator* NumberOpFromSpeculativeNumberOp() {
     314       55730 :     switch (node_->opcode()) {
     315             :       case IrOpcode::kSpeculativeNumberEqual:
     316        1511 :         return simplified()->NumberEqual();
     317             :       case IrOpcode::kSpeculativeNumberLessThan:
     318        7066 :         return simplified()->NumberLessThan();
     319             :       case IrOpcode::kSpeculativeNumberLessThanOrEqual:
     320         288 :         return simplified()->NumberLessThanOrEqual();
     321             :       case IrOpcode::kSpeculativeNumberAdd:
     322           0 :         return simplified()->NumberAdd();
     323             :       case IrOpcode::kSpeculativeNumberSubtract:
     324        1114 :         return simplified()->NumberSubtract();
     325             :       case IrOpcode::kSpeculativeNumberMultiply:
     326        8617 :         return simplified()->NumberMultiply();
     327             :       case IrOpcode::kSpeculativeNumberDivide:
     328        8884 :         return simplified()->NumberDivide();
     329             :       case IrOpcode::kSpeculativeNumberModulus:
     330         385 :         return simplified()->NumberModulus();
     331             :       default:
     332             :         break;
     333             :     }
     334           0 :     UNREACHABLE();
     335             :     return nullptr;
     336             :   }
     337             : 
     338     4456640 :   bool LeftInputIs(Type* t) { return left_type()->Is(t); }
     339             : 
     340     1762474 :   bool RightInputIs(Type* t) { return right_type()->Is(t); }
     341             : 
     342      331006 :   bool OneInputIs(Type* t) { return LeftInputIs(t) || RightInputIs(t); }
     343             : 
     344     1826375 :   bool BothInputsAre(Type* t) { return LeftInputIs(t) && RightInputIs(t); }
     345             : 
     346       10410 :   bool BothInputsMaybe(Type* t) {
     347       10410 :     return left_type()->Maybe(t) && right_type()->Maybe(t);
     348             :   }
     349             : 
     350      509563 :   bool OneInputCannotBe(Type* t) {
     351      509563 :     return !left_type()->Maybe(t) || !right_type()->Maybe(t);
     352             :   }
     353             : 
     354      267609 :   bool NeitherInputCanBe(Type* t) {
     355      267609 :     return !left_type()->Maybe(t) && !right_type()->Maybe(t);
     356             :   }
     357             : 
     358        8188 :   Node* effect() { return NodeProperties::GetEffectInput(node_); }
     359        8188 :   Node* control() { return NodeProperties::GetControlInput(node_); }
     360        2693 :   Node* context() { return NodeProperties::GetContextInput(node_); }
     361      547736 :   Node* left() { return NodeProperties::GetValueInput(node_, 0); }
     362      534608 :   Node* right() { return NodeProperties::GetValueInput(node_, 1); }
     363             :   Type* left_type() { return NodeProperties::GetType(node_->InputAt(0)); }
     364             :   Type* right_type() { return NodeProperties::GetType(node_->InputAt(1)); }
     365             :   Type* type() { return NodeProperties::GetType(node_); }
     366             : 
     367             :   SimplifiedOperatorBuilder* simplified() { return lowering_->simplified(); }
     368             :   Graph* graph() const { return lowering_->graph(); }
     369           0 :   JSGraph* jsgraph() { return lowering_->jsgraph(); }
     370             :   JSOperatorBuilder* javascript() { return lowering_->javascript(); }
     371           0 :   CommonOperatorBuilder* common() { return jsgraph()->common(); }
     372      699668 :   Zone* zone() const { return graph()->zone(); }
     373             : 
     374             :  private:
     375             :   JSTypedLowering* lowering_;  // The containing lowering instance.
     376             :   Node* node_;                 // The original node.
     377             : 
     378             :   Node* CreateFrameStateForLeftInput() {
     379             :     // Deoptimization is disabled => return dummy frame state instead.
     380        2558 :     Node* dummy_state = NodeProperties::GetFrameStateInput(node_);
     381             :     DCHECK(OpParameter<FrameStateInfo>(dummy_state).bailout_id().IsNone());
     382             :     return dummy_state;
     383             :   }
     384             : 
     385             :   Node* CreateFrameStateForRightInput(Node* converted_left) {
     386             :     // Deoptimization is disabled => return dummy frame state instead.
     387         135 :     Node* dummy_state = NodeProperties::GetFrameStateInput(node_);
     388             :     DCHECK(OpParameter<FrameStateInfo>(dummy_state).bailout_id().IsNone());
     389             :     return dummy_state;
     390             :   }
     391             : 
     392      465493 :   Node* ConvertPlainPrimitiveToNumber(Node* node) {
     393             :     DCHECK(NodeProperties::GetType(node)->Is(Type::PlainPrimitive()));
     394             :     // Avoid inserting too many eager ToNumber() operations.
     395      432991 :     Reduction const reduction = lowering_->ReduceJSToNumberInput(node);
     396      432991 :     if (reduction.Changed()) return reduction.replacement();
     397       16251 :     if (NodeProperties::GetType(node)->Is(Type::Number())) {
     398             :       return node;
     399             :     }
     400       32502 :     return graph()->NewNode(simplified()->PlainPrimitiveToNumber(), node);
     401             :   }
     402             : 
     403       16158 :   Node* ConvertSingleInputToNumber(Node* node, Node* frame_state) {
     404             :     DCHECK(!NodeProperties::GetType(node)->Is(Type::PlainPrimitive()));
     405             :     Node* const n = graph()->NewNode(javascript()->ToNumber(), node, context(),
     406        2693 :                                      frame_state, effect(), control());
     407        2693 :     NodeProperties::ReplaceControlInput(node_, n);
     408             :     update_effect(n);
     409        2693 :     return n;
     410             :   }
     411             : 
     412           0 :   void ConvertBothInputsToNumber(Node** left_result, Node** right_result) {
     413             :     Node* projections[2];
     414             : 
     415             :     // Find {IfSuccess} and {IfException} continuations of the operation.
     416           0 :     NodeProperties::CollectControlProjections(node_, projections, 2);
     417           0 :     Node* if_exception = projections[1];
     418           0 :     Node* if_success = projections[0];
     419             : 
     420             :     // Insert two ToNumber() operations that both potentially throw.
     421             :     Node* left_state = CreateFrameStateForLeftInput();
     422             :     Node* left_conv =
     423             :         graph()->NewNode(javascript()->ToNumber(), left(), context(),
     424           0 :                          left_state, effect(), control());
     425           0 :     Node* left_success = graph()->NewNode(common()->IfSuccess(), left_conv);
     426             :     Node* right_state = CreateFrameStateForRightInput(left_conv);
     427             :     Node* right_conv =
     428             :         graph()->NewNode(javascript()->ToNumber(), right(), context(),
     429           0 :                          right_state, left_conv, left_success);
     430             :     Node* left_exception =
     431           0 :         graph()->NewNode(common()->IfException(), left_conv, left_conv);
     432             :     Node* right_exception =
     433           0 :         graph()->NewNode(common()->IfException(), right_conv, right_conv);
     434           0 :     NodeProperties::ReplaceControlInput(if_success, right_conv);
     435             :     update_effect(right_conv);
     436             : 
     437             :     // Wire conversions to existing {IfException} continuation.
     438             :     Node* exception_merge = if_exception;
     439             :     Node* exception_value =
     440             :         graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
     441           0 :                          left_exception, right_exception, exception_merge);
     442             :     Node* exception_effect =
     443             :         graph()->NewNode(common()->EffectPhi(2), left_exception,
     444           0 :                          right_exception, exception_merge);
     445           0 :     for (Edge edge : exception_merge->use_edges()) {
     446           0 :       if (NodeProperties::IsEffectEdge(edge)) edge.UpdateTo(exception_effect);
     447           0 :       if (NodeProperties::IsValueEdge(edge)) edge.UpdateTo(exception_value);
     448             :     }
     449             :     NodeProperties::RemoveType(exception_merge);
     450           0 :     exception_merge->ReplaceInput(0, left_exception);
     451           0 :     exception_merge->ReplaceInput(1, right_exception);
     452           0 :     NodeProperties::ChangeOp(exception_merge, common()->Merge(2));
     453             : 
     454           0 :     *left_result = left_conv;
     455           0 :     *right_result = right_conv;
     456           0 :   }
     457             : 
     458      248100 :   Node* ConvertToUI32(Node* node, Signedness signedness) {
     459             :     // Avoid introducing too many eager NumberToXXnt32() operations.
     460             :     Type* type = NodeProperties::GetType(node);
     461      138390 :     if (signedness == kSigned) {
     462      101170 :       if (!type->Is(Type::Signed32())) {
     463       41180 :         node = graph()->NewNode(simplified()->NumberToInt32(), node);
     464             :       }
     465             :     } else {
     466             :       DCHECK_EQ(kUnsigned, signedness);
     467       37220 :       if (!type->Is(Type::Unsigned32())) {
     468       13675 :         node = graph()->NewNode(simplified()->NumberToUint32(), node);
     469             :       }
     470             :     }
     471      138390 :     return node;
     472             :   }
     473             : 
     474             :   void update_effect(Node* effect) {
     475        8188 :     NodeProperties::ReplaceEffectInput(node_, effect);
     476             :   }
     477             : };
     478             : 
     479             : 
     480             : // TODO(turbofan): js-typed-lowering improvements possible
     481             : // - immediately put in type bounds for all new nodes
     482             : // - relax effects from generic but not-side-effecting operations
     483             : 
     484      418317 : JSTypedLowering::JSTypedLowering(Editor* editor,
     485             :                                  CompilationDependencies* dependencies,
     486             :                                  Flags flags, JSGraph* jsgraph, Zone* zone)
     487             :     : AdvancedReducer(editor),
     488             :       dependencies_(dependencies),
     489             :       flags_(flags),
     490             :       jsgraph_(jsgraph),
     491             :       pointer_comparable_type_(Type::Union(
     492             :           Type::Oddball(),
     493             :           Type::Union(
     494             :               Type::SymbolOrReceiver(),
     495             :               Type::HeapConstant(factory()->empty_string(), graph()->zone()),
     496             :               graph()->zone()),
     497      836634 :           graph()->zone())),
     498      836634 :       type_cache_(TypeCache::Get()) {
     499     2091585 :   for (size_t k = 0; k < arraysize(shifted_int32_ranges_); ++k) {
     500     1673268 :     double min = kMinInt / (1 << k);
     501     1673268 :     double max = kMaxInt / (1 << k);
     502     3346536 :     shifted_int32_ranges_[k] = Type::Range(min, max, graph()->zone());
     503             :   }
     504      418317 : }
     505             : 
     506      311816 : Reduction JSTypedLowering::ReduceSpeculativeNumberAdd(Node* node) {
     507             :   JSBinopReduction r(this, node);
     508      155908 :   NumberOperationHint hint = NumberOperationHintOf(node->op());
     509      207885 :   if (hint == NumberOperationHint::kNumberOrOddball &&
     510      207207 :       r.BothInputsAre(Type::PlainPrimitive()) &&
     511       51299 :       r.NeitherInputCanBe(Type::StringOrReceiver())) {
     512             :     // SpeculativeNumberAdd(x:-string, y:-string) =>
     513             :     //     NumberAdd(ToNumber(x), ToNumber(y))
     514       51299 :     r.ConvertInputsToNumber();
     515       51299 :     return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number());
     516             :   }
     517             :   return NoChange();
     518             : }
     519             : 
     520      262449 : Reduction JSTypedLowering::ReduceJSAdd(Node* node) {
     521             :   JSBinopReduction r(this, node);
     522      120613 :   if (r.BothInputsAre(Type::Number())) {
     523             :     // JSAdd(x:number, y:number) => NumberAdd(x, y)
     524       23312 :     r.ConvertInputsToNumber();
     525       23312 :     return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number());
     526             :   }
     527      254814 :   if ((r.BothInputsAre(Type::PlainPrimitive()) ||
     528      134763 :        !(flags() & kDeoptimizationEnabled)) &&
     529       37462 :       r.NeitherInputCanBe(Type::StringOrReceiver())) {
     530             :     // JSAdd(x:-string, y:-string) => NumberAdd(ToNumber(x), ToNumber(y))
     531         168 :     r.ConvertInputsToNumber();
     532         168 :     return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number());
     533             :   }
     534       97133 :   if (r.OneInputIs(Type::String())) {
     535       74259 :     if (r.ShouldCreateConsString()) {
     536        3341 :       return ReduceCreateConsString(node);
     537             :     }
     538             :     StringAddFlags flags = STRING_ADD_CHECK_NONE;
     539       70918 :     if (!r.LeftInputIs(Type::String())) {
     540             :       flags = STRING_ADD_CONVERT_LEFT;
     541       55837 :     } else if (!r.RightInputIs(Type::String())) {
     542             :       flags = STRING_ADD_CONVERT_RIGHT;
     543             :     }
     544       70918 :     Operator::Properties properties = node->op()->properties();
     545       70918 :     if (r.NeitherInputCanBe(Type::Receiver())) {
     546             :       // Both sides are already strings, so we know that the
     547             :       // string addition will not cause any observable side
     548             :       // effects; it can still throw obviously.
     549       28075 :       properties = Operator::kNoWrite | Operator::kNoDeopt;
     550             :     }
     551             :     // JSAdd(x:string, y) => CallStub[StringAdd](x, y)
     552             :     // JSAdd(x, y:string) => CallStub[StringAdd](x, y)
     553             :     Callable const callable =
     554       70918 :         CodeFactory::StringAdd(isolate(), flags, NOT_TENURED);
     555             :     CallDescriptor const* const desc = Linkage::GetStubCallDescriptor(
     556             :         isolate(), graph()->zone(), callable.descriptor(), 0,
     557      212754 :         CallDescriptor::kNeedsFrameState, properties);
     558             :     DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
     559             :     node->InsertInput(graph()->zone(), 0,
     560      141836 :                       jsgraph()->HeapConstant(callable.code()));
     561       70918 :     NodeProperties::ChangeOp(node, common()->Call(desc));
     562             :     return Changed(node);
     563             :   }
     564             :   return NoChange();
     565             : }
     566             : 
     567       88140 : Reduction JSTypedLowering::ReduceNumberBinop(Node* node) {
     568             :   JSBinopReduction r(this, node);
     569      130281 :   if (r.BothInputsAre(Type::PlainPrimitive()) ||
     570             :       !(flags() & kDeoptimizationEnabled)) {
     571       46154 :     r.ConvertInputsToNumber();
     572       46154 :     return r.ChangeToPureOperator(r.NumberOp(), Type::Number());
     573             :   }
     574             :   return NoChange();
     575             : }
     576             : 
     577      144718 : Reduction JSTypedLowering::ReduceSpeculativeNumberBinop(Node* node) {
     578             :   JSBinopReduction r(this, node);
     579       72359 :   NumberOperationHint hint = NumberOperationHintOf(node->op());
     580      110258 :   if (hint == NumberOperationHint::kNumberOrOddball &&
     581       37899 :       r.BothInputsAre(Type::NumberOrOddball())) {
     582       19000 :     r.ConvertInputsToNumber();
     583             :     return r.ChangeToPureOperator(r.NumberOpFromSpeculativeNumberOp(),
     584       19000 :                                   Type::Number());
     585             :   }
     586             :   return NoChange();
     587             : }
     588             : 
     589       44899 : Reduction JSTypedLowering::ReduceInt32Binop(Node* node) {
     590             :   JSBinopReduction r(this, node);
     591       51621 :   if (r.BothInputsAre(Type::PlainPrimitive()) ||
     592             :       !(flags() & kDeoptimizationEnabled)) {
     593       40492 :     r.ConvertInputsToNumber();
     594       40492 :     r.ConvertInputsToUI32(kSigned, kSigned);
     595       40492 :     return r.ChangeToPureOperator(r.NumberOp(), Type::Signed32());
     596             :   }
     597             :   return NoChange();
     598             : }
     599             : 
     600       30543 : Reduction JSTypedLowering::ReduceUI32Shift(Node* node, Signedness signedness) {
     601             :   JSBinopReduction r(this, node);
     602       32459 :   if (r.BothInputsAre(Type::PlainPrimitive()) ||
     603             :       !(flags() & kDeoptimizationEnabled)) {
     604       28703 :     r.ConvertInputsToNumber();
     605       28703 :     r.ConvertInputsToUI32(signedness, kUnsigned);
     606             :     return r.ChangeToPureOperator(r.NumberOp(), signedness == kUnsigned
     607             :                                                     ? Type::Unsigned32()
     608       28703 :                                                     : Type::Signed32());
     609             :   }
     610             :   return NoChange();
     611             : }
     612             : 
     613       16776 : Reduction JSTypedLowering::ReduceCreateConsString(Node* node) {
     614        3341 :   Node* first = NodeProperties::GetValueInput(node, 0);
     615        3341 :   Node* second = NodeProperties::GetValueInput(node, 1);
     616        3341 :   Node* context = NodeProperties::GetContextInput(node);
     617        3341 :   Node* frame_state = NodeProperties::GetFrameStateInput(node);
     618        3341 :   Node* effect = NodeProperties::GetEffectInput(node);
     619        3341 :   Node* control = NodeProperties::GetControlInput(node);
     620             : 
     621             :   // Make sure {first} is actually a String.
     622             :   Type* first_type = NodeProperties::GetType(first);
     623        3341 :   if (!first_type->Is(Type::String())) {
     624             :     first = effect =
     625          73 :         graph()->NewNode(simplified()->CheckString(), first, effect, control);
     626             :     first_type = NodeProperties::GetType(first);
     627             :   }
     628             : 
     629             :   // Make sure {second} is actually a String.
     630             :   Type* second_type = NodeProperties::GetType(second);
     631        3341 :   if (!second_type->Is(Type::String())) {
     632             :     second = effect =
     633          87 :         graph()->NewNode(simplified()->CheckString(), second, effect, control);
     634             :     second_type = NodeProperties::GetType(second);
     635             :   }
     636             : 
     637             :   // Determine the {first} length.
     638        3341 :   HeapObjectBinopMatcher m(node);
     639             :   Node* first_length =
     640        3661 :       (m.left().HasValue() && m.left().Value()->IsString())
     641             :           ? jsgraph()->Constant(
     642             :                 Handle<String>::cast(m.left().Value())->length())
     643             :           : effect = graph()->NewNode(
     644             :                 simplified()->LoadField(AccessBuilder::ForStringLength()),
     645       10023 :                 first, effect, control);
     646             : 
     647             :   // Determine the {second} length.
     648             :   Node* second_length =
     649        6433 :       (m.right().HasValue() && m.right().Value()->IsString())
     650             :           ? jsgraph()->Constant(
     651             :                 Handle<String>::cast(m.right().Value())->length())
     652             :           : effect = graph()->NewNode(
     653             :                 simplified()->LoadField(AccessBuilder::ForStringLength()),
     654       10023 :                 second, effect, control);
     655             : 
     656             :   // Compute the resulting length.
     657             :   Node* length =
     658        3341 :       graph()->NewNode(simplified()->NumberAdd(), first_length, second_length);
     659             : 
     660             :   // Check if we would overflow the allowed maximum string length.
     661             :   Node* check = graph()->NewNode(simplified()->NumberLessThanOrEqual(), length,
     662        6682 :                                  jsgraph()->Constant(String::kMaxLength));
     663        3341 :   if (isolate()->IsStringLengthOverflowIntact()) {
     664             :     // Add a code dependency on the string length overflow protector.
     665             :     dependencies()->AssumePropertyCell(factory()->string_length_protector());
     666             : 
     667             :     // We can just deoptimize if the {check} fails. Besides generating a
     668             :     // shorter code sequence than the version below, this has the additional
     669             :     // benefit of not holding on to the lazy {frame_state} and thus potentially
     670             :     // reduces the number of live ranges and allows for more truncations.
     671        3297 :     effect = graph()->NewNode(simplified()->CheckIf(), check, effect, control);
     672             :   } else {
     673             :     Node* branch =
     674          44 :         graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
     675          44 :     Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
     676             :     Node* efalse = effect;
     677             :     {
     678             :       // Throw a RangeError in case of overflow.
     679             :       Node* vfalse = efalse = if_false = graph()->NewNode(
     680             :           javascript()->CallRuntime(Runtime::kThrowInvalidStringLength),
     681          44 :           context, frame_state, efalse, if_false);
     682             : 
     683             :       // Update potential {IfException} uses of {node} to point to the
     684             :       // %ThrowInvalidStringLength runtime call node instead.
     685          44 :       Node* on_exception = nullptr;
     686          44 :       if (NodeProperties::IsExceptionalCall(node, &on_exception)) {
     687          18 :         NodeProperties::ReplaceControlInput(on_exception, vfalse);
     688          18 :         NodeProperties::ReplaceEffectInput(on_exception, efalse);
     689          18 :         if_false = graph()->NewNode(common()->IfSuccess(), vfalse);
     690        3403 :         Revisit(on_exception);
     691             :       }
     692             : 
     693             :       // The above %ThrowInvalidStringLength runtime call is an unconditional
     694             :       // throw, making it impossible to return a successful completion in this
     695             :       // case. We simply connect the successful completion to the graph end.
     696          44 :       if_false = graph()->NewNode(common()->Throw(), efalse, if_false);
     697             :       // TODO(bmeurer): This should be on the AdvancedReducer somehow.
     698          44 :       NodeProperties::MergeControlToEnd(graph(), common(), if_false);
     699          44 :       Revisit(graph()->end());
     700             :     }
     701          44 :     control = graph()->NewNode(common()->IfTrue(), branch);
     702             :   }
     703             : 
     704             :   // Figure out the map for the resulting ConsString.
     705             :   // TODO(turbofan): We currently just use the cons_string_map here for
     706             :   // the sake of simplicity; we could also try to be smarter here and
     707             :   // use the one_byte_cons_string_map instead when the resulting ConsString
     708             :   // contains only one byte characters.
     709        3341 :   Node* value_map = jsgraph()->HeapConstant(factory()->cons_string_map());
     710             : 
     711             :   // Allocate the resulting ConsString.
     712             :   effect = graph()->NewNode(
     713        3341 :       common()->BeginRegion(RegionObservability::kNotObservable), effect);
     714             :   Node* value = effect =
     715             :       graph()->NewNode(simplified()->Allocate(Type::OtherString(), NOT_TENURED),
     716        6682 :                        jsgraph()->Constant(ConsString::kSize), effect, control);
     717             :   effect = graph()->NewNode(simplified()->StoreField(AccessBuilder::ForMap()),
     718       10023 :                             value, value_map, effect, control);
     719             :   effect = graph()->NewNode(
     720             :       simplified()->StoreField(AccessBuilder::ForNameHashField()), value,
     721       10023 :       jsgraph()->Constant(Name::kEmptyHashField), effect, control);
     722             :   effect = graph()->NewNode(
     723             :       simplified()->StoreField(AccessBuilder::ForStringLength()), value, length,
     724       10023 :       effect, control);
     725             :   effect = graph()->NewNode(
     726             :       simplified()->StoreField(AccessBuilder::ForConsStringFirst()), value,
     727       10023 :       first, effect, control);
     728             :   effect = graph()->NewNode(
     729             :       simplified()->StoreField(AccessBuilder::ForConsStringSecond()), value,
     730       10023 :       second, effect, control);
     731             : 
     732             :   // Morph the {node} into a {FinishRegion}.
     733             :   ReplaceWithValue(node, node, node, control);
     734        3341 :   node->ReplaceInput(0, value);
     735        3341 :   node->ReplaceInput(1, effect);
     736        3341 :   node->TrimInputCount(2);
     737        3341 :   NodeProperties::ChangeOp(node, common()->FinishRegion());
     738        3341 :   return Changed(node);
     739             : }
     740             : 
     741       53880 : Reduction JSTypedLowering::ReduceSpeculativeNumberComparison(Node* node) {
     742             :   JSBinopReduction r(this, node);
     743       99081 :   if (r.BothInputsAre(Type::Signed32()) ||
     744       45201 :       r.BothInputsAre(Type::Unsigned32())) {
     745        8865 :     return r.ChangeToPureOperator(r.NumberOpFromSpeculativeNumberOp());
     746             :   }
     747             :   return Changed(node);
     748             : }
     749             : 
     750       54225 : Reduction JSTypedLowering::ReduceJSComparison(Node* node) {
     751             :   JSBinopReduction r(this, node);
     752       38228 :   if (r.BothInputsAre(Type::String())) {
     753             :     // If both inputs are definitely strings, perform a string comparison.
     754             :     const Operator* stringOp;
     755         647 :     switch (node->opcode()) {
     756             :       case IrOpcode::kJSLessThan:
     757         424 :         stringOp = simplified()->StringLessThan();
     758         424 :         break;
     759             :       case IrOpcode::kJSGreaterThan:
     760          80 :         stringOp = simplified()->StringLessThan();
     761          80 :         r.SwapInputs();  // a > b => b < a
     762          80 :         break;
     763             :       case IrOpcode::kJSLessThanOrEqual:
     764          71 :         stringOp = simplified()->StringLessThanOrEqual();
     765          71 :         break;
     766             :       case IrOpcode::kJSGreaterThanOrEqual:
     767          72 :         stringOp = simplified()->StringLessThanOrEqual();
     768          72 :         r.SwapInputs();  // a >= b => b <= a
     769          72 :         break;
     770             :       default:
     771             :         return NoChange();
     772             :     }
     773         647 :     r.ChangeToPureOperator(stringOp);
     774             :     return Changed(node);
     775             :   }
     776             : 
     777             :   const Operator* less_than;
     778             :   const Operator* less_than_or_equal;
     779       69314 :   if (r.BothInputsAre(Type::Signed32()) ||
     780       31733 :       r.BothInputsAre(Type::Unsigned32())) {
     781        6564 :     less_than = simplified()->NumberLessThan();
     782        6564 :     less_than_or_equal = simplified()->NumberLessThanOrEqual();
     783       90467 :   } else if (r.OneInputCannotBe(Type::StringOrReceiver()) &&
     784       48222 :              (r.BothInputsAre(Type::PlainPrimitive()) ||
     785             :               !(flags() & kDeoptimizationEnabled))) {
     786        8714 :     r.ConvertInputsToNumber();
     787        8714 :     less_than = simplified()->NumberLessThan();
     788        8714 :     less_than_or_equal = simplified()->NumberLessThanOrEqual();
     789       22303 :   } else if (r.IsStringCompareOperation()) {
     790          72 :     r.CheckInputsToString();
     791          72 :     less_than = simplified()->StringLessThan();
     792          72 :     less_than_or_equal = simplified()->StringLessThanOrEqual();
     793             :   } else {
     794             :     return NoChange();
     795             :   }
     796             :   const Operator* comparison;
     797       15350 :   switch (node->opcode()) {
     798             :     case IrOpcode::kJSLessThan:
     799             :       comparison = less_than;
     800             :       break;
     801             :     case IrOpcode::kJSGreaterThan:
     802             :       comparison = less_than;
     803        3572 :       r.SwapInputs();  // a > b => b < a
     804        3572 :       break;
     805             :     case IrOpcode::kJSLessThanOrEqual:
     806             :       comparison = less_than_or_equal;
     807        2079 :       break;
     808             :     case IrOpcode::kJSGreaterThanOrEqual:
     809             :       comparison = less_than_or_equal;
     810        2116 :       r.SwapInputs();  // a >= b => b <= a
     811        2116 :       break;
     812             :     default:
     813             :       return NoChange();
     814             :   }
     815       15350 :   return r.ChangeToPureOperator(comparison);
     816             : }
     817             : 
     818       43738 : Reduction JSTypedLowering::ReduceJSTypeOf(Node* node) {
     819             :   Node* const input = node->InputAt(0);
     820             :   Type* type = NodeProperties::GetType(input);
     821             :   Factory* const f = factory();
     822       31284 :   if (type->Is(Type::Boolean())) {
     823        2903 :     return Replace(jsgraph()->Constant(f->boolean_string()));
     824       28381 :   } else if (type->Is(Type::Number())) {
     825        8168 :     return Replace(jsgraph()->Constant(f->number_string()));
     826       20213 :   } else if (type->Is(Type::String())) {
     827         851 :     return Replace(jsgraph()->Constant(f->string_string()));
     828       19362 :   } else if (type->Is(Type::Symbol())) {
     829           0 :     return Replace(jsgraph()->Constant(f->symbol_string()));
     830       19362 :   } else if (type->Is(Type::OtherUndetectableOrUndefined())) {
     831         363 :     return Replace(jsgraph()->Constant(f->undefined_string()));
     832       18999 :   } else if (type->Is(Type::NonCallableOrNull())) {
     833         142 :     return Replace(jsgraph()->Constant(f->object_string()));
     834       18857 :   } else if (type->Is(Type::Function())) {
     835          27 :     return Replace(jsgraph()->Constant(f->function_string()));
     836       18830 :   } else if (type->IsHeapConstant()) {
     837             :     return Replace(jsgraph()->Constant(
     838           0 :         Object::TypeOf(isolate(), type->AsHeapConstant()->Value())));
     839             :   }
     840             : 
     841             :   return NoChange();
     842             : }
     843             : 
     844       18233 : Reduction JSTypedLowering::ReduceJSEqual(Node* node) {
     845             :   JSBinopReduction r(this, node);
     846             : 
     847       18233 :   if (r.BothInputsAre(Type::UniqueName())) {
     848        1459 :     return r.ChangeToPureOperator(simplified()->ReferenceEqual());
     849             :   }
     850       16774 :   if (r.IsInternalizedStringCompareOperation()) {
     851         103 :     r.CheckInputsToInternalizedString();
     852         103 :     return r.ChangeToPureOperator(simplified()->ReferenceEqual());
     853             :   }
     854       16671 :   if (r.BothInputsAre(Type::String())) {
     855         306 :     return r.ChangeToPureOperator(simplified()->StringEqual());
     856             :   }
     857       16365 :   if (r.BothInputsAre(Type::Boolean())) {
     858          39 :     return r.ChangeToPureOperator(simplified()->ReferenceEqual());
     859             :   }
     860       16326 :   if (r.BothInputsAre(Type::Receiver())) {
     861          20 :     return r.ChangeToPureOperator(simplified()->ReferenceEqual());
     862             :   }
     863       16306 :   if (r.OneInputIs(Type::Undetectable())) {
     864             :     RelaxEffectsAndControls(node);
     865          21 :     node->RemoveInput(r.LeftInputIs(Type::Undetectable()) ? 0 : 1);
     866          21 :     node->TrimInputCount(1);
     867          21 :     NodeProperties::ChangeOp(node, simplified()->ObjectIsUndetectable());
     868             :     return Changed(node);
     869             :   }
     870             : 
     871       26924 :   if (r.BothInputsAre(Type::Signed32()) ||
     872       10639 :       r.BothInputsAre(Type::Unsigned32())) {
     873        5704 :     return r.ChangeToPureOperator(simplified()->NumberEqual());
     874       10581 :   } else if (r.BothInputsAre(Type::Number())) {
     875         951 :     return r.ChangeToPureOperator(simplified()->NumberEqual());
     876        9630 :   } else if (r.IsReceiverCompareOperation()) {
     877         204 :     r.CheckInputsToReceiver();
     878         204 :     return r.ChangeToPureOperator(simplified()->ReferenceEqual());
     879        9426 :   } else if (r.IsStringCompareOperation()) {
     880          20 :     r.CheckInputsToString();
     881          20 :     return r.ChangeToPureOperator(simplified()->StringEqual());
     882             :   }
     883             :   return NoChange();
     884             : }
     885             : 
     886      241521 : Reduction JSTypedLowering::ReduceJSStrictEqual(Node* node) {
     887             :   JSBinopReduction r(this, node);
     888      482662 :   if (r.left() == r.right()) {
     889             :     // x === x is always true if x != NaN
     890             :     Node* replacement = graph()->NewNode(
     891             :         simplified()->BooleanNot(),
     892       25299 :         graph()->NewNode(simplified()->ObjectIsNaN(), r.left()));
     893        8623 :     ReplaceWithValue(node, replacement);
     894             :     return Replace(replacement);
     895             :   }
     896      232898 :   if (r.OneInputCannotBe(Type::NumberOrString())) {
     897             :     // For values with canonical representation (i.e. neither String, nor
     898             :     // Number) an empty type intersection means the values cannot be strictly
     899             :     // equal.
     900        4554 :     if (!r.left_type()->Maybe(r.right_type())) {
     901         190 :       Node* replacement = jsgraph()->FalseConstant();
     902             :       ReplaceWithValue(node, replacement);
     903             :       return Replace(replacement);
     904             :     }
     905             :   }
     906             : 
     907      232708 :   if (r.BothInputsAre(Type::Unique())) {
     908       15141 :     return r.ChangeToPureOperator(simplified()->ReferenceEqual());
     909             :   }
     910      217567 :   if (r.OneInputIs(pointer_comparable_type_)) {
     911        1556 :     return r.ChangeToPureOperator(simplified()->ReferenceEqual());
     912             :   }
     913      216011 :   if (r.IsInternalizedStringCompareOperation()) {
     914        4153 :     r.CheckInputsToInternalizedString();
     915        4153 :     return r.ChangeToPureOperator(simplified()->ReferenceEqual());
     916             :   }
     917      211858 :   if (r.BothInputsAre(Type::String())) {
     918        1398 :     return r.ChangeToPureOperator(simplified()->StringEqual());
     919             :   }
     920             : 
     921             :   NumberOperationHint hint;
     922      361349 :   if (r.BothInputsAre(Type::Signed32()) ||
     923      150889 :       r.BothInputsAre(Type::Unsigned32())) {
     924       59726 :     return r.ChangeToPureOperator(simplified()->NumberEqual());
     925      150734 :   } else if (r.GetCompareNumberOperationHint(&hint)) {
     926             :     return r.ChangeToSpeculativeOperator(
     927       32122 :         simplified()->SpeculativeNumberEqual(hint), Type::Boolean());
     928      134673 :   } else if (r.BothInputsAre(Type::Number())) {
     929        8350 :     return r.ChangeToPureOperator(simplified()->NumberEqual());
     930      126323 :   } else if (r.IsReceiverCompareOperation()) {
     931             :     // For strict equality, it's enough to know that one input is a Receiver,
     932             :     // as a strict equality comparison with a Receiver can only yield true if
     933             :     // both sides refer to the same Receiver than.
     934         183 :     r.CheckLeftInputToReceiver();
     935         183 :     return r.ChangeToPureOperator(simplified()->ReferenceEqual());
     936      126140 :   } else if (r.IsStringCompareOperation()) {
     937         470 :     r.CheckInputsToString();
     938         470 :     return r.ChangeToPureOperator(simplified()->StringEqual());
     939             :   }
     940             :   return NoChange();
     941             : }
     942             : 
     943      113502 : Reduction JSTypedLowering::ReduceJSToBoolean(Node* node) {
     944             :   Node* const input = node->InputAt(0);
     945             :   Type* const input_type = NodeProperties::GetType(input);
     946      112618 :   if (input_type->Is(Type::Boolean())) {
     947             :     // JSToBoolean(x:boolean) => x
     948             :     return Replace(input);
     949       74391 :   } else if (input_type->Is(Type::OrderedNumber())) {
     950             :     // JSToBoolean(x:ordered-number) => BooleanNot(NumberEqual(x,#0))
     951             :     node->ReplaceInput(0, graph()->NewNode(simplified()->NumberEqual(), input,
     952        2610 :                                            jsgraph()->ZeroConstant()));
     953         870 :     node->TrimInputCount(1);
     954         870 :     NodeProperties::ChangeOp(node, simplified()->BooleanNot());
     955             :     return Changed(node);
     956       73521 :   } else if (input_type->Is(Type::Number())) {
     957             :     // JSToBoolean(x:number) => NumberToBoolean(x)
     958         253 :     node->TrimInputCount(1);
     959         253 :     NodeProperties::ChangeOp(node, simplified()->NumberToBoolean());
     960             :     return Changed(node);
     961       73268 :   } else if (input_type->Is(Type::DetectableReceiverOrNull())) {
     962             :     // JSToBoolean(x:detectable receiver \/ null)
     963             :     //   => BooleanNot(ReferenceEqual(x,#null))
     964             :     node->ReplaceInput(0, graph()->NewNode(simplified()->ReferenceEqual(),
     965          21 :                                            input, jsgraph()->NullConstant()));
     966           7 :     node->TrimInputCount(1);
     967           7 :     NodeProperties::ChangeOp(node, simplified()->BooleanNot());
     968             :     return Changed(node);
     969       73261 :   } else if (input_type->Is(Type::ReceiverOrNullOrUndefined())) {
     970             :     // JSToBoolean(x:receiver \/ null \/ undefined)
     971             :     //   => BooleanNot(ObjectIsUndetectable(x))
     972             :     node->ReplaceInput(
     973         124 :         0, graph()->NewNode(simplified()->ObjectIsUndetectable(), input));
     974          62 :     node->TrimInputCount(1);
     975          62 :     NodeProperties::ChangeOp(node, simplified()->BooleanNot());
     976             :     return Changed(node);
     977       73199 :   } else if (input_type->Is(Type::String())) {
     978             :     // JSToBoolean(x:string) => BooleanNot(ReferenceEqual(x,""))
     979             :     node->ReplaceInput(0,
     980             :                        graph()->NewNode(simplified()->ReferenceEqual(), input,
     981          21 :                                         jsgraph()->EmptyStringConstant()));
     982           7 :     node->TrimInputCount(1);
     983           7 :     NodeProperties::ChangeOp(node, simplified()->BooleanNot());
     984             :     return Changed(node);
     985             :   }
     986             :   return NoChange();
     987             : }
     988             : 
     989         271 : Reduction JSTypedLowering::ReduceJSToInteger(Node* node) {
     990         271 :   Node* const input = NodeProperties::GetValueInput(node, 0);
     991             :   Type* const input_type = NodeProperties::GetType(input);
     992         542 :   if (input_type->Is(type_cache_.kIntegerOrMinusZero)) {
     993             :     // JSToInteger(x:integer) => x
     994           0 :     ReplaceWithValue(node, input);
     995             :     return Replace(input);
     996             :   }
     997             :   return NoChange();
     998             : }
     999             : 
    1000        1531 : Reduction JSTypedLowering::ReduceJSToName(Node* node) {
    1001        1531 :   Node* const input = NodeProperties::GetValueInput(node, 0);
    1002             :   Type* const input_type = NodeProperties::GetType(input);
    1003        1531 :   if (input_type->Is(Type::Name())) {
    1004             :     // JSToName(x:name) => x
    1005         167 :     ReplaceWithValue(node, input);
    1006             :     return Replace(input);
    1007             :   }
    1008             :   return NoChange();
    1009             : }
    1010             : 
    1011         281 : Reduction JSTypedLowering::ReduceJSToLength(Node* node) {
    1012         257 :   Node* input = NodeProperties::GetValueInput(node, 0);
    1013             :   Type* input_type = NodeProperties::GetType(input);
    1014         514 :   if (input_type->Is(type_cache_.kIntegerOrMinusZero)) {
    1015          24 :     if (input_type->Max() <= 0.0) {
    1016           4 :       input = jsgraph()->ZeroConstant();
    1017          20 :     } else if (input_type->Min() >= kMaxSafeInteger) {
    1018           4 :       input = jsgraph()->Constant(kMaxSafeInteger);
    1019             :     } else {
    1020          16 :       if (input_type->Min() <= 0.0) {
    1021             :         input = graph()->NewNode(simplified()->NumberMax(),
    1022          32 :                                  jsgraph()->ZeroConstant(), input);
    1023             :       }
    1024          16 :       if (input_type->Max() > kMaxSafeInteger) {
    1025             :         input = graph()->NewNode(simplified()->NumberMin(),
    1026           0 :                                  jsgraph()->Constant(kMaxSafeInteger), input);
    1027             :       }
    1028             :     }
    1029          24 :     ReplaceWithValue(node, input);
    1030             :     return Replace(input);
    1031             :   }
    1032             :   return NoChange();
    1033             : }
    1034             : 
    1035      444868 : Reduction JSTypedLowering::ReduceJSToNumberInput(Node* input) {
    1036             :   // Try constant-folding of JSToNumber with constant inputs.
    1037             :   Type* input_type = NodeProperties::GetType(input);
    1038      440160 :   if (input_type->Is(Type::String())) {
    1039             :     HeapObjectMatcher m(input);
    1040        2807 :     if (m.HasValue() && m.Value()->IsString()) {
    1041             :       Handle<Object> input_value = m.Value();
    1042             :       return Replace(jsgraph()->Constant(
    1043        1360 :           String::ToNumber(Handle<String>::cast(input_value))));
    1044             :     }
    1045             :   }
    1046      439480 :   if (input_type->IsHeapConstant()) {
    1047             :     Handle<Object> input_value = input_type->AsHeapConstant()->Value();
    1048        1732 :     if (input_value->IsOddball()) {
    1049             :       return Replace(jsgraph()->Constant(
    1050        3464 :           Oddball::ToNumber(Handle<Oddball>::cast(input_value))));
    1051             :     }
    1052             :   }
    1053      437748 :   if (input_type->Is(Type::Number())) {
    1054             :     // JSToNumber(x:number) => x
    1055             :     return Changed(input);
    1056             :   }
    1057       23984 :   if (input_type->Is(Type::Undefined())) {
    1058             :     // JSToNumber(undefined) => #NaN
    1059        1148 :     return Replace(jsgraph()->NaNConstant());
    1060             :   }
    1061       22836 :   if (input_type->Is(Type::Null())) {
    1062             :     // JSToNumber(null) => #0
    1063        1148 :     return Replace(jsgraph()->ZeroConstant());
    1064             :   }
    1065             :   return NoChange();
    1066             : }
    1067             : 
    1068        6497 : Reduction JSTypedLowering::ReduceJSToNumber(Node* node) {
    1069             :   // Try to reduce the input first.
    1070             :   Node* const input = node->InputAt(0);
    1071        6497 :   Reduction reduction = ReduceJSToNumberInput(input);
    1072        6497 :   if (reduction.Changed()) {
    1073        1684 :     ReplaceWithValue(node, reduction.replacement());
    1074        1684 :     return reduction;
    1075             :   }
    1076             :   Type* const input_type = NodeProperties::GetType(input);
    1077        4813 :   if (input_type->Is(Type::PlainPrimitive())) {
    1078             :     RelaxEffectsAndControls(node);
    1079          64 :     node->TrimInputCount(1);
    1080          64 :     NodeProperties::ChangeOp(node, simplified()->PlainPrimitiveToNumber());
    1081             :     return Changed(node);
    1082             :   }
    1083             :   return NoChange();
    1084             : }
    1085             : 
    1086        2380 : Reduction JSTypedLowering::ReduceJSToStringInput(Node* input) {
    1087        2380 :   if (input->opcode() == IrOpcode::kJSToString) {
    1088             :     // Recursively try to reduce the input first.
    1089           0 :     Reduction result = ReduceJSToString(input);
    1090           0 :     if (result.Changed()) return result;
    1091             :     return Changed(input);  // JSToString(JSToString(x)) => JSToString(x)
    1092             :   }
    1093             :   Type* input_type = NodeProperties::GetType(input);
    1094        2380 :   if (input_type->Is(Type::String())) {
    1095             :     return Changed(input);  // JSToString(x:string) => x
    1096             :   }
    1097        2340 :   if (input_type->Is(Type::Boolean())) {
    1098             :     return Replace(graph()->NewNode(
    1099             :         common()->Select(MachineRepresentation::kTagged), input,
    1100             :         jsgraph()->HeapConstant(factory()->true_string()),
    1101          56 :         jsgraph()->HeapConstant(factory()->false_string())));
    1102             :   }
    1103        2326 :   if (input_type->Is(Type::Undefined())) {
    1104          16 :     return Replace(jsgraph()->HeapConstant(factory()->undefined_string()));
    1105             :   }
    1106        2310 :   if (input_type->Is(Type::Null())) {
    1107          16 :     return Replace(jsgraph()->HeapConstant(factory()->null_string()));
    1108             :   }
    1109             :   // TODO(turbofan): js-typed-lowering of ToString(x:number)
    1110             :   return NoChange();
    1111             : }
    1112             : 
    1113        2380 : Reduction JSTypedLowering::ReduceJSToString(Node* node) {
    1114             :   // Try to reduce the input first.
    1115             :   Node* const input = node->InputAt(0);
    1116        2380 :   Reduction reduction = ReduceJSToStringInput(input);
    1117        2380 :   if (reduction.Changed()) {
    1118          86 :     ReplaceWithValue(node, reduction.replacement());
    1119          86 :     return reduction;
    1120             :   }
    1121             :   return NoChange();
    1122             : }
    1123             : 
    1124        5109 : Reduction JSTypedLowering::ReduceJSToObject(Node* node) {
    1125             :   DCHECK_EQ(IrOpcode::kJSToObject, node->opcode());
    1126        2433 :   Node* receiver = NodeProperties::GetValueInput(node, 0);
    1127             :   Type* receiver_type = NodeProperties::GetType(receiver);
    1128        2433 :   Node* context = NodeProperties::GetContextInput(node);
    1129        2433 :   Node* frame_state = NodeProperties::GetFrameStateInput(node);
    1130        2433 :   Node* effect = NodeProperties::GetEffectInput(node);
    1131        2433 :   Node* control = NodeProperties::GetControlInput(node);
    1132        2433 :   if (receiver_type->Is(Type::Receiver())) {
    1133        2392 :     ReplaceWithValue(node, receiver, effect, control);
    1134             :     return Replace(receiver);
    1135             :   }
    1136             : 
    1137             :   // TODO(bmeurer/mstarzinger): Add support for lowering inside try blocks.
    1138        2719 :   if (receiver_type->Maybe(Type::NullOrUndefined()) &&
    1139        1340 :       NodeProperties::IsExceptionalCall(node)) {
    1140             :     // ToObject throws for null or undefined inputs.
    1141             :     return NoChange();
    1142             :   }
    1143             : 
    1144             :   // Check whether {receiver} is a spec object.
    1145        1338 :   Node* check = graph()->NewNode(simplified()->ObjectIsReceiver(), receiver);
    1146             :   Node* branch =
    1147        1338 :       graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
    1148             : 
    1149        1338 :   Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
    1150             :   Node* etrue = effect;
    1151             :   Node* rtrue = receiver;
    1152             : 
    1153        1338 :   Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
    1154             :   Node* efalse = effect;
    1155             :   Node* rfalse;
    1156             :   {
    1157             :     // Convert {receiver} using the ToObjectStub.
    1158        1338 :     Callable callable = CodeFactory::ToObject(isolate());
    1159             :     CallDescriptor const* const desc = Linkage::GetStubCallDescriptor(
    1160             :         isolate(), graph()->zone(), callable.descriptor(), 0,
    1161        4014 :         CallDescriptor::kNeedsFrameState, node->op()->properties());
    1162             :     rfalse = efalse = if_false = graph()->NewNode(
    1163             :         common()->Call(desc), jsgraph()->HeapConstant(callable.code()),
    1164        4014 :         receiver, context, frame_state, efalse, if_false);
    1165             :   }
    1166             : 
    1167        1338 :   control = graph()->NewNode(common()->Merge(2), if_true, if_false);
    1168        1338 :   effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
    1169             : 
    1170             :   // Morph the {node} into an appropriate Phi.
    1171             :   ReplaceWithValue(node, node, effect, control);
    1172        1338 :   node->ReplaceInput(0, rtrue);
    1173        1338 :   node->ReplaceInput(1, rfalse);
    1174        1338 :   node->ReplaceInput(2, control);
    1175        1338 :   node->TrimInputCount(3);
    1176             :   NodeProperties::ChangeOp(node,
    1177        1338 :                            common()->Phi(MachineRepresentation::kTagged, 2));
    1178             :   return Changed(node);
    1179             : }
    1180             : 
    1181      701918 : Reduction JSTypedLowering::ReduceJSLoadNamed(Node* node) {
    1182             :   DCHECK_EQ(IrOpcode::kJSLoadNamed, node->opcode());
    1183      350959 :   Node* receiver = NodeProperties::GetValueInput(node, 0);
    1184             :   Type* receiver_type = NodeProperties::GetType(receiver);
    1185      350959 :   Node* effect = NodeProperties::GetEffectInput(node);
    1186      350959 :   Node* control = NodeProperties::GetControlInput(node);
    1187      350959 :   Handle<Name> name = NamedAccessOf(node->op()).name();
    1188             :   // Optimize "length" property of strings.
    1189      382018 :   if (name.is_identical_to(factory()->length_string()) &&
    1190             :       receiver_type->Is(Type::String())) {
    1191             :     Node* value = effect = graph()->NewNode(
    1192             :         simplified()->LoadField(AccessBuilder::ForStringLength()), receiver,
    1193         489 :         effect, control);
    1194         163 :     ReplaceWithValue(node, value, effect);
    1195             :     return Replace(value);
    1196             :   }
    1197             :   return NoChange();
    1198             : }
    1199             : 
    1200       78274 : Reduction JSTypedLowering::ReduceJSLoadProperty(Node* node) {
    1201       59116 :   Node* key = NodeProperties::GetValueInput(node, 1);
    1202       59116 :   Node* base = NodeProperties::GetValueInput(node, 0);
    1203             :   Type* key_type = NodeProperties::GetType(key);
    1204             :   HeapObjectMatcher mbase(base);
    1205       69660 :   if (mbase.HasValue() && mbase.Value()->IsJSTypedArray()) {
    1206             :     Handle<JSTypedArray> const array =
    1207             :         Handle<JSTypedArray>::cast(mbase.Value());
    1208       14314 :     if (!array->GetBuffer()->was_neutered()) {
    1209       14314 :       array->GetBuffer()->set_is_neuterable(false);
    1210        7157 :       BufferAccess const access(array->type());
    1211             :       size_t const k =
    1212        7157 :           ElementSizeLog2Of(access.machine_type().representation());
    1213             :       double const byte_length = array->byte_length()->Number();
    1214        7157 :       CHECK_LT(k, arraysize(shifted_int32_ranges_));
    1215       14314 :       if (key_type->Is(shifted_int32_ranges_[k]) && byte_length <= kMaxInt) {
    1216             :         // JSLoadProperty(typed-array, int32)
    1217             :         Handle<FixedTypedArrayBase> elements =
    1218             :             Handle<FixedTypedArrayBase>::cast(handle(array->elements()));
    1219             :         Node* buffer = jsgraph()->PointerConstant(elements->external_pointer());
    1220        7018 :         Node* length = jsgraph()->Constant(byte_length);
    1221        7018 :         Node* effect = NodeProperties::GetEffectInput(node);
    1222        7018 :         Node* control = NodeProperties::GetControlInput(node);
    1223             :         // Check if we can avoid the bounds check.
    1224        8307 :         if (key_type->Min() >= 0 && key_type->Max() < array->length_value()) {
    1225             :           Node* load = graph()->NewNode(
    1226             :               simplified()->LoadElement(
    1227        1213 :                   AccessBuilder::ForTypedArrayElement(array->type(), true)),
    1228        3639 :               buffer, key, effect, control);
    1229        7018 :           ReplaceWithValue(node, load, load);
    1230             :           return Replace(load);
    1231             :         }
    1232             :         // Compute byte offset.
    1233             :         Node* offset =
    1234             :             (k == 0) ? key : graph()->NewNode(
    1235             :                                  simplified()->NumberShiftLeft(), key,
    1236       16049 :                                  jsgraph()->Constant(static_cast<double>(k)));
    1237             :         Node* load = graph()->NewNode(simplified()->LoadBuffer(access), buffer,
    1238        5805 :                                       offset, length, effect, control);
    1239             :         ReplaceWithValue(node, load, load);
    1240             :         return Replace(load);
    1241             :       }
    1242             :     }
    1243             :   }
    1244             :   return NoChange();
    1245             : }
    1246             : 
    1247       47096 : Reduction JSTypedLowering::ReduceJSStoreProperty(Node* node) {
    1248       33863 :   Node* key = NodeProperties::GetValueInput(node, 1);
    1249       33863 :   Node* base = NodeProperties::GetValueInput(node, 0);
    1250       33863 :   Node* value = NodeProperties::GetValueInput(node, 2);
    1251             :   Type* key_type = NodeProperties::GetType(key);
    1252             :   Type* value_type = NodeProperties::GetType(value);
    1253             : 
    1254       33863 :   if (!value_type->Is(Type::PlainPrimitive())) return NoChange();
    1255             : 
    1256             :   HeapObjectMatcher mbase(base);
    1257       18167 :   if (mbase.HasValue() && mbase.Value()->IsJSTypedArray()) {
    1258             :     Handle<JSTypedArray> const array =
    1259             :         Handle<JSTypedArray>::cast(mbase.Value());
    1260       10416 :     if (!array->GetBuffer()->was_neutered()) {
    1261       10416 :       array->GetBuffer()->set_is_neuterable(false);
    1262        5208 :       BufferAccess const access(array->type());
    1263             :       size_t const k =
    1264        5208 :           ElementSizeLog2Of(access.machine_type().representation());
    1265             :       double const byte_length = array->byte_length()->Number();
    1266        5208 :       CHECK_LT(k, arraysize(shifted_int32_ranges_));
    1267       10302 :       if (access.external_array_type() != kExternalUint8ClampedArray &&
    1268       10046 :           key_type->Is(shifted_int32_ranges_[k]) && byte_length <= kMaxInt) {
    1269             :         // JSLoadProperty(typed-array, int32)
    1270             :         Handle<FixedTypedArrayBase> elements =
    1271             :             Handle<FixedTypedArrayBase>::cast(handle(array->elements()));
    1272             :         Node* buffer = jsgraph()->PointerConstant(elements->external_pointer());
    1273        4838 :         Node* length = jsgraph()->Constant(byte_length);
    1274        4838 :         Node* effect = NodeProperties::GetEffectInput(node);
    1275        4838 :         Node* control = NodeProperties::GetControlInput(node);
    1276             :         // Convert to a number first.
    1277        4838 :         if (!value_type->Is(Type::Number())) {
    1278         672 :           Reduction number_reduction = ReduceJSToNumberInput(value);
    1279         672 :           if (number_reduction.Changed()) {
    1280             :             value = number_reduction.replacement();
    1281             :           } else {
    1282             :             value =
    1283         624 :                 graph()->NewNode(simplified()->PlainPrimitiveToNumber(), value);
    1284             :           }
    1285             :         }
    1286             :         // Check if we can avoid the bounds check.
    1287        5735 :         if (key_type->Min() >= 0 && key_type->Max() < array->length_value()) {
    1288             :           RelaxControls(node);
    1289         844 :           node->ReplaceInput(0, buffer);
    1290             :           DCHECK_EQ(key, node->InputAt(1));
    1291         844 :           node->ReplaceInput(2, value);
    1292         844 :           node->ReplaceInput(3, effect);
    1293         844 :           node->ReplaceInput(4, control);
    1294         844 :           node->TrimInputCount(5);
    1295             :           NodeProperties::ChangeOp(
    1296             :               node,
    1297             :               simplified()->StoreElement(
    1298        1688 :                   AccessBuilder::ForTypedArrayElement(array->type(), true)));
    1299             :           return Changed(node);
    1300             :         }
    1301             :         // Compute byte offset.
    1302             :         Node* offset =
    1303             :             (k == 0) ? key : graph()->NewNode(
    1304             :                                  simplified()->NumberShiftLeft(), key,
    1305       11108 :                                  jsgraph()->Constant(static_cast<double>(k)));
    1306             :         // Turn into a StoreBuffer operation.
    1307             :         RelaxControls(node);
    1308        3994 :         node->ReplaceInput(0, buffer);
    1309        3994 :         node->ReplaceInput(1, offset);
    1310        3994 :         node->ReplaceInput(2, length);
    1311        3994 :         node->ReplaceInput(3, value);
    1312        3994 :         node->ReplaceInput(4, effect);
    1313        3994 :         node->ReplaceInput(5, control);
    1314        3994 :         node->TrimInputCount(6);
    1315        3994 :         NodeProperties::ChangeOp(node, simplified()->StoreBuffer(access));
    1316             :         return Changed(node);
    1317             :       }
    1318             :     }
    1319             :   }
    1320             :   return NoChange();
    1321             : }
    1322             : 
    1323          88 : Reduction JSTypedLowering::ReduceJSOrdinaryHasInstance(Node* node) {
    1324             :   DCHECK_EQ(IrOpcode::kJSOrdinaryHasInstance, node->opcode());
    1325          64 :   Node* constructor = NodeProperties::GetValueInput(node, 0);
    1326             :   Type* constructor_type = NodeProperties::GetType(constructor);
    1327          64 :   Node* object = NodeProperties::GetValueInput(node, 1);
    1328             :   Type* object_type = NodeProperties::GetType(object);
    1329             : 
    1330             :   // Check if the {constructor} cannot be callable.
    1331             :   // See ES6 section 7.3.19 OrdinaryHasInstance ( C, O ) step 1.
    1332          64 :   if (!constructor_type->Maybe(Type::Callable())) {
    1333           8 :     Node* value = jsgraph()->FalseConstant();
    1334          24 :     ReplaceWithValue(node, value);
    1335             :     return Replace(value);
    1336             :   }
    1337             : 
    1338             :   // If the {constructor} cannot be a JSBoundFunction and then {object}
    1339             :   // cannot be a JSReceiver, then this can be constant-folded to false.
    1340             :   // See ES6 section 7.3.19 OrdinaryHasInstance ( C, O ) step 2 and 3.
    1341          72 :   if (!object_type->Maybe(Type::Receiver()) &&
    1342          16 :       !constructor_type->Maybe(Type::BoundFunction())) {
    1343          16 :     Node* value = jsgraph()->FalseConstant();
    1344             :     ReplaceWithValue(node, value);
    1345             :     return Replace(value);
    1346             :   }
    1347             : 
    1348             :   return NoChange();
    1349             : }
    1350             : 
    1351     1184630 : Reduction JSTypedLowering::ReduceJSLoadContext(Node* node) {
    1352             :   DCHECK_EQ(IrOpcode::kJSLoadContext, node->opcode());
    1353     1779262 :   ContextAccess const& access = ContextAccessOf(node->op());
    1354      592315 :   Node* effect = NodeProperties::GetEffectInput(node);
    1355      592315 :   Node* context = NodeProperties::GetContextInput(node);
    1356      592315 :   Node* control = graph()->start();
    1357     1189264 :   for (size_t i = 0; i < access.depth(); ++i) {
    1358             :     context = effect = graph()->NewNode(
    1359             :         simplified()->LoadField(
    1360             :             AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX)),
    1361        6951 :         context, effect, control);
    1362             :   }
    1363      592315 :   node->ReplaceInput(0, context);
    1364      592315 :   node->ReplaceInput(1, effect);
    1365      592315 :   node->AppendInput(jsgraph()->zone(), control);
    1366             :   NodeProperties::ChangeOp(
    1367             :       node,
    1368     1184630 :       simplified()->LoadField(AccessBuilder::ForContextSlot(access.index())));
    1369      592315 :   return Changed(node);
    1370             : }
    1371             : 
    1372      156349 : Reduction JSTypedLowering::ReduceJSStoreContext(Node* node) {
    1373             :   DCHECK_EQ(IrOpcode::kJSStoreContext, node->opcode());
    1374      469099 :   ContextAccess const& access = ContextAccessOf(node->op());
    1375      156349 :   Node* effect = NodeProperties::GetEffectInput(node);
    1376      156349 :   Node* context = NodeProperties::GetContextInput(node);
    1377      156349 :   Node* control = graph()->start();
    1378      156349 :   Node* value = NodeProperties::GetValueInput(node, 0);
    1379      312802 :   for (size_t i = 0; i < access.depth(); ++i) {
    1380             :     context = effect = graph()->NewNode(
    1381             :         simplified()->LoadField(
    1382             :             AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX)),
    1383         156 :         context, effect, control);
    1384             :   }
    1385      156349 :   node->ReplaceInput(0, context);
    1386      156349 :   node->ReplaceInput(1, value);
    1387      156349 :   node->ReplaceInput(2, effect);
    1388             :   NodeProperties::ChangeOp(
    1389             :       node,
    1390      312698 :       simplified()->StoreField(AccessBuilder::ForContextSlot(access.index())));
    1391      156349 :   return Changed(node);
    1392             : }
    1393             : 
    1394         406 : Reduction JSTypedLowering::ReduceJSLoadModule(Node* node) {
    1395             :   DCHECK_EQ(IrOpcode::kJSLoadModule, node->opcode());
    1396         406 :   Node* effect = NodeProperties::GetEffectInput(node);
    1397         406 :   Node* control = NodeProperties::GetControlInput(node);
    1398             : 
    1399         406 :   int32_t cell_index = OpParameter<int32_t>(node);
    1400         406 :   Node* module = NodeProperties::GetValueInput(node, 0);
    1401             : 
    1402             :   Node* array;
    1403             :   int index;
    1404         406 :   if (ModuleDescriptor::GetCellIndexKind(cell_index) ==
    1405             :       ModuleDescriptor::kExport) {
    1406             :     array = effect = graph()->NewNode(
    1407             :         simplified()->LoadField(AccessBuilder::ForModuleRegularExports()),
    1408         702 :         module, effect, control);
    1409         234 :     index = cell_index - 1;
    1410             :   } else {
    1411             :     DCHECK_EQ(ModuleDescriptor::GetCellIndexKind(cell_index),
    1412             :               ModuleDescriptor::kImport);
    1413             :     array = effect = graph()->NewNode(
    1414             :         simplified()->LoadField(AccessBuilder::ForModuleRegularImports()),
    1415         516 :         module, effect, control);
    1416         172 :     index = -cell_index - 1;
    1417             :   }
    1418             : 
    1419             :   Node* cell = effect = graph()->NewNode(
    1420             :       simplified()->LoadField(AccessBuilder::ForFixedArraySlot(index)), array,
    1421        1218 :       effect, control);
    1422             : 
    1423             :   Node* value = effect =
    1424             :       graph()->NewNode(simplified()->LoadField(AccessBuilder::ForCellValue()),
    1425        1218 :                        cell, effect, control);
    1426             : 
    1427         406 :   ReplaceWithValue(node, value, effect, control);
    1428         406 :   return Changed(value);
    1429             : }
    1430             : 
    1431         486 : Reduction JSTypedLowering::ReduceJSStoreModule(Node* node) {
    1432             :   DCHECK_EQ(IrOpcode::kJSStoreModule, node->opcode());
    1433         486 :   Node* effect = NodeProperties::GetEffectInput(node);
    1434         486 :   Node* control = NodeProperties::GetControlInput(node);
    1435             : 
    1436         486 :   int32_t cell_index = OpParameter<int32_t>(node);
    1437         486 :   Node* module = NodeProperties::GetValueInput(node, 0);
    1438         486 :   Node* value = NodeProperties::GetValueInput(node, 1);
    1439             : 
    1440             :   Node* array;
    1441             :   int index;
    1442         486 :   if (ModuleDescriptor::GetCellIndexKind(cell_index) ==
    1443             :       ModuleDescriptor::kExport) {
    1444             :     array = effect = graph()->NewNode(
    1445             :         simplified()->LoadField(AccessBuilder::ForModuleRegularExports()),
    1446        1458 :         module, effect, control);
    1447         486 :     index = cell_index - 1;
    1448             :   } else {
    1449             :     DCHECK_EQ(ModuleDescriptor::GetCellIndexKind(cell_index),
    1450             :               ModuleDescriptor::kImport);
    1451             :     array = effect = graph()->NewNode(
    1452             :         simplified()->LoadField(AccessBuilder::ForModuleRegularImports()),
    1453           0 :         module, effect, control);
    1454           0 :     index = -cell_index - 1;
    1455             :   }
    1456             : 
    1457             :   Node* cell = effect = graph()->NewNode(
    1458             :       simplified()->LoadField(AccessBuilder::ForFixedArraySlot(index)), array,
    1459        1458 :       effect, control);
    1460             : 
    1461             :   effect =
    1462             :       graph()->NewNode(simplified()->StoreField(AccessBuilder::ForCellValue()),
    1463        1458 :                        cell, value, effect, control);
    1464             : 
    1465         486 :   ReplaceWithValue(node, effect, effect, control);
    1466         486 :   return Changed(value);
    1467             : }
    1468             : 
    1469      151993 : Reduction JSTypedLowering::ReduceJSConvertReceiver(Node* node) {
    1470             :   DCHECK_EQ(IrOpcode::kJSConvertReceiver, node->opcode());
    1471      119027 :   ConvertReceiverMode mode = ConvertReceiverModeOf(node->op());
    1472      119027 :   Node* receiver = NodeProperties::GetValueInput(node, 0);
    1473             :   Type* receiver_type = NodeProperties::GetType(receiver);
    1474      119027 :   Node* context = NodeProperties::GetContextInput(node);
    1475             :   Type* context_type = NodeProperties::GetType(context);
    1476      119027 :   Node* effect = NodeProperties::GetEffectInput(node);
    1477      119027 :   Node* control = NodeProperties::GetControlInput(node);
    1478             : 
    1479             :   // Check if {receiver} is known to be a receiver.
    1480      119027 :   if (receiver_type->Is(Type::Receiver())) {
    1481      119027 :     ReplaceWithValue(node, receiver, effect, control);
    1482             :     return Replace(receiver);
    1483             :   }
    1484             : 
    1485             :   // If the {receiver} is known to be null or undefined, we can just replace it
    1486             :   // with the global proxy unconditionally.
    1487      119009 :   if (receiver_type->Is(Type::NullOrUndefined()) ||
    1488             :       mode == ConvertReceiverMode::kNullOrUndefined) {
    1489      117276 :     if (context_type->IsHeapConstant()) {
    1490             :       Handle<JSObject> global_proxy(
    1491             :           Handle<Context>::cast(context_type->AsHeapConstant()->Value())
    1492             :               ->global_proxy(),
    1493       29377 :           isolate());
    1494       29377 :       receiver = jsgraph()->Constant(global_proxy);
    1495             :     } else {
    1496             :       Node* native_context = effect = graph()->NewNode(
    1497             :           javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true),
    1498       87899 :           context, effect);
    1499             :       receiver = effect = graph()->NewNode(
    1500             :           javascript()->LoadContext(0, Context::GLOBAL_PROXY_INDEX, true),
    1501       87899 :           native_context, effect);
    1502             :     }
    1503             :     ReplaceWithValue(node, receiver, effect, control);
    1504             :     return Replace(receiver);
    1505             :   }
    1506             : 
    1507             :   // If {receiver} cannot be null or undefined we can skip a few checks.
    1508        1733 :   if (!receiver_type->Maybe(Type::NullOrUndefined()) ||
    1509             :       mode == ConvertReceiverMode::kNotNullOrUndefined) {
    1510        1684 :     Node* check = graph()->NewNode(simplified()->ObjectIsReceiver(), receiver);
    1511             :     Node* branch =
    1512        1684 :         graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
    1513             : 
    1514        1684 :     Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
    1515             :     Node* etrue = effect;
    1516             :     Node* rtrue = receiver;
    1517             : 
    1518        1684 :     Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
    1519             :     Node* efalse = effect;
    1520             :     Node* rfalse;
    1521             :     {
    1522             :       // Convert {receiver} using the ToObjectStub. The call does not require a
    1523             :       // frame-state in this case, because neither null nor undefined is passed.
    1524        1684 :       Callable callable = CodeFactory::ToObject(isolate());
    1525             :       CallDescriptor const* const desc = Linkage::GetStubCallDescriptor(
    1526             :           isolate(), graph()->zone(), callable.descriptor(), 0,
    1527        5052 :           CallDescriptor::kNoFlags, node->op()->properties());
    1528             :       rfalse = efalse = graph()->NewNode(
    1529             :           common()->Call(desc), jsgraph()->HeapConstant(callable.code()),
    1530        5052 :           receiver, context, efalse);
    1531             :     }
    1532             : 
    1533        1684 :     control = graph()->NewNode(common()->Merge(2), if_true, if_false);
    1534        1684 :     effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control);
    1535             : 
    1536             :     // Morph the {node} into an appropriate Phi.
    1537             :     ReplaceWithValue(node, node, effect, control);
    1538        1684 :     node->ReplaceInput(0, rtrue);
    1539        1684 :     node->ReplaceInput(1, rfalse);
    1540        1684 :     node->ReplaceInput(2, control);
    1541        1684 :     node->TrimInputCount(3);
    1542             :     NodeProperties::ChangeOp(node,
    1543        1684 :                              common()->Phi(MachineRepresentation::kTagged, 2));
    1544             :     return Changed(node);
    1545             :   }
    1546             : 
    1547             :   // Check if {receiver} is already a JSReceiver.
    1548          49 :   Node* check0 = graph()->NewNode(simplified()->ObjectIsReceiver(), receiver);
    1549             :   Node* branch0 =
    1550          49 :       graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
    1551          49 :   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
    1552          49 :   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
    1553             : 
    1554             :   // Check {receiver} for undefined.
    1555             :   Node* check1 = graph()->NewNode(simplified()->ReferenceEqual(), receiver,
    1556          98 :                                   jsgraph()->UndefinedConstant());
    1557             :   Node* branch1 =
    1558          49 :       graph()->NewNode(common()->Branch(BranchHint::kFalse), check1, if_false0);
    1559          49 :   Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
    1560          49 :   Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
    1561             : 
    1562             :   // Check {receiver} for null.
    1563             :   Node* check2 = graph()->NewNode(simplified()->ReferenceEqual(), receiver,
    1564          98 :                                   jsgraph()->NullConstant());
    1565             :   Node* branch2 =
    1566          49 :       graph()->NewNode(common()->Branch(BranchHint::kFalse), check2, if_false1);
    1567          49 :   Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
    1568          49 :   Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
    1569             : 
    1570             :   // We just use {receiver} directly.
    1571             :   Node* if_noop = if_true0;
    1572             :   Node* enoop = effect;
    1573             :   Node* rnoop = receiver;
    1574             : 
    1575             :   // Convert {receiver} using ToObject.
    1576             :   Node* if_convert = if_false2;
    1577             :   Node* econvert = effect;
    1578             :   Node* rconvert;
    1579             :   {
    1580             :     // Convert {receiver} using the ToObjectStub. The call does not require a
    1581             :     // frame-state in this case, because neither null nor undefined is passed.
    1582          49 :     Callable callable = CodeFactory::ToObject(isolate());
    1583             :     CallDescriptor const* const desc = Linkage::GetStubCallDescriptor(
    1584             :         isolate(), graph()->zone(), callable.descriptor(), 0,
    1585         147 :         CallDescriptor::kNoFlags, node->op()->properties());
    1586             :     rconvert = econvert = graph()->NewNode(
    1587             :         common()->Call(desc), jsgraph()->HeapConstant(callable.code()),
    1588         147 :         receiver, context, econvert);
    1589             :   }
    1590             : 
    1591             :   // Replace {receiver} with global proxy of {context}.
    1592          49 :   Node* if_global = graph()->NewNode(common()->Merge(2), if_true1, if_true2);
    1593             :   Node* eglobal = effect;
    1594             :   Node* rglobal;
    1595             :   {
    1596          49 :     if (context_type->IsHeapConstant()) {
    1597             :       Handle<JSObject> global_proxy(
    1598             :           Handle<Context>::cast(context_type->AsHeapConstant()->Value())
    1599             :               ->global_proxy(),
    1600          25 :           isolate());
    1601          25 :       rglobal = jsgraph()->Constant(global_proxy);
    1602             :     } else {
    1603             :       Node* native_context = eglobal = graph()->NewNode(
    1604             :           javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true),
    1605          24 :           context, eglobal);
    1606             :       rglobal = eglobal = graph()->NewNode(
    1607             :           javascript()->LoadContext(0, Context::GLOBAL_PROXY_INDEX, true),
    1608          24 :           native_context, eglobal);
    1609             :     }
    1610             :   }
    1611             : 
    1612             :   control =
    1613          49 :       graph()->NewNode(common()->Merge(3), if_noop, if_convert, if_global);
    1614             :   effect = graph()->NewNode(common()->EffectPhi(3), enoop, econvert, eglobal,
    1615          49 :                             control);
    1616             :   // Morph the {node} into an appropriate Phi.
    1617             :   ReplaceWithValue(node, node, effect, control);
    1618          49 :   node->ReplaceInput(0, rnoop);
    1619          49 :   node->ReplaceInput(1, rconvert);
    1620          49 :   node->ReplaceInput(2, rglobal);
    1621          49 :   node->ReplaceInput(3, control);
    1622          49 :   node->TrimInputCount(4);
    1623             :   NodeProperties::ChangeOp(node,
    1624          49 :                            common()->Phi(MachineRepresentation::kTagged, 3));
    1625             :   return Changed(node);
    1626             : }
    1627             : 
    1628             : namespace {
    1629             : 
    1630       35292 : void ReduceBuiltin(Isolate* isolate, JSGraph* jsgraph, Node* node,
    1631             :                    int builtin_index, int arity, CallDescriptor::Flags flags) {
    1632             :   // Patch {node} to a direct CEntryStub call.
    1633             :   //
    1634             :   // ----------- A r g u m e n t s -----------
    1635             :   // -- 0: CEntryStub
    1636             :   // --- Stack args ---
    1637             :   // -- 1: receiver
    1638             :   // -- [2, 2 + n[: the n actual arguments passed to the builtin
    1639             :   // -- 2 + n: argc, including the receiver and implicit args (Smi)
    1640             :   // -- 2 + n + 1: target
    1641             :   // -- 2 + n + 2: new_target
    1642             :   // --- Register args ---
    1643             :   // -- 2 + n + 3: the C entry point
    1644             :   // -- 2 + n + 4: argc (Int32)
    1645             :   // -----------------------------------
    1646             : 
    1647             :   // The logic contained here is mirrored in Builtins::Generate_Adaptor.
    1648             :   // Keep these in sync.
    1649             : 
    1650       11764 :   const bool is_construct = (node->opcode() == IrOpcode::kJSConstruct);
    1651             : 
    1652             :   DCHECK(Builtins::HasCppImplementation(builtin_index));
    1653             :   DCHECK_EQ(0, flags & CallDescriptor::kSupportsTailCalls);
    1654             : 
    1655       11764 :   Node* target = NodeProperties::GetValueInput(node, 0);
    1656             :   Node* new_target = is_construct
    1657        2758 :                          ? NodeProperties::GetValueInput(node, arity + 1)
    1658       14522 :                          : jsgraph->UndefinedConstant();
    1659             : 
    1660             :   // API and CPP builtins are implemented in C++, and we can inline both.
    1661             :   // CPP builtins create a builtin exit frame, API builtins don't.
    1662       11764 :   const bool has_builtin_exit_frame = Builtins::IsCpp(builtin_index);
    1663             : 
    1664             :   Node* stub = jsgraph->CEntryStubConstant(1, kDontSaveFPRegs, kArgvOnStack,
    1665       11764 :                                            has_builtin_exit_frame);
    1666       11764 :   node->ReplaceInput(0, stub);
    1667             : 
    1668             :   Zone* zone = jsgraph->zone();
    1669       11764 :   if (is_construct) {
    1670             :     // Unify representations between construct and call nodes.
    1671             :     // Remove new target and add receiver as a stack parameter.
    1672        2758 :     Node* receiver = jsgraph->UndefinedConstant();
    1673        2758 :     node->RemoveInput(arity + 1);
    1674        2758 :     node->InsertInput(zone, 1, receiver);
    1675             :   }
    1676             : 
    1677       11764 :   const int argc = arity + BuiltinArguments::kNumExtraArgsWithReceiver;
    1678       11764 :   Node* argc_node = jsgraph->Constant(argc);
    1679             : 
    1680             :   static const int kStubAndReceiver = 2;
    1681       11764 :   int cursor = arity + kStubAndReceiver;
    1682       11764 :   node->InsertInput(zone, cursor++, argc_node);
    1683       11764 :   node->InsertInput(zone, cursor++, target);
    1684       11764 :   node->InsertInput(zone, cursor++, new_target);
    1685             : 
    1686       11764 :   Address entry = Builtins::CppEntryOf(builtin_index);
    1687       11764 :   ExternalReference entry_ref(ExternalReference(entry, isolate));
    1688       11764 :   Node* entry_node = jsgraph->ExternalConstant(entry_ref);
    1689             : 
    1690       11764 :   node->InsertInput(zone, cursor++, entry_node);
    1691       11764 :   node->InsertInput(zone, cursor++, argc_node);
    1692             : 
    1693             :   static const int kReturnCount = 1;
    1694       11764 :   const char* debug_name = Builtins::name(builtin_index);
    1695       11764 :   Operator::Properties properties = node->op()->properties();
    1696             :   CallDescriptor* desc = Linkage::GetCEntryStubCallDescriptor(
    1697       11764 :       zone, kReturnCount, argc, debug_name, properties, flags);
    1698             : 
    1699       11764 :   NodeProperties::ChangeOp(node, jsgraph->common()->Call(desc));
    1700       11764 : }
    1701             : 
    1702             : bool NeedsArgumentAdaptorFrame(Handle<SharedFunctionInfo> shared, int arity) {
    1703             :   static const int sentinel = SharedFunctionInfo::kDontAdaptArgumentsSentinel;
    1704             :   const int num_decl_parms = shared->internal_formal_parameter_count();
    1705      173520 :   return (num_decl_parms != arity && num_decl_parms != sentinel);
    1706             : }
    1707             : 
    1708             : }  // namespace
    1709             : 
    1710      107843 : Reduction JSTypedLowering::ReduceJSConstruct(Node* node) {
    1711             :   DCHECK_EQ(IrOpcode::kJSConstruct, node->opcode());
    1712       28689 :   ConstructParameters const& p = ConstructParametersOf(node->op());
    1713             :   DCHECK_LE(2u, p.arity());
    1714       28689 :   int const arity = static_cast<int>(p.arity() - 2);
    1715       28689 :   Node* target = NodeProperties::GetValueInput(node, 0);
    1716             :   Type* target_type = NodeProperties::GetType(target);
    1717       28689 :   Node* new_target = NodeProperties::GetValueInput(node, arity + 1);
    1718       28689 :   Node* effect = NodeProperties::GetEffectInput(node);
    1719       28689 :   Node* control = NodeProperties::GetControlInput(node);
    1720             : 
    1721             :   // Check if {target} is a known JSFunction.
    1722       50066 :   if (target_type->IsHeapConstant() &&
    1723             :       target_type->AsHeapConstant()->Value()->IsJSFunction()) {
    1724             :     Handle<JSFunction> function =
    1725             :         Handle<JSFunction>::cast(target_type->AsHeapConstant()->Value());
    1726             :     Handle<SharedFunctionInfo> shared(function->shared(), isolate());
    1727             :     const int builtin_index = shared->construct_stub()->builtin_index();
    1728             :     const bool is_builtin = (builtin_index != -1);
    1729             : 
    1730             :     CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState;
    1731             : 
    1732       24123 :     if (is_builtin && Builtins::HasCppImplementation(builtin_index) &&
    1733             :         !NeedsArgumentAdaptorFrame(shared, arity)) {
    1734             :       // Patch {node} to a direct CEntryStub call.
    1735             : 
    1736             :       // Load the context from the {target}.
    1737             :       Node* context = effect = graph()->NewNode(
    1738             :           simplified()->LoadField(AccessBuilder::ForJSFunctionContext()),
    1739        8274 :           target, effect, control);
    1740        2758 :       NodeProperties::ReplaceContextInput(node, context);
    1741             : 
    1742             :       // Update the effect dependency for the {node}.
    1743        2758 :       NodeProperties::ReplaceEffectInput(node, effect);
    1744             : 
    1745        2758 :       ReduceBuiltin(isolate(), jsgraph(), node, builtin_index, arity, flags);
    1746             :     } else {
    1747             :       // Patch {node} to an indirect call via the {function}s construct stub.
    1748             :       Callable callable(handle(shared->construct_stub(), isolate()),
    1749       37214 :                         ConstructStubDescriptor(isolate()));
    1750       18607 :       node->RemoveInput(arity + 1);
    1751             :       node->InsertInput(graph()->zone(), 0,
    1752       37214 :                         jsgraph()->HeapConstant(callable.code()));
    1753       18607 :       node->InsertInput(graph()->zone(), 2, new_target);
    1754       37214 :       node->InsertInput(graph()->zone(), 3, jsgraph()->Constant(arity));
    1755       37214 :       node->InsertInput(graph()->zone(), 4, jsgraph()->UndefinedConstant());
    1756       37214 :       node->InsertInput(graph()->zone(), 5, jsgraph()->UndefinedConstant());
    1757             :       NodeProperties::ChangeOp(
    1758             :           node, common()->Call(Linkage::GetStubCallDescriptor(
    1759             :                     isolate(), graph()->zone(), callable.descriptor(),
    1760       55821 :                     1 + arity, flags)));
    1761             :     }
    1762             :     return Changed(node);
    1763             :   }
    1764             : 
    1765             :   // Check if {target} is a JSFunction.
    1766        7324 :   if (target_type->Is(Type::Function())) {
    1767             :     // Patch {node} to an indirect call via the ConstructFunction builtin.
    1768         656 :     Callable callable = CodeFactory::ConstructFunction(isolate());
    1769         656 :     node->RemoveInput(arity + 1);
    1770             :     node->InsertInput(graph()->zone(), 0,
    1771        1312 :                       jsgraph()->HeapConstant(callable.code()));
    1772         656 :     node->InsertInput(graph()->zone(), 2, new_target);
    1773        1312 :     node->InsertInput(graph()->zone(), 3, jsgraph()->Constant(arity));
    1774        1312 :     node->InsertInput(graph()->zone(), 4, jsgraph()->UndefinedConstant());
    1775             :     NodeProperties::ChangeOp(
    1776             :         node, common()->Call(Linkage::GetStubCallDescriptor(
    1777             :                   isolate(), graph()->zone(), callable.descriptor(), 1 + arity,
    1778        1968 :                   CallDescriptor::kNeedsFrameState)));
    1779             :     return Changed(node);
    1780             :   }
    1781             : 
    1782             :   return NoChange();
    1783             : }
    1784             : 
    1785         611 : Reduction JSTypedLowering::ReduceJSCallForwardVarargs(Node* node) {
    1786             :   DCHECK_EQ(IrOpcode::kJSCallForwardVarargs, node->opcode());
    1787         215 :   CallForwardVarargsParameters p = CallForwardVarargsParametersOf(node->op());
    1788         215 :   Node* target = NodeProperties::GetValueInput(node, 0);
    1789             :   Type* target_type = NodeProperties::GetType(target);
    1790             : 
    1791             :   // Check if {target} is a JSFunction.
    1792         215 :   if (target_type->Is(Type::Function())) {
    1793             :     // Compute flags for the call.
    1794             :     CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState;
    1795         198 :     if (p.tail_call_mode() == TailCallMode::kAllow) {
    1796             :       flags |= CallDescriptor::kSupportsTailCalls;
    1797             :     }
    1798             : 
    1799             :     // Patch {node} to an indirect call via CallFunctionForwardVarargs.
    1800         198 :     Callable callable = CodeFactory::CallFunctionForwardVarargs(isolate());
    1801             :     node->InsertInput(graph()->zone(), 0,
    1802         396 :                       jsgraph()->HeapConstant(callable.code()));
    1803         396 :     node->InsertInput(graph()->zone(), 2, jsgraph()->Constant(p.start_index()));
    1804             :     NodeProperties::ChangeOp(
    1805             :         node,
    1806             :         common()->Call(Linkage::GetStubCallDescriptor(
    1807         594 :             isolate(), graph()->zone(), callable.descriptor(), 1, flags)));
    1808             :     return Changed(node);
    1809             :   }
    1810             : 
    1811             :   return NoChange();
    1812             : }
    1813             : 
    1814      644717 : Reduction JSTypedLowering::ReduceJSCall(Node* node) {
    1815             :   DCHECK_EQ(IrOpcode::kJSCall, node->opcode());
    1816      378656 :   CallParameters const& p = CallParametersOf(node->op());
    1817      188937 :   int const arity = static_cast<int>(p.arity() - 2);
    1818             :   ConvertReceiverMode convert_mode = p.convert_mode();
    1819      188937 :   Node* target = NodeProperties::GetValueInput(node, 0);
    1820             :   Type* target_type = NodeProperties::GetType(target);
    1821      188937 :   Node* receiver = NodeProperties::GetValueInput(node, 1);
    1822             :   Type* receiver_type = NodeProperties::GetType(receiver);
    1823      188937 :   Node* effect = NodeProperties::GetEffectInput(node);
    1824      188937 :   Node* control = NodeProperties::GetControlInput(node);
    1825             : 
    1826             :   // Try to infer receiver {convert_mode} from {receiver} type.
    1827      188937 :   if (receiver_type->Is(Type::NullOrUndefined())) {
    1828             :     convert_mode = ConvertReceiverMode::kNullOrUndefined;
    1829       49343 :   } else if (!receiver_type->Maybe(Type::NullOrUndefined())) {
    1830             :     convert_mode = ConvertReceiverMode::kNotNullOrUndefined;
    1831             :   }
    1832             : 
    1833             :   // Check if {target} is a known JSFunction.
    1834      359824 :   if (target_type->IsHeapConstant() &&
    1835             :       target_type->AsHeapConstant()->Value()->IsJSFunction()) {
    1836             :     Handle<JSFunction> function =
    1837             :         Handle<JSFunction>::cast(target_type->AsHeapConstant()->Value());
    1838             :     Handle<SharedFunctionInfo> shared(function->shared(), isolate());
    1839             :     const int builtin_index = shared->code()->builtin_index();
    1840             :     const bool is_builtin = (builtin_index != -1);
    1841             : 
    1842             :     // Class constructors are callable, but [[Call]] will raise an exception.
    1843             :     // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList ).
    1844      170776 :     if (IsClassConstructor(shared->kind())) return NoChange();
    1845             : 
    1846             :     // Load the context from the {target}.
    1847             :     Node* context = effect = graph()->NewNode(
    1848             :         simplified()->LoadField(AccessBuilder::ForJSFunctionContext()), target,
    1849      512286 :         effect, control);
    1850      170762 :     NodeProperties::ReplaceContextInput(node, context);
    1851             : 
    1852             :     // Check if we need to convert the {receiver}.
    1853      405965 :     if (is_sloppy(shared->language_mode()) && !shared->native() &&
    1854             :         !receiver_type->Is(Type::Receiver())) {
    1855             :       receiver = effect =
    1856             :           graph()->NewNode(javascript()->ConvertReceiver(convert_mode),
    1857       89197 :                            receiver, context, effect, control);
    1858       89197 :       NodeProperties::ReplaceValueInput(node, receiver, 1);
    1859             :     }
    1860             : 
    1861             :     // Update the effect dependency for the {node}.
    1862      170762 :     NodeProperties::ReplaceEffectInput(node, effect);
    1863             : 
    1864             :     // Compute flags for the call.
    1865             :     CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState;
    1866      170762 :     if (p.tail_call_mode() == TailCallMode::kAllow) {
    1867             :       flags |= CallDescriptor::kSupportsTailCalls;
    1868             :     }
    1869             : 
    1870      170762 :     Node* new_target = jsgraph()->UndefinedConstant();
    1871      170762 :     Node* argument_count = jsgraph()->Constant(arity);
    1872      170762 :     if (NeedsArgumentAdaptorFrame(shared, arity)) {
    1873             :       // Patch {node} to an indirect call via the ArgumentsAdaptorTrampoline.
    1874       51548 :       Callable callable = CodeFactory::ArgumentAdaptor(isolate());
    1875             :       node->InsertInput(graph()->zone(), 0,
    1876      103096 :                         jsgraph()->HeapConstant(callable.code()));
    1877       51548 :       node->InsertInput(graph()->zone(), 2, new_target);
    1878       51548 :       node->InsertInput(graph()->zone(), 3, argument_count);
    1879             :       node->InsertInput(
    1880             :           graph()->zone(), 4,
    1881      103096 :           jsgraph()->Constant(shared->internal_formal_parameter_count()));
    1882             :       NodeProperties::ChangeOp(
    1883             :           node, common()->Call(Linkage::GetStubCallDescriptor(
    1884             :                     isolate(), graph()->zone(), callable.descriptor(),
    1885      206192 :                     1 + arity, flags)));
    1886      128233 :     } else if (is_builtin && Builtins::HasCppImplementation(builtin_index) &&
    1887             :                ((flags & CallDescriptor::kSupportsTailCalls) == 0)) {
    1888             :       // Patch {node} to a direct CEntryStub call.
    1889        9006 :       ReduceBuiltin(isolate(), jsgraph(), node, builtin_index, arity, flags);
    1890             :     } else {
    1891             :       // Patch {node} to a direct call.
    1892      220416 :       node->InsertInput(graph()->zone(), arity + 2, new_target);
    1893      220416 :       node->InsertInput(graph()->zone(), arity + 3, argument_count);
    1894             :       NodeProperties::ChangeOp(node,
    1895             :                                common()->Call(Linkage::GetJSCallDescriptor(
    1896      330624 :                                    graph()->zone(), false, 1 + arity, flags)));
    1897             :     }
    1898             :     return Changed(node);
    1899             :   }
    1900             : 
    1901             :   // Check if {target} is a JSFunction.
    1902       18161 :   if (target_type->Is(Type::Function())) {
    1903             :     // Compute flags for the call.
    1904             :     CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState;
    1905        1077 :     if (p.tail_call_mode() == TailCallMode::kAllow) {
    1906             :       flags |= CallDescriptor::kSupportsTailCalls;
    1907             :     }
    1908             : 
    1909             :     // Patch {node} to an indirect call via the CallFunction builtin.
    1910        1077 :     Callable callable = CodeFactory::CallFunction(isolate(), convert_mode);
    1911             :     node->InsertInput(graph()->zone(), 0,
    1912        2154 :                       jsgraph()->HeapConstant(callable.code()));
    1913        2154 :     node->InsertInput(graph()->zone(), 2, jsgraph()->Constant(arity));
    1914             :     NodeProperties::ChangeOp(
    1915             :         node, common()->Call(Linkage::GetStubCallDescriptor(
    1916             :                   isolate(), graph()->zone(), callable.descriptor(), 1 + arity,
    1917        4308 :                   flags)));
    1918             :     return Changed(node);
    1919             :   }
    1920             : 
    1921             :   // Maybe we did at least learn something about the {receiver}.
    1922       17084 :   if (p.convert_mode() != convert_mode) {
    1923             :     NodeProperties::ChangeOp(
    1924             :         node,
    1925         796 :         javascript()->Call(p.arity(), p.frequency(), p.feedback(), convert_mode,
    1926         796 :                            p.tail_call_mode()));
    1927             :     return Changed(node);
    1928             :   }
    1929             : 
    1930             :   return NoChange();
    1931             : }
    1932             : 
    1933             : 
    1934        2944 : Reduction JSTypedLowering::ReduceJSForInNext(Node* node) {
    1935             :   DCHECK_EQ(IrOpcode::kJSForInNext, node->opcode());
    1936        1472 :   Node* receiver = NodeProperties::GetValueInput(node, 0);
    1937        1472 :   Node* cache_array = NodeProperties::GetValueInput(node, 1);
    1938        1472 :   Node* cache_type = NodeProperties::GetValueInput(node, 2);
    1939        1472 :   Node* index = NodeProperties::GetValueInput(node, 3);
    1940        1472 :   Node* context = NodeProperties::GetContextInput(node);
    1941        1472 :   Node* frame_state = NodeProperties::GetFrameStateInput(node);
    1942        1472 :   Node* effect = NodeProperties::GetEffectInput(node);
    1943        1472 :   Node* control = NodeProperties::GetControlInput(node);
    1944             : 
    1945             :   // We know that the {index} is in Unsigned32 range here, otherwise executing
    1946             :   // the JSForInNext wouldn't be valid. Unfortunately due to OSR and generators
    1947             :   // this is not always reflected in the types, hence we might need to rename
    1948             :   // the {index} here.
    1949        1472 :   if (!NodeProperties::GetType(index)->Is(Type::Unsigned32())) {
    1950             :     index = graph()->NewNode(common()->TypeGuard(Type::Unsigned32()), index,
    1951         209 :                              control);
    1952             :   }
    1953             : 
    1954             :   // Load the next {key} from the {cache_array}.
    1955             :   Node* key = effect = graph()->NewNode(
    1956             :       simplified()->LoadElement(AccessBuilder::ForFixedArrayElement()),
    1957        4416 :       cache_array, index, effect, control);
    1958             : 
    1959             :   // Load the map of the {receiver}.
    1960             :   Node* receiver_map = effect =
    1961             :       graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
    1962        4416 :                        receiver, effect, control);
    1963             : 
    1964             :   // Check if the expected map still matches that of the {receiver}.
    1965             :   Node* check0 = graph()->NewNode(simplified()->ReferenceEqual(), receiver_map,
    1966        1472 :                                   cache_type);
    1967             :   Node* branch0 =
    1968        1472 :       graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
    1969             : 
    1970        1472 :   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
    1971             :   Node* etrue0;
    1972             :   Node* vtrue0;
    1973             :   {
    1974             :     // Don't need filtering since expected map still matches that of the
    1975             :     // {receiver}.
    1976             :     etrue0 = effect;
    1977             :     vtrue0 = key;
    1978             :   }
    1979             : 
    1980        1472 :   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
    1981             :   Node* efalse0;
    1982             :   Node* vfalse0;
    1983             :   {
    1984             :     // Filter the {key} to check if it's still a valid property of the
    1985             :     // {receiver} (does the ToName conversion implicitly).
    1986        1472 :     Callable const callable = CodeFactory::ForInFilter(isolate());
    1987             :     CallDescriptor const* const desc = Linkage::GetStubCallDescriptor(
    1988             :         isolate(), graph()->zone(), callable.descriptor(), 0,
    1989        4416 :         CallDescriptor::kNeedsFrameState);
    1990             :     vfalse0 = efalse0 = if_false0 = graph()->NewNode(
    1991             :         common()->Call(desc), jsgraph()->HeapConstant(callable.code()), key,
    1992        4416 :         receiver, context, frame_state, effect, if_false0);
    1993             : 
    1994             :     // Update potential {IfException} uses of {node} to point to the ahove
    1995             :     // ForInFilter stub call node instead.
    1996        1472 :     Node* if_exception = nullptr;
    1997        1472 :     if (NodeProperties::IsExceptionalCall(node, &if_exception)) {
    1998          59 :       if_false0 = graph()->NewNode(common()->IfSuccess(), vfalse0);
    1999          59 :       NodeProperties::ReplaceControlInput(if_exception, vfalse0);
    2000          59 :       NodeProperties::ReplaceEffectInput(if_exception, efalse0);
    2001        1531 :       Revisit(if_exception);
    2002             :     }
    2003             :   }
    2004             : 
    2005        1472 :   control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
    2006        1472 :   effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
    2007             :   ReplaceWithValue(node, node, effect, control);
    2008             : 
    2009             :   // Morph the {node} into a Phi.
    2010        1472 :   node->ReplaceInput(0, vtrue0);
    2011        1472 :   node->ReplaceInput(1, vfalse0);
    2012        1472 :   node->ReplaceInput(2, control);
    2013        1472 :   node->TrimInputCount(3);
    2014             :   NodeProperties::ChangeOp(node,
    2015        1472 :                            common()->Phi(MachineRepresentation::kTagged, 2));
    2016        1472 :   return Changed(node);
    2017             : }
    2018             : 
    2019       78952 : Reduction JSTypedLowering::ReduceJSLoadMessage(Node* node) {
    2020             :   DCHECK_EQ(IrOpcode::kJSLoadMessage, node->opcode());
    2021             :   ExternalReference const ref =
    2022       39476 :       ExternalReference::address_of_pending_message_obj(isolate());
    2023       39476 :   node->ReplaceInput(0, jsgraph()->ExternalConstant(ref));
    2024             :   NodeProperties::ChangeOp(
    2025       78952 :       node, simplified()->LoadField(AccessBuilder::ForExternalTaggedValue()));
    2026       39476 :   return Changed(node);
    2027             : }
    2028             : 
    2029       78952 : Reduction JSTypedLowering::ReduceJSStoreMessage(Node* node) {
    2030             :   DCHECK_EQ(IrOpcode::kJSStoreMessage, node->opcode());
    2031             :   ExternalReference const ref =
    2032       39476 :       ExternalReference::address_of_pending_message_obj(isolate());
    2033       39476 :   Node* value = NodeProperties::GetValueInput(node, 0);
    2034       39476 :   node->ReplaceInput(0, jsgraph()->ExternalConstant(ref));
    2035       39476 :   node->ReplaceInput(1, value);
    2036             :   NodeProperties::ChangeOp(
    2037       78952 :       node, simplified()->StoreField(AccessBuilder::ForExternalTaggedValue()));
    2038       39476 :   return Changed(node);
    2039             : }
    2040             : 
    2041       12858 : Reduction JSTypedLowering::ReduceJSGeneratorStore(Node* node) {
    2042             :   DCHECK_EQ(IrOpcode::kJSGeneratorStore, node->opcode());
    2043        6429 :   Node* generator = NodeProperties::GetValueInput(node, 0);
    2044        6429 :   Node* continuation = NodeProperties::GetValueInput(node, 1);
    2045        6429 :   Node* offset = NodeProperties::GetValueInput(node, 2);
    2046        6429 :   Node* context = NodeProperties::GetContextInput(node);
    2047        6429 :   Node* effect = NodeProperties::GetEffectInput(node);
    2048        6429 :   Node* control = NodeProperties::GetControlInput(node);
    2049      108447 :   const GeneratorStoreParameters& p = GeneratorStoreParametersOf(node->op());
    2050             : 
    2051        6429 :   FieldAccess array_field = AccessBuilder::ForJSGeneratorObjectRegisterFile();
    2052        6429 :   FieldAccess context_field = AccessBuilder::ForJSGeneratorObjectContext();
    2053             :   FieldAccess continuation_field =
    2054        6429 :       AccessBuilder::ForJSGeneratorObjectContinuation();
    2055             :   FieldAccess input_or_debug_pos_field =
    2056             :       p.suspend_flags() == SuspendFlags::kAsyncGeneratorAwait
    2057             :           ? AccessBuilder::ForJSAsyncGeneratorObjectAwaitInputOrDebugPos()
    2058        6429 :           : AccessBuilder::ForJSGeneratorObjectInputOrDebugPos();
    2059             : 
    2060             :   Node* array = effect = graph()->NewNode(simplified()->LoadField(array_field),
    2061        6429 :                                           generator, effect, control);
    2062             : 
    2063      191178 :   for (int i = 0; i < p.register_count(); ++i) {
    2064       89160 :     Node* value = NodeProperties::GetValueInput(node, 3 + i);
    2065             :     effect = graph()->NewNode(
    2066             :         simplified()->StoreField(AccessBuilder::ForFixedArraySlot(i)), array,
    2067      267480 :         value, effect, control);
    2068             :   }
    2069             : 
    2070             :   effect = graph()->NewNode(simplified()->StoreField(context_field), generator,
    2071        6429 :                             context, effect, control);
    2072             :   effect = graph()->NewNode(simplified()->StoreField(continuation_field),
    2073        6429 :                             generator, continuation, effect, control);
    2074             :   effect = graph()->NewNode(simplified()->StoreField(input_or_debug_pos_field),
    2075        6429 :                             generator, offset, effect, control);
    2076             : 
    2077        6429 :   ReplaceWithValue(node, effect, effect, control);
    2078        6429 :   return Changed(effect);
    2079             : }
    2080             : 
    2081        4446 : Reduction JSTypedLowering::ReduceJSGeneratorRestoreContinuation(Node* node) {
    2082             :   DCHECK_EQ(IrOpcode::kJSGeneratorRestoreContinuation, node->opcode());
    2083        2223 :   Node* generator = NodeProperties::GetValueInput(node, 0);
    2084        2223 :   Node* effect = NodeProperties::GetEffectInput(node);
    2085        2223 :   Node* control = NodeProperties::GetControlInput(node);
    2086             : 
    2087             :   FieldAccess continuation_field =
    2088        2223 :       AccessBuilder::ForJSGeneratorObjectContinuation();
    2089             : 
    2090             :   Node* continuation = effect = graph()->NewNode(
    2091        2223 :       simplified()->LoadField(continuation_field), generator, effect, control);
    2092        2223 :   Node* executing = jsgraph()->Constant(JSGeneratorObject::kGeneratorExecuting);
    2093             :   effect = graph()->NewNode(simplified()->StoreField(continuation_field),
    2094        2223 :                             generator, executing, effect, control);
    2095             : 
    2096        2223 :   ReplaceWithValue(node, continuation, effect, control);
    2097        2223 :   return Changed(continuation);
    2098             : }
    2099             : 
    2100       60138 : Reduction JSTypedLowering::ReduceJSGeneratorRestoreRegister(Node* node) {
    2101             :   DCHECK_EQ(IrOpcode::kJSGeneratorRestoreRegister, node->opcode());
    2102       30069 :   Node* generator = NodeProperties::GetValueInput(node, 0);
    2103       30069 :   Node* effect = NodeProperties::GetEffectInput(node);
    2104       30069 :   Node* control = NodeProperties::GetControlInput(node);
    2105       30069 :   int index = OpParameter<int>(node);
    2106             : 
    2107       30069 :   FieldAccess array_field = AccessBuilder::ForJSGeneratorObjectRegisterFile();
    2108       30069 :   FieldAccess element_field = AccessBuilder::ForFixedArraySlot(index);
    2109             : 
    2110             :   Node* array = effect = graph()->NewNode(simplified()->LoadField(array_field),
    2111       30069 :                                           generator, effect, control);
    2112             :   Node* element = effect = graph()->NewNode(
    2113       30069 :       simplified()->LoadField(element_field), array, effect, control);
    2114       30069 :   Node* stale = jsgraph()->StaleRegisterConstant();
    2115             :   effect = graph()->NewNode(simplified()->StoreField(element_field), array,
    2116       30069 :                             stale, effect, control);
    2117             : 
    2118       30069 :   ReplaceWithValue(node, element, effect, control);
    2119       30069 :   return Changed(element);
    2120             : }
    2121             : 
    2122    30175065 : Reduction JSTypedLowering::Reduce(Node* node) {
    2123    30175065 :   switch (node->opcode()) {
    2124             :     case IrOpcode::kJSEqual:
    2125       18233 :       return ReduceJSEqual(node);
    2126             :     case IrOpcode::kJSStrictEqual:
    2127      241331 :       return ReduceJSStrictEqual(node);
    2128             :     case IrOpcode::kJSLessThan:         // fall through
    2129             :     case IrOpcode::kJSGreaterThan:      // fall through
    2130             :     case IrOpcode::kJSLessThanOrEqual:  // fall through
    2131             :     case IrOpcode::kJSGreaterThanOrEqual:
    2132       38228 :       return ReduceJSComparison(node);
    2133             :     case IrOpcode::kJSBitwiseOr:
    2134             :     case IrOpcode::kJSBitwiseXor:
    2135             :     case IrOpcode::kJSBitwiseAnd:
    2136       44899 :       return ReduceInt32Binop(node);
    2137             :     case IrOpcode::kJSShiftLeft:
    2138             :     case IrOpcode::kJSShiftRight:
    2139       21706 :       return ReduceUI32Shift(node, kSigned);
    2140             :     case IrOpcode::kJSShiftRightLogical:
    2141        8837 :       return ReduceUI32Shift(node, kUnsigned);
    2142             :     case IrOpcode::kJSAdd:
    2143      120613 :       return ReduceJSAdd(node);
    2144             :     case IrOpcode::kJSSubtract:
    2145             :     case IrOpcode::kJSMultiply:
    2146             :     case IrOpcode::kJSDivide:
    2147             :     case IrOpcode::kJSModulus:
    2148       88140 :       return ReduceNumberBinop(node);
    2149             :     case IrOpcode::kJSOrdinaryHasInstance:
    2150          64 :       return ReduceJSOrdinaryHasInstance(node);
    2151             :     case IrOpcode::kJSToBoolean:
    2152      112618 :       return ReduceJSToBoolean(node);
    2153             :     case IrOpcode::kJSToInteger:
    2154         271 :       return ReduceJSToInteger(node);
    2155             :     case IrOpcode::kJSToLength:
    2156         257 :       return ReduceJSToLength(node);
    2157             :     case IrOpcode::kJSToName:
    2158        1531 :       return ReduceJSToName(node);
    2159             :     case IrOpcode::kJSToNumber:
    2160        6497 :       return ReduceJSToNumber(node);
    2161             :     case IrOpcode::kJSToString:
    2162        2380 :       return ReduceJSToString(node);
    2163             :     case IrOpcode::kJSToObject:
    2164        2433 :       return ReduceJSToObject(node);
    2165             :     case IrOpcode::kJSTypeOf:
    2166       31284 :       return ReduceJSTypeOf(node);
    2167             :     case IrOpcode::kJSLoadNamed:
    2168      350959 :       return ReduceJSLoadNamed(node);
    2169             :     case IrOpcode::kJSLoadProperty:
    2170       59116 :       return ReduceJSLoadProperty(node);
    2171             :     case IrOpcode::kJSStoreProperty:
    2172       33863 :       return ReduceJSStoreProperty(node);
    2173             :     case IrOpcode::kJSLoadContext:
    2174      592315 :       return ReduceJSLoadContext(node);
    2175             :     case IrOpcode::kJSStoreContext:
    2176      156349 :       return ReduceJSStoreContext(node);
    2177             :     case IrOpcode::kJSLoadModule:
    2178         406 :       return ReduceJSLoadModule(node);
    2179             :     case IrOpcode::kJSStoreModule:
    2180         486 :       return ReduceJSStoreModule(node);
    2181             :     case IrOpcode::kJSConvertReceiver:
    2182      119027 :       return ReduceJSConvertReceiver(node);
    2183             :     case IrOpcode::kJSConstruct:
    2184       28689 :       return ReduceJSConstruct(node);
    2185             :     case IrOpcode::kJSCallForwardVarargs:
    2186         215 :       return ReduceJSCallForwardVarargs(node);
    2187             :     case IrOpcode::kJSCall:
    2188      188937 :       return ReduceJSCall(node);
    2189             :     case IrOpcode::kJSForInNext:
    2190        1472 :       return ReduceJSForInNext(node);
    2191             :     case IrOpcode::kJSLoadMessage:
    2192       39476 :       return ReduceJSLoadMessage(node);
    2193             :     case IrOpcode::kJSStoreMessage:
    2194       39476 :       return ReduceJSStoreMessage(node);
    2195             :     case IrOpcode::kJSGeneratorStore:
    2196        6429 :       return ReduceJSGeneratorStore(node);
    2197             :     case IrOpcode::kJSGeneratorRestoreContinuation:
    2198        2223 :       return ReduceJSGeneratorRestoreContinuation(node);
    2199             :     case IrOpcode::kJSGeneratorRestoreRegister:
    2200       30069 :       return ReduceJSGeneratorRestoreRegister(node);
    2201             :     // TODO(mstarzinger): Simplified operations hiding in JS-level reducer not
    2202             :     // fooling anyone. Consider moving this into a separate reducer.
    2203             :     case IrOpcode::kSpeculativeNumberAdd:
    2204      155908 :       return ReduceSpeculativeNumberAdd(node);
    2205             :     case IrOpcode::kSpeculativeNumberSubtract:
    2206             :     case IrOpcode::kSpeculativeNumberMultiply:
    2207             :     case IrOpcode::kSpeculativeNumberDivide:
    2208             :     case IrOpcode::kSpeculativeNumberModulus:
    2209       72359 :       return ReduceSpeculativeNumberBinop(node);
    2210             :     case IrOpcode::kSpeculativeNumberEqual:
    2211             :     case IrOpcode::kSpeculativeNumberLessThan:
    2212             :     case IrOpcode::kSpeculativeNumberLessThanOrEqual:
    2213       53880 :       return ReduceSpeculativeNumberComparison(node);
    2214             :     default:
    2215             :       break;
    2216             :   }
    2217             :   return NoChange();
    2218             : }
    2219             : 
    2220             : 
    2221      385644 : Factory* JSTypedLowering::factory() const { return jsgraph()->factory(); }
    2222             : 
    2223             : 
    2224     4882906 : Graph* JSTypedLowering::graph() const { return jsgraph()->graph(); }
    2225             : 
    2226             : 
    2227      629301 : Isolate* JSTypedLowering::isolate() const { return jsgraph()->isolate(); }
    2228             : 
    2229             : 
    2230      268576 : JSOperatorBuilder* JSTypedLowering::javascript() const {
    2231      268576 :   return jsgraph()->javascript();
    2232             : }
    2233             : 
    2234             : 
    2235      292514 : CommonOperatorBuilder* JSTypedLowering::common() const {
    2236      292558 :   return jsgraph()->common();
    2237             : }
    2238             : 
    2239     1738969 : SimplifiedOperatorBuilder* JSTypedLowering::simplified() const {
    2240     1738969 :   return jsgraph()->simplified();
    2241             : }
    2242             : 
    2243             : 
    2244           0 : CompilationDependencies* JSTypedLowering::dependencies() const {
    2245        3297 :   return dependencies_;
    2246             : }
    2247             : 
    2248             : }  // namespace compiler
    2249             : }  // namespace internal
    2250             : }  // namespace v8

Generated by: LCOV version 1.10