LCOV - code coverage report
Current view: top level - src/compiler - simplified-lowering.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 1639 1734 94.5 %
Date: 2019-04-18 Functions: 90 94 95.7 %

          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/simplified-lowering.h"
       6             : 
       7             : #include <limits>
       8             : 
       9             : #include "src/address-map.h"
      10             : #include "src/base/bits.h"
      11             : #include "src/code-factory.h"
      12             : #include "src/compiler/access-builder.h"
      13             : #include "src/compiler/common-operator.h"
      14             : #include "src/compiler/compiler-source-position-table.h"
      15             : #include "src/compiler/diamond.h"
      16             : #include "src/compiler/linkage.h"
      17             : #include "src/compiler/node-matchers.h"
      18             : #include "src/compiler/node-origin-table.h"
      19             : #include "src/compiler/node-properties.h"
      20             : #include "src/compiler/operation-typer.h"
      21             : #include "src/compiler/operator-properties.h"
      22             : #include "src/compiler/representation-change.h"
      23             : #include "src/compiler/simplified-operator.h"
      24             : #include "src/compiler/type-cache.h"
      25             : #include "src/conversions-inl.h"
      26             : #include "src/objects.h"
      27             : 
      28             : namespace v8 {
      29             : namespace internal {
      30             : namespace compiler {
      31             : 
      32             : // Macro for outputting trace information from representation inference.
      33             : #define TRACE(...)                                      \
      34             :   do {                                                  \
      35             :     if (FLAG_trace_representation) PrintF(__VA_ARGS__); \
      36             :   } while (false)
      37             : 
      38             : // Representation selection and lowering of {Simplified} operators to machine
      39             : // operators are interwined. We use a fixpoint calculation to compute both the
      40             : // output representation and the best possible lowering for {Simplified} nodes.
      41             : // Representation change insertion ensures that all values are in the correct
      42             : // machine representation after this phase, as dictated by the machine
      43             : // operators themselves.
      44             : enum Phase {
      45             :   // 1.) PROPAGATE: Traverse the graph from the end, pushing usage information
      46             :   //     backwards from uses to definitions, around cycles in phis, according
      47             :   //     to local rules for each operator.
      48             :   //     During this phase, the usage information for a node determines the best
      49             :   //     possible lowering for each operator so far, and that in turn determines
      50             :   //     the output representation.
      51             :   //     Therefore, to be correct, this phase must iterate to a fixpoint before
      52             :   //     the next phase can begin.
      53             :   PROPAGATE,
      54             : 
      55             :   // 2.) RETYPE: Propagate types from type feedback forwards.
      56             :   RETYPE,
      57             : 
      58             :   // 3.) LOWER: perform lowering for all {Simplified} nodes by replacing some
      59             :   //     operators for some nodes, expanding some nodes to multiple nodes, or
      60             :   //     removing some (redundant) nodes.
      61             :   //     During this phase, use the {RepresentationChanger} to insert
      62             :   //     representation changes between uses that demand a particular
      63             :   //     representation and nodes that produce a different representation.
      64             :   LOWER
      65             : };
      66             : 
      67             : namespace {
      68             : 
      69       33735 : MachineRepresentation MachineRepresentationFromArrayType(
      70             :     ExternalArrayType array_type) {
      71       33735 :   switch (array_type) {
      72             :     case kExternalUint8Array:
      73             :     case kExternalUint8ClampedArray:
      74             :     case kExternalInt8Array:
      75             :       return MachineRepresentation::kWord8;
      76             :     case kExternalUint16Array:
      77             :     case kExternalInt16Array:
      78        5184 :       return MachineRepresentation::kWord16;
      79             :     case kExternalUint32Array:
      80             :     case kExternalInt32Array:
      81        6525 :       return MachineRepresentation::kWord32;
      82             :     case kExternalFloat32Array:
      83        7852 :       return MachineRepresentation::kFloat32;
      84             :     case kExternalFloat64Array:
      85        3090 :       return MachineRepresentation::kFloat64;
      86             :     case kExternalBigInt64Array:
      87             :     case kExternalBigUint64Array:
      88           0 :       UNIMPLEMENTED();
      89             :   }
      90           0 :   UNREACHABLE();
      91             : }
      92             : 
      93     1086254 : UseInfo CheckedUseInfoAsWord32FromHint(
      94             :     NumberOperationHint hint, const VectorSlotPair& feedback = VectorSlotPair(),
      95             :     IdentifyZeros identify_zeros = kDistinguishZeros) {
      96     1086254 :   switch (hint) {
      97             :     case NumberOperationHint::kSignedSmall:
      98             :     case NumberOperationHint::kSignedSmallInputs:
      99             :       return UseInfo::CheckedSignedSmallAsWord32(identify_zeros, feedback);
     100             :     case NumberOperationHint::kSigned32:
     101             :       return UseInfo::CheckedSigned32AsWord32(identify_zeros, feedback);
     102             :     case NumberOperationHint::kNumber:
     103             :       return UseInfo::CheckedNumberAsWord32(feedback);
     104             :     case NumberOperationHint::kNumberOrOddball:
     105             :       return UseInfo::CheckedNumberOrOddballAsWord32(feedback);
     106             :   }
     107           0 :   UNREACHABLE();
     108             : }
     109             : 
     110      166172 : UseInfo CheckedUseInfoAsFloat64FromHint(
     111             :     NumberOperationHint hint, const VectorSlotPair& feedback,
     112             :     IdentifyZeros identify_zeros = kDistinguishZeros) {
     113      166172 :   switch (hint) {
     114             :     case NumberOperationHint::kSignedSmall:
     115             :     case NumberOperationHint::kSignedSmallInputs:
     116             :     case NumberOperationHint::kSigned32:
     117             :       // Not used currently.
     118           0 :       UNREACHABLE();
     119             :       break;
     120             :     case NumberOperationHint::kNumber:
     121             :       return UseInfo::CheckedNumberAsFloat64(identify_zeros, feedback);
     122             :     case NumberOperationHint::kNumberOrOddball:
     123             :       return UseInfo::CheckedNumberOrOddballAsFloat64(identify_zeros, feedback);
     124             :   }
     125           0 :   UNREACHABLE();
     126             : }
     127             : 
     128     8161063 : UseInfo TruncatingUseInfoFromRepresentation(MachineRepresentation rep) {
     129     8161063 :   switch (rep) {
     130             :     case MachineRepresentation::kTaggedSigned:
     131             :       return UseInfo::TaggedSigned();
     132             :     case MachineRepresentation::kTaggedPointer:
     133             :     case MachineRepresentation::kTagged:
     134             :       return UseInfo::AnyTagged();
     135             :     case MachineRepresentation::kCompressedSigned:
     136             :       return UseInfo::CompressedSigned();
     137             :     case MachineRepresentation::kCompressedPointer:
     138             :     case MachineRepresentation::kCompressed:
     139             :       return UseInfo::AnyCompressed();
     140             :     case MachineRepresentation::kFloat64:
     141             :       return UseInfo::TruncatingFloat64();
     142             :     case MachineRepresentation::kFloat32:
     143             :       return UseInfo::Float32();
     144             :     case MachineRepresentation::kWord8:
     145             :     case MachineRepresentation::kWord16:
     146             :     case MachineRepresentation::kWord32:
     147             :       return UseInfo::TruncatingWord32();
     148             :     case MachineRepresentation::kWord64:
     149             :       return UseInfo::Word64();
     150             :     case MachineRepresentation::kBit:
     151             :       return UseInfo::Bool();
     152             :     case MachineRepresentation::kSimd128:
     153             :     case MachineRepresentation::kNone:
     154             :       break;
     155             :   }
     156           0 :   UNREACHABLE();
     157             : }
     158             : 
     159    10064468 : UseInfo UseInfoForBasePointer(const FieldAccess& access) {
     160    20128971 :   return access.tag() != 0 ? UseInfo::AnyTagged() : UseInfo::Word();
     161             : }
     162             : 
     163      178518 : UseInfo UseInfoForBasePointer(const ElementAccess& access) {
     164      357036 :   return access.tag() != 0 ? UseInfo::AnyTagged() : UseInfo::Word();
     165             : }
     166             : 
     167      351498 : void ReplaceEffectControlUses(Node* node, Node* effect, Node* control) {
     168     2024513 :   for (Edge edge : node->use_edges()) {
     169      836526 :     if (NodeProperties::IsControlEdge(edge)) {
     170           0 :       edge.UpdateTo(control);
     171      836508 :     } else if (NodeProperties::IsEffectEdge(edge)) {
     172      425844 :       edge.UpdateTo(effect);
     173             :     } else {
     174             :       DCHECK(NodeProperties::IsValueEdge(edge) ||
     175             :              NodeProperties::IsContextEdge(edge));
     176             :     }
     177             :   }
     178      351461 : }
     179             : 
     180      154777 : bool CanOverflowSigned32(const Operator* op, Type left, Type right,
     181             :                          Zone* type_zone) {
     182             :   // We assume the inputs are checked Signed32 (or known statically
     183             :   // to be Signed32). Technically, the inputs could also be minus zero, but
     184             :   // that cannot cause overflow.
     185      154777 :   left = Type::Intersect(left, Type::Signed32(), type_zone);
     186      154762 :   right = Type::Intersect(right, Type::Signed32(), type_zone);
     187      309505 :   if (left.IsNone() || right.IsNone()) return false;
     188      154736 :   switch (op->opcode()) {
     189             :     case IrOpcode::kSpeculativeSafeIntegerAdd:
     190      150469 :       return (left.Max() + right.Max() > kMaxInt) ||
     191        4354 :              (left.Min() + right.Min() < kMinInt);
     192             : 
     193             :     case IrOpcode::kSpeculativeSafeIntegerSubtract:
     194       16494 :       return (left.Max() - right.Min() > kMaxInt) ||
     195        7873 :              (left.Min() - right.Max() < kMinInt);
     196             : 
     197             :     default:
     198           0 :       UNREACHABLE();
     199             :   }
     200             :   return true;
     201             : }
     202             : 
     203        9083 : bool IsSomePositiveOrderedNumber(Type type) {
     204       15214 :   return type.Is(Type::OrderedNumber()) && !type.IsNone() && type.Min() > 0;
     205             : }
     206             : 
     207             : }  // namespace
     208             : 
     209             : #ifdef DEBUG
     210             : // Helpers for monotonicity checking.
     211             : class InputUseInfos {
     212             :  public:
     213             :   explicit InputUseInfos(Zone* zone) : input_use_infos_(zone) {}
     214             : 
     215             :   void SetAndCheckInput(Node* node, int index, UseInfo use_info) {
     216             :     if (input_use_infos_.empty()) {
     217             :       input_use_infos_.resize(node->InputCount(), UseInfo::None());
     218             :     }
     219             :     // Check that the new use informatin is a super-type of the old
     220             :     // one.
     221             :     DCHECK(IsUseLessGeneral(input_use_infos_[index], use_info));
     222             :     input_use_infos_[index] = use_info;
     223             :   }
     224             : 
     225             :  private:
     226             :   ZoneVector<UseInfo> input_use_infos_;
     227             : 
     228             :   static bool IsUseLessGeneral(UseInfo use1, UseInfo use2) {
     229             :     return use1.truncation().IsLessGeneralThan(use2.truncation());
     230             :   }
     231             : };
     232             : 
     233             : #endif  // DEBUG
     234             : 
     235      463671 : class RepresentationSelector {
     236             :  public:
     237             :   // Information for each node tracked during the fixpoint.
     238      463670 :   class NodeInfo final {
     239             :    public:
     240             :     // Adds new use to the node. Returns true if something has changed
     241             :     // and the node has to be requeued.
     242   100131708 :     bool AddUse(UseInfo info) {
     243   100131708 :       Truncation old_truncation = truncation_;
     244   100129540 :       truncation_ = Truncation::Generalize(truncation_, info.truncation());
     245   100129540 :       return truncation_ != old_truncation;
     246             :     }
     247             : 
     248    36508929 :     void set_queued() { state_ = kQueued; }
     249    67055532 :     void set_visited() { state_ = kVisited; }
     250    30547581 :     void set_pushed() { state_ = kPushed; }
     251    43214960 :     void reset_state() { state_ = kUnvisited; }
     252             :     bool visited() const { return state_ == kVisited; }
     253             :     bool queued() const { return state_ == kQueued; }
     254             :     bool unvisited() const { return state_ == kUnvisited; }
     255             :     Truncation truncation() const { return truncation_; }
     256    34841378 :     void set_output(MachineRepresentation output) { representation_ = output; }
     257             : 
     258             :     MachineRepresentation representation() const { return representation_; }
     259             : 
     260             :     // Helpers for feedback typing.
     261    21393600 :     void set_feedback_type(Type type) { feedback_type_ = type; }
     262             :     Type feedback_type() const { return feedback_type_; }
     263       91684 :     void set_weakened() { weakened_ = true; }
     264             :     bool weakened() const { return weakened_; }
     265    30645237 :     void set_restriction_type(Type type) { restriction_type_ = type; }
     266             :     Type restriction_type() const { return restriction_type_; }
     267             : 
     268             :    private:
     269             :     enum State : uint8_t { kUnvisited, kPushed, kVisited, kQueued };
     270             :     State state_ = kUnvisited;
     271             :     MachineRepresentation representation_ =
     272             :         MachineRepresentation::kNone;             // Output representation.
     273             :     Truncation truncation_ = Truncation::None();  // Information about uses.
     274             : 
     275             :     Type restriction_type_ = Type::Any();
     276             :     Type feedback_type_;
     277             :     bool weakened_ = false;
     278             :   };
     279             : 
     280      463670 :   RepresentationSelector(JSGraph* jsgraph, JSHeapBroker* broker, Zone* zone,
     281             :                          RepresentationChanger* changer,
     282             :                          SourcePositionTable* source_positions,
     283             :                          NodeOriginTable* node_origins)
     284             :       : jsgraph_(jsgraph),
     285             :         zone_(zone),
     286             :         count_(jsgraph->graph()->NodeCount()),
     287             :         info_(count_, zone),
     288             : #ifdef DEBUG
     289             :         node_input_use_infos_(count_, InputUseInfos(zone), zone),
     290             : #endif
     291             :         nodes_(zone),
     292             :         replacements_(zone),
     293             :         phase_(PROPAGATE),
     294             :         changer_(changer),
     295             :         queue_(zone),
     296             :         typing_stack_(zone),
     297             :         source_positions_(source_positions),
     298             :         node_origins_(node_origins),
     299      463670 :         type_cache_(TypeCache::Get()),
     300     1854680 :         op_typer_(broker, graph_zone()) {
     301      463668 :   }
     302             : 
     303             :   // Forward propagation of types from type feedback.
     304      463671 :   void RunTypePropagationPhase() {
     305             :     // Run type propagation.
     306      463671 :     TRACE("--{Type propagation phase}--\n");
     307      463671 :     phase_ = RETYPE;
     308             :     ResetNodeInfoState();
     309             : 
     310             :     DCHECK(typing_stack_.empty());
     311      926809 :     typing_stack_.push({graph()->end(), 0});
     312             :     GetInfo(graph()->end())->set_pushed();
     313    61095888 :     while (!typing_stack_.empty()) {
     314             :       NodeState& current = typing_stack_.top();
     315             : 
     316             :       // If there is an unvisited input, push it and continue.
     317             :       bool pushed_unvisited = false;
     318   255195736 :       while (current.input_index < current.node->InputCount()) {
     319             :         Node* input = current.node->InputAt(current.input_index);
     320             :         NodeInfo* input_info = GetInfo(input);
     321    97049997 :         current.input_index++;
     322    97049997 :         if (input_info->unvisited()) {
     323             :           input_info->set_pushed();
     324    60169025 :           typing_stack_.push({input, 0});
     325             :           pushed_unvisited = true;
     326    30084582 :           break;
     327             :         }
     328             :       }
     329    60632453 :       if (pushed_unvisited) continue;
     330             : 
     331             :       // Process the top of the stack.
     332    30547866 :       Node* node = current.node;
     333             :       typing_stack_.pop();
     334             :       NodeInfo* info = GetInfo(node);
     335             :       info->set_visited();
     336    30547739 :       bool updated = UpdateFeedbackType(node);
     337    30547403 :       TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic());
     338    30547403 :       VisitNode(node, info->truncation(), nullptr);
     339    30547710 :       TRACE("  ==> output ");
     340    30547710 :       PrintOutputInfo(info);
     341    30547632 :       TRACE("\n");
     342    30548178 :       if (updated) {
     343   180226131 :         for (Node* const user : node->uses()) {
     344    80162125 :           if (GetInfo(user)->visited()) {
     345             :             GetInfo(user)->set_queued();
     346             :             queue_.push(user);
     347             :           }
     348             :         }
     349             :       }
     350             :     }
     351             : 
     352             :     // Process the revisit queue.
     353     5474088 :     while (!queue_.empty()) {
     354     5010419 :       Node* node = queue_.front();
     355             :       queue_.pop();
     356             :       NodeInfo* info = GetInfo(node);
     357             :       info->set_visited();
     358     5010420 :       bool updated = UpdateFeedbackType(node);
     359     5010412 :       TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic());
     360     5010412 :       VisitNode(node, info->truncation(), nullptr);
     361     5010442 :       TRACE("  ==> output ");
     362     5010442 :       PrintOutputInfo(info);
     363     5010439 :       TRACE("\n");
     364     5010516 :       if (updated) {
     365    13105075 :         for (Node* const user : node->uses()) {
     366     5806691 :           if (GetInfo(user)->visited()) {
     367             :             GetInfo(user)->set_queued();
     368             :             queue_.push(user);
     369             :           }
     370             :         }
     371             :       }
     372             :     }
     373      463669 :   }
     374             : 
     375             :   void ResetNodeInfoState() {
     376             :     // Clean up for the next phase.
     377    43678631 :     for (NodeInfo& info : info_) {
     378             :       info.reset_state();
     379             :     }
     380             :   }
     381             : 
     382             :   Type TypeOf(Node* node) {
     383             :     Type type = GetInfo(node)->feedback_type();
     384    45470745 :     return type.IsInvalid() ? NodeProperties::GetType(node) : type;
     385             :   }
     386             : 
     387             :   Type FeedbackTypeOf(Node* node) {
     388             :     Type type = GetInfo(node)->feedback_type();
     389    38172840 :     return type.IsInvalid() ? Type::None() : type;
     390             :   }
     391             : 
     392      802348 :   Type TypePhi(Node* node) {
     393             :     int arity = node->op()->ValueInputCount();
     394             :     Type type = FeedbackTypeOf(node->InputAt(0));
     395     3179220 :     for (int i = 1; i < arity; ++i) {
     396     1188436 :       type = op_typer_.Merge(type, FeedbackTypeOf(node->InputAt(i)));
     397             :     }
     398      802348 :     return type;
     399             :   }
     400             : 
     401       12525 :   Type TypeSelect(Node* node) {
     402             :     return op_typer_.Merge(FeedbackTypeOf(node->InputAt(1)),
     403       12525 :                            FeedbackTypeOf(node->InputAt(2)));
     404             :   }
     405             : 
     406    35557120 :   bool UpdateFeedbackType(Node* node) {
     407    35557120 :     if (node->op()->ValueOutputCount() == 0) return false;
     408             : 
     409             :     NodeInfo* info = GetInfo(node);
     410             :     Type type = info->feedback_type();
     411    25145185 :     Type new_type = type;
     412             : 
     413             :     // For any non-phi node just wait until we get all inputs typed. We only
     414             :     // allow untyped inputs for phi nodes because phis are the only places
     415             :     // where cycles need to be broken.
     416    25145185 :     if (node->opcode() != IrOpcode::kPhi) {
     417   141796719 :       for (int i = 0; i < node->op()->ValueInputCount(); i++) {
     418    59572753 :         if (GetInfo(node->InputAt(i))->feedback_type().IsInvalid()) {
     419             :           return false;
     420             :         }
     421             :       }
     422             :     }
     423             : 
     424             :     // We preload these values here to avoid increasing the binary size too
     425             :     // much, which happens if we inline the calls into the macros below.
     426             :     Type input0_type;
     427    43877921 :     if (node->InputCount() > 0) input0_type = FeedbackTypeOf(node->InputAt(0));
     428             :     Type input1_type;
     429    40815765 :     if (node->InputCount() > 1) input1_type = FeedbackTypeOf(node->InputAt(1));
     430             : 
     431    24299433 :     switch (node->opcode()) {
     432             : #define DECLARE_CASE(Name)                               \
     433             :   case IrOpcode::k##Name: {                              \
     434             :     new_type = op_typer_.Name(input0_type, input1_type); \
     435             :     break;                                               \
     436             :   }
     437      480606 :       SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_CASE)
     438          77 :       DECLARE_CASE(SameValue)
     439             : #undef DECLARE_CASE
     440             : 
     441             : #define DECLARE_CASE(Name)                                               \
     442             :   case IrOpcode::k##Name: {                                              \
     443             :     new_type = Type::Intersect(op_typer_.Name(input0_type, input1_type), \
     444             :                                info->restriction_type(), graph_zone());  \
     445             :     break;                                                               \
     446             :   }
     447        1060 :       SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DECLARE_CASE)
     448             : #undef DECLARE_CASE
     449             : 
     450             : #define DECLARE_CASE(Name)                  \
     451             :   case IrOpcode::k##Name: {                 \
     452             :     new_type = op_typer_.Name(input0_type); \
     453             :     break;                                  \
     454             :   }
     455         295 :       SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_CASE)
     456             : #undef DECLARE_CASE
     457             : 
     458             : #define DECLARE_CASE(Name)                                              \
     459             :   case IrOpcode::k##Name: {                                             \
     460             :     new_type = Type::Intersect(op_typer_.Name(input0_type),             \
     461             :                                info->restriction_type(), graph_zone()); \
     462             :     break;                                                              \
     463             :   }
     464       40753 :       SIMPLIFIED_SPECULATIVE_NUMBER_UNOP_LIST(DECLARE_CASE)
     465         595 :       DECLARE_CASE(CheckFloat64Hole)
     466         534 :       DECLARE_CASE(CheckNumber)
     467        1484 :       DECLARE_CASE(CheckInternalizedString)
     468          18 :       DECLARE_CASE(CheckNonEmptyString)
     469        1778 :       DECLARE_CASE(CheckNonEmptyOneByteString)
     470         236 :       DECLARE_CASE(CheckNonEmptyTwoByteString)
     471        5672 :       DECLARE_CASE(CheckString)
     472             : #undef DECLARE_CASE
     473             : 
     474             :       case IrOpcode::kConvertReceiver:
     475         882 :         new_type = op_typer_.ConvertReceiver(input0_type);
     476         882 :         break;
     477             : 
     478             :       case IrOpcode::kPlainPrimitiveToNumber:
     479        1053 :         new_type = op_typer_.ToNumber(input0_type);
     480        1053 :         break;
     481             : 
     482             :       case IrOpcode::kCheckBounds:
     483             :         new_type =
     484             :             Type::Intersect(op_typer_.CheckBounds(input0_type, input1_type),
     485       64203 :                             info->restriction_type(), graph_zone());
     486       64203 :         break;
     487             : 
     488             :       case IrOpcode::kStringConcat:
     489             :         new_type = op_typer_.StringConcat(input0_type, input1_type,
     490       26427 :                                           FeedbackTypeOf(node->InputAt(2)));
     491       26427 :         break;
     492             : 
     493             :       case IrOpcode::kPhi: {
     494      802337 :         new_type = TypePhi(node);
     495      802345 :         if (!type.IsInvalid()) {
     496      482446 :           new_type = Weaken(node, type, new_type);
     497             :         }
     498             :         break;
     499             :       }
     500             : 
     501             :       case IrOpcode::kConvertTaggedHoleToUndefined:
     502             :         new_type = op_typer_.ConvertTaggedHoleToUndefined(
     503        2131 :             FeedbackTypeOf(node->InputAt(0)));
     504        2131 :         break;
     505             : 
     506             :       case IrOpcode::kTypeGuard: {
     507             :         new_type = op_typer_.TypeTypeGuard(node->op(),
     508       33628 :                                            FeedbackTypeOf(node->InputAt(0)));
     509       33628 :         break;
     510             :       }
     511             : 
     512             :       case IrOpcode::kSelect: {
     513       12525 :         new_type = TypeSelect(node);
     514       12525 :         break;
     515             :       }
     516             : 
     517             :       default:
     518             :         // Shortcut for operations that we do not handle.
     519    22373616 :         if (type.IsInvalid()) {
     520             :           GetInfo(node)->set_feedback_type(NodeProperties::GetType(node));
     521    19684160 :           return true;
     522             :         }
     523             :         return false;
     524             :     }
     525             :     // We need to guarantee that the feedback type is a subtype of the upper
     526             :     // bound. Naively that should hold, but weakening can actually produce
     527             :     // a bigger type if we are unlucky with ordering of phi typing. To be
     528             :     // really sure, just intersect the upper bound with the feedback type.
     529     1925795 :     new_type = Type::Intersect(GetUpperBound(node), new_type, graph_zone());
     530             : 
     531     2887925 :     if (!type.IsInvalid() && new_type.Is(type)) return false;
     532             :     GetInfo(node)->set_feedback_type(new_type);
     533     1709440 :     if (FLAG_trace_representation) {
     534           0 :       PrintNodeFeedbackType(node);
     535             :     }
     536             :     return true;
     537             :   }
     538             : 
     539           0 :   void PrintNodeFeedbackType(Node* n) {
     540           0 :     StdoutStream os;
     541           0 :     os << "#" << n->id() << ":" << *n->op() << "(";
     542             :     int j = 0;
     543           0 :     for (Node* const i : n->inputs()) {
     544           0 :       if (j++ > 0) os << ", ";
     545           0 :       os << "#" << i->id() << ":" << i->op()->mnemonic();
     546             :     }
     547           0 :     os << ")";
     548           0 :     if (NodeProperties::IsTyped(n)) {
     549             :       Type static_type = NodeProperties::GetType(n);
     550           0 :       os << "  [Static type: " << static_type;
     551             :       Type feedback_type = GetInfo(n)->feedback_type();
     552           0 :       if (!feedback_type.IsInvalid() && feedback_type != static_type) {
     553           0 :         os << ", Feedback type: " << feedback_type;
     554             :       }
     555           0 :       os << "]";
     556             :     }
     557             :     os << std::endl;
     558           0 :   }
     559             : 
     560      482446 :   Type Weaken(Node* node, Type previous_type, Type current_type) {
     561             :     // If the types have nothing to do with integers, return the types.
     562      482446 :     Type const integer = type_cache_->kInteger;
     563      482446 :     if (!previous_type.Maybe(integer)) {
     564       30068 :       return current_type;
     565             :     }
     566             :     DCHECK(current_type.Maybe(integer));
     567             : 
     568      452381 :     Type current_integer = Type::Intersect(current_type, integer, graph_zone());
     569             :     DCHECK(!current_integer.IsNone());
     570             :     Type previous_integer =
     571      452381 :         Type::Intersect(previous_type, integer, graph_zone());
     572             :     DCHECK(!previous_integer.IsNone());
     573             : 
     574             :     // Once we start weakening a node, we should always weaken.
     575      452379 :     if (!GetInfo(node)->weakened()) {
     576             :       // Only weaken if there is range involved; we should converge quickly
     577             :       // for all other types (the exception is a union of many constants,
     578             :       // but we currently do not increase the number of constants in unions).
     579       96012 :       Type previous = previous_integer.GetRange();
     580       96012 :       Type current = current_integer.GetRange();
     581      187789 :       if (current.IsInvalid() || previous.IsInvalid()) {
     582        4327 :         return current_type;
     583             :       }
     584             :       // Range is involved => we are weakening.
     585             :       GetInfo(node)->set_weakened();
     586             :     }
     587             : 
     588             :     return Type::Union(current_type,
     589             :                        op_typer_.WeakenRange(previous_integer, current_integer),
     590      448051 :                        graph_zone());
     591             :   }
     592             : 
     593             :   // Backward propagation of truncations.
     594      463668 :   void RunTruncationPropagationPhase() {
     595             :     // Run propagation phase to a fixpoint.
     596      463668 :     TRACE("--{Propagation phase}--\n");
     597      463668 :     phase_ = PROPAGATE;
     598      463668 :     EnqueueInitial(jsgraph_->graph()->end());
     599             :     // Process nodes from the queue until it is empty.
     600    63458508 :     while (!queue_.empty()) {
     601    31497416 :       Node* node = queue_.front();
     602             :       NodeInfo* info = GetInfo(node);
     603             :       queue_.pop();
     604             :       info->set_visited();
     605    31497373 :       TRACE(" visit #%d: %s (trunc: %s)\n", node->id(), node->op()->mnemonic(),
     606             :             info->truncation().description());
     607    31497373 :       VisitNode(node, info->truncation(), nullptr);
     608             :     }
     609      463671 :   }
     610             : 
     611      463668 :   void Run(SimplifiedLowering* lowering) {
     612      463668 :     RunTruncationPropagationPhase();
     613             : 
     614      463671 :     RunTypePropagationPhase();
     615             : 
     616             :     // Run lowering and change insertion phase.
     617      463669 :     TRACE("--{Simplified lowering phase}--\n");
     618      463680 :     phase_ = LOWER;
     619             :     // Process nodes from the collected {nodes_} vector.
     620    31011090 :     for (NodeVector::iterator i = nodes_.begin(); i != nodes_.end(); ++i) {
     621    30547418 :       Node* node = *i;
     622             :       NodeInfo* info = GetInfo(node);
     623    30547418 :       TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic());
     624             :       // Reuse {VisitNode()} so the representation rules are in one place.
     625             :       SourcePositionTable::Scope scope(
     626    30547418 :           source_positions_, source_positions_->GetSourcePosition(node));
     627             :       NodeOriginTable::Scope origin_scope(node_origins_, "simplified lowering",
     628    30547316 :                                           node);
     629    30547316 :       VisitNode(node, info->truncation(), lowering);
     630             :     }
     631             : 
     632             :     // Perform the final replacements.
     633     1725074 :     for (NodeVector::iterator i = replacements_.begin();
     634             :          i != replacements_.end(); ++i) {
     635     1261403 :       Node* node = *i;
     636     1261403 :       Node* replacement = *(++i);
     637     1261403 :       node->ReplaceUses(replacement);
     638     1261402 :       node->Kill();
     639             :       // We also need to replace the node in the rest of the vector.
     640   187016063 :       for (NodeVector::iterator j = i + 1; j != replacements_.end(); ++j) {
     641             :         ++j;
     642   185754661 :         if (*j == node) *j = replacement;
     643             :       }
     644             :     }
     645      463671 :   }
     646             : 
     647      463668 :   void EnqueueInitial(Node* node) {
     648      463668 :     NodeInfo* info = GetInfo(node);
     649             :     info->set_queued();
     650      463668 :     nodes_.push_back(node);
     651             :     queue_.push(node);
     652      463666 :   }
     653             : 
     654             :   // Enqueue {use_node}'s {index} input if the {use} contains new information
     655             :   // for that input node. Add the input to {nodes_} if this is the first time
     656             :   // it's been visited.
     657   159152580 :   void EnqueueInput(Node* use_node, int index,
     658             :                     UseInfo use_info = UseInfo::None()) {
     659   159152580 :     Node* node = use_node->InputAt(index);
     660   248252671 :     if (phase_ != PROPAGATE) return;
     661             :     NodeInfo* info = GetInfo(node);
     662             : #ifdef DEBUG
     663             :     // Check monotonicity of input requirements.
     664             :     node_input_use_infos_[use_node->id()].SetAndCheckInput(use_node, index,
     665             :                                                            use_info);
     666             : #endif  // DEBUG
     667   100136369 :     if (info->unvisited()) {
     668             :       // First visit of this node.
     669             :       info->set_queued();
     670    30084531 :       nodes_.push_back(node);
     671             :       queue_.push(node);
     672    30084337 :       TRACE("  initial #%i: ", node->id());
     673    30084337 :       info->AddUse(use_info);
     674    30083969 :       PrintTruncation(info->truncation());
     675    30083880 :       return;
     676             :     }
     677    70051838 :     TRACE("   queue #%i?: ", node->id());
     678    70051838 :     PrintTruncation(info->truncation());
     679    70051161 :     if (info->AddUse(use_info)) {
     680             :       // New usage information for the node is available.
     681     2352354 :       if (!info->queued()) {
     682             :         queue_.push(node);
     683             :         info->set_queued();
     684      950179 :         TRACE("   added: ");
     685             :       } else {
     686     1402173 :         TRACE(" inqueue: ");
     687             :       }
     688     2352352 :       PrintTruncation(info->truncation());
     689             :     }
     690             :   }
     691             : 
     692             :   bool lower() const { return phase_ == LOWER; }
     693             :   bool retype() const { return phase_ == RETYPE; }
     694             :   bool propagate() const { return phase_ == PROPAGATE; }
     695             : 
     696             :   void SetOutput(Node* node, MachineRepresentation representation,
     697             :                  Type restriction_type = Type::Any()) {
     698             :     NodeInfo* const info = GetInfo(node);
     699    95404419 :     switch (phase_) {
     700             :       case PROPAGATE:
     701             :         info->set_restriction_type(restriction_type);
     702             :         break;
     703             :       case RETYPE:
     704             :         DCHECK(info->restriction_type().Is(restriction_type));
     705             :         DCHECK(restriction_type.Is(info->restriction_type()));
     706             :         info->set_output(representation);
     707             :         break;
     708             :       case LOWER:
     709             :         DCHECK_EQ(info->representation(), representation);
     710             :         DCHECK(info->restriction_type().Is(restriction_type));
     711             :         DCHECK(restriction_type.Is(info->restriction_type()));
     712             :         break;
     713             :     }
     714             :   }
     715             : 
     716             :   Type GetUpperBound(Node* node) { return NodeProperties::GetType(node); }
     717             : 
     718       88564 :   bool InputCannotBe(Node* node, Type type) {
     719             :     DCHECK_EQ(1, node->op()->ValueInputCount());
     720       88564 :     return !GetUpperBound(node->InputAt(0)).Maybe(type);
     721             :   }
     722             : 
     723       60309 :   bool InputIs(Node* node, Type type) {
     724             :     DCHECK_EQ(1, node->op()->ValueInputCount());
     725      120618 :     return GetUpperBound(node->InputAt(0)).Is(type);
     726             :   }
     727             : 
     728             :   bool BothInputsAreSigned32(Node* node) {
     729       95860 :     return BothInputsAre(node, Type::Signed32());
     730             :   }
     731             : 
     732             :   bool BothInputsAreUnsigned32(Node* node) {
     733      102747 :     return BothInputsAre(node, Type::Unsigned32());
     734             :   }
     735             : 
     736     1038095 :   bool BothInputsAre(Node* node, Type type) {
     737             :     DCHECK_EQ(2, node->op()->ValueInputCount());
     738     2384605 :     return GetUpperBound(node->InputAt(0)).Is(type) &&
     739     1346510 :            GetUpperBound(node->InputAt(1)).Is(type);
     740             :   }
     741             : 
     742             :   bool IsNodeRepresentationTagged(Node* node) {
     743             :     MachineRepresentation representation = GetInfo(node)->representation();
     744             :     return IsAnyTagged(representation);
     745             :   }
     746             : 
     747          72 :   bool OneInputCannotBe(Node* node, Type type) {
     748             :     DCHECK_EQ(2, node->op()->ValueInputCount());
     749         144 :     return !GetUpperBound(node->InputAt(0)).Maybe(type) ||
     750         144 :            !GetUpperBound(node->InputAt(1)).Maybe(type);
     751             :   }
     752             : 
     753      334451 :   void ChangeToPureOp(Node* node, const Operator* new_op) {
     754             :     DCHECK(new_op->HasProperty(Operator::kPure));
     755      334451 :     if (node->op()->EffectInputCount() > 0) {
     756             :       DCHECK_LT(0, node->op()->ControlInputCount());
     757      211072 :       Node* control = NodeProperties::GetControlInput(node);
     758      211058 :       Node* effect = NodeProperties::GetEffectInput(node);
     759      211051 :       if (TypeOf(node).IsNone()) {
     760             :         // If the node is unreachable, insert an Unreachable node and mark the
     761             :         // value dead.
     762             :         // TODO(jarin,tebbi) Find a way to unify/merge this insertion with
     763             :         // InsertUnreachableIfNecessary.
     764         320 :         Node* unreachable = effect = graph()->NewNode(
     765         320 :             jsgraph_->common()->Unreachable(), effect, control);
     766         320 :         new_op = jsgraph_->common()->DeadValue(GetInfo(node)->representation());
     767         320 :         node->ReplaceInput(0, unreachable);
     768             :       }
     769             :       // Rewire the effect and control chains.
     770      211051 :       node->TrimInputCount(new_op->ValueInputCount());
     771      211055 :       ReplaceEffectControlUses(node, effect, control);
     772             :     } else {
     773             :       DCHECK_EQ(0, node->op()->ControlInputCount());
     774             :     }
     775      334429 :     NodeProperties::ChangeOp(node, new_op);
     776      334422 :   }
     777             : 
     778             :   // Converts input {index} of {node} according to given UseInfo {use},
     779             :   // assuming the type of the input is {input_type}. If {input_type} is null,
     780             :   // it takes the input from the input node {TypeOf(node->InputAt(index))}.
     781    53253919 :   void ConvertInput(Node* node, int index, UseInfo use,
     782             :                     Type input_type = Type::Invalid()) {
     783             :     Node* input = node->InputAt(index);
     784             :     // In the change phase, insert a change before the use if necessary.
     785    53253919 :     if (use.representation() == MachineRepresentation::kNone)
     786             :       return;  // No input requirement on the use.
     787             :     DCHECK_NOT_NULL(input);
     788             :     NodeInfo* input_info = GetInfo(input);
     789             :     MachineRepresentation input_rep = input_info->representation();
     790    50799907 :     if (input_rep != use.representation() ||
     791             :         use.type_check() != TypeCheckKind::kNone) {
     792             :       // Output representation doesn't match usage.
     793    16073482 :       TRACE("  change: #%d:%s(@%d #%d:%s) ", node->id(), node->op()->mnemonic(),
     794             :             index, input->id(), input->op()->mnemonic());
     795    16073454 :       TRACE(" from ");
     796    16073454 :       PrintOutputInfo(input_info);
     797    16073402 :       TRACE(" to ");
     798    16073402 :       PrintUseInfo(use);
     799    16073368 :       TRACE("\n");
     800    16073381 :       if (input_type.IsInvalid()) {
     801             :         input_type = TypeOf(input);
     802             :       }
     803    16073381 :       Node* n = changer_->GetRepresentationFor(
     804    16073381 :           input, input_info->representation(), input_type, node, use);
     805    16073223 :       node->ReplaceInput(index, n);
     806             :     }
     807             :   }
     808             : 
     809   172027402 :   void ProcessInput(Node* node, int index, UseInfo use) {
     810   172027402 :     switch (phase_) {
     811             :       case PROPAGATE:
     812    55114403 :         EnqueueInput(node, index, use);
     813    55112430 :         break;
     814             :       case RETYPE:
     815             :         break;
     816             :       case LOWER:
     817    53231381 :         ConvertInput(node, index, use);
     818    53230657 :         break;
     819             :     }
     820   172024705 :   }
     821             : 
     822    18433868 :   void ProcessRemainingInputs(Node* node, int index) {
     823             :     DCHECK_GE(index, NodeProperties::PastValueIndex(node));
     824             :     DCHECK_GE(index, NodeProperties::PastContextIndex(node));
     825    79045585 :     for (int i = std::max(index, NodeProperties::FirstEffectIndex(node));
     826    30305904 :          i < NodeProperties::PastEffectIndex(node); ++i) {
     827    11872089 :       EnqueueInput(node, i);  // Effect inputs: just visit
     828             :     }
     829    79173726 :     for (int i = std::max(index, NodeProperties::FirstControlIndex(node));
     830    30369970 :          i < NodeProperties::PastControlIndex(node); ++i) {
     831    11936181 :       EnqueueInput(node, i);  // Control inputs: just visit
     832             :     }
     833    18433851 :   }
     834             : 
     835             :   // The default, most general visitation case. For {node}, process all value,
     836             :   // context, frame state, effect, and control inputs, assuming that value
     837             :   // inputs should have {kRepTagged} representation and can observe all output
     838             :   // values {kTypeAny}.
     839    29681477 :   void VisitInputs(Node* node) {
     840    29681242 :     int tagged_count = node->op()->ValueInputCount() +
     841             :                        OperatorProperties::GetContextInputCount(node->op()) +
     842    29680894 :                        OperatorProperties::GetFrameStateInputCount(node->op());
     843             :     // Visit value, context and frame state inputs as tagged.
     844   116130232 :     for (int i = 0; i < tagged_count; i++) {
     845    43224700 :       ProcessInput(node, i, UseInfo::AnyTagged());
     846             :     }
     847             :     // Only enqueue other inputs (effects, control).
     848   141602331 :     for (int i = tagged_count; i < node->InputCount(); i++) {
     849    55961020 :       EnqueueInput(node, i);
     850             :     }
     851    29681815 :   }
     852             : 
     853     1674960 :   void VisitReturn(Node* node) {
     854     1674959 :     int tagged_limit = node->op()->ValueInputCount() +
     855             :                        OperatorProperties::GetContextInputCount(node->op()) +
     856     1674960 :                        OperatorProperties::GetFrameStateInputCount(node->op());
     857             :     // Visit integer slot count to pop
     858     1674963 :     ProcessInput(node, 0, UseInfo::TruncatingWord32());
     859             : 
     860             :     // Visit value, context and frame state inputs as tagged.
     861     5024887 :     for (int i = 1; i < tagged_limit; i++) {
     862     1674963 :       ProcessInput(node, i, UseInfo::AnyTagged());
     863             :     }
     864             :     // Only enqueue other inputs (effects, control).
     865     8374811 :     for (int i = tagged_limit; i < node->InputCount(); i++) {
     866     3349925 :       EnqueueInput(node, i);
     867             :     }
     868     1674964 :   }
     869             : 
     870             :   // Helper for an unused node.
     871      330252 :   void VisitUnused(Node* node) {
     872      330252 :     int value_count = node->op()->ValueInputCount() +
     873             :                       OperatorProperties::GetContextInputCount(node->op()) +
     874      330252 :                       OperatorProperties::GetFrameStateInputCount(node->op());
     875     1373758 :     for (int i = 0; i < value_count; i++) {
     876      521753 :       ProcessInput(node, i, UseInfo::None());
     877             :     }
     878      330252 :     ProcessRemainingInputs(node, value_count);
     879      330252 :     if (lower()) Kill(node);
     880      330252 :   }
     881             : 
     882             :   // Helper for no-op node.
     883          36 :   void VisitNoop(Node* node, Truncation truncation) {
     884          36 :     if (truncation.IsUnused()) return VisitUnused(node);
     885             :     MachineRepresentation representation =
     886          22 :         GetOutputInfoForPhi(node, TypeOf(node), truncation);
     887          44 :     VisitUnop(node, UseInfo(representation, truncation), representation);
     888          33 :     if (lower()) DeferReplacement(node, node->InputAt(0));
     889             :   }
     890             : 
     891             :   // Helper for binops of the R x L -> O variety.
     892     3513456 :   void VisitBinop(Node* node, UseInfo left_use, UseInfo right_use,
     893             :                   MachineRepresentation output,
     894             :                   Type restriction_type = Type::Any()) {
     895             :     DCHECK_EQ(2, node->op()->ValueInputCount());
     896     3513456 :     ProcessInput(node, 0, left_use);
     897     3512834 :     ProcessInput(node, 1, right_use);
     898    10209392 :     for (int i = 2; i < node->InputCount(); i++) {
     899     3348393 :       EnqueueInput(node, i);
     900             :     }
     901             :     SetOutput(node, output, restriction_type);
     902     3513327 :   }
     903             : 
     904             :   // Helper for binops of the I x I -> O variety.
     905             :   void VisitBinop(Node* node, UseInfo input_use, MachineRepresentation output,
     906             :                   Type restriction_type = Type::Any()) {
     907     2867356 :     VisitBinop(node, input_use, input_use, output, restriction_type);
     908             :   }
     909             : 
     910       81632 :   void VisitSpeculativeInt32Binop(Node* node) {
     911             :     DCHECK_EQ(2, node->op()->ValueInputCount());
     912       81632 :     if (BothInputsAre(node, Type::NumberOrOddball())) {
     913             :       return VisitBinop(node, UseInfo::TruncatingWord32(),
     914             :                         MachineRepresentation::kWord32);
     915             :     }
     916       18470 :     NumberOperationHint hint = NumberOperationHintOf(node->op());
     917       36940 :     return VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
     918       18470 :                       MachineRepresentation::kWord32);
     919             :   }
     920             : 
     921             :   // Helper for unops of the I -> O variety.
     922    10723226 :   void VisitUnop(Node* node, UseInfo input_use, MachineRepresentation output,
     923             :                  Type restriction_type = Type::Any()) {
     924             :     DCHECK_EQ(1, node->op()->ValueInputCount());
     925    10723226 :     ProcessInput(node, 0, input_use);
     926    10723218 :     ProcessRemainingInputs(node, 1);
     927             :     SetOutput(node, output, restriction_type);
     928    10723215 :   }
     929             : 
     930             :   // Helper for leaf nodes.
     931             :   void VisitLeaf(Node* node, MachineRepresentation output) {
     932             :     DCHECK_EQ(0, node->InputCount());
     933             :     SetOutput(node, output);
     934             :   }
     935             : 
     936             :   // Helpers for specific types of binops.
     937      631499 :   void VisitFloat64Binop(Node* node) {
     938             :     VisitBinop(node, UseInfo::TruncatingFloat64(),
     939             :                MachineRepresentation::kFloat64);
     940      631527 :   }
     941        2098 :   void VisitInt64Binop(Node* node) {
     942             :     VisitBinop(node, UseInfo::Word64(), MachineRepresentation::kWord64);
     943        2098 :   }
     944      490012 :   void VisitWord32TruncatingBinop(Node* node) {
     945             :     VisitBinop(node, UseInfo::TruncatingWord32(),
     946             :                MachineRepresentation::kWord32);
     947      490043 :   }
     948             : 
     949             :   // Infer representation for phi-like nodes.
     950             :   // The {node} parameter is only used to decide on the int64 representation.
     951             :   // Once the type system supports an external pointer type, the {node}
     952             :   // parameter can be removed.
     953     1653861 :   MachineRepresentation GetOutputInfoForPhi(Node* node, Type type,
     954             :                                             Truncation use) {
     955             :     // Compute the representation.
     956     1653816 :     if (type.Is(Type::None())) {
     957             :       return MachineRepresentation::kNone;
     958     2951700 :     } else if (type.Is(Type::Signed32()) || type.Is(Type::Unsigned32())) {
     959             :       return MachineRepresentation::kWord32;
     960     2132346 :     } else if (type.Is(Type::NumberOrOddball()) && use.IsUsedAsWord32()) {
     961             :       return MachineRepresentation::kWord32;
     962     1302189 :     } else if (type.Is(Type::Boolean())) {
     963             :       return MachineRepresentation::kBit;
     964     1952375 :     } else if (type.Is(Type::NumberOrOddball()) && use.IsUsedAsFloat64()) {
     965             :       return MachineRepresentation::kFloat64;
     966     2293121 :     } else if (type.Is(Type::Union(Type::SignedSmall(), Type::NaN(), zone()))) {
     967             :       // TODO(turbofan): For Phis that return either NaN or some Smi, it's
     968             :       // beneficial to not go all the way to double, unless the uses are
     969             :       // double uses. For tagging that just means some potentially expensive
     970             :       // allocation code; we might want to do the same for -0 as well?
     971             :       return MachineRepresentation::kTagged;
     972     1146434 :     } else if (type.Is(Type::Number())) {
     973             :       return MachineRepresentation::kFloat64;
     974      493305 :     } else if (type.Is(Type::ExternalPointer())) {
     975             :       return MachineType::PointerRepresentation();
     976             :     }
     977      493305 :     return MachineRepresentation::kTagged;
     978             :   }
     979             : 
     980             :   // Helper for handling selects.
     981       38504 :   void VisitSelect(Node* node, Truncation truncation,
     982             :                    SimplifiedLowering* lowering) {
     983             :     DCHECK(TypeOf(node->InputAt(0)).Is(Type::Boolean()));
     984       38504 :     ProcessInput(node, 0, UseInfo::Bool());
     985             : 
     986             :     MachineRepresentation output =
     987       38504 :         GetOutputInfoForPhi(node, TypeOf(node), truncation);
     988             :     SetOutput(node, output);
     989             : 
     990       38504 :     if (lower()) {
     991             :       // Update the select operator.
     992       12525 :       SelectParameters p = SelectParametersOf(node->op());
     993       12525 :       if (output != p.representation()) {
     994        7228 :         NodeProperties::ChangeOp(node,
     995        7228 :                                  lowering->common()->Select(output, p.hint()));
     996             :       }
     997             :     }
     998             :     // Convert inputs to the output representation of this phi, pass the
     999             :     // truncation truncation along.
    1000       77008 :     UseInfo input_use(output, truncation);
    1001       38504 :     ProcessInput(node, 1, input_use);
    1002       38504 :     ProcessInput(node, 2, input_use);
    1003       38504 :   }
    1004             : 
    1005             :   // Helper for handling phis.
    1006     1523749 :   void VisitPhi(Node* node, Truncation truncation,
    1007             :                 SimplifiedLowering* lowering) {
    1008             :     MachineRepresentation output =
    1009     1523749 :         GetOutputInfoForPhi(node, TypeOf(node), truncation);
    1010             :     // Only set the output representation if not running with type
    1011             :     // feedback. (Feedback typing will set the representation.)
    1012             :     SetOutput(node, output);
    1013             : 
    1014             :     int values = node->op()->ValueInputCount();
    1015     1523705 :     if (lower()) {
    1016             :       // Update the phi operator.
    1017      319914 :       if (output != PhiRepresentationOf(node->op())) {
    1018      177081 :         NodeProperties::ChangeOp(node, lowering->common()->Phi(output, values));
    1019             :       }
    1020             :     }
    1021             : 
    1022             :     // Convert inputs to the output representation of this phi, pass the
    1023             :     // truncation along.
    1024     3047817 :     UseInfo input_use(output, truncation);
    1025    12769094 :     for (int i = 0; i < node->InputCount(); i++) {
    1026    11245596 :       ProcessInput(node, i, i < values ? input_use : UseInfo::None());
    1027             :     }
    1028     1523787 :   }
    1029             : 
    1030      161822 :   void VisitObjectIs(Node* node, Type type, SimplifiedLowering* lowering) {
    1031      161822 :     Type const input_type = TypeOf(node->InputAt(0));
    1032      161822 :     if (input_type.Is(type)) {
    1033        3999 :       VisitUnop(node, UseInfo::None(), MachineRepresentation::kBit);
    1034        3999 :       if (lower()) {
    1035        1365 :         DeferReplacement(node, lowering->jsgraph()->Int32Constant(1));
    1036             :       }
    1037             :     } else {
    1038      157823 :       VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
    1039      157823 :       if (lower() && !input_type.Maybe(type)) {
    1040         482 :         DeferReplacement(node, lowering->jsgraph()->Int32Constant(0));
    1041             :       }
    1042             :     }
    1043      161822 :   }
    1044             : 
    1045       15387 :   void VisitCheck(Node* node, Type type, SimplifiedLowering* lowering) {
    1046       15387 :     if (InputIs(node, type)) {
    1047             :       VisitUnop(node, UseInfo::AnyTagged(),
    1048         953 :                 MachineRepresentation::kTaggedPointer);
    1049        1243 :       if (lower()) DeferReplacement(node, node->InputAt(0));
    1050             :     } else {
    1051       28868 :       VisitUnop(node,
    1052             :                 UseInfo::CheckedHeapObjectAsTaggedPointer(VectorSlotPair()),
    1053       14434 :                 MachineRepresentation::kTaggedPointer);
    1054             :     }
    1055       15387 :   }
    1056             : 
    1057      338051 :   void VisitCall(Node* node, SimplifiedLowering* lowering) {
    1058      338051 :     auto call_descriptor = CallDescriptorOf(node->op());
    1059      338063 :     int params = static_cast<int>(call_descriptor->ParameterCount());
    1060             :     int value_input_count = node->op()->ValueInputCount();
    1061             :     // Propagate representation information from call descriptor.
    1062     5136875 :     for (int i = 0; i < value_input_count; i++) {
    1063     2399415 :       if (i == 0) {
    1064             :         // The target of the call.
    1065      338053 :         ProcessInput(node, i, UseInfo::Any());
    1066     2061362 :       } else if ((i - 1) < params) {
    1067     1728275 :         ProcessInput(node, i,
    1068             :                      TruncatingUseInfoFromRepresentation(
    1069     3456547 :                          call_descriptor->GetInputType(i).representation()));
    1070             :       } else {
    1071      333087 :         ProcessInput(node, i, UseInfo::AnyTagged());
    1072             :       }
    1073             :     }
    1074      338054 :     ProcessRemainingInputs(node, value_input_count);
    1075             : 
    1076      338057 :     if (call_descriptor->ReturnCount() > 0) {
    1077             :       SetOutput(node, call_descriptor->GetReturnType(0).representation());
    1078             :     } else {
    1079             :       SetOutput(node, MachineRepresentation::kTagged);
    1080             :     }
    1081      338057 :   }
    1082             : 
    1083       10056 :   void MaskShiftOperand(Node* node, Type rhs_type) {
    1084       20112 :     if (!rhs_type.Is(type_cache_->kZeroToThirtyOne)) {
    1085         950 :       Node* const rhs = NodeProperties::GetValueInput(node, 1);
    1086        1900 :       node->ReplaceInput(1,
    1087         950 :                          graph()->NewNode(jsgraph_->machine()->Word32And(), rhs,
    1088        1900 :                                           jsgraph_->Int32Constant(0x1F)));
    1089             :     }
    1090       10056 :   }
    1091             : 
    1092      533048 :   static MachineSemantic DeoptValueSemanticOf(Type type) {
    1093             :     // We only need signedness to do deopt correctly.
    1094      533044 :     if (type.Is(Type::Signed32())) {
    1095             :       return MachineSemantic::kInt32;
    1096      363454 :     } else if (type.Is(Type::Unsigned32())) {
    1097             :       return MachineSemantic::kUint32;
    1098             :     } else {
    1099      361866 :       return MachineSemantic::kAny;
    1100             :     }
    1101             :   }
    1102             : 
    1103    11285040 :   static MachineType DeoptMachineTypeOf(MachineRepresentation rep, Type type) {
    1104    11285040 :     if (type.IsNone()) {
    1105             :       return MachineType::None();
    1106             :     }
    1107             :     // Do not distinguish between various Tagged variations.
    1108    11285040 :     if (IsAnyTagged(rep)) {
    1109             :       return MachineType::AnyTagged();
    1110             :     }
    1111             :     // Do not distinguish between various Compressed variations.
    1112      533101 :     if (IsAnyCompressed(rep)) {
    1113             :       return MachineType::AnyCompressed();
    1114             :     }
    1115             :     // Word64 representation is only valid for safe integer values.
    1116      533101 :     if (rep == MachineRepresentation::kWord64) {
    1117             :       DCHECK(type.Is(TypeCache::Get()->kSafeInteger));
    1118          51 :       return MachineType(rep, MachineSemantic::kInt64);
    1119             :     }
    1120      533050 :     MachineType machine_type(rep, DeoptValueSemanticOf(type));
    1121             :     DCHECK(machine_type.representation() != MachineRepresentation::kWord32 ||
    1122             :            machine_type.semantic() == MachineSemantic::kInt32 ||
    1123             :            machine_type.semantic() == MachineSemantic::kUint32);
    1124             :     DCHECK(machine_type.representation() != MachineRepresentation::kBit ||
    1125             :            type.Is(Type::Boolean()));
    1126      533034 :     return machine_type;
    1127             :   }
    1128             : 
    1129    10984700 :   void VisitStateValues(Node* node) {
    1130    10984700 :     if (propagate()) {
    1131    23688556 :       for (int i = 0; i < node->InputCount(); i++) {
    1132    10287407 :         EnqueueInput(node, i, UseInfo::Any());
    1133             :       }
    1134     7870840 :     } else if (lower()) {
    1135     3113913 :       Zone* zone = jsgraph_->zone();
    1136             :       ZoneVector<MachineType>* types =
    1137             :           new (zone->New(sizeof(ZoneVector<MachineType>)))
    1138     6227831 :               ZoneVector<MachineType>(node->InputCount(), zone);
    1139    23688619 :       for (int i = 0; i < node->InputCount(); i++) {
    1140             :         Node* input = node->InputAt(i);
    1141    10287362 :         (*types)[i] =
    1142    10287362 :             DeoptMachineTypeOf(GetInfo(input)->representation(), TypeOf(input));
    1143             :       }
    1144     3113907 :       SparseInputMask mask = SparseInputMaskOf(node->op());
    1145     3113907 :       NodeProperties::ChangeOp(
    1146     6227814 :           node, jsgraph_->common()->TypedStateValues(types, mask));
    1147             :     }
    1148             :     SetOutput(node, MachineRepresentation::kTagged);
    1149    10984705 :   }
    1150             : 
    1151    16608800 :   void VisitFrameState(Node* node) {
    1152             :     DCHECK_EQ(5, node->op()->ValueInputCount());
    1153             :     DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
    1154             : 
    1155    16608828 :     ProcessInput(node, 0, UseInfo::AnyTagged());  // Parameters.
    1156    16608817 :     ProcessInput(node, 1, UseInfo::AnyTagged());  // Registers.
    1157             : 
    1158             :     // Accumulator is a special flower - we need to remember its type in
    1159             :     // a singleton typed-state-values node (as if it was a singleton
    1160             :     // state-values node).
    1161    16608842 :     if (propagate()) {
    1162     5256102 :       EnqueueInput(node, 2, UseInfo::Any());
    1163    11352747 :     } else if (lower()) {
    1164     5256105 :       Zone* zone = jsgraph_->zone();
    1165             :       Node* accumulator = node->InputAt(2);
    1166     5256105 :       if (accumulator == jsgraph_->OptimizedOutConstant()) {
    1167     4392799 :         node->ReplaceInput(2, jsgraph_->SingleDeadTypedStateValues());
    1168             :       } else {
    1169             :         ZoneVector<MachineType>* types =
    1170             :             new (zone->New(sizeof(ZoneVector<MachineType>)))
    1171      863305 :                 ZoneVector<MachineType>(1, zone);
    1172             :         (*types)[0] = DeoptMachineTypeOf(GetInfo(accumulator)->representation(),
    1173      863304 :                                          TypeOf(accumulator));
    1174             : 
    1175      863304 :         node->ReplaceInput(
    1176     1726609 :             2, jsgraph_->graph()->NewNode(jsgraph_->common()->TypedStateValues(
    1177             :                                               types, SparseInputMask::Dense()),
    1178      863304 :                                           accumulator));
    1179             :       }
    1180             :     }
    1181             : 
    1182    16608837 :     ProcessInput(node, 3, UseInfo::AnyTagged());  // Context.
    1183    16608823 :     ProcessInput(node, 4, UseInfo::AnyTagged());  // Closure.
    1184    16608829 :     ProcessInput(node, 5, UseInfo::AnyTagged());  // Outer frame state.
    1185    16608825 :     return SetOutput(node, MachineRepresentation::kTagged);
    1186             :   }
    1187             : 
    1188       69801 :   void VisitObjectState(Node* node) {
    1189       69801 :     if (propagate()) {
    1190      291227 :       for (int i = 0; i < node->InputCount(); i++) {
    1191      134329 :         EnqueueInput(node, i, UseInfo::Any());
    1192             :       }
    1193       47232 :     } else if (lower()) {
    1194       22569 :       Zone* zone = jsgraph_->zone();
    1195             :       ZoneVector<MachineType>* types =
    1196             :           new (zone->New(sizeof(ZoneVector<MachineType>)))
    1197       45138 :               ZoneVector<MachineType>(node->InputCount(), zone);
    1198      291227 :       for (int i = 0; i < node->InputCount(); i++) {
    1199             :         Node* input = node->InputAt(i);
    1200      134329 :         (*types)[i] =
    1201      134329 :             DeoptMachineTypeOf(GetInfo(input)->representation(), TypeOf(input));
    1202             :       }
    1203       22569 :       NodeProperties::ChangeOp(node, jsgraph_->common()->TypedObjectState(
    1204       22569 :                                          ObjectIdOf(node->op()), types));
    1205             :     }
    1206             :     SetOutput(node, MachineRepresentation::kTagged);
    1207       69801 :   }
    1208             : 
    1209             :   const Operator* Int32Op(Node* node) {
    1210      213226 :     return changer_->Int32OperatorFor(node->opcode());
    1211             :   }
    1212             : 
    1213             :   const Operator* Int32OverflowOp(Node* node) {
    1214      151002 :     return changer_->Int32OverflowOperatorFor(node->opcode());
    1215             :   }
    1216             : 
    1217             :   const Operator* Int64Op(Node* node) {
    1218         481 :     return changer_->Int64OperatorFor(node->opcode());
    1219             :   }
    1220             : 
    1221             :   const Operator* Uint32Op(Node* node) {
    1222       36293 :     return changer_->Uint32OperatorFor(node->opcode());
    1223             :   }
    1224             : 
    1225             :   const Operator* Uint32OverflowOp(Node* node) {
    1226         113 :     return changer_->Uint32OverflowOperatorFor(node->opcode());
    1227             :   }
    1228             : 
    1229             :   const Operator* Float64Op(Node* node) {
    1230      168249 :     return changer_->Float64OperatorFor(node->opcode());
    1231             :   }
    1232             : 
    1233     6416398 :   WriteBarrierKind WriteBarrierKindFor(
    1234             :       BaseTaggedness base_taggedness,
    1235             :       MachineRepresentation field_representation, Type field_type,
    1236             :       MachineRepresentation value_representation, Node* value) {
    1237    12832796 :     if (base_taggedness == kTaggedBase &&
    1238             :         CanBeTaggedPointer(field_representation)) {
    1239     5624643 :       Type value_type = NodeProperties::GetType(value);
    1240    11249286 :       if (field_representation == MachineRepresentation::kTaggedSigned ||
    1241     5624643 :           value_representation == MachineRepresentation::kTaggedSigned) {
    1242             :         // Write barriers are only for stores of heap objects.
    1243             :         return kNoWriteBarrier;
    1244             :       }
    1245    11249266 :       if (field_type.Is(Type::BooleanOrNullOrUndefined()) ||
    1246             :           value_type.Is(Type::BooleanOrNullOrUndefined())) {
    1247             :         // Write barriers are not necessary when storing true, false, null or
    1248             :         // undefined, because these special oddballs are always in the root set.
    1249             :         return kNoWriteBarrier;
    1250             :       }
    1251     5238719 :       if (value_type.IsHeapConstant()) {
    1252             :         RootIndex root_index;
    1253     1897060 :         const RootsTable& roots_table = jsgraph_->isolate()->roots_table();
    1254     3794119 :         if (roots_table.IsRootHandle(value_type.AsHeapConstant()->Value(),
    1255             :                                      &root_index)) {
    1256     1089909 :           if (RootsTable::IsImmortalImmovable(root_index)) {
    1257             :             // Write barriers are unnecessary for immortal immovable roots.
    1258             :             return kNoWriteBarrier;
    1259             :           }
    1260             :         }
    1261             :       }
    1262     8297620 :       if (field_representation == MachineRepresentation::kTaggedPointer ||
    1263     4148810 :           value_representation == MachineRepresentation::kTaggedPointer) {
    1264             :         // Write barriers for heap objects are cheaper.
    1265             :         return kPointerWriteBarrier;
    1266             :       }
    1267             :       NumberMatcher m(value);
    1268     3199497 :       if (m.HasValue()) {
    1269        1358 :         if (IsSmiDouble(m.Value())) {
    1270             :           // Storing a smi doesn't need a write barrier.
    1271             :           return kNoWriteBarrier;
    1272             :         }
    1273             :         // The NumberConstant will be represented as HeapNumber.
    1274        1358 :         return kPointerWriteBarrier;
    1275             :       }
    1276             :       return kFullWriteBarrier;
    1277             :     }
    1278             :     return kNoWriteBarrier;
    1279             :   }
    1280             : 
    1281             :   WriteBarrierKind WriteBarrierKindFor(
    1282             :       BaseTaggedness base_taggedness,
    1283             :       MachineRepresentation field_representation, int field_offset,
    1284             :       Type field_type, MachineRepresentation value_representation,
    1285             :       Node* value) {
    1286             :     WriteBarrierKind write_barrier_kind =
    1287     6300463 :         WriteBarrierKindFor(base_taggedness, field_representation, field_type,
    1288     6300463 :                             value_representation, value);
    1289     6300464 :     if (write_barrier_kind != kNoWriteBarrier) {
    1290     8207834 :       if (base_taggedness == kTaggedBase &&
    1291     4103917 :           field_offset == HeapObject::kMapOffset) {
    1292             :         write_barrier_kind = kMapWriteBarrier;
    1293             :       }
    1294             :     }
    1295             :     return write_barrier_kind;
    1296             :   }
    1297             : 
    1298             :   Graph* graph() const { return jsgraph_->graph(); }
    1299             :   CommonOperatorBuilder* common() const { return jsgraph_->common(); }
    1300             :   SimplifiedOperatorBuilder* simplified() const {
    1301             :     return jsgraph_->simplified();
    1302             :   }
    1303             : 
    1304        6216 :   void LowerToCheckedInt32Mul(Node* node, Truncation truncation,
    1305             :                               Type input0_type, Type input1_type) {
    1306             :     // If one of the inputs is positive and/or truncation is being applied,
    1307             :     // there is no need to return -0.
    1308             :     CheckForMinusZeroMode mz_mode =
    1309        4562 :         truncation.IdentifiesZeroAndMinusZero() ||
    1310        9083 :                 IsSomePositiveOrderedNumber(input0_type) ||
    1311        4521 :                 IsSomePositiveOrderedNumber(input1_type)
    1312             :             ? CheckForMinusZeroMode::kDontCheckForMinusZero
    1313        6216 :             : CheckForMinusZeroMode::kCheckForMinusZero;
    1314             : 
    1315        6216 :     NodeProperties::ChangeOp(node, simplified()->CheckedInt32Mul(mz_mode));
    1316        6216 :   }
    1317             : 
    1318      151002 :   void ChangeToInt32OverflowOp(Node* node) {
    1319      150997 :     NodeProperties::ChangeOp(node, Int32OverflowOp(node));
    1320      150990 :   }
    1321             : 
    1322         113 :   void ChangeToUint32OverflowOp(Node* node) {
    1323         113 :     NodeProperties::ChangeOp(node, Uint32OverflowOp(node));
    1324         113 :   }
    1325             : 
    1326      795515 :   void VisitSpeculativeIntegerAdditiveOp(Node* node, Truncation truncation,
    1327             :                                          SimplifiedLowering* lowering) {
    1328      795515 :     Type left_upper = GetUpperBound(node->InputAt(0));
    1329      795515 :     Type right_upper = GetUpperBound(node->InputAt(1));
    1330             : 
    1331     1940401 :     if (left_upper.Is(type_cache_->kAdditiveSafeIntegerOrMinusZero) &&
    1332      349486 :         right_upper.Is(type_cache_->kAdditiveSafeIntegerOrMinusZero)) {
    1333             :       // Only eliminate the node if its typing rule can be satisfied, namely
    1334             :       // that a safe integer is produced.
    1335      343469 :       if (truncation.IsUnused()) return VisitUnused(node);
    1336             : 
    1337             :       // If we know how to interpret the result or if the users only care
    1338             :       // about the low 32-bits, we can truncate to Word32 do a wrapping
    1339             :       // addition.
    1340      719947 :       if (GetUpperBound(node).Is(Type::Signed32()) ||
    1341      393832 :           GetUpperBound(node).Is(Type::Unsigned32()) ||
    1342             :           truncation.IsUsedAsWord32()) {
    1343             :         // => Int32Add/Sub
    1344      262089 :         VisitWord32TruncatingBinop(node);
    1345      325871 :         if (lower()) ChangeToPureOp(node, Int32Op(node));
    1346             :         return;
    1347             :       }
    1348             :     }
    1349             : 
    1350             :     // Try to use type feedback.
    1351      515817 :     NumberOperationHint hint = NumberOperationHintOf(node->op());
    1352             :     DCHECK(hint == NumberOperationHint::kSignedSmall ||
    1353             :            hint == NumberOperationHint::kSigned32);
    1354             : 
    1355      516090 :     Type left_feedback_type = TypeOf(node->InputAt(0));
    1356      516090 :     Type right_feedback_type = TypeOf(node->InputAt(1));
    1357             :     // Handle the case when no int32 checks on inputs are necessary (but
    1358             :     // an overflow check is needed on the output). Note that we do not
    1359             :     // have to do any check if at most one side can be minus zero. For
    1360             :     // subtraction we need to handle the case of -0 - 0 properly, since
    1361             :     // that can produce -0.
    1362             :     Type left_constraint_type =
    1363             :         node->opcode() == IrOpcode::kSpeculativeSafeIntegerAdd
    1364             :             ? Type::Signed32OrMinusZero()
    1365      516090 :             : Type::Signed32();
    1366      583963 :     if (left_upper.Is(left_constraint_type) &&
    1367      577831 :         right_upper.Is(Type::Signed32OrMinusZero()) &&
    1368          21 :         (left_upper.Is(Type::Signed32()) || right_upper.Is(Type::Signed32()))) {
    1369             :       VisitBinop(node, UseInfo::TruncatingWord32(),
    1370             :                  MachineRepresentation::kWord32, Type::Signed32());
    1371             :     } else {
    1372             :       // If the output's truncation is identify-zeros, we can pass it
    1373             :       // along. Moreover, if the operation is addition and we know the
    1374             :       // right-hand side is not minus zero, we do not have to distinguish
    1375             :       // between 0 and -0.
    1376             :       IdentifyZeros left_identify_zeros = truncation.identify_zeros();
    1377      893817 :       if (node->opcode() == IrOpcode::kSpeculativeSafeIntegerAdd &&
    1378      439439 :           !right_feedback_type.Maybe(Type::MinusZero())) {
    1379             :         left_identify_zeros = kIdentifyZeros;
    1380             :       }
    1381             :       UseInfo left_use = CheckedUseInfoAsWord32FromHint(hint, VectorSlotPair(),
    1382      454378 :                                                         left_identify_zeros);
    1383             :       // For CheckedInt32Add and CheckedInt32Sub, we don't need to do
    1384             :       // a minus zero check for the right hand side, since we already
    1385             :       // know that the left hand side is a proper Signed32 value,
    1386             :       // potentially guarded by a check.
    1387             :       UseInfo right_use = CheckedUseInfoAsWord32FromHint(hint, VectorSlotPair(),
    1388      454548 :                                                          kIdentifyZeros);
    1389             :       VisitBinop(node, left_use, right_use, MachineRepresentation::kWord32,
    1390      454512 :                  Type::Signed32());
    1391             :     }
    1392      516297 :     if (lower()) {
    1393      310101 :       if (truncation.IsUsedAsWord32() ||
    1394      154779 :           !CanOverflowSigned32(node->op(), left_feedback_type,
    1395             :                                right_feedback_type, graph_zone())) {
    1396        5800 :         ChangeToPureOp(node, Int32Op(node));
    1397             : 
    1398             :       } else {
    1399      149522 :         ChangeToInt32OverflowOp(node);
    1400             :       }
    1401             :     }
    1402             :     return;
    1403             :   }
    1404             : 
    1405        3876 :   void VisitSpeculativeAdditiveOp(Node* node, Truncation truncation,
    1406             :                                   SimplifiedLowering* lowering) {
    1407       11628 :     if (BothInputsAre(node, type_cache_->kAdditiveSafeIntegerOrMinusZero) &&
    1408        3876 :         (GetUpperBound(node).Is(Type::Signed32()) ||
    1409           0 :          GetUpperBound(node).Is(Type::Unsigned32()) ||
    1410             :          truncation.IsUsedAsWord32())) {
    1411             :       // => Int32Add/Sub
    1412           0 :       VisitWord32TruncatingBinop(node);
    1413           0 :       if (lower()) ChangeToPureOp(node, Int32Op(node));
    1414             :       return;
    1415             :     }
    1416             : 
    1417             :     // default case => Float64Add/Sub
    1418        7752 :     VisitBinop(node,
    1419             :                UseInfo::CheckedNumberOrOddballAsFloat64(kDistinguishZeros,
    1420             :                                                         VectorSlotPair()),
    1421             :                MachineRepresentation::kFloat64, Type::Number());
    1422        3876 :     if (lower()) {
    1423        1109 :       ChangeToPureOp(node, Float64Op(node));
    1424             :     }
    1425             :     return;
    1426             :   }
    1427             : 
    1428       13678 :   void VisitSpeculativeNumberModulus(Node* node, Truncation truncation,
    1429             :                                      SimplifiedLowering* lowering) {
    1430       41641 :     if (BothInputsAre(node, Type::Unsigned32OrMinusZeroOrNaN()) &&
    1431         165 :         (truncation.IsUsedAsWord32() ||
    1432       14008 :          NodeProperties::GetType(node).Is(Type::Unsigned32()))) {
    1433             :       // => unsigned Uint32Mod
    1434         640 :       VisitWord32TruncatingBinop(node);
    1435         640 :       if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
    1436             :       return;
    1437             :     }
    1438       46122 :     if (BothInputsAre(node, Type::Signed32OrMinusZeroOrNaN()) &&
    1439        1239 :         (truncation.IsUsedAsWord32() ||
    1440       15516 :          NodeProperties::GetType(node).Is(Type::Signed32()))) {
    1441             :       // => signed Int32Mod
    1442        7008 :       VisitWord32TruncatingBinop(node);
    1443        7008 :       if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
    1444             :       return;
    1445             :     }
    1446             : 
    1447             :     // Try to use type feedback.
    1448        6030 :     NumberOperationHint hint = NumberOperationHintOf(node->op());
    1449             : 
    1450             :     // Handle the case when no uint32 checks on inputs are necessary
    1451             :     // (but an overflow check is needed on the output).
    1452        6030 :     if (BothInputsAreUnsigned32(node)) {
    1453         264 :       if (hint == NumberOperationHint::kSignedSmall ||
    1454         132 :           hint == NumberOperationHint::kSigned32) {
    1455             :         VisitBinop(node, UseInfo::TruncatingWord32(),
    1456             :                    MachineRepresentation::kWord32, Type::Unsigned32());
    1457         132 :         if (lower()) ChangeToUint32OverflowOp(node);
    1458             :         return;
    1459             :       }
    1460             :     }
    1461             : 
    1462             :     // Handle the case when no int32 checks on inputs are necessary
    1463             :     // (but an overflow check is needed on the output).
    1464        5898 :     if (BothInputsAre(node, Type::Signed32())) {
    1465             :       // If both the inputs the feedback are int32, use the overflow op.
    1466        2214 :       if (hint == NumberOperationHint::kSignedSmall ||
    1467        1107 :           hint == NumberOperationHint::kSigned32) {
    1468             :         VisitBinop(node, UseInfo::TruncatingWord32(),
    1469             :                    MachineRepresentation::kWord32, Type::Signed32());
    1470        1107 :         if (lower()) ChangeToInt32OverflowOp(node);
    1471             :         return;
    1472             :       }
    1473             :     }
    1474             : 
    1475        9582 :     if (hint == NumberOperationHint::kSignedSmall ||
    1476        4791 :         hint == NumberOperationHint::kSigned32) {
    1477             :       // If the result is truncated, we only need to check the inputs.
    1478             :       // For the left hand side we just propagate the identify zeros
    1479             :       // mode of the {truncation}; and for modulus the sign of the
    1480             :       // right hand side doesn't matter anyways, so in particular there's
    1481             :       // no observable difference between a 0 and a -0 then.
    1482             :       UseInfo const lhs_use = CheckedUseInfoAsWord32FromHint(
    1483        3997 :           hint, VectorSlotPair(), truncation.identify_zeros());
    1484             :       UseInfo const rhs_use = CheckedUseInfoAsWord32FromHint(
    1485        3997 :           hint, VectorSlotPair(), kIdentifyZeros);
    1486        3997 :       if (truncation.IsUsedAsWord32()) {
    1487         190 :         VisitBinop(node, lhs_use, rhs_use, MachineRepresentation::kWord32);
    1488         190 :         if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
    1489        3807 :       } else if (BothInputsAre(node, Type::Unsigned32OrMinusZeroOrNaN())) {
    1490             :         VisitBinop(node, lhs_use, rhs_use, MachineRepresentation::kWord32,
    1491           0 :                    Type::Unsigned32());
    1492           0 :         if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
    1493             :       } else {
    1494             :         VisitBinop(node, lhs_use, rhs_use, MachineRepresentation::kWord32,
    1495        3807 :                    Type::Signed32());
    1496        3807 :         if (lower()) ChangeToInt32OverflowOp(node);
    1497             :       }
    1498             :       return;
    1499             :     }
    1500             : 
    1501        1640 :     if (TypeOf(node->InputAt(0)).Is(Type::Unsigned32()) &&
    1502        1640 :         TypeOf(node->InputAt(1)).Is(Type::Unsigned32()) &&
    1503           0 :         (truncation.IsUsedAsWord32() ||
    1504         794 :          NodeProperties::GetType(node).Is(Type::Unsigned32()))) {
    1505             :       VisitBinop(node, UseInfo::TruncatingWord32(),
    1506             :                  MachineRepresentation::kWord32, Type::Number());
    1507           0 :       if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
    1508             :       return;
    1509             :     }
    1510        1707 :     if (TypeOf(node->InputAt(0)).Is(Type::Signed32()) &&
    1511        1707 :         TypeOf(node->InputAt(1)).Is(Type::Signed32()) &&
    1512           0 :         (truncation.IsUsedAsWord32() ||
    1513         794 :          NodeProperties::GetType(node).Is(Type::Signed32()))) {
    1514             :       VisitBinop(node, UseInfo::TruncatingWord32(),
    1515             :                  MachineRepresentation::kWord32, Type::Number());
    1516           0 :       if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
    1517             :       return;
    1518             :     }
    1519             : 
    1520             :     // default case => Float64Mod
    1521             :     // For the left hand side we just propagate the identify zeros
    1522             :     // mode of the {truncation}; and for modulus the sign of the
    1523             :     // right hand side doesn't matter anyways, so in particular there's
    1524             :     // no observable difference between a 0 and a -0 then.
    1525             :     UseInfo const lhs_use = UseInfo::CheckedNumberOrOddballAsFloat64(
    1526        1588 :         truncation.identify_zeros(), VectorSlotPair());
    1527             :     UseInfo const rhs_use = UseInfo::CheckedNumberOrOddballAsFloat64(
    1528        1588 :         kIdentifyZeros, VectorSlotPair());
    1529             :     VisitBinop(node, lhs_use, rhs_use, MachineRepresentation::kFloat64,
    1530         794 :                Type::Number());
    1531        1001 :     if (lower()) ChangeToPureOp(node, Float64Op(node));
    1532             :     return;
    1533             :   }
    1534             : 
    1535    30546926 :   void InsertUnreachableIfNecessary(Node* node) {
    1536             :     DCHECK(lower());
    1537             :     // If the node is effectful and it produces an impossible value, then we
    1538             :     // insert Unreachable node after it.
    1539    51193698 :     if (node->op()->ValueOutputCount() > 0 &&
    1540     5464483 :         node->op()->EffectOutputCount() > 0 &&
    1541    36010640 :         node->opcode() != IrOpcode::kUnreachable && TypeOf(node).IsNone()) {
    1542             :       Node* control =
    1543             :           (node->op()->ControlOutputCount() == 0)
    1544             :               ? NodeProperties::GetControlInput(node, 0)
    1545        1176 :               : NodeProperties::FindSuccessfulControlProjection(node);
    1546             : 
    1547             :       Node* unreachable =
    1548        1176 :           graph()->NewNode(common()->Unreachable(), node, control);
    1549             : 
    1550             :       // Insert unreachable node and replace all the effect uses of the {node}
    1551             :       // with the new unreachable node.
    1552        7392 :       for (Edge edge : node->use_edges()) {
    1553        3108 :         if (!NodeProperties::IsEffectEdge(edge)) continue;
    1554             :         // Make sure to not overwrite the unreachable node's input. That would
    1555             :         // create a cycle.
    1556        2359 :         if (edge.from() == unreachable) continue;
    1557             :         // Avoid messing up the exceptional path.
    1558        1183 :         if (edge.from()->opcode() == IrOpcode::kIfException) {
    1559             :           DCHECK(!node->op()->HasProperty(Operator::kNoThrow));
    1560             :           DCHECK_EQ(NodeProperties::GetControlInput(edge.from()), node);
    1561             :           continue;
    1562             :         }
    1563             : 
    1564        1176 :         edge.UpdateTo(unreachable);
    1565             :       }
    1566             :     }
    1567    30546926 :   }
    1568             : 
    1569      187704 :   void VisitCheckBounds(Node* node, SimplifiedLowering* lowering) {
    1570      187704 :     CheckParameters const& p = CheckParametersOf(node->op());
    1571      187704 :     Type const index_type = TypeOf(node->InputAt(0));
    1572      187704 :     Type const length_type = TypeOf(node->InputAt(1));
    1573      187704 :     if (length_type.Is(Type::Unsigned31())) {
    1574      187082 :       if (index_type.Is(Type::Integral32OrMinusZero())) {
    1575             :         // Map -0 to 0, and the values in the [-2^31,-1] range to the
    1576             :         // [2^31,2^32-1] range, which will be considered out-of-bounds
    1577             :         // as well, because the {length_type} is limited to Unsigned31.
    1578             :         VisitBinop(node, UseInfo::TruncatingWord32(),
    1579             :                    MachineRepresentation::kWord32);
    1580      173496 :         if (lower()) {
    1581             :           CheckBoundsParameters::Mode mode =
    1582             :               CheckBoundsParameters::kDeoptOnOutOfBounds;
    1583      104446 :           if (lowering->poisoning_level_ ==
    1584      104446 :                   PoisoningMitigationLevel::kDontPoison &&
    1585      104446 :               (index_type.IsNone() || length_type.IsNone() ||
    1586      100557 :                (index_type.Min() >= 0.0 &&
    1587       48334 :                 index_type.Max() < length_type.Min()))) {
    1588             :             // The bounds check is redundant if we already know that
    1589             :             // the index is within the bounds of [0.0, length[.
    1590             :             mode = CheckBoundsParameters::kAbortOnOutOfBounds;
    1591             :           }
    1592       52223 :           NodeProperties::ChangeOp(
    1593       52223 :               node, simplified()->CheckedUint32Bounds(p.feedback(), mode));
    1594             :         }
    1595             :       } else {
    1596             :         VisitBinop(
    1597             :             node,
    1598             :             UseInfo::CheckedSigned32AsWord32(kIdentifyZeros, p.feedback()),
    1599       13586 :             UseInfo::TruncatingWord32(), MachineRepresentation::kWord32);
    1600       13586 :         if (lower()) {
    1601        2639 :           NodeProperties::ChangeOp(
    1602             :               node,
    1603             :               simplified()->CheckedUint32Bounds(
    1604        2639 :                   p.feedback(), CheckBoundsParameters::kDeoptOnOutOfBounds));
    1605             :         }
    1606             :       }
    1607             :     } else {
    1608             :       DCHECK(length_type.Is(type_cache_->kPositiveSafeInteger));
    1609             :       VisitBinop(node,
    1610             :                  UseInfo::CheckedSigned64AsWord64(kIdentifyZeros, p.feedback()),
    1611         622 :                  UseInfo::Word64(), MachineRepresentation::kWord64);
    1612         622 :       if (lower()) {
    1613         202 :         NodeProperties::ChangeOp(
    1614         202 :             node, simplified()->CheckedUint64Bounds(p.feedback()));
    1615             :       }
    1616             :     }
    1617      187704 :   }
    1618             : 
    1619             :   // Dispatching routine for visiting the node {node} with the usage {use}.
    1620             :   // Depending on the operator, propagate new usage info to the inputs.
    1621    97593101 :   void VisitNode(Node* node, Truncation truncation,
    1622             :                  SimplifiedLowering* lowering) {
    1623             :     // Unconditionally eliminate unused pure nodes (only relevant if there's
    1624             :     // a pure operation in between two effectful ones, where the last one
    1625             :     // is unused).
    1626             :     // Note: We must not do this for constants, as they are cached and we
    1627             :     // would thus kill the cached {node} during lowering (i.e. replace all
    1628             :     // uses with Dead), but at that point some node lowering might have
    1629             :     // already taken the constant {node} from the cache (while it was in
    1630             :     // a sane state still) and we would afterwards replace that use with
    1631             :     // Dead as well.
    1632   158333716 :     if (node->op()->ValueInputCount() > 0 &&
    1633   134458559 :         node->op()->HasProperty(Operator::kPure) && truncation.IsUnused()) {
    1634      109346 :       return VisitUnused(node);
    1635             :     }
    1636             : 
    1637    97483755 :     if (lower()) InsertUnreachableIfNecessary(node);
    1638             : 
    1639    97495633 :     switch (node->opcode()) {
    1640             :       //------------------------------------------------------------------
    1641             :       // Common operators.
    1642             :       //------------------------------------------------------------------
    1643             :       case IrOpcode::kStart:
    1644             :         // We use Start as a terminator for the frame state chain, so even
    1645             :         // tho Start doesn't really produce a value, we have to say Tagged
    1646             :         // here, otherwise the input conversion will fail.
    1647             :         return VisitLeaf(node, MachineRepresentation::kTagged);
    1648             :       case IrOpcode::kParameter:
    1649             :         // TODO(titzer): use representation from linkage.
    1650     5998145 :         return VisitUnop(node, UseInfo::None(), MachineRepresentation::kTagged);
    1651             :       case IrOpcode::kInt32Constant:
    1652             :         return VisitLeaf(node, MachineRepresentation::kWord32);
    1653             :       case IrOpcode::kInt64Constant:
    1654             :         return VisitLeaf(node, MachineRepresentation::kWord64);
    1655             :       case IrOpcode::kExternalConstant:
    1656             :         return VisitLeaf(node, MachineType::PointerRepresentation());
    1657             :       case IrOpcode::kNumberConstant: {
    1658     3571082 :         double const value = OpParameter<double>(node->op());
    1659             :         int value_as_int;
    1660     3571082 :         if (DoubleToSmiInteger(value, &value_as_int)) {
    1661             :           VisitLeaf(node, MachineRepresentation::kTaggedSigned);
    1662     3428335 :           if (lower()) {
    1663             :             intptr_t smi = bit_cast<intptr_t>(Smi::FromInt(value_as_int));
    1664     1098521 :             DeferReplacement(node, lowering->jsgraph()->IntPtrConstant(smi));
    1665             :           }
    1666             :           return;
    1667             :         }
    1668             :         VisitLeaf(node, MachineRepresentation::kTagged);
    1669             :         return;
    1670             :       }
    1671             :       case IrOpcode::kHeapConstant:
    1672             :       case IrOpcode::kDelayedStringConstant:
    1673             :         return VisitLeaf(node, MachineRepresentation::kTaggedPointer);
    1674             :       case IrOpcode::kPointerConstant: {
    1675             :         VisitLeaf(node, MachineType::PointerRepresentation());
    1676         666 :         if (lower()) {
    1677         222 :           intptr_t const value = OpParameter<intptr_t>(node->op());
    1678         222 :           DeferReplacement(node, lowering->jsgraph()->IntPtrConstant(value));
    1679             :         }
    1680             :         return;
    1681             :       }
    1682             : 
    1683             :       case IrOpcode::kBranch: {
    1684             :         DCHECK(TypeOf(node->InputAt(0)).Is(Type::Boolean()));
    1685     1845416 :         ProcessInput(node, 0, UseInfo::Bool());
    1686     1845344 :         EnqueueInput(node, NodeProperties::FirstControlIndex(node));
    1687     1845344 :         return;
    1688             :       }
    1689             :       case IrOpcode::kSwitch:
    1690       21860 :         ProcessInput(node, 0, UseInfo::TruncatingWord32());
    1691       21860 :         EnqueueInput(node, NodeProperties::FirstControlIndex(node));
    1692       21860 :         return;
    1693             :       case IrOpcode::kSelect:
    1694       38504 :         return VisitSelect(node, truncation, lowering);
    1695             :       case IrOpcode::kPhi:
    1696     1523763 :         return VisitPhi(node, truncation, lowering);
    1697             :       case IrOpcode::kCall:
    1698      338053 :         return VisitCall(node, lowering);
    1699             : 
    1700             :       //------------------------------------------------------------------
    1701             :       // JavaScript operators.
    1702             :       //------------------------------------------------------------------
    1703             :       case IrOpcode::kToBoolean: {
    1704      153296 :         if (truncation.IsUsedAsBool()) {
    1705      152696 :           ProcessInput(node, 0, UseInfo::Bool());
    1706             :           SetOutput(node, MachineRepresentation::kBit);
    1707      201085 :           if (lower()) DeferReplacement(node, node->InputAt(0));
    1708             :         } else {
    1709         600 :           VisitInputs(node);
    1710             :           SetOutput(node, MachineRepresentation::kTaggedPointer);
    1711             :         }
    1712             :         return;
    1713             :       }
    1714             :       case IrOpcode::kJSToNumber:
    1715             :       case IrOpcode::kJSToNumberConvertBigInt:
    1716             :       case IrOpcode::kJSToNumeric: {
    1717       38161 :         VisitInputs(node);
    1718             :         // TODO(bmeurer): Optimize somewhat based on input type?
    1719       38161 :         if (truncation.IsUsedAsWord32()) {
    1720             :           SetOutput(node, MachineRepresentation::kWord32);
    1721         333 :           if (lower())
    1722          75 :             lowering->DoJSToNumberOrNumericTruncatesToWord32(node, this);
    1723       37828 :         } else if (truncation.IsUsedAsFloat64()) {
    1724             :           SetOutput(node, MachineRepresentation::kFloat64);
    1725        4987 :           if (lower())
    1726        1413 :             lowering->DoJSToNumberOrNumericTruncatesToFloat64(node, this);
    1727             :         } else {
    1728             :           SetOutput(node, MachineRepresentation::kTagged);
    1729             :         }
    1730             :         return;
    1731             :       }
    1732             : 
    1733             :       //------------------------------------------------------------------
    1734             :       // Simplified operators.
    1735             :       //------------------------------------------------------------------
    1736             :       case IrOpcode::kBooleanNot: {
    1737        9597 :         if (lower()) {
    1738             :           NodeInfo* input_info = GetInfo(node->InputAt(0));
    1739        3087 :           if (input_info->representation() == MachineRepresentation::kBit) {
    1740             :             // BooleanNot(x: kRepBit) => Word32Equal(x, #0)
    1741        2051 :             node->AppendInput(jsgraph_->zone(), jsgraph_->Int32Constant(0));
    1742        2051 :             NodeProperties::ChangeOp(node, lowering->machine()->Word32Equal());
    1743        1036 :           } else if (CanBeTaggedPointer(input_info->representation())) {
    1744             :             // BooleanNot(x: kRepTagged) => WordEqual(x, #false)
    1745        1036 :             node->AppendInput(jsgraph_->zone(), jsgraph_->FalseConstant());
    1746        1036 :             NodeProperties::ChangeOp(node, lowering->machine()->WordEqual());
    1747             :           } else {
    1748             :             DCHECK(TypeOf(node->InputAt(0)).IsNone());
    1749           0 :             DeferReplacement(node, lowering->jsgraph()->Int32Constant(0));
    1750             :           }
    1751             :         } else {
    1752             :           // No input representation requirement; adapt during lowering.
    1753        6510 :           ProcessInput(node, 0, UseInfo::AnyTruncatingToBool());
    1754             :           SetOutput(node, MachineRepresentation::kBit);
    1755             :         }
    1756             :         return;
    1757             :       }
    1758             :       case IrOpcode::kNumberEqual: {
    1759      155789 :         Type const lhs_type = TypeOf(node->InputAt(0));
    1760      155789 :         Type const rhs_type = TypeOf(node->InputAt(1));
    1761             :         // Regular number comparisons in JavaScript generally identify zeros,
    1762             :         // so we always pass kIdentifyZeros for the inputs, and in addition
    1763             :         // we can truncate -0 to 0 for otherwise Unsigned32 or Signed32 inputs.
    1764             :         // For equality we also handle the case that one side is non-zero, in
    1765             :         // which case we allow to truncate NaN to 0 on the other side.
    1766      209869 :         if ((lhs_type.Is(Type::Unsigned32OrMinusZero()) &&
    1767      257564 :              rhs_type.Is(Type::Unsigned32OrMinusZero())) ||
    1768         102 :             (lhs_type.Is(Type::Unsigned32OrMinusZeroOrNaN()) &&
    1769          36 :              rhs_type.Is(Type::Unsigned32OrMinusZeroOrNaN()) &&
    1770          36 :              OneInputCannotBe(node, type_cache_->kZeroish))) {
    1771             :           // => unsigned Int32Cmp
    1772             :           VisitBinop(node, UseInfo::TruncatingWord32(),
    1773             :                      MachineRepresentation::kBit);
    1774       66655 :           if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node));
    1775             :           return;
    1776             :         }
    1777      123023 :         if ((lhs_type.Is(Type::Signed32OrMinusZero()) &&
    1778      182331 :              rhs_type.Is(Type::Signed32OrMinusZero())) ||
    1779          65 :             (lhs_type.Is(Type::Signed32OrMinusZeroOrNaN()) &&
    1780          36 :              rhs_type.Is(Type::Signed32OrMinusZeroOrNaN()) &&
    1781          36 :              OneInputCannotBe(node, type_cache_->kZeroish))) {
    1782             :           // => signed Int32Cmp
    1783             :           VisitBinop(node, UseInfo::TruncatingWord32(),
    1784             :                      MachineRepresentation::kBit);
    1785       27925 :           if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
    1786             :           return;
    1787             :         }
    1788             :         // => Float64Cmp
    1789             :         VisitBinop(node, UseInfo::TruncatingFloat64(kIdentifyZeros),
    1790             :                    MachineRepresentation::kBit);
    1791       89137 :         if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
    1792             :         return;
    1793             :       }
    1794             :       case IrOpcode::kNumberLessThan:
    1795             :       case IrOpcode::kNumberLessThanOrEqual: {
    1796      163406 :         Type const lhs_type = TypeOf(node->InputAt(0));
    1797      163406 :         Type const rhs_type = TypeOf(node->InputAt(1));
    1798             :         // Regular number comparisons in JavaScript generally identify zeros,
    1799             :         // so we always pass kIdentifyZeros for the inputs, and in addition
    1800             :         // we can truncate -0 to 0 for otherwise Unsigned32 or Signed32 inputs.
    1801      266346 :         if (lhs_type.Is(Type::Unsigned32OrMinusZero()) &&
    1802             :             rhs_type.Is(Type::Unsigned32OrMinusZero())) {
    1803             :           // => unsigned Int32Cmp
    1804             :           VisitBinop(node, UseInfo::TruncatingWord32(),
    1805             :                      MachineRepresentation::kBit);
    1806      115545 :           if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node));
    1807       84250 :         } else if (lhs_type.Is(Type::Signed32OrMinusZero()) &&
    1808             :                    rhs_type.Is(Type::Signed32OrMinusZero())) {
    1809             :           // => signed Int32Cmp
    1810             :           VisitBinop(node, UseInfo::TruncatingWord32(),
    1811             :                      MachineRepresentation::kBit);
    1812       13680 :           if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
    1813             :         } else {
    1814             :           // => Float64Cmp
    1815             :           VisitBinop(node, UseInfo::TruncatingFloat64(kIdentifyZeros),
    1816             :                      MachineRepresentation::kBit);
    1817       62017 :           if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
    1818             :         }
    1819             :         return;
    1820             :       }
    1821             : 
    1822             :       case IrOpcode::kSpeculativeSafeIntegerAdd:
    1823             :       case IrOpcode::kSpeculativeSafeIntegerSubtract:
    1824      795526 :         return VisitSpeculativeIntegerAdditiveOp(node, truncation, lowering);
    1825             : 
    1826             :       case IrOpcode::kSpeculativeNumberAdd:
    1827             :       case IrOpcode::kSpeculativeNumberSubtract:
    1828        3876 :         return VisitSpeculativeAdditiveOp(node, truncation, lowering);
    1829             : 
    1830             :       case IrOpcode::kSpeculativeNumberLessThan:
    1831             :       case IrOpcode::kSpeculativeNumberLessThanOrEqual:
    1832             :       case IrOpcode::kSpeculativeNumberEqual: {
    1833      390906 :         Type const lhs_type = TypeOf(node->InputAt(0));
    1834      390906 :         Type const rhs_type = TypeOf(node->InputAt(1));
    1835             :         // Regular number comparisons in JavaScript generally identify zeros,
    1836             :         // so we always pass kIdentifyZeros for the inputs, and in addition
    1837             :         // we can truncate -0 to 0 for otherwise Unsigned32 or Signed32 inputs.
    1838      663015 :         if (lhs_type.Is(Type::Unsigned32OrMinusZero()) &&
    1839             :             rhs_type.Is(Type::Unsigned32OrMinusZero())) {
    1840             :           // => unsigned Int32Cmp
    1841             :           VisitBinop(node, UseInfo::TruncatingWord32(),
    1842             :                      MachineRepresentation::kBit);
    1843        6219 :           if (lower()) ChangeToPureOp(node, Uint32Op(node));
    1844             :           return;
    1845      668160 :         } else if (lhs_type.Is(Type::Signed32OrMinusZero()) &&
    1846             :                    rhs_type.Is(Type::Signed32OrMinusZero())) {
    1847             :           // => signed Int32Cmp
    1848             :           VisitBinop(node, UseInfo::TruncatingWord32(),
    1849             :                      MachineRepresentation::kBit);
    1850      248000 :           if (lower()) ChangeToPureOp(node, Int32Op(node));
    1851             :           return;
    1852             :         }
    1853             :         // Try to use type feedback.
    1854      200548 :         NumberOperationHint hint = NumberOperationHintOf(node->op());
    1855      200548 :         switch (hint) {
    1856             :           case NumberOperationHint::kSigned32:
    1857             :           case NumberOperationHint::kSignedSmall:
    1858      161292 :             if (propagate()) {
    1859      234030 :               VisitBinop(node,
    1860             :                          CheckedUseInfoAsWord32FromHint(hint, VectorSlotPair(),
    1861             :                                                         kIdentifyZeros),
    1862             :                          MachineRepresentation::kBit);
    1863       44275 :             } else if (retype()) {
    1864             :               SetOutput(node, MachineRepresentation::kBit, Type::Any());
    1865             :             } else {
    1866             :               DCHECK(lower());
    1867             :               Node* lhs = node->InputAt(0);
    1868             :               Node* rhs = node->InputAt(1);
    1869       32055 :               if (IsNodeRepresentationTagged(lhs) &&
    1870             :                   IsNodeRepresentationTagged(rhs)) {
    1871       28874 :                 VisitBinop(node,
    1872             :                            UseInfo::CheckedSignedSmallAsTaggedSigned(
    1873             :                                VectorSlotPair(), kIdentifyZeros),
    1874             :                            MachineRepresentation::kBit);
    1875       14437 :                 ChangeToPureOp(
    1876       28874 :                     node, changer_->TaggedSignedOperatorFor(node->opcode()));
    1877             : 
    1878             :               } else {
    1879        5390 :                 VisitBinop(node,
    1880             :                            CheckedUseInfoAsWord32FromHint(
    1881             :                                hint, VectorSlotPair(), kIdentifyZeros),
    1882             :                            MachineRepresentation::kBit);
    1883        2695 :                 ChangeToPureOp(node, Int32Op(node));
    1884             :               }
    1885             :             }
    1886             :             return;
    1887             :           case NumberOperationHint::kSignedSmallInputs:
    1888             :             // This doesn't make sense for compare operations.
    1889           0 :             UNREACHABLE();
    1890             :           case NumberOperationHint::kNumberOrOddball:
    1891             :             // Abstract and strict equality don't perform ToNumber conversions
    1892             :             // on Oddballs, so make sure we don't accidentially sneak in a
    1893             :             // hint with Oddball feedback here.
    1894             :             DCHECK_NE(IrOpcode::kSpeculativeNumberEqual, node->opcode());
    1895             :             V8_FALLTHROUGH;
    1896             :           case NumberOperationHint::kNumber:
    1897       78512 :             VisitBinop(node,
    1898             :                        CheckedUseInfoAsFloat64FromHint(hint, VectorSlotPair(),
    1899             :                                                        kIdentifyZeros),
    1900             :                        MachineRepresentation::kBit);
    1901       48571 :             if (lower()) ChangeToPureOp(node, Float64Op(node));
    1902             :             return;
    1903             :         }
    1904           0 :         UNREACHABLE();
    1905             :         return;
    1906             :       }
    1907             : 
    1908             :       case IrOpcode::kNumberAdd:
    1909             :       case IrOpcode::kNumberSubtract: {
    1910     1538757 :         if (TypeOf(node->InputAt(0))
    1911     1300449 :                 .Is(type_cache_->kAdditiveSafeIntegerOrMinusZero) &&
    1912     1300436 :             TypeOf(node->InputAt(1))
    1913     1206675 :                 .Is(type_cache_->kAdditiveSafeIntegerOrMinusZero) &&
    1914     1487657 :             (TypeOf(node).Is(Type::Signed32()) ||
    1915      547442 :              TypeOf(node).Is(Type::Unsigned32()) ||
    1916             :              truncation.IsUsedAsWord32())) {
    1917             :           // => Int32Add/Sub
    1918      171700 :           VisitWord32TruncatingBinop(node);
    1919      210228 :           if (lower()) ChangeToPureOp(node, Int32Op(node));
    1920     2389062 :         } else if (jsgraph_->machine()->Is64() &&
    1921      599244 :                    BothInputsAre(node, type_cache_->kSafeInteger) &&
    1922      600800 :                    GetUpperBound(node).Is(type_cache_->kSafeInteger)) {
    1923             :           // => Int64Add/Sub
    1924        1545 :           VisitInt64Binop(node);
    1925        2026 :           if (lower()) ChangeToPureOp(node, Int64Op(node));
    1926             :         } else {
    1927             :           // => Float64Add/Sub
    1928      596109 :           VisitFloat64Binop(node);
    1929      669549 :           if (lower()) ChangeToPureOp(node, Float64Op(node));
    1930             :         }
    1931             :         return;
    1932             :       }
    1933             :       case IrOpcode::kSpeculativeNumberMultiply: {
    1934      127635 :         if (BothInputsAre(node, Type::Integral32()) &&
    1935       56656 :             (NodeProperties::GetType(node).Is(Type::Signed32()) ||
    1936       49767 :              NodeProperties::GetType(node).Is(Type::Unsigned32()) ||
    1937         414 :              (truncation.IsUsedAsWord32() &&
    1938       42959 :               NodeProperties::GetType(node).Is(
    1939         414 :                   type_cache_->kSafeIntegerOrMinusZero)))) {
    1940             :           // Multiply reduces to Int32Mul if the inputs are integers, and
    1941             :           // (a) the output is either known to be Signed32, or
    1942             :           // (b) the output is known to be Unsigned32, or
    1943             :           // (c) the uses are truncating and the result is in the safe
    1944             :           //     integer range.
    1945        2023 :           VisitWord32TruncatingBinop(node);
    1946        2560 :           if (lower()) ChangeToPureOp(node, Int32Op(node));
    1947             :           return;
    1948             :         }
    1949             :         // Try to use type feedback.
    1950       40522 :         NumberOperationHint hint = NumberOperationHintOf(node->op());
    1951       40522 :         Type input0_type = TypeOf(node->InputAt(0));
    1952       40522 :         Type input1_type = TypeOf(node->InputAt(1));
    1953             : 
    1954             :         // Handle the case when no int32 checks on inputs are necessary
    1955             :         // (but an overflow check is needed on the output).
    1956       40522 :         if (BothInputsAre(node, Type::Signed32())) {
    1957             :           // If both inputs and feedback are int32, use the overflow op.
    1958        5716 :           if (hint == NumberOperationHint::kSignedSmall ||
    1959        2858 :               hint == NumberOperationHint::kSigned32) {
    1960             :             VisitBinop(node, UseInfo::TruncatingWord32(),
    1961             :                        MachineRepresentation::kWord32, Type::Signed32());
    1962        2858 :             if (lower()) {
    1963             :               LowerToCheckedInt32Mul(node, truncation, input0_type,
    1964         918 :                                      input1_type);
    1965             :             }
    1966             :             return;
    1967             :           }
    1968             :         }
    1969             : 
    1970       75328 :         if (hint == NumberOperationHint::kSignedSmall ||
    1971       37664 :             hint == NumberOperationHint::kSigned32) {
    1972       35768 :           VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
    1973             :                      MachineRepresentation::kWord32, Type::Signed32());
    1974       17884 :           if (lower()) {
    1975        5298 :             LowerToCheckedInt32Mul(node, truncation, input0_type, input1_type);
    1976             :           }
    1977             :           return;
    1978             :         }
    1979             : 
    1980             :         // Checked float64 x float64 => float64
    1981       39560 :         VisitBinop(node,
    1982             :                    UseInfo::CheckedNumberOrOddballAsFloat64(kDistinguishZeros,
    1983             :                                                             VectorSlotPair()),
    1984             :                    MachineRepresentation::kFloat64, Type::Number());
    1985       25378 :         if (lower()) ChangeToPureOp(node, Float64Op(node));
    1986             :         return;
    1987             :       }
    1988             :       case IrOpcode::kNumberMultiply: {
    1989       55340 :         if (TypeOf(node->InputAt(0)).Is(Type::Integral32()) &&
    1990       60032 :             TypeOf(node->InputAt(1)).Is(Type::Integral32()) &&
    1991       31864 :             (TypeOf(node).Is(Type::Signed32()) ||
    1992       30156 :              TypeOf(node).Is(Type::Unsigned32()) ||
    1993         566 :              (truncation.IsUsedAsWord32() &&
    1994       25299 :               TypeOf(node).Is(type_cache_->kSafeIntegerOrMinusZero)))) {
    1995             :           // Multiply reduces to Int32Mul if the inputs are integers, and
    1996             :           // (a) the output is either known to be Signed32, or
    1997             :           // (b) the output is known to be Unsigned32, or
    1998             :           // (c) the uses are truncating and the result is in the safe
    1999             :           //     integer range.
    2000        2250 :           VisitWord32TruncatingBinop(node);
    2001        2712 :           if (lower()) ChangeToPureOp(node, Int32Op(node));
    2002             :           return;
    2003             :         }
    2004             :         // Number x Number => Float64Mul
    2005       21917 :         VisitFloat64Binop(node);
    2006       27981 :         if (lower()) ChangeToPureOp(node, Float64Op(node));
    2007             :         return;
    2008             :       }
    2009             :       case IrOpcode::kSpeculativeNumberDivide: {
    2010       58857 :         if (BothInputsAreUnsigned32(node) && truncation.IsUsedAsWord32()) {
    2011             :           // => unsigned Uint32Div
    2012         568 :           VisitWord32TruncatingBinop(node);
    2013         568 :           if (lower()) DeferReplacement(node, lowering->Uint32Div(node));
    2014             :           return;
    2015             :         }
    2016       51530 :         if (BothInputsAreSigned32(node)) {
    2017       30444 :           if (NodeProperties::GetType(node).Is(Type::Signed32())) {
    2018             :             // => signed Int32Div
    2019           0 :             VisitWord32TruncatingBinop(node);
    2020           0 :             if (lower()) DeferReplacement(node, lowering->Int32Div(node));
    2021             :             return;
    2022             :           }
    2023       15222 :           if (truncation.IsUsedAsWord32()) {
    2024             :             // => signed Int32Div
    2025        6911 :             VisitWord32TruncatingBinop(node);
    2026        6911 :             if (lower()) DeferReplacement(node, lowering->Int32Div(node));
    2027             :             return;
    2028             :           }
    2029             :         }
    2030             : 
    2031             :         // Try to use type feedback.
    2032       44619 :         NumberOperationHint hint = NumberOperationHintOf(node->op());
    2033             : 
    2034             :         // Handle the case when no uint32 checks on inputs are necessary
    2035             :         // (but an overflow check is needed on the output).
    2036       44619 :         if (BothInputsAreUnsigned32(node)) {
    2037       12382 :           if (hint == NumberOperationHint::kSignedSmall ||
    2038        6191 :               hint == NumberOperationHint::kSigned32) {
    2039             :             VisitBinop(node, UseInfo::TruncatingWord32(),
    2040             :                        MachineRepresentation::kWord32, Type::Unsigned32());
    2041         289 :             if (lower()) ChangeToUint32OverflowOp(node);
    2042             :             return;
    2043             :           }
    2044             :         }
    2045             : 
    2046             :         // Handle the case when no int32 checks on inputs are necessary
    2047             :         // (but an overflow check is needed on the output).
    2048       44330 :         if (BothInputsAreSigned32(node)) {
    2049             :           // If both the inputs the feedback are int32, use the overflow op.
    2050       16068 :           if (hint == NumberOperationHint::kSignedSmall ||
    2051        8034 :               hint == NumberOperationHint::kSigned32) {
    2052             :             VisitBinop(node, UseInfo::TruncatingWord32(),
    2053             :                        MachineRepresentation::kWord32, Type::Signed32());
    2054          12 :             if (lower()) ChangeToInt32OverflowOp(node);
    2055             :             return;
    2056             :           }
    2057             :         }
    2058             : 
    2059       88636 :         if (hint == NumberOperationHint::kSigned32 ||
    2060       87740 :             hint == NumberOperationHint::kSignedSmall ||
    2061             :             hint == NumberOperationHint::kSignedSmallInputs) {
    2062             :           // If the result is truncated, we only need to check the inputs.
    2063       38001 :           if (truncation.IsUsedAsWord32()) {
    2064        4834 :             VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
    2065             :                        MachineRepresentation::kWord32);
    2066        2417 :             if (lower()) DeferReplacement(node, lowering->Int32Div(node));
    2067             :             return;
    2068       35584 :           } else if (hint != NumberOperationHint::kSignedSmallInputs) {
    2069        1598 :             VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
    2070             :                        MachineRepresentation::kWord32, Type::Signed32());
    2071         799 :             if (lower()) ChangeToInt32OverflowOp(node);
    2072             :             return;
    2073             :           }
    2074             :         }
    2075             : 
    2076             :         // default case => Float64Div
    2077       82204 :         VisitBinop(node,
    2078             :                    UseInfo::CheckedNumberOrOddballAsFloat64(kDistinguishZeros,
    2079             :                                                             VectorSlotPair()),
    2080             :                    MachineRepresentation::kFloat64, Type::Number());
    2081       53084 :         if (lower()) ChangeToPureOp(node, Float64Op(node));
    2082             :         return;
    2083             :       }
    2084             :       case IrOpcode::kNumberDivide: {
    2085       36490 :         if (TypeOf(node->InputAt(0)).Is(Type::Unsigned32()) &&
    2086       37299 :             TypeOf(node->InputAt(1)).Is(Type::Unsigned32()) &&
    2087         667 :             (truncation.IsUsedAsWord32() ||
    2088       14289 :              TypeOf(node).Is(Type::Unsigned32()))) {
    2089             :           // => unsigned Uint32Div
    2090         142 :           VisitWord32TruncatingBinop(node);
    2091         142 :           if (lower()) DeferReplacement(node, lowering->Uint32Div(node));
    2092             :           return;
    2093             :         }
    2094       36150 :         if (TypeOf(node->InputAt(0)).Is(Type::Signed32()) &&
    2095       37598 :             TypeOf(node->InputAt(1)).Is(Type::Signed32()) &&
    2096        1440 :             (truncation.IsUsedAsWord32() ||
    2097       14920 :              TypeOf(node).Is(Type::Signed32()))) {
    2098             :           // => signed Int32Div
    2099           8 :           VisitWord32TruncatingBinop(node);
    2100           8 :           if (lower()) DeferReplacement(node, lowering->Int32Div(node));
    2101             :           return;
    2102             :         }
    2103             :         // Number x Number => Float64Div
    2104       13472 :         VisitFloat64Binop(node);
    2105       16827 :         if (lower()) ChangeToPureOp(node, Float64Op(node));
    2106             :         return;
    2107             :       }
    2108             :       case IrOpcode::kSpeculativeNumberModulus:
    2109       13678 :         return VisitSpeculativeNumberModulus(node, truncation, lowering);
    2110             :       case IrOpcode::kNumberModulus: {
    2111        2564 :         Type const lhs_type = TypeOf(node->InputAt(0));
    2112        2564 :         Type const rhs_type = TypeOf(node->InputAt(1));
    2113        5426 :         if ((lhs_type.Is(Type::Unsigned32OrMinusZeroOrNaN()) &&
    2114        2884 :              rhs_type.Is(Type::Unsigned32OrMinusZeroOrNaN())) &&
    2115         153 :             (truncation.IsUsedAsWord32() ||
    2116        2870 :              TypeOf(node).Is(Type::Unsigned32()))) {
    2117             :           // => unsigned Uint32Mod
    2118         320 :           VisitWord32TruncatingBinop(node);
    2119         320 :           if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
    2120             :           return;
    2121             :         }
    2122        4761 :         if ((lhs_type.Is(Type::Signed32OrMinusZeroOrNaN()) &&
    2123        2452 :              rhs_type.Is(Type::Signed32OrMinusZeroOrNaN())) &&
    2124        2754 :             (truncation.IsUsedAsWord32() || TypeOf(node).Is(Type::Signed32()) ||
    2125          42 :              (truncation.IdentifiesZeroAndMinusZero() &&
    2126        2286 :               TypeOf(node).Is(Type::Signed32OrMinusZero())))) {
    2127             :           // => signed Int32Mod
    2128          98 :           VisitWord32TruncatingBinop(node);
    2129          98 :           if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
    2130             :           return;
    2131             :         }
    2132             :         // => Float64Mod
    2133             :         // For the left hand side we just propagate the identify zeros
    2134             :         // mode of the {truncation}; and for modulus the sign of the
    2135             :         // right hand side doesn't matter anyways, so in particular there's
    2136             :         // no observable difference between a 0 and a -0 then.
    2137             :         UseInfo const lhs_use =
    2138             :             UseInfo::TruncatingFloat64(truncation.identify_zeros());
    2139             :         UseInfo const rhs_use = UseInfo::TruncatingFloat64(kIdentifyZeros);
    2140        2146 :         VisitBinop(node, lhs_use, rhs_use, MachineRepresentation::kFloat64);
    2141        2500 :         if (lower()) ChangeToPureOp(node, Float64Op(node));
    2142             :         return;
    2143             :       }
    2144             :       case IrOpcode::kNumberBitwiseOr:
    2145             :       case IrOpcode::kNumberBitwiseXor:
    2146             :       case IrOpcode::kNumberBitwiseAnd: {
    2147       19682 :         VisitWord32TruncatingBinop(node);
    2148       26131 :         if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
    2149             :         return;
    2150             :       }
    2151             :       case IrOpcode::kSpeculativeNumberBitwiseOr:
    2152             :       case IrOpcode::kSpeculativeNumberBitwiseXor:
    2153             :       case IrOpcode::kSpeculativeNumberBitwiseAnd:
    2154       81632 :         VisitSpeculativeInt32Binop(node);
    2155       81635 :         if (lower()) {
    2156       22462 :           ChangeToPureOp(node, Int32Op(node));
    2157             :         }
    2158             :         return;
    2159             :       case IrOpcode::kNumberShiftLeft: {
    2160        1287 :         Type rhs_type = GetUpperBound(node->InputAt(1));
    2161             :         VisitBinop(node, UseInfo::TruncatingWord32(),
    2162        1287 :                    UseInfo::TruncatingWord32(), MachineRepresentation::kWord32);
    2163        1287 :         if (lower()) {
    2164         374 :           MaskShiftOperand(node, rhs_type);
    2165         374 :           ChangeToPureOp(node, lowering->machine()->Word32Shl());
    2166             :         }
    2167             :         return;
    2168             :       }
    2169             :       case IrOpcode::kSpeculativeNumberShiftLeft: {
    2170        8111 :         if (BothInputsAre(node, Type::NumberOrOddball())) {
    2171        7291 :           Type rhs_type = GetUpperBound(node->InputAt(1));
    2172             :           VisitBinop(node, UseInfo::TruncatingWord32(),
    2173             :                      UseInfo::TruncatingWord32(),
    2174        7291 :                      MachineRepresentation::kWord32);
    2175        7291 :           if (lower()) {
    2176        1838 :             MaskShiftOperand(node, rhs_type);
    2177        1838 :             ChangeToPureOp(node, lowering->machine()->Word32Shl());
    2178             :           }
    2179             :           return;
    2180             :         }
    2181         820 :         NumberOperationHint hint = NumberOperationHintOf(node->op());
    2182         820 :         Type rhs_type = GetUpperBound(node->InputAt(1));
    2183        1640 :         VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
    2184             :                    MachineRepresentation::kWord32, Type::Signed32());
    2185         820 :         if (lower()) {
    2186         263 :           MaskShiftOperand(node, rhs_type);
    2187         263 :           ChangeToPureOp(node, lowering->machine()->Word32Shl());
    2188             :         }
    2189             :         return;
    2190             :       }
    2191             :       case IrOpcode::kNumberShiftRight: {
    2192         555 :         Type rhs_type = GetUpperBound(node->InputAt(1));
    2193             :         VisitBinop(node, UseInfo::TruncatingWord32(),
    2194         555 :                    UseInfo::TruncatingWord32(), MachineRepresentation::kWord32);
    2195         555 :         if (lower()) {
    2196         155 :           MaskShiftOperand(node, rhs_type);
    2197         155 :           ChangeToPureOp(node, lowering->machine()->Word32Sar());
    2198             :         }
    2199             :         return;
    2200             :       }
    2201             :       case IrOpcode::kSpeculativeNumberShiftRight: {
    2202       22837 :         if (BothInputsAre(node, Type::NumberOrOddball())) {
    2203       21606 :           Type rhs_type = GetUpperBound(node->InputAt(1));
    2204             :           VisitBinop(node, UseInfo::TruncatingWord32(),
    2205             :                      UseInfo::TruncatingWord32(),
    2206       21607 :                      MachineRepresentation::kWord32);
    2207       21607 :           if (lower()) {
    2208        5218 :             MaskShiftOperand(node, rhs_type);
    2209        5218 :             ChangeToPureOp(node, lowering->machine()->Word32Sar());
    2210             :           }
    2211             :           return;
    2212             :         }
    2213        1233 :         NumberOperationHint hint = NumberOperationHintOf(node->op());
    2214        1233 :         Type rhs_type = GetUpperBound(node->InputAt(1));
    2215        2466 :         VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
    2216             :                    MachineRepresentation::kWord32, Type::Signed32());
    2217        1233 :         if (lower()) {
    2218         380 :           MaskShiftOperand(node, rhs_type);
    2219         380 :           ChangeToPureOp(node, lowering->machine()->Word32Sar());
    2220             :         }
    2221             :         return;
    2222             :       }
    2223             :       case IrOpcode::kNumberShiftRightLogical: {
    2224         683 :         Type rhs_type = GetUpperBound(node->InputAt(1));
    2225             :         VisitBinop(node, UseInfo::TruncatingWord32(),
    2226         683 :                    UseInfo::TruncatingWord32(), MachineRepresentation::kWord32);
    2227         683 :         if (lower()) {
    2228         209 :           MaskShiftOperand(node, rhs_type);
    2229         209 :           ChangeToPureOp(node, lowering->machine()->Word32Shr());
    2230             :         }
    2231             :         return;
    2232             :       }
    2233             :       case IrOpcode::kSpeculativeNumberShiftRightLogical: {
    2234        5968 :         NumberOperationHint hint = NumberOperationHintOf(node->op());
    2235        5968 :         Type rhs_type = GetUpperBound(node->InputAt(1));
    2236       15176 :         if (rhs_type.Is(type_cache_->kZeroish) &&
    2237        6480 :             (hint == NumberOperationHint::kSignedSmall ||
    2238        9874 :              hint == NumberOperationHint::kSigned32) &&
    2239             :             !truncation.IsUsedAsWord32()) {
    2240             :           // The SignedSmall or Signed32 feedback means that the results that we
    2241             :           // have seen so far were of type Unsigned31.  We speculate that this
    2242             :           // will continue to hold.  Moreover, since the RHS is 0, the result
    2243             :           // will just be the (converted) LHS.
    2244         650 :           VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
    2245             :                      MachineRepresentation::kWord32, Type::Unsigned31());
    2246         325 :           if (lower()) {
    2247          92 :             node->RemoveInput(1);
    2248         184 :             NodeProperties::ChangeOp(
    2249          92 :                 node, simplified()->CheckedUint32ToInt32(VectorSlotPair()));
    2250             :           }
    2251             :           return;
    2252             :         }
    2253        5643 :         if (BothInputsAre(node, Type::NumberOrOddball())) {
    2254             :           VisitBinop(node, UseInfo::TruncatingWord32(),
    2255             :                      UseInfo::TruncatingWord32(),
    2256        4257 :                      MachineRepresentation::kWord32);
    2257        4257 :           if (lower()) {
    2258        1198 :             MaskShiftOperand(node, rhs_type);
    2259        1198 :             ChangeToPureOp(node, lowering->machine()->Word32Shr());
    2260             :           }
    2261             :           return;
    2262             :         }
    2263        2772 :         VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
    2264             :                    MachineRepresentation::kWord32, Type::Unsigned32());
    2265        1386 :         if (lower()) {
    2266         421 :           MaskShiftOperand(node, rhs_type);
    2267         421 :           ChangeToPureOp(node, lowering->machine()->Word32Shr());
    2268             :         }
    2269             :         return;
    2270             :       }
    2271             :       case IrOpcode::kNumberAbs: {
    2272             :         // NumberAbs maps both 0 and -0 to 0, so we can generally
    2273             :         // pass the kIdentifyZeros truncation to its input, and
    2274             :         // choose to ignore minus zero in all cases.
    2275         903 :         Type const input_type = TypeOf(node->InputAt(0));
    2276         903 :         if (input_type.Is(Type::Unsigned32OrMinusZero())) {
    2277             :           VisitUnop(node, UseInfo::TruncatingWord32(),
    2278          37 :                     MachineRepresentation::kWord32);
    2279          52 :           if (lower()) DeferReplacement(node, node->InputAt(0));
    2280         866 :         } else if (input_type.Is(Type::Signed32OrMinusZero())) {
    2281             :           VisitUnop(node, UseInfo::TruncatingWord32(),
    2282         208 :                     MachineRepresentation::kWord32);
    2283         208 :           if (lower()) DeferReplacement(node, lowering->Int32Abs(node));
    2284        1316 :         } else if (input_type.Is(type_cache_->kPositiveIntegerOrNaN)) {
    2285             :           VisitUnop(node, UseInfo::TruncatingFloat64(kIdentifyZeros),
    2286          14 :                     MachineRepresentation::kFloat64);
    2287          21 :           if (lower()) DeferReplacement(node, node->InputAt(0));
    2288             :         } else {
    2289             :           VisitUnop(node, UseInfo::TruncatingFloat64(kIdentifyZeros),
    2290         644 :                     MachineRepresentation::kFloat64);
    2291         834 :           if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
    2292             :         }
    2293             :         return;
    2294             :       }
    2295             :       case IrOpcode::kNumberClz32: {
    2296             :         VisitUnop(node, UseInfo::TruncatingWord32(),
    2297          90 :                   MachineRepresentation::kWord32);
    2298         120 :         if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node));
    2299             :         return;
    2300             :       }
    2301             :       case IrOpcode::kNumberImul: {
    2302             :         VisitBinop(node, UseInfo::TruncatingWord32(),
    2303        2616 :                    UseInfo::TruncatingWord32(), MachineRepresentation::kWord32);
    2304        3488 :         if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node));
    2305             :         return;
    2306             :       }
    2307             :       case IrOpcode::kNumberFround: {
    2308             :         VisitUnop(node, UseInfo::TruncatingFloat64(),
    2309        3896 :                   MachineRepresentation::kFloat32);
    2310        5182 :         if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
    2311             :         return;
    2312             :       }
    2313             :       case IrOpcode::kNumberMax: {
    2314             :         // It is safe to use the feedback types for left and right hand side
    2315             :         // here, since we can only narrow those types and thus we can only
    2316             :         // promise a more specific truncation.
    2317             :         // For NumberMax we generally propagate whether the truncation
    2318             :         // identifies zeros to the inputs, and we choose to ignore minus
    2319             :         // zero in those cases.
    2320        7706 :         Type const lhs_type = TypeOf(node->InputAt(0));
    2321        7706 :         Type const rhs_type = TypeOf(node->InputAt(1));
    2322       11844 :         if ((lhs_type.Is(Type::Unsigned32()) &&
    2323       11883 :              rhs_type.Is(Type::Unsigned32())) ||
    2324         681 :             (lhs_type.Is(Type::Unsigned32OrMinusZero()) &&
    2325         102 :              rhs_type.Is(Type::Unsigned32OrMinusZero()) &&
    2326             :              truncation.IdentifiesZeroAndMinusZero())) {
    2327        3550 :           VisitWord32TruncatingBinop(node);
    2328        3550 :           if (lower()) {
    2329        1125 :             lowering->DoMax(node, lowering->machine()->Uint32LessThan(),
    2330        1125 :                             MachineRepresentation::kWord32);
    2331             :           }
    2332        7989 :         } else if ((lhs_type.Is(Type::Signed32()) &&
    2333        5053 :                     rhs_type.Is(Type::Signed32())) ||
    2334         625 :                    (lhs_type.Is(Type::Signed32OrMinusZero()) &&
    2335          81 :                     rhs_type.Is(Type::Signed32OrMinusZero()) &&
    2336             :                     truncation.IdentifiesZeroAndMinusZero())) {
    2337        3259 :           VisitWord32TruncatingBinop(node);
    2338        3259 :           if (lower()) {
    2339        1062 :             lowering->DoMax(node, lowering->machine()->Int32LessThan(),
    2340        1062 :                             MachineRepresentation::kWord32);
    2341             :           }
    2342        2691 :         } else if (jsgraph_->machine()->Is64() &&
    2343        1536 :                    lhs_type.Is(type_cache_->kSafeInteger) &&
    2344         639 :                    rhs_type.Is(type_cache_->kSafeInteger)) {
    2345         513 :           VisitInt64Binop(node);
    2346         513 :           if (lower()) {
    2347         167 :             lowering->DoMax(node, lowering->machine()->Int64LessThan(),
    2348         167 :                             MachineRepresentation::kWord64);
    2349             :           }
    2350             :         } else {
    2351             :           VisitBinop(node,
    2352             :                      UseInfo::TruncatingFloat64(truncation.identify_zeros()),
    2353             :                      MachineRepresentation::kFloat64);
    2354         384 :           if (lower()) {
    2355             :             // If the right hand side is not NaN, and the left hand side
    2356             :             // is not NaN (or -0 if the difference between the zeros is
    2357             :             // observed), we can do a simple floating point comparison here.
    2358         240 :             if (lhs_type.Is(truncation.IdentifiesZeroAndMinusZero()
    2359             :                                 ? Type::OrderedNumber()
    2360         193 :                                 : Type::PlainNumber()) &&
    2361             :                 rhs_type.Is(Type::OrderedNumber())) {
    2362          48 :               lowering->DoMax(node, lowering->machine()->Float64LessThan(),
    2363          48 :                               MachineRepresentation::kFloat64);
    2364             :             } else {
    2365          72 :               NodeProperties::ChangeOp(node, Float64Op(node));
    2366             :             }
    2367             :           }
    2368             :         }
    2369             :         return;
    2370             :       }
    2371             :       case IrOpcode::kNumberMin: {
    2372             :         // It is safe to use the feedback types for left and right hand side
    2373             :         // here, since we can only narrow those types and thus we can only
    2374             :         // promise a more specific truncation.
    2375             :         // For NumberMin we generally propagate whether the truncation
    2376             :         // identifies zeros to the inputs, and we choose to ignore minus
    2377             :         // zero in those cases.
    2378       10405 :         Type const lhs_type = TypeOf(node->InputAt(0));
    2379       10405 :         Type const rhs_type = TypeOf(node->InputAt(1));
    2380       20192 :         if ((lhs_type.Is(Type::Unsigned32()) &&
    2381       11295 :              rhs_type.Is(Type::Unsigned32())) ||
    2382         326 :             (lhs_type.Is(Type::Unsigned32OrMinusZero()) &&
    2383          81 :              rhs_type.Is(Type::Unsigned32OrMinusZero()) &&
    2384             :              truncation.IdentifiesZeroAndMinusZero())) {
    2385        9515 :           VisitWord32TruncatingBinop(node);
    2386        9515 :           if (lower()) {
    2387        3046 :             lowering->DoMin(node, lowering->machine()->Uint32LessThan(),
    2388        3046 :                             MachineRepresentation::kWord32);
    2389             :           }
    2390        1308 :         } else if ((lhs_type.Is(Type::Signed32()) &&
    2391        1525 :                     rhs_type.Is(Type::Signed32())) ||
    2392         217 :                    (lhs_type.Is(Type::Signed32OrMinusZero()) &&
    2393          81 :                     rhs_type.Is(Type::Signed32OrMinusZero()) &&
    2394             :                     truncation.IdentifiesZeroAndMinusZero())) {
    2395         255 :           VisitWord32TruncatingBinop(node);
    2396         255 :           if (lower()) {
    2397          76 :             lowering->DoMin(node, lowering->machine()->Int32LessThan(),
    2398          76 :                             MachineRepresentation::kWord32);
    2399             :           }
    2400        1905 :         } else if (jsgraph_->machine()->Is64() &&
    2401         822 :                    lhs_type.Is(type_cache_->kSafeInteger) &&
    2402         187 :                    rhs_type.Is(type_cache_->kSafeInteger)) {
    2403          40 :           VisitInt64Binop(node);
    2404          40 :           if (lower()) {
    2405          16 :             lowering->DoMin(node, lowering->machine()->Int64LessThan(),
    2406          16 :                             MachineRepresentation::kWord64);
    2407             :           }
    2408             :         } else {
    2409             :           VisitBinop(node,
    2410             :                      UseInfo::TruncatingFloat64(truncation.identify_zeros()),
    2411             :                      MachineRepresentation::kFloat64);
    2412         595 :           if (lower()) {
    2413             :             // If the left hand side is not NaN, and the right hand side
    2414             :             // is not NaN (or -0 if the difference between the zeros is
    2415             :             // observed), we can do a simple floating point comparison here.
    2416         277 :             if (lhs_type.Is(Type::OrderedNumber()) &&
    2417          84 :                 rhs_type.Is(truncation.IdentifiesZeroAndMinusZero()
    2418             :                                 ? Type::OrderedNumber()
    2419             :                                 : Type::PlainNumber())) {
    2420          45 :               lowering->DoMin(node,
    2421             :                               lowering->machine()->Float64LessThanOrEqual(),
    2422          45 :                               MachineRepresentation::kFloat64);
    2423             :             } else {
    2424         148 :               NodeProperties::ChangeOp(node, Float64Op(node));
    2425             :             }
    2426             :           }
    2427             :         }
    2428             :         return;
    2429             :       }
    2430             :       case IrOpcode::kNumberAtan2:
    2431             :       case IrOpcode::kNumberPow: {
    2432             :         VisitBinop(node, UseInfo::TruncatingFloat64(),
    2433             :                    MachineRepresentation::kFloat64);
    2434        3772 :         if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
    2435             :         return;
    2436             :       }
    2437             :       case IrOpcode::kNumberCeil:
    2438             :       case IrOpcode::kNumberFloor:
    2439             :       case IrOpcode::kNumberRound:
    2440             :       case IrOpcode::kNumberTrunc: {
    2441             :         // For NumberCeil, NumberFloor, NumberRound and NumberTrunc we propagate
    2442             :         // the zero identification part of the truncation, and we turn them into
    2443             :         // no-ops if we figure out (late) that their input is already an
    2444             :         // integer, NaN or -0.
    2445      134540 :         Type const input_type = TypeOf(node->InputAt(0));
    2446             :         VisitUnop(node, UseInfo::TruncatingFloat64(truncation.identify_zeros()),
    2447      134540 :                   MachineRepresentation::kFloat64);
    2448      134540 :         if (lower()) {
    2449       88524 :           if (input_type.Is(type_cache_->kIntegerOrMinusZeroOrNaN)) {
    2450        1246 :             DeferReplacement(node, node->InputAt(0));
    2451       43016 :           } else if (node->opcode() == IrOpcode::kNumberRound) {
    2452        1554 :             DeferReplacement(node, lowering->Float64Round(node));
    2453             :           } else {
    2454       41462 :             NodeProperties::ChangeOp(node, Float64Op(node));
    2455             :           }
    2456             :         }
    2457             :         return;
    2458             :       }
    2459             :       case IrOpcode::kNumberAcos:
    2460             :       case IrOpcode::kNumberAcosh:
    2461             :       case IrOpcode::kNumberAsin:
    2462             :       case IrOpcode::kNumberAsinh:
    2463             :       case IrOpcode::kNumberAtan:
    2464             :       case IrOpcode::kNumberAtanh:
    2465             :       case IrOpcode::kNumberCos:
    2466             :       case IrOpcode::kNumberCosh:
    2467             :       case IrOpcode::kNumberExp:
    2468             :       case IrOpcode::kNumberExpm1:
    2469             :       case IrOpcode::kNumberLog:
    2470             :       case IrOpcode::kNumberLog1p:
    2471             :       case IrOpcode::kNumberLog2:
    2472             :       case IrOpcode::kNumberLog10:
    2473             :       case IrOpcode::kNumberCbrt:
    2474             :       case IrOpcode::kNumberSin:
    2475             :       case IrOpcode::kNumberSinh:
    2476             :       case IrOpcode::kNumberTan:
    2477             :       case IrOpcode::kNumberTanh: {
    2478             :         VisitUnop(node, UseInfo::TruncatingFloat64(),
    2479         858 :                   MachineRepresentation::kFloat64);
    2480        1136 :         if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
    2481             :         return;
    2482             :       }
    2483             :       case IrOpcode::kNumberSign: {
    2484         111 :         if (InputIs(node, Type::Signed32())) {
    2485             :           VisitUnop(node, UseInfo::TruncatingWord32(),
    2486          21 :                     MachineRepresentation::kWord32);
    2487          21 :           if (lower()) DeferReplacement(node, lowering->Int32Sign(node));
    2488             :         } else {
    2489             :           VisitUnop(node, UseInfo::TruncatingFloat64(),
    2490          90 :                     MachineRepresentation::kFloat64);
    2491          90 :           if (lower()) DeferReplacement(node, lowering->Float64Sign(node));
    2492             :         }
    2493             :         return;
    2494             :       }
    2495             :       case IrOpcode::kNumberSilenceNaN: {
    2496        2304 :         Type const input_type = TypeOf(node->InputAt(0));
    2497        2304 :         if (input_type.Is(Type::OrderedNumber())) {
    2498             :           // No need to silence anything if the input cannot be NaN.
    2499             :           VisitUnop(node, UseInfo::TruncatingFloat64(),
    2500          14 :                     MachineRepresentation::kFloat64);
    2501          21 :           if (lower()) DeferReplacement(node, node->InputAt(0));
    2502             :         } else {
    2503             :           VisitUnop(node, UseInfo::TruncatingFloat64(),
    2504        2290 :                     MachineRepresentation::kFloat64);
    2505        3030 :           if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
    2506             :         }
    2507             :         return;
    2508             :       }
    2509             :       case IrOpcode::kNumberSqrt: {
    2510             :         VisitUnop(node, UseInfo::TruncatingFloat64(),
    2511         156 :                   MachineRepresentation::kFloat64);
    2512         207 :         if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
    2513             :         return;
    2514             :       }
    2515             :       case IrOpcode::kNumberToBoolean: {
    2516             :         // For NumberToBoolean we don't care whether the input is 0 or
    2517             :         // -0, since both of them are mapped to false anyways, so we
    2518             :         // can generally pass kIdentifyZeros truncation.
    2519         558 :         Type const input_type = TypeOf(node->InputAt(0));
    2520         558 :         if (input_type.Is(Type::Integral32OrMinusZeroOrNaN())) {
    2521             :           // 0, -0 and NaN all map to false, so we can safely truncate
    2522             :           // all of them to zero here.
    2523             :           VisitUnop(node, UseInfo::TruncatingWord32(),
    2524         305 :                     MachineRepresentation::kBit);
    2525         305 :           if (lower()) lowering->DoIntegral32ToBit(node);
    2526         253 :         } else if (input_type.Is(Type::OrderedNumber())) {
    2527             :           VisitUnop(node, UseInfo::TruncatingFloat64(kIdentifyZeros),
    2528          77 :                     MachineRepresentation::kBit);
    2529          77 :           if (lower()) lowering->DoOrderedNumberToBit(node);
    2530             :         } else {
    2531             :           VisitUnop(node, UseInfo::TruncatingFloat64(kIdentifyZeros),
    2532         176 :                     MachineRepresentation::kBit);
    2533         176 :           if (lower()) lowering->DoNumberToBit(node);
    2534             :         }
    2535             :         return;
    2536             :       }
    2537             :       case IrOpcode::kNumberToInt32: {
    2538             :         // Just change representation if necessary.
    2539             :         VisitUnop(node, UseInfo::TruncatingWord32(),
    2540        1621 :                   MachineRepresentation::kWord32);
    2541        1906 :         if (lower()) DeferReplacement(node, node->InputAt(0));
    2542             :         return;
    2543             :       }
    2544             :       case IrOpcode::kNumberToString: {
    2545             :         VisitUnop(node, UseInfo::AnyTagged(),
    2546       11298 :                   MachineRepresentation::kTaggedPointer);
    2547       11298 :         return;
    2548             :       }
    2549             :       case IrOpcode::kNumberToUint32: {
    2550             :         // Just change representation if necessary.
    2551             :         VisitUnop(node, UseInfo::TruncatingWord32(),
    2552        6276 :                   MachineRepresentation::kWord32);
    2553        8240 :         if (lower()) DeferReplacement(node, node->InputAt(0));
    2554             :         return;
    2555             :       }
    2556             :       case IrOpcode::kNumberToUint8Clamped: {
    2557        1446 :         Type const input_type = TypeOf(node->InputAt(0));
    2558        2892 :         if (input_type.Is(type_cache_->kUint8OrMinusZeroOrNaN)) {
    2559             :           VisitUnop(node, UseInfo::TruncatingWord32(),
    2560          45 :                     MachineRepresentation::kWord32);
    2561          60 :           if (lower()) DeferReplacement(node, node->InputAt(0));
    2562        1401 :         } else if (input_type.Is(Type::Unsigned32OrMinusZeroOrNaN())) {
    2563             :           VisitUnop(node, UseInfo::TruncatingWord32(),
    2564         240 :                     MachineRepresentation::kWord32);
    2565         240 :           if (lower()) lowering->DoUnsigned32ToUint8Clamped(node);
    2566        1161 :         } else if (input_type.Is(Type::Signed32OrMinusZeroOrNaN())) {
    2567             :           VisitUnop(node, UseInfo::TruncatingWord32(),
    2568         216 :                     MachineRepresentation::kWord32);
    2569         216 :           if (lower()) lowering->DoSigned32ToUint8Clamped(node);
    2570        1890 :         } else if (input_type.Is(type_cache_->kIntegerOrMinusZeroOrNaN)) {
    2571             :           VisitUnop(node, UseInfo::TruncatingFloat64(),
    2572          63 :                     MachineRepresentation::kFloat64);
    2573          63 :           if (lower()) lowering->DoIntegerToUint8Clamped(node);
    2574             :         } else {
    2575             :           VisitUnop(node, UseInfo::TruncatingFloat64(),
    2576         882 :                     MachineRepresentation::kFloat64);
    2577         882 :           if (lower()) lowering->DoNumberToUint8Clamped(node);
    2578             :         }
    2579             :         return;
    2580             :       }
    2581             :       case IrOpcode::kReferenceEqual: {
    2582             :         VisitBinop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
    2583      599549 :         if (lower()) {
    2584      197989 :           NodeProperties::ChangeOp(node, lowering->machine()->WordEqual());
    2585             :         }
    2586             :         return;
    2587             :       }
    2588             :       case IrOpcode::kSameValueNumbersOnly: {
    2589             :         VisitBinop(node, UseInfo::AnyTagged(),
    2590             :                    MachineRepresentation::kTaggedPointer);
    2591             :         return;
    2592             :       }
    2593             :       case IrOpcode::kSameValue: {
    2594         231 :         if (truncation.IsUnused()) return VisitUnused(node);
    2595         231 :         if (BothInputsAre(node, Type::Number())) {
    2596             :           VisitBinop(node, UseInfo::TruncatingFloat64(),
    2597             :                      MachineRepresentation::kBit);
    2598         231 :           if (lower()) {
    2599          77 :             NodeProperties::ChangeOp(node,
    2600          77 :                                      lowering->simplified()->NumberSameValue());
    2601             :           }
    2602             :         } else {
    2603             :           VisitBinop(node, UseInfo::AnyTagged(),
    2604             :                      MachineRepresentation::kTaggedPointer);
    2605             :         }
    2606             :         return;
    2607             :       }
    2608             :       case IrOpcode::kTypeOf: {
    2609             :         return VisitUnop(node, UseInfo::AnyTagged(),
    2610       66801 :                          MachineRepresentation::kTaggedPointer);
    2611             :       }
    2612             :       case IrOpcode::kStringConcat: {
    2613       82815 :         Type const length_type = TypeOf(node->InputAt(0));
    2614       82815 :         Type const first_type = TypeOf(node->InputAt(1));
    2615       82815 :         Type const second_type = TypeOf(node->InputAt(2));
    2616      185745 :         if (length_type.Is(type_cache_->kConsStringLengthType) &&
    2617       98706 :             first_type.Is(Type::NonEmptyString()) &&
    2618             :             second_type.Is(Type::NonEmptyString())) {
    2619             :           // We know that we'll construct a ConsString here, so we
    2620             :           // can inline a fast-path into TurboFan optimized code.
    2621       12406 :           ProcessInput(node, 0, UseInfo::TruncatingWord32());  // length
    2622       12406 :           ProcessInput(node, 1, UseInfo::AnyTagged());         // first
    2623       12406 :           ProcessInput(node, 2, UseInfo::AnyTagged());         // second
    2624             :           SetOutput(node, MachineRepresentation::kTaggedPointer);
    2625       12406 :           if (lower()) {
    2626        8916 :             if (first_type.Is(Type::NonEmptyOneByteString()) &&
    2627             :                 second_type.Is(Type::NonEmptyOneByteString())) {
    2628        3892 :               NodeProperties::ChangeOp(
    2629        3892 :                   node, lowering->simplified()->NewConsOneByteString());
    2630        2216 :             } else if (first_type.Is(Type::NonEmptyTwoByteString()) ||
    2631             :                        second_type.Is(Type::NonEmptyTwoByteString())) {
    2632          33 :               NodeProperties::ChangeOp(
    2633          33 :                   node, lowering->simplified()->NewConsTwoByteString());
    2634             :             } else {
    2635        1091 :               NodeProperties::ChangeOp(node,
    2636        1091 :                                        lowering->simplified()->NewConsString());
    2637             :             }
    2638             :           }
    2639             :         } else {
    2640       70409 :           ProcessInput(node, 0, UseInfo::TaggedSigned());  // length
    2641       70409 :           ProcessInput(node, 1, UseInfo::AnyTagged());     // first
    2642       70409 :           ProcessInput(node, 2, UseInfo::AnyTagged());     // second
    2643             :           SetOutput(node, MachineRepresentation::kTaggedPointer);
    2644             :         }
    2645             :         return;
    2646             :       }
    2647             :       case IrOpcode::kStringEqual:
    2648             :       case IrOpcode::kStringLessThan:
    2649             :       case IrOpcode::kStringLessThanOrEqual: {
    2650             :         return VisitBinop(node, UseInfo::AnyTagged(),
    2651             :                           MachineRepresentation::kTaggedPointer);
    2652             :       }
    2653             :       case IrOpcode::kStringCharCodeAt: {
    2654             :         return VisitBinop(node, UseInfo::AnyTagged(), UseInfo::Word(),
    2655        8077 :                           MachineRepresentation::kWord32);
    2656             :       }
    2657             :       case IrOpcode::kStringCodePointAt: {
    2658             :         return VisitBinop(node, UseInfo::AnyTagged(), UseInfo::Word(),
    2659         721 :                           MachineRepresentation::kTaggedSigned);
    2660             :       }
    2661             :       case IrOpcode::kStringFromSingleCharCode: {
    2662             :         VisitUnop(node, UseInfo::TruncatingWord32(),
    2663        3537 :                   MachineRepresentation::kTaggedPointer);
    2664        3537 :         return;
    2665             :       }
    2666             :       case IrOpcode::kStringFromSingleCodePoint: {
    2667             :         VisitUnop(node, UseInfo::TruncatingWord32(),
    2668         718 :                   MachineRepresentation::kTaggedPointer);
    2669         718 :         return;
    2670             :       }
    2671             :       case IrOpcode::kStringIndexOf: {
    2672         855 :         ProcessInput(node, 0, UseInfo::AnyTagged());
    2673         855 :         ProcessInput(node, 1, UseInfo::AnyTagged());
    2674         855 :         ProcessInput(node, 2, UseInfo::TaggedSigned());
    2675             :         SetOutput(node, MachineRepresentation::kTaggedSigned);
    2676             :         return;
    2677             :       }
    2678             :       case IrOpcode::kStringLength: {
    2679             :         // TODO(bmeurer): The input representation should be TaggedPointer.
    2680             :         // Fix this once we have a dedicated StringConcat/JSStringAdd
    2681             :         // operator, which marks it's output as TaggedPointer properly.
    2682       72956 :         VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kWord32);
    2683       72956 :         return;
    2684             :       }
    2685             :       case IrOpcode::kStringSubstring: {
    2686        4143 :         ProcessInput(node, 0, UseInfo::AnyTagged());
    2687        4143 :         ProcessInput(node, 1, UseInfo::TruncatingWord32());
    2688        4143 :         ProcessInput(node, 2, UseInfo::TruncatingWord32());
    2689        4143 :         ProcessRemainingInputs(node, 3);
    2690             :         SetOutput(node, MachineRepresentation::kTaggedPointer);
    2691             :         return;
    2692             :       }
    2693             :       case IrOpcode::kStringToLowerCaseIntl:
    2694             :       case IrOpcode::kStringToUpperCaseIntl: {
    2695             :         VisitUnop(node, UseInfo::AnyTagged(),
    2696         465 :                   MachineRepresentation::kTaggedPointer);
    2697         465 :         return;
    2698             :       }
    2699             :       case IrOpcode::kCheckBounds:
    2700      187704 :         return VisitCheckBounds(node, lowering);
    2701             :       case IrOpcode::kPoisonIndex: {
    2702             :         VisitUnop(node, UseInfo::TruncatingWord32(),
    2703        3723 :                   MachineRepresentation::kWord32);
    2704        3723 :         return;
    2705             :       }
    2706             :       case IrOpcode::kCheckHeapObject: {
    2707       88564 :         if (InputCannotBe(node, Type::SignedSmall())) {
    2708             :           VisitUnop(node, UseInfo::AnyTagged(),
    2709           3 :                     MachineRepresentation::kTaggedPointer);
    2710             :         } else {
    2711      177122 :           VisitUnop(node,
    2712             :                     UseInfo::CheckedHeapObjectAsTaggedPointer(VectorSlotPair()),
    2713       88561 :                     MachineRepresentation::kTaggedPointer);
    2714             :         }
    2715      116436 :         if (lower()) DeferReplacement(node, node->InputAt(0));
    2716             :         return;
    2717             :       }
    2718             :       case IrOpcode::kCheckIf: {
    2719       50734 :         ProcessInput(node, 0, UseInfo::Bool());
    2720       50734 :         ProcessRemainingInputs(node, 1);
    2721             :         SetOutput(node, MachineRepresentation::kNone);
    2722             :         return;
    2723             :       }
    2724             :       case IrOpcode::kCheckInternalizedString: {
    2725        5603 :         VisitCheck(node, Type::InternalizedString(), lowering);
    2726        5603 :         return;
    2727             :       }
    2728             :       case IrOpcode::kCheckNonEmptyString: {
    2729          54 :         VisitCheck(node, Type::NonEmptyString(), lowering);
    2730          54 :         return;
    2731             :       }
    2732             :       case IrOpcode::kCheckNonEmptyOneByteString: {
    2733        5488 :         VisitCheck(node, Type::NonEmptyOneByteString(), lowering);
    2734        5488 :         return;
    2735             :       }
    2736             :       case IrOpcode::kCheckNonEmptyTwoByteString: {
    2737         694 :         VisitCheck(node, Type::NonEmptyTwoByteString(), lowering);
    2738         694 :         return;
    2739             :       }
    2740             :       case IrOpcode::kCheckNumber: {
    2741        1600 :         Type const input_type = TypeOf(node->InputAt(0));
    2742        1600 :         if (input_type.Is(Type::Number())) {
    2743          36 :           VisitNoop(node, truncation);
    2744             :         } else {
    2745        1564 :           VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged);
    2746             :         }
    2747             :         return;
    2748             :       }
    2749             :       case IrOpcode::kCheckReceiver: {
    2750        3210 :         VisitCheck(node, Type::Receiver(), lowering);
    2751        3210 :         return;
    2752             :       }
    2753             :       case IrOpcode::kCheckReceiverOrNullOrUndefined: {
    2754         234 :         VisitCheck(node, Type::ReceiverOrNullOrUndefined(), lowering);
    2755         234 :         return;
    2756             :       }
    2757             :       case IrOpcode::kCheckSmi: {
    2758      100762 :         const CheckParameters& params = CheckParametersOf(node->op());
    2759      100762 :         if (SmiValuesAre32Bits() && truncation.IsUsedAsWord32()) {
    2760             :           VisitUnop(node,
    2761             :                     UseInfo::CheckedSignedSmallAsWord32(kDistinguishZeros,
    2762             :                                                         params.feedback()),
    2763       28021 :                     MachineRepresentation::kWord32);
    2764             :         } else {
    2765             :           VisitUnop(
    2766             :               node,
    2767             :               UseInfo::CheckedSignedSmallAsTaggedSigned(params.feedback()),
    2768       72741 :               MachineRepresentation::kTaggedSigned);
    2769             :         }
    2770      131047 :         if (lower()) DeferReplacement(node, node->InputAt(0));
    2771             :         return;
    2772             :       }
    2773             :       case IrOpcode::kCheckString: {
    2774       18907 :         const CheckParameters& params = CheckParametersOf(node->op());
    2775       18907 :         if (InputIs(node, Type::String())) {
    2776             :           VisitUnop(node, UseInfo::AnyTagged(),
    2777           0 :                     MachineRepresentation::kTaggedPointer);
    2778           0 :           if (lower()) DeferReplacement(node, node->InputAt(0));
    2779             :         } else {
    2780             :           VisitUnop(
    2781             :               node,
    2782             :               UseInfo::CheckedHeapObjectAsTaggedPointer(params.feedback()),
    2783       18908 :               MachineRepresentation::kTaggedPointer);
    2784             :         }
    2785             :         return;
    2786             :       }
    2787             :       case IrOpcode::kCheckSymbol: {
    2788         104 :         VisitCheck(node, Type::Symbol(), lowering);
    2789         104 :         return;
    2790             :       }
    2791             : 
    2792             :       case IrOpcode::kAllocate: {
    2793      343493 :         ProcessInput(node, 0, UseInfo::Word());
    2794      343493 :         ProcessRemainingInputs(node, 1);
    2795             :         SetOutput(node, MachineRepresentation::kTaggedPointer);
    2796             :         return;
    2797             :       }
    2798             :       case IrOpcode::kLoadMessage: {
    2799       89334 :         if (truncation.IsUnused()) return VisitUnused(node);
    2800       21734 :         VisitUnop(node, UseInfo::Word(), MachineRepresentation::kTagged);
    2801       21734 :         return;
    2802             :       }
    2803             :       case IrOpcode::kStoreMessage: {
    2804       89709 :         ProcessInput(node, 0, UseInfo::Word());
    2805       89709 :         ProcessInput(node, 1, UseInfo::AnyTagged());
    2806       89709 :         ProcessRemainingInputs(node, 2);
    2807             :         SetOutput(node, MachineRepresentation::kNone);
    2808             :         return;
    2809             :       }
    2810             :       case IrOpcode::kLoadFieldByIndex: {
    2811        2107 :         if (truncation.IsUnused()) return VisitUnused(node);
    2812             :         VisitBinop(node, UseInfo::AnyTagged(), UseInfo::TruncatingWord32(),
    2813        2073 :                    MachineRepresentation::kTagged);
    2814        2073 :         return;
    2815             :       }
    2816             :       case IrOpcode::kLoadField: {
    2817     3875347 :         if (truncation.IsUnused()) return VisitUnused(node);
    2818     3764011 :         FieldAccess access = FieldAccessOf(node->op());
    2819             :         MachineRepresentation const representation =
    2820             :             access.machine_type.representation();
    2821     3764011 :         VisitUnop(node, UseInfoForBasePointer(access), representation);
    2822     3764010 :         return;
    2823             :       }
    2824             :       case IrOpcode::kStoreField: {
    2825     6300481 :         FieldAccess access = FieldAccessOf(node->op());
    2826             :         Node* value_node = node->InputAt(1);
    2827             :         NodeInfo* input_info = GetInfo(value_node);
    2828             :         MachineRepresentation field_representation =
    2829             :             access.machine_type.representation();
    2830             : 
    2831             :         // Convert to Smi if possible, such that we can avoid a write barrier.
    2832    18901403 :         if (field_representation == MachineRepresentation::kTagged &&
    2833    16435628 :             TypeOf(value_node).Is(Type::SignedSmall())) {
    2834             :           field_representation = MachineRepresentation::kTaggedSigned;
    2835             :         }
    2836     6300463 :         WriteBarrierKind write_barrier_kind = WriteBarrierKindFor(
    2837     6300463 :             access.base_is_tagged, field_representation, access.offset,
    2838             :             access.type, input_info->representation(), value_node);
    2839             : 
    2840     6300464 :         ProcessInput(node, 0, UseInfoForBasePointer(access));
    2841     6300499 :         ProcessInput(node, 1,
    2842     6300503 :                      TruncatingUseInfoFromRepresentation(field_representation));
    2843     6300497 :         ProcessRemainingInputs(node, 2);
    2844             :         SetOutput(node, MachineRepresentation::kNone);
    2845     6300479 :         if (lower()) {
    2846     2096807 :           if (write_barrier_kind < access.write_barrier_kind) {
    2847      727996 :             access.write_barrier_kind = write_barrier_kind;
    2848      727996 :             NodeProperties::ChangeOp(
    2849     1455992 :                 node, jsgraph_->simplified()->StoreField(access));
    2850             :           }
    2851             :         }
    2852             :         return;
    2853             :       }
    2854             :       case IrOpcode::kLoadElement: {
    2855       64698 :         if (truncation.IsUnused()) return VisitUnused(node);
    2856       62587 :         ElementAccess access = ElementAccessOf(node->op());
    2857       62587 :         VisitBinop(node, UseInfoForBasePointer(access), UseInfo::Word(),
    2858       62587 :                    access.machine_type.representation());
    2859       62587 :         return;
    2860             :       }
    2861             :       case IrOpcode::kLoadStackArgument: {
    2862        2346 :         if (truncation.IsUnused()) return VisitUnused(node);
    2863             :         VisitBinop(node, UseInfo::Word(), MachineRepresentation::kTagged);
    2864             :         return;
    2865             :       }
    2866             :       case IrOpcode::kStoreElement: {
    2867      115931 :         ElementAccess access = ElementAccessOf(node->op());
    2868             :         Node* value_node = node->InputAt(2);
    2869             :         NodeInfo* input_info = GetInfo(value_node);
    2870             :         MachineRepresentation element_representation =
    2871             :             access.machine_type.representation();
    2872             : 
    2873             :         // Convert to Smi if possible, such that we can avoid a write barrier.
    2874      347793 :         if (element_representation == MachineRepresentation::kTagged &&
    2875      273493 :             TypeOf(value_node).Is(Type::SignedSmall())) {
    2876             :           element_representation = MachineRepresentation::kTaggedSigned;
    2877             :         }
    2878      115931 :         WriteBarrierKind write_barrier_kind = WriteBarrierKindFor(
    2879      115931 :             access.base_is_tagged, element_representation, access.type,
    2880      115931 :             input_info->representation(), value_node);
    2881      115931 :         ProcessInput(node, 0, UseInfoForBasePointer(access));  // base
    2882      115931 :         ProcessInput(node, 1, UseInfo::Word());                // index
    2883      115931 :         ProcessInput(node, 2,
    2884             :                      TruncatingUseInfoFromRepresentation(
    2885      115931 :                          element_representation));  // value
    2886      115931 :         ProcessRemainingInputs(node, 3);
    2887             :         SetOutput(node, MachineRepresentation::kNone);
    2888      115931 :         if (lower()) {
    2889       37765 :           if (write_barrier_kind < access.write_barrier_kind) {
    2890       22904 :             access.write_barrier_kind = write_barrier_kind;
    2891       22904 :             NodeProperties::ChangeOp(
    2892       45808 :                 node, jsgraph_->simplified()->StoreElement(access));
    2893             :           }
    2894             :         }
    2895             :         return;
    2896             :       }
    2897             :       case IrOpcode::kNumberIsFloat64Hole: {
    2898             :         VisitUnop(node, UseInfo::TruncatingFloat64(),
    2899         230 :                   MachineRepresentation::kBit);
    2900         230 :         return;
    2901             :       }
    2902             :       case IrOpcode::kTransitionAndStoreElement: {
    2903         885 :         Type value_type = TypeOf(node->InputAt(2));
    2904             : 
    2905         885 :         ProcessInput(node, 0, UseInfo::AnyTagged());  // array
    2906         885 :         ProcessInput(node, 1, UseInfo::Word());       // index
    2907             : 
    2908         885 :         if (value_type.Is(Type::SignedSmall())) {
    2909         294 :           ProcessInput(node, 2, UseInfo::TruncatingWord32());  // value
    2910         294 :           if (lower()) {
    2911          71 :             NodeProperties::ChangeOp(node,
    2912          71 :                                      simplified()->StoreSignedSmallElement());
    2913             :           }
    2914         591 :         } else if (value_type.Is(Type::Number())) {
    2915         123 :           ProcessInput(node, 2, UseInfo::TruncatingFloat64());  // value
    2916         123 :           if (lower()) {
    2917          28 :             Handle<Map> double_map = DoubleMapParameterOf(node->op());
    2918          28 :             NodeProperties::ChangeOp(
    2919             :                 node,
    2920          28 :                 simplified()->TransitionAndStoreNumberElement(double_map));
    2921             :           }
    2922         468 :         } else if (value_type.Is(Type::NonNumber())) {
    2923          92 :           ProcessInput(node, 2, UseInfo::AnyTagged());  // value
    2924          92 :           if (lower()) {
    2925          20 :             Handle<Map> fast_map = FastMapParameterOf(node->op());
    2926          20 :             NodeProperties::ChangeOp(
    2927             :                 node, simplified()->TransitionAndStoreNonNumberElement(
    2928          20 :                           fast_map, value_type));
    2929             :           }
    2930             :         } else {
    2931         376 :           ProcessInput(node, 2, UseInfo::AnyTagged());  // value
    2932             :         }
    2933             : 
    2934         885 :         ProcessRemainingInputs(node, 3);
    2935             :         SetOutput(node, MachineRepresentation::kNone);
    2936             :         return;
    2937             :       }
    2938             :       case IrOpcode::kLoadTypedElement: {
    2939             :         MachineRepresentation const rep =
    2940       16577 :             MachineRepresentationFromArrayType(ExternalArrayTypeOf(node->op()));
    2941       16577 :         ProcessInput(node, 0, UseInfo::AnyTagged());  // buffer
    2942       16577 :         ProcessInput(node, 1, UseInfo::AnyTagged());  // base pointer
    2943       16577 :         ProcessInput(node, 2, UseInfo::Word());       // external pointer
    2944       16577 :         ProcessInput(node, 3, UseInfo::Word());       // index
    2945       16577 :         ProcessRemainingInputs(node, 4);
    2946             :         SetOutput(node, rep);
    2947             :         return;
    2948             :       }
    2949             :       case IrOpcode::kLoadDataViewElement: {
    2950             :         MachineRepresentation const rep =
    2951         804 :             MachineRepresentationFromArrayType(ExternalArrayTypeOf(node->op()));
    2952         804 :         ProcessInput(node, 0, UseInfo::AnyTagged());  // buffer
    2953         804 :         ProcessInput(node, 1, UseInfo::Word());       // external pointer
    2954         804 :         ProcessInput(node, 2, UseInfo::Word());       // byte offset
    2955         804 :         ProcessInput(node, 3, UseInfo::Word());       // index
    2956         804 :         ProcessInput(node, 4, UseInfo::Bool());       // little-endian
    2957         804 :         ProcessRemainingInputs(node, 5);
    2958             :         SetOutput(node, rep);
    2959             :         return;
    2960             :       }
    2961             :       case IrOpcode::kStoreTypedElement: {
    2962             :         MachineRepresentation const rep =
    2963       15766 :             MachineRepresentationFromArrayType(ExternalArrayTypeOf(node->op()));
    2964       15766 :         ProcessInput(node, 0, UseInfo::AnyTagged());  // buffer
    2965       15766 :         ProcessInput(node, 1, UseInfo::AnyTagged());  // base pointer
    2966       15766 :         ProcessInput(node, 2, UseInfo::Word());       // external pointer
    2967       15766 :         ProcessInput(node, 3, UseInfo::Word());       // index
    2968       15766 :         ProcessInput(node, 4,
    2969       15766 :                      TruncatingUseInfoFromRepresentation(rep));  // value
    2970       15766 :         ProcessRemainingInputs(node, 5);
    2971             :         SetOutput(node, MachineRepresentation::kNone);
    2972             :         return;
    2973             :       }
    2974             :       case IrOpcode::kStoreDataViewElement: {
    2975             :         MachineRepresentation const rep =
    2976         588 :             MachineRepresentationFromArrayType(ExternalArrayTypeOf(node->op()));
    2977         588 :         ProcessInput(node, 0, UseInfo::AnyTagged());         // buffer
    2978         588 :         ProcessInput(node, 1, UseInfo::Word());              // external pointer
    2979         588 :         ProcessInput(node, 2, UseInfo::Word());              // byte offset
    2980         588 :         ProcessInput(node, 3, UseInfo::Word());              // index
    2981         588 :         ProcessInput(node, 4,
    2982         588 :                      TruncatingUseInfoFromRepresentation(rep));  // value
    2983         588 :         ProcessInput(node, 5, UseInfo::Bool());  // little-endian
    2984         588 :         ProcessRemainingInputs(node, 6);
    2985             :         SetOutput(node, MachineRepresentation::kNone);
    2986             :         return;
    2987             :       }
    2988             :       case IrOpcode::kConvertReceiver: {
    2989        2681 :         Type input_type = TypeOf(node->InputAt(0));
    2990             :         VisitBinop(node, UseInfo::AnyTagged(),
    2991             :                    MachineRepresentation::kTaggedPointer);
    2992        2681 :         if (lower()) {
    2993             :           // Try to optimize the {node} based on the input type.
    2994         875 :           if (input_type.Is(Type::Receiver())) {
    2995           0 :             DeferReplacement(node, node->InputAt(0));
    2996         875 :           } else if (input_type.Is(Type::NullOrUndefined())) {
    2997           0 :             DeferReplacement(node, node->InputAt(1));
    2998         875 :           } else if (!input_type.Maybe(Type::NullOrUndefined())) {
    2999          85 :             NodeProperties::ChangeOp(
    3000             :                 node, lowering->simplified()->ConvertReceiver(
    3001          85 :                           ConvertReceiverMode::kNotNullOrUndefined));
    3002             :           }
    3003             :         }
    3004             :         return;
    3005             :       }
    3006             :       case IrOpcode::kPlainPrimitiveToNumber: {
    3007        2639 :         if (InputIs(node, Type::Boolean())) {
    3008         199 :           VisitUnop(node, UseInfo::Bool(), MachineRepresentation::kWord32);
    3009         258 :           if (lower()) DeferReplacement(node, node->InputAt(0));
    3010        2440 :         } else if (InputIs(node, Type::String())) {
    3011         998 :           VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged);
    3012         998 :           if (lower()) {
    3013         330 :             NodeProperties::ChangeOp(node, simplified()->StringToNumber());
    3014             :           }
    3015        1442 :         } else if (truncation.IsUsedAsWord32()) {
    3016          57 :           if (InputIs(node, Type::NumberOrOddball())) {
    3017             :             VisitUnop(node, UseInfo::TruncatingWord32(),
    3018          30 :                       MachineRepresentation::kWord32);
    3019          40 :             if (lower()) DeferReplacement(node, node->InputAt(0));
    3020             :           } else {
    3021             :             VisitUnop(node, UseInfo::AnyTagged(),
    3022          27 :                       MachineRepresentation::kWord32);
    3023          27 :             if (lower()) {
    3024           9 :               NodeProperties::ChangeOp(node,
    3025           9 :                                        simplified()->PlainPrimitiveToWord32());
    3026             :             }
    3027             :           }
    3028        1385 :         } else if (truncation.IsUsedAsFloat64()) {
    3029        1309 :           if (InputIs(node, Type::NumberOrOddball())) {
    3030             :             VisitUnop(node, UseInfo::TruncatingFloat64(),
    3031        1309 :                       MachineRepresentation::kFloat64);
    3032        1647 :             if (lower()) DeferReplacement(node, node->InputAt(0));
    3033             :           } else {
    3034             :             VisitUnop(node, UseInfo::AnyTagged(),
    3035           0 :                       MachineRepresentation::kFloat64);
    3036           0 :             if (lower()) {
    3037           0 :               NodeProperties::ChangeOp(node,
    3038           0 :                                        simplified()->PlainPrimitiveToFloat64());
    3039             :             }
    3040             :           }
    3041             :         } else {
    3042          76 :           VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged);
    3043             :         }
    3044             :         return;
    3045             :       }
    3046             :       case IrOpcode::kSpeculativeToNumber: {
    3047             :         NumberOperationParameters const& p =
    3048      133210 :             NumberOperationParametersOf(node->op());
    3049      133210 :         switch (p.hint()) {
    3050             :           case NumberOperationHint::kSigned32:
    3051             :           case NumberOperationHint::kSignedSmall:
    3052             :           case NumberOperationHint::kSignedSmallInputs:
    3053        6294 :             VisitUnop(node,
    3054             :                       CheckedUseInfoAsWord32FromHint(p.hint(), p.feedback()),
    3055        6294 :                       MachineRepresentation::kWord32, Type::Signed32());
    3056        6294 :             break;
    3057             :           case NumberOperationHint::kNumber:
    3058             :           case NumberOperationHint::kNumberOrOddball:
    3059      126916 :             VisitUnop(node,
    3060             :                       CheckedUseInfoAsFloat64FromHint(p.hint(), p.feedback()),
    3061      126916 :                       MachineRepresentation::kFloat64);
    3062      126916 :             break;
    3063             :         }
    3064      173544 :         if (lower()) DeferReplacement(node, node->InputAt(0));
    3065             :         return;
    3066             :       }
    3067             :       case IrOpcode::kObjectIsArrayBufferView: {
    3068             :         // TODO(turbofan): Introduce a Type::ArrayBufferView?
    3069          48 :         VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
    3070          48 :         return;
    3071             :       }
    3072             :       case IrOpcode::kObjectIsBigInt: {
    3073          75 :         VisitObjectIs(node, Type::BigInt(), lowering);
    3074          75 :         return;
    3075             :       }
    3076             :       case IrOpcode::kObjectIsCallable: {
    3077         330 :         VisitObjectIs(node, Type::Callable(), lowering);
    3078         330 :         return;
    3079             :       }
    3080             :       case IrOpcode::kObjectIsConstructor: {
    3081             :         // TODO(turbofan): Introduce a Type::Constructor?
    3082        1131 :         VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
    3083        1131 :         return;
    3084             :       }
    3085             :       case IrOpcode::kObjectIsDetectableCallable: {
    3086       43653 :         VisitObjectIs(node, Type::DetectableCallable(), lowering);
    3087       43653 :         return;
    3088             :       }
    3089             :       case IrOpcode::kObjectIsFiniteNumber: {
    3090         588 :         Type const input_type = GetUpperBound(node->InputAt(0));
    3091        1176 :         if (input_type.Is(type_cache_->kSafeInteger)) {
    3092         210 :           VisitUnop(node, UseInfo::None(), MachineRepresentation::kBit);
    3093         210 :           if (lower()) {
    3094          70 :             DeferReplacement(node, lowering->jsgraph()->Int32Constant(1));
    3095             :           }
    3096         378 :         } else if (!input_type.Maybe(Type::Number())) {
    3097          42 :           VisitUnop(node, UseInfo::Any(), MachineRepresentation::kBit);
    3098          42 :           if (lower()) {
    3099          14 :             DeferReplacement(node, lowering->jsgraph()->Int32Constant(0));
    3100             :           }
    3101         336 :         } else if (input_type.Is(Type::Number())) {
    3102             :           VisitUnop(node, UseInfo::TruncatingFloat64(),
    3103         315 :                     MachineRepresentation::kBit);
    3104         315 :           if (lower()) {
    3105         105 :             NodeProperties::ChangeOp(node,
    3106         105 :                                      lowering->simplified()->NumberIsFinite());
    3107             :           }
    3108             :         } else {
    3109          21 :           VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
    3110             :         }
    3111             :         return;
    3112             :       }
    3113             :       case IrOpcode::kNumberIsFinite: {
    3114             :         VisitUnop(node, UseInfo::TruncatingFloat64(),
    3115          70 :                   MachineRepresentation::kBit);
    3116          70 :         return;
    3117             :       }
    3118             :       case IrOpcode::kObjectIsSafeInteger: {
    3119          42 :         Type const input_type = GetUpperBound(node->InputAt(0));
    3120          84 :         if (input_type.Is(type_cache_->kSafeInteger)) {
    3121           0 :           VisitUnop(node, UseInfo::None(), MachineRepresentation::kBit);
    3122           0 :           if (lower()) {
    3123           0 :             DeferReplacement(node, lowering->jsgraph()->Int32Constant(1));
    3124             :           }
    3125          42 :         } else if (!input_type.Maybe(Type::Number())) {
    3126           0 :           VisitUnop(node, UseInfo::Any(), MachineRepresentation::kBit);
    3127           0 :           if (lower()) {
    3128           0 :             DeferReplacement(node, lowering->jsgraph()->Int32Constant(0));
    3129             :           }
    3130          42 :         } else if (input_type.Is(Type::Number())) {
    3131             :           VisitUnop(node, UseInfo::TruncatingFloat64(),
    3132          21 :                     MachineRepresentation::kBit);
    3133          21 :           if (lower()) {
    3134           7 :             NodeProperties::ChangeOp(
    3135           7 :                 node, lowering->simplified()->NumberIsSafeInteger());
    3136             :           }
    3137             :         } else {
    3138          21 :           VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
    3139             :         }
    3140             :         return;
    3141             :       }
    3142             :       case IrOpcode::kNumberIsSafeInteger: {
    3143           0 :         UNREACHABLE();
    3144             :       }
    3145             :       case IrOpcode::kObjectIsInteger: {
    3146         588 :         Type const input_type = GetUpperBound(node->InputAt(0));
    3147        1176 :         if (input_type.Is(type_cache_->kSafeInteger)) {
    3148         210 :           VisitUnop(node, UseInfo::None(), MachineRepresentation::kBit);
    3149         210 :           if (lower()) {
    3150          70 :             DeferReplacement(node, lowering->jsgraph()->Int32Constant(1));
    3151             :           }
    3152         378 :         } else if (!input_type.Maybe(Type::Number())) {
    3153           0 :           VisitUnop(node, UseInfo::Any(), MachineRepresentation::kBit);
    3154           0 :           if (lower()) {
    3155           0 :             DeferReplacement(node, lowering->jsgraph()->Int32Constant(0));
    3156             :           }
    3157         378 :         } else if (input_type.Is(Type::Number())) {
    3158             :           VisitUnop(node, UseInfo::TruncatingFloat64(),
    3159         357 :                     MachineRepresentation::kBit);
    3160         357 :           if (lower()) {
    3161         119 :             NodeProperties::ChangeOp(node,
    3162         119 :                                      lowering->simplified()->NumberIsInteger());
    3163             :           }
    3164             :         } else {
    3165          21 :           VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
    3166             :         }
    3167             :         return;
    3168             :       }
    3169             :       case IrOpcode::kNumberIsInteger: {
    3170             :         VisitUnop(node, UseInfo::TruncatingFloat64(),
    3171           0 :                   MachineRepresentation::kBit);
    3172           0 :         return;
    3173             :       }
    3174             :       case IrOpcode::kObjectIsMinusZero: {
    3175         363 :         Type const input_type = GetUpperBound(node->InputAt(0));
    3176         363 :         if (input_type.Is(Type::MinusZero())) {
    3177           0 :           VisitUnop(node, UseInfo::None(), MachineRepresentation::kBit);
    3178           0 :           if (lower()) {
    3179           0 :             DeferReplacement(node, lowering->jsgraph()->Int32Constant(1));
    3180             :           }
    3181         363 :         } else if (!input_type.Maybe(Type::MinusZero())) {
    3182           0 :           VisitUnop(node, UseInfo::Any(), MachineRepresentation::kBit);
    3183           0 :           if (lower()) {
    3184           0 :             DeferReplacement(node, lowering->jsgraph()->Int32Constant(0));
    3185             :           }
    3186         363 :         } else if (input_type.Is(Type::Number())) {
    3187             :           VisitUnop(node, UseInfo::TruncatingFloat64(),
    3188         294 :                     MachineRepresentation::kBit);
    3189         294 :           if (lower()) {
    3190          98 :             NodeProperties::ChangeOp(node, simplified()->NumberIsMinusZero());
    3191             :           }
    3192             :         } else {
    3193          69 :           VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
    3194             :         }
    3195             :         return;
    3196             :       }
    3197             :       case IrOpcode::kObjectIsNaN: {
    3198        2724 :         Type const input_type = GetUpperBound(node->InputAt(0));
    3199        2724 :         if (input_type.Is(Type::NaN())) {
    3200           0 :           VisitUnop(node, UseInfo::None(), MachineRepresentation::kBit);
    3201           0 :           if (lower()) {
    3202           0 :             DeferReplacement(node, lowering->jsgraph()->Int32Constant(1));
    3203             :           }
    3204        2724 :         } else if (!input_type.Maybe(Type::NaN())) {
    3205          36 :           VisitUnop(node, UseInfo::Any(), MachineRepresentation::kBit);
    3206          36 :           if (lower()) {
    3207          12 :             DeferReplacement(node, lowering->jsgraph()->Int32Constant(0));
    3208             :           }
    3209        2688 :         } else if (input_type.Is(Type::Number())) {
    3210             :           VisitUnop(node, UseInfo::TruncatingFloat64(),
    3211         540 :                     MachineRepresentation::kBit);
    3212         540 :           if (lower()) {
    3213         180 :             NodeProperties::ChangeOp(node, simplified()->NumberIsNaN());
    3214             :           }
    3215             :         } else {
    3216        2148 :           VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
    3217             :         }
    3218             :         return;
    3219             :       }
    3220             :       case IrOpcode::kNumberIsNaN: {
    3221             :         VisitUnop(node, UseInfo::TruncatingFloat64(),
    3222        8508 :                   MachineRepresentation::kBit);
    3223        8508 :         return;
    3224             :       }
    3225             :       case IrOpcode::kObjectIsNonCallable: {
    3226       18711 :         VisitObjectIs(node, Type::NonCallable(), lowering);
    3227       18711 :         return;
    3228             :       }
    3229             :       case IrOpcode::kObjectIsNumber: {
    3230       23605 :         VisitObjectIs(node, Type::Number(), lowering);
    3231       23605 :         return;
    3232             :       }
    3233             :       case IrOpcode::kObjectIsReceiver: {
    3234       63494 :         VisitObjectIs(node, Type::Receiver(), lowering);
    3235       63494 :         return;
    3236             :       }
    3237             :       case IrOpcode::kObjectIsSmi: {
    3238             :         // TODO(turbofan): Optimize based on input representation.
    3239        3865 :         VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
    3240        3865 :         return;
    3241             :       }
    3242             :       case IrOpcode::kObjectIsString: {
    3243        7107 :         VisitObjectIs(node, Type::String(), lowering);
    3244        7107 :         return;
    3245             :       }
    3246             :       case IrOpcode::kObjectIsSymbol: {
    3247          71 :         VisitObjectIs(node, Type::Symbol(), lowering);
    3248          71 :         return;
    3249             :       }
    3250             :       case IrOpcode::kObjectIsUndetectable: {
    3251        4776 :         VisitObjectIs(node, Type::Undetectable(), lowering);
    3252        4776 :         return;
    3253             :       }
    3254             :       case IrOpcode::kArgumentsFrame: {
    3255             :         SetOutput(node, MachineType::PointerRepresentation());
    3256             :         return;
    3257             :       }
    3258             :       case IrOpcode::kArgumentsLength: {
    3259       50948 :         VisitUnop(node, UseInfo::Word(), MachineRepresentation::kTaggedSigned);
    3260       50948 :         return;
    3261             :       }
    3262             :       case IrOpcode::kNewDoubleElements:
    3263             :       case IrOpcode::kNewSmiOrObjectElements: {
    3264        1701 :         VisitUnop(node, UseInfo::Word(), MachineRepresentation::kTaggedPointer);
    3265        1701 :         return;
    3266             :       }
    3267             :       case IrOpcode::kNewArgumentsElements: {
    3268             :         VisitBinop(node, UseInfo::Word(), UseInfo::TaggedSigned(),
    3269       58980 :                    MachineRepresentation::kTaggedPointer);
    3270       58980 :         return;
    3271             :       }
    3272             :       case IrOpcode::kCheckFloat64Hole: {
    3273        1903 :         Type const input_type = TypeOf(node->InputAt(0));
    3274             :         CheckFloat64HoleMode mode =
    3275        1903 :             CheckFloat64HoleParametersOf(node->op()).mode();
    3276        1903 :         if (mode == CheckFloat64HoleMode::kAllowReturnHole) {
    3277             :           // If {mode} is allow-return-hole _and_ the {truncation}
    3278             :           // identifies NaN and undefined, we can just pass along
    3279             :           // the {truncation} and completely wipe the {node}.
    3280        1358 :           if (truncation.IsUnused()) return VisitUnused(node);
    3281        1262 :           if (truncation.IsUsedAsFloat64()) {
    3282             :             VisitUnop(node, UseInfo::TruncatingFloat64(),
    3283         129 :                       MachineRepresentation::kFloat64);
    3284         172 :             if (lower()) DeferReplacement(node, node->InputAt(0));
    3285             :             return;
    3286             :           }
    3287             :         }
    3288        3356 :         VisitUnop(node,
    3289             :                   UseInfo(MachineRepresentation::kFloat64, Truncation::Any()),
    3290        1678 :                   MachineRepresentation::kFloat64, Type::Number());
    3291        2216 :         if (lower() && input_type.Is(Type::Number())) {
    3292          64 :           DeferReplacement(node, node->InputAt(0));
    3293             :         }
    3294             :         return;
    3295             :       }
    3296             :       case IrOpcode::kCheckNotTaggedHole: {
    3297         316 :         VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged);
    3298         316 :         return;
    3299             :       }
    3300             :       case IrOpcode::kConvertTaggedHoleToUndefined: {
    3301       10208 :         if (InputIs(node, Type::NumberOrOddball()) &&
    3302             :             truncation.IsUsedAsWord32()) {
    3303             :           // Propagate the Word32 truncation.
    3304             :           VisitUnop(node, UseInfo::TruncatingWord32(),
    3305        1009 :                     MachineRepresentation::kWord32);
    3306        1259 :           if (lower()) DeferReplacement(node, node->InputAt(0));
    3307        8190 :         } else if (InputIs(node, Type::NumberOrOddball()) &&
    3308             :                    truncation.IsUsedAsFloat64()) {
    3309             :           // Propagate the Float64 truncation.
    3310             :           VisitUnop(node, UseInfo::TruncatingFloat64(),
    3311         143 :                     MachineRepresentation::kFloat64);
    3312         187 :           if (lower()) DeferReplacement(node, node->InputAt(0));
    3313        6055 :         } else if (InputIs(node, Type::NonInternal())) {
    3314         126 :           VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged);
    3315         168 :           if (lower()) DeferReplacement(node, node->InputAt(0));
    3316             :         } else {
    3317             :           // TODO(turbofan): Add a (Tagged) truncation that identifies hole
    3318             :           // and undefined, i.e. for a[i] === obj cases.
    3319        5929 :           VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged);
    3320             :         }
    3321             :         return;
    3322             :       }
    3323             :       case IrOpcode::kCheckEqualsSymbol:
    3324             :       case IrOpcode::kCheckEqualsInternalizedString:
    3325             :         return VisitBinop(node, UseInfo::AnyTagged(),
    3326             :                           MachineRepresentation::kNone);
    3327             :       case IrOpcode::kMapGuard:
    3328             :         // Eliminate MapGuard nodes here.
    3329       22139 :         return VisitUnused(node);
    3330             :       case IrOpcode::kCheckMaps:
    3331             :       case IrOpcode::kTransitionElementsKind: {
    3332      160971 :         VisitInputs(node);
    3333             :         return SetOutput(node, MachineRepresentation::kNone);
    3334             :       }
    3335             :       case IrOpcode::kCompareMaps:
    3336             :         return VisitUnop(node, UseInfo::AnyTagged(),
    3337       24069 :                          MachineRepresentation::kBit);
    3338             :       case IrOpcode::kEnsureWritableFastElements:
    3339             :         return VisitBinop(node, UseInfo::AnyTagged(),
    3340             :                           MachineRepresentation::kTaggedPointer);
    3341             :       case IrOpcode::kMaybeGrowFastElements: {
    3342       11640 :         Type const index_type = TypeOf(node->InputAt(2));
    3343       11640 :         Type const length_type = TypeOf(node->InputAt(3));
    3344       11640 :         ProcessInput(node, 0, UseInfo::AnyTagged());         // object
    3345       11640 :         ProcessInput(node, 1, UseInfo::AnyTagged());         // elements
    3346       11640 :         ProcessInput(node, 2, UseInfo::TruncatingWord32());  // index
    3347       11640 :         ProcessInput(node, 3, UseInfo::TruncatingWord32());  // length
    3348       11640 :         ProcessRemainingInputs(node, 4);
    3349             :         SetOutput(node, MachineRepresentation::kTaggedPointer);
    3350       11640 :         if (lower()) {
    3351             :           // If the index is known to be less than the length (or if
    3352             :           // we're in dead code), we know that we don't need to grow
    3353             :           // the elements, so we can just remove this operation all
    3354             :           // together and replace it with the elements that we have
    3355             :           // on the inputs.
    3356       10734 :           if (index_type.IsNone() || length_type.IsNone() ||
    3357        3578 :               index_type.Max() < length_type.Min()) {
    3358          51 :             DeferReplacement(node, node->InputAt(1));
    3359             :           }
    3360             :         }
    3361             :         return;
    3362             :       }
    3363             : 
    3364             :       case IrOpcode::kDateNow:
    3365          39 :         VisitInputs(node);
    3366             :         return SetOutput(node, MachineRepresentation::kTaggedPointer);
    3367             :       case IrOpcode::kFrameState:
    3368    16608805 :         return VisitFrameState(node);
    3369             :       case IrOpcode::kStateValues:
    3370    10984716 :         return VisitStateValues(node);
    3371             :       case IrOpcode::kObjectState:
    3372       69801 :         return VisitObjectState(node);
    3373             :       case IrOpcode::kObjectId:
    3374             :         return SetOutput(node, MachineRepresentation::kTaggedPointer);
    3375             :       case IrOpcode::kTypeGuard: {
    3376             :         // We just get rid of the sigma here, choosing the best representation
    3377             :         // for the sigma's type.
    3378       91610 :         Type type = TypeOf(node);
    3379             :         MachineRepresentation representation =
    3380       91610 :             GetOutputInfoForPhi(node, type, truncation);
    3381             : 
    3382             :         // Here we pretend that the input has the sigma's type for the
    3383             :         // conversion.
    3384      183220 :         UseInfo use(representation, truncation);
    3385       91610 :         if (propagate()) {
    3386       30785 :           EnqueueInput(node, 0, use);
    3387       60825 :         } else if (lower()) {
    3388       22673 :           ConvertInput(node, 0, use, type);
    3389             :         }
    3390       91610 :         ProcessRemainingInputs(node, 1);
    3391             :         SetOutput(node, representation);
    3392             :         return;
    3393             :       }
    3394             : 
    3395             :       case IrOpcode::kFinishRegion:
    3396      407202 :         VisitInputs(node);
    3397             :         // Assume the output is tagged pointer.
    3398             :         return SetOutput(node, MachineRepresentation::kTaggedPointer);
    3399             : 
    3400             :       case IrOpcode::kReturn:
    3401     1674961 :         VisitReturn(node);
    3402             :         // Assume the output is tagged.
    3403             :         return SetOutput(node, MachineRepresentation::kTagged);
    3404             : 
    3405             :       case IrOpcode::kFindOrderedHashMapEntry: {
    3406         677 :         Type const key_type = TypeOf(node->InputAt(1));
    3407         677 :         if (key_type.Is(Type::Signed32OrMinusZero())) {
    3408             :           VisitBinop(node, UseInfo::AnyTagged(), UseInfo::TruncatingWord32(),
    3409          68 :                      MachineType::PointerRepresentation());
    3410          68 :           if (lower()) {
    3411          17 :             NodeProperties::ChangeOp(
    3412             :                 node,
    3413          17 :                 lowering->simplified()->FindOrderedHashMapEntryForInt32Key());
    3414             :           }
    3415             :         } else {
    3416             :           VisitBinop(node, UseInfo::AnyTagged(),
    3417             :                      MachineRepresentation::kTaggedSigned);
    3418             :         }
    3419             :         return;
    3420             :       }
    3421             : 
    3422             :       // Operators with all inputs tagged and no or tagged output have uniform
    3423             :       // handling.
    3424             :       case IrOpcode::kEnd:
    3425             :       case IrOpcode::kIfSuccess:
    3426             :       case IrOpcode::kIfException:
    3427             :       case IrOpcode::kIfTrue:
    3428             :       case IrOpcode::kIfFalse:
    3429             :       case IrOpcode::kIfValue:
    3430             :       case IrOpcode::kIfDefault:
    3431             :       case IrOpcode::kDeoptimize:
    3432             :       case IrOpcode::kEffectPhi:
    3433             :       case IrOpcode::kTerminate:
    3434             :       case IrOpcode::kCheckpoint:
    3435             :       case IrOpcode::kLoop:
    3436             :       case IrOpcode::kMerge:
    3437             :       case IrOpcode::kThrow:
    3438             :       case IrOpcode::kBeginRegion:
    3439             :       case IrOpcode::kProjection:
    3440             :       case IrOpcode::kOsrValue:
    3441             :       case IrOpcode::kArgumentsElementsState:
    3442             :       case IrOpcode::kArgumentsLengthState:
    3443             :       case IrOpcode::kUnreachable:
    3444             :       case IrOpcode::kRuntimeAbort:
    3445             : // All JavaScript operators except JSToNumber have uniform handling.
    3446             : #define OPCODE_CASE(name) case IrOpcode::k##name:
    3447             :         JS_SIMPLE_BINOP_LIST(OPCODE_CASE)
    3448             :         JS_OBJECT_OP_LIST(OPCODE_CASE)
    3449             :         JS_CONTEXT_OP_LIST(OPCODE_CASE)
    3450             :         JS_OTHER_OP_LIST(OPCODE_CASE)
    3451             : #undef OPCODE_CASE
    3452             :       case IrOpcode::kJSBitwiseNot:
    3453             :       case IrOpcode::kJSDecrement:
    3454             :       case IrOpcode::kJSIncrement:
    3455             :       case IrOpcode::kJSNegate:
    3456             :       case IrOpcode::kJSToLength:
    3457             :       case IrOpcode::kJSToName:
    3458             :       case IrOpcode::kJSToObject:
    3459             :       case IrOpcode::kJSToString:
    3460             :       case IrOpcode::kJSParseInt:
    3461    29074539 :         VisitInputs(node);
    3462             :         // Assume the output is tagged.
    3463             :         return SetOutput(node, MachineRepresentation::kTagged);
    3464             :       case IrOpcode::kDeadValue:
    3465        1612 :         ProcessInput(node, 0, UseInfo::Any());
    3466             :         return SetOutput(node, MachineRepresentation::kNone);
    3467             :       default:
    3468           0 :         FATAL(
    3469             :             "Representation inference: unsupported opcode %i (%s), node #%i\n.",
    3470           0 :             node->opcode(), node->op()->mnemonic(), node->id());
    3471             :         break;
    3472             :     }
    3473             :     UNREACHABLE();
    3474             :   }
    3475             : 
    3476     1261398 :   void DeferReplacement(Node* node, Node* replacement) {
    3477     1261398 :     TRACE("defer replacement #%d:%s with #%d:%s\n", node->id(),
    3478             :           node->op()->mnemonic(), replacement->id(),
    3479             :           replacement->op()->mnemonic());
    3480             : 
    3481             :     // Disconnect the node from effect and control chains, if necessary.
    3482     2522798 :     if (node->op()->EffectInputCount() > 0) {
    3483             :       DCHECK_LT(0, node->op()->ControlInputCount());
    3484             :       // Disconnect the node from effect and control chains.
    3485      106151 :       Node* control = NodeProperties::GetControlInput(node);
    3486      106151 :       Node* effect = NodeProperties::GetEffectInput(node);
    3487      106151 :       ReplaceEffectControlUses(node, effect, control);
    3488             :     }
    3489             : 
    3490     1261399 :     replacements_.push_back(node);
    3491     1261397 :     replacements_.push_back(replacement);
    3492             : 
    3493     1261398 :     node->NullAllInputs();  // Node is now dead.
    3494     1261397 :   }
    3495             : 
    3496       34274 :   void Kill(Node* node) {
    3497       34274 :     TRACE("killing #%d:%s\n", node->id(), node->op()->mnemonic());
    3498             : 
    3499       34274 :     if (node->op()->EffectInputCount() == 1) {
    3500             :       DCHECK_LT(0, node->op()->ControlInputCount());
    3501             :       // Disconnect the node from effect and control chains.
    3502       34260 :       Node* control = NodeProperties::GetControlInput(node);
    3503       34260 :       Node* effect = NodeProperties::GetEffectInput(node);
    3504       34260 :       ReplaceEffectControlUses(node, effect, control);
    3505             :     } else {
    3506             :       DCHECK_EQ(0, node->op()->EffectInputCount());
    3507             :       DCHECK_EQ(0, node->op()->ControlOutputCount());
    3508             :       DCHECK_EQ(0, node->op()->EffectOutputCount());
    3509             :     }
    3510             : 
    3511       34274 :     node->ReplaceUses(jsgraph_->Dead());
    3512             : 
    3513       34274 :     node->NullAllInputs();  // The {node} is now dead.
    3514       34274 :   }
    3515             : 
    3516    51629045 :   void PrintOutputInfo(NodeInfo* info) {
    3517    51629045 :     if (FLAG_trace_representation) {
    3518           0 :       StdoutStream{} << info->representation();
    3519             :     }
    3520    51629045 :   }
    3521             : 
    3522             :   void PrintRepresentation(MachineRepresentation rep) {
    3523             :     if (FLAG_trace_representation) {
    3524             :       StdoutStream{} << rep;
    3525             :     }
    3526             :   }
    3527             : 
    3528   102481926 :   void PrintTruncation(Truncation truncation) {
    3529   102481926 :     if (FLAG_trace_representation) {
    3530           0 :       StdoutStream{} << truncation.description() << std::endl;
    3531             :     }
    3532   102481926 :   }
    3533             : 
    3534    16073392 :   void PrintUseInfo(UseInfo info) {
    3535    16073392 :     if (FLAG_trace_representation) {
    3536           0 :       StdoutStream{} << info.representation() << ":"
    3537           0 :                      << info.truncation().description();
    3538             :     }
    3539    16073392 :   }
    3540             : 
    3541             :  private:
    3542             :   JSGraph* jsgraph_;
    3543             :   Zone* zone_;                      // Temporary zone.
    3544             :   size_t const count_;              // number of nodes in the graph
    3545             :   ZoneVector<NodeInfo> info_;       // node id -> usage information
    3546             : #ifdef DEBUG
    3547             :   ZoneVector<InputUseInfos> node_input_use_infos_;  // Debug information about
    3548             :                                                     // requirements on inputs.
    3549             : #endif                                              // DEBUG
    3550             :   NodeVector nodes_;                // collected nodes
    3551             :   NodeVector replacements_;         // replacements to be done after lowering
    3552             :   Phase phase_;                     // current phase of algorithm
    3553             :   RepresentationChanger* changer_;  // for inserting representation changes
    3554             :   ZoneQueue<Node*> queue_;          // queue for traversing the graph
    3555             : 
    3556             :   struct NodeState {
    3557             :     Node* node;
    3558             :     int input_index;
    3559             :   };
    3560             :   ZoneStack<NodeState> typing_stack_;  // stack for graph typing.
    3561             :   // TODO(danno): RepresentationSelector shouldn't know anything about the
    3562             :   // source positions table, but must for now since there currently is no other
    3563             :   // way to pass down source position information to nodes created during
    3564             :   // lowering. Once this phase becomes a vanilla reducer, it should get source
    3565             :   // position information via the SourcePositionWrapper like all other reducers.
    3566             :   SourcePositionTable* source_positions_;
    3567             :   NodeOriginTable* node_origins_;
    3568             :   TypeCache const* type_cache_;
    3569             :   OperationTyper op_typer_;  // helper for the feedback typer
    3570             : 
    3571             :   NodeInfo* GetInfo(Node* node) {
    3572             :     DCHECK(node->id() < count_);
    3573   704956204 :     return &info_[node->id()];
    3574             :   }
    3575             :   Zone* zone() { return zone_; }
    3576             :   Zone* graph_zone() { return jsgraph_->zone(); }
    3577             : };
    3578             : 
    3579      463669 : SimplifiedLowering::SimplifiedLowering(JSGraph* jsgraph, JSHeapBroker* broker,
    3580             :                                        Zone* zone,
    3581             :                                        SourcePositionTable* source_positions,
    3582             :                                        NodeOriginTable* node_origins,
    3583             :                                        PoisoningMitigationLevel poisoning_level)
    3584             :     : jsgraph_(jsgraph),
    3585             :       broker_(broker),
    3586             :       zone_(zone),
    3587      463669 :       type_cache_(TypeCache::Get()),
    3588             :       source_positions_(source_positions),
    3589             :       node_origins_(node_origins),
    3590     1391005 :       poisoning_level_(poisoning_level) {}
    3591             : 
    3592      463668 : void SimplifiedLowering::LowerAllNodes() {
    3593      463668 :   RepresentationChanger changer(jsgraph(), jsgraph()->isolate());
    3594      463669 :   RepresentationSelector selector(jsgraph(), broker_, zone_, &changer,
    3595      927338 :                                   source_positions_, node_origins_);
    3596      463668 :   selector.Run(this);
    3597      463671 : }
    3598             : 
    3599        1413 : void SimplifiedLowering::DoJSToNumberOrNumericTruncatesToFloat64(
    3600             :     Node* node, RepresentationSelector* selector) {
    3601             :   DCHECK(node->opcode() == IrOpcode::kJSToNumber ||
    3602             :          node->opcode() == IrOpcode::kJSToNumberConvertBigInt ||
    3603             :          node->opcode() == IrOpcode::kJSToNumeric);
    3604             :   Node* value = node->InputAt(0);
    3605             :   Node* context = node->InputAt(1);
    3606             :   Node* frame_state = node->InputAt(2);
    3607             :   Node* effect = node->InputAt(3);
    3608             :   Node* control = node->InputAt(4);
    3609             : 
    3610        1413 :   Node* check0 = graph()->NewNode(simplified()->ObjectIsSmi(), value);
    3611             :   Node* branch0 =
    3612        1413 :       graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
    3613             : 
    3614        1413 :   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
    3615             :   Node* etrue0 = effect;
    3616             :   Node* vtrue0;
    3617             :   {
    3618        1413 :     vtrue0 = graph()->NewNode(simplified()->ChangeTaggedSignedToInt32(), value);
    3619        1413 :     vtrue0 = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue0);
    3620             :   }
    3621             : 
    3622        1413 :   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
    3623             :   Node* efalse0 = effect;
    3624             :   Node* vfalse0;
    3625             :   {
    3626             :     Operator const* op =
    3627             :         node->opcode() == IrOpcode::kJSToNumber
    3628             :             ? (node->opcode() == IrOpcode::kJSToNumberConvertBigInt
    3629             :                    ? ToNumberConvertBigIntOperator()
    3630             :                    : ToNumberOperator())
    3631        1413 :             : ToNumericOperator();
    3632             :     Node* code = node->opcode() == IrOpcode::kJSToNumber
    3633             :                      ? ToNumberCode()
    3634             :                      : (node->opcode() == IrOpcode::kJSToNumberConvertBigInt
    3635             :                             ? ToNumberConvertBigIntCode()
    3636        1413 :                             : ToNumericCode());
    3637             :     vfalse0 = efalse0 = if_false0 = graph()->NewNode(
    3638             :         op, code, value, context, frame_state, efalse0, if_false0);
    3639             : 
    3640             :     // Update potential {IfException} uses of {node} to point to the above
    3641             :     // stub call node instead.
    3642        1413 :     Node* on_exception = nullptr;
    3643        1413 :     if (NodeProperties::IsExceptionalCall(node, &on_exception)) {
    3644           0 :       NodeProperties::ReplaceControlInput(on_exception, vfalse0);
    3645           0 :       NodeProperties::ReplaceEffectInput(on_exception, efalse0);
    3646           0 :       if_false0 = graph()->NewNode(common()->IfSuccess(), vfalse0);
    3647             :     }
    3648             : 
    3649        1413 :     Node* check1 = graph()->NewNode(simplified()->ObjectIsSmi(), vfalse0);
    3650        1413 :     Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0);
    3651             : 
    3652        1413 :     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
    3653             :     Node* etrue1 = efalse0;
    3654             :     Node* vtrue1;
    3655             :     {
    3656             :       vtrue1 =
    3657        1413 :           graph()->NewNode(simplified()->ChangeTaggedSignedToInt32(), vfalse0);
    3658        1413 :       vtrue1 = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue1);
    3659             :     }
    3660             : 
    3661        1413 :     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
    3662             :     Node* efalse1 = efalse0;
    3663             :     Node* vfalse1;
    3664             :     {
    3665        1413 :       vfalse1 = efalse1 = graph()->NewNode(
    3666        2826 :           simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), efalse0,
    3667             :           efalse1, if_false1);
    3668             :     }
    3669             : 
    3670        1413 :     if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
    3671             :     efalse0 =
    3672        1413 :         graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_false0);
    3673             :     vfalse0 =
    3674        1413 :         graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
    3675             :                          vtrue1, vfalse1, if_false0);
    3676             :   }
    3677             : 
    3678        1413 :   control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
    3679        1413 :   effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
    3680        1413 :   value = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
    3681             :                            vtrue0, vfalse0, control);
    3682             : 
    3683             :   // Replace effect and control uses appropriately.
    3684        9893 :   for (Edge edge : node->use_edges()) {
    3685        4240 :     if (NodeProperties::IsControlEdge(edge)) {
    3686        1413 :       if (edge.from()->opcode() == IrOpcode::kIfSuccess) {
    3687           0 :         edge.from()->ReplaceUses(control);
    3688           0 :         edge.from()->Kill();
    3689             :       } else {
    3690             :         DCHECK_NE(IrOpcode::kIfException, edge.from()->opcode());
    3691        1413 :         edge.UpdateTo(control);
    3692             :       }
    3693        2827 :     } else if (NodeProperties::IsEffectEdge(edge)) {
    3694        1414 :       edge.UpdateTo(effect);
    3695             :     }
    3696             :   }
    3697             : 
    3698        1413 :   selector->DeferReplacement(node, value);
    3699        1413 : }
    3700             : 
    3701          75 : void SimplifiedLowering::DoJSToNumberOrNumericTruncatesToWord32(
    3702             :     Node* node, RepresentationSelector* selector) {
    3703             :   DCHECK(node->opcode() == IrOpcode::kJSToNumber ||
    3704             :          node->opcode() == IrOpcode::kJSToNumberConvertBigInt ||
    3705             :          node->opcode() == IrOpcode::kJSToNumeric);
    3706             :   Node* value = node->InputAt(0);
    3707             :   Node* context = node->InputAt(1);
    3708             :   Node* frame_state = node->InputAt(2);
    3709             :   Node* effect = node->InputAt(3);
    3710             :   Node* control = node->InputAt(4);
    3711             : 
    3712          75 :   Node* check0 = graph()->NewNode(simplified()->ObjectIsSmi(), value);
    3713             :   Node* branch0 =
    3714          75 :       graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
    3715             : 
    3716          75 :   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
    3717             :   Node* etrue0 = effect;
    3718             :   Node* vtrue0 =
    3719          75 :       graph()->NewNode(simplified()->ChangeTaggedSignedToInt32(), value);
    3720             : 
    3721          75 :   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
    3722             :   Node* efalse0 = effect;
    3723             :   Node* vfalse0;
    3724             :   {
    3725             :     Operator const* op =
    3726             :         node->opcode() == IrOpcode::kJSToNumber
    3727             :             ? (node->opcode() == IrOpcode::kJSToNumberConvertBigInt
    3728             :                    ? ToNumberConvertBigIntOperator()
    3729             :                    : ToNumberOperator())
    3730          75 :             : ToNumericOperator();
    3731             :     Node* code = node->opcode() == IrOpcode::kJSToNumber
    3732             :                      ? ToNumberCode()
    3733             :                      : (node->opcode() == IrOpcode::kJSToNumberConvertBigInt
    3734             :                             ? ToNumberConvertBigIntCode()
    3735          75 :                             : ToNumericCode());
    3736             :     vfalse0 = efalse0 = if_false0 = graph()->NewNode(
    3737             :         op, code, value, context, frame_state, efalse0, if_false0);
    3738             : 
    3739             :     // Update potential {IfException} uses of {node} to point to the above
    3740             :     // stub call node instead.
    3741          75 :     Node* on_exception = nullptr;
    3742          75 :     if (NodeProperties::IsExceptionalCall(node, &on_exception)) {
    3743           8 :       NodeProperties::ReplaceControlInput(on_exception, vfalse0);
    3744           8 :       NodeProperties::ReplaceEffectInput(on_exception, efalse0);
    3745           8 :       if_false0 = graph()->NewNode(common()->IfSuccess(), vfalse0);
    3746             :     }
    3747             : 
    3748          75 :     Node* check1 = graph()->NewNode(simplified()->ObjectIsSmi(), vfalse0);
    3749          75 :     Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0);
    3750             : 
    3751          75 :     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
    3752             :     Node* etrue1 = efalse0;
    3753             :     Node* vtrue1 =
    3754          75 :         graph()->NewNode(simplified()->ChangeTaggedSignedToInt32(), vfalse0);
    3755             : 
    3756          75 :     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
    3757             :     Node* efalse1 = efalse0;
    3758             :     Node* vfalse1;
    3759             :     {
    3760          75 :       vfalse1 = efalse1 = graph()->NewNode(
    3761         150 :           simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), efalse0,
    3762             :           efalse1, if_false1);
    3763          75 :       vfalse1 = graph()->NewNode(machine()->TruncateFloat64ToWord32(), vfalse1);
    3764             :     }
    3765             : 
    3766          75 :     if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
    3767             :     efalse0 =
    3768          75 :         graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_false0);
    3769          75 :     vfalse0 = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
    3770             :                                vtrue1, vfalse1, if_false0);
    3771             :   }
    3772             : 
    3773          75 :   control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
    3774          75 :   effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
    3775          75 :   value = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
    3776             :                            vtrue0, vfalse0, control);
    3777             : 
    3778             :   // Replace effect and control uses appropriately.
    3779         459 :   for (Edge edge : node->use_edges()) {
    3780         192 :     if (NodeProperties::IsControlEdge(edge)) {
    3781         114 :       if (edge.from()->opcode() == IrOpcode::kIfSuccess) {
    3782           8 :         edge.from()->ReplaceUses(control);
    3783           8 :         edge.from()->Kill();
    3784             :       } else {
    3785             :         DCHECK_NE(IrOpcode::kIfException, edge.from()->opcode());
    3786         106 :         edge.UpdateTo(control);
    3787             :       }
    3788          78 :     } else if (NodeProperties::IsEffectEdge(edge)) {
    3789          75 :       edge.UpdateTo(effect);
    3790             :     }
    3791             :   }
    3792             : 
    3793          75 :   selector->DeferReplacement(node, value);
    3794          75 : }
    3795             : 
    3796        1554 : Node* SimplifiedLowering::Float64Round(Node* const node) {
    3797        1554 :   Node* const one = jsgraph()->Float64Constant(1.0);
    3798        1554 :   Node* const one_half = jsgraph()->Float64Constant(0.5);
    3799             :   Node* const input = node->InputAt(0);
    3800             : 
    3801             :   // Round up towards Infinity, and adjust if the difference exceeds 0.5.
    3802        3108 :   Node* result = graph()->NewNode(machine()->Float64RoundUp().placeholder(),
    3803             :                                   node->InputAt(0));
    3804        6216 :   return graph()->NewNode(
    3805             :       common()->Select(MachineRepresentation::kFloat64),
    3806             :       graph()->NewNode(
    3807             :           machine()->Float64LessThanOrEqual(),
    3808             :           graph()->NewNode(machine()->Float64Sub(), result, one_half), input),
    3809        1554 :       result, graph()->NewNode(machine()->Float64Sub(), result, one));
    3810             : }
    3811             : 
    3812          30 : Node* SimplifiedLowering::Float64Sign(Node* const node) {
    3813          30 :   Node* const minus_one = jsgraph()->Float64Constant(-1.0);
    3814          30 :   Node* const zero = jsgraph()->Float64Constant(0.0);
    3815          30 :   Node* const one = jsgraph()->Float64Constant(1.0);
    3816             : 
    3817             :   Node* const input = node->InputAt(0);
    3818             : 
    3819         120 :   return graph()->NewNode(
    3820             :       common()->Select(MachineRepresentation::kFloat64),
    3821             :       graph()->NewNode(machine()->Float64LessThan(), input, zero), minus_one,
    3822             :       graph()->NewNode(
    3823             :           common()->Select(MachineRepresentation::kFloat64),
    3824             :           graph()->NewNode(machine()->Float64LessThan(), zero, input), one,
    3825          30 :           input));
    3826             : }
    3827             : 
    3828          83 : Node* SimplifiedLowering::Int32Abs(Node* const node) {
    3829             :   Node* const input = node->InputAt(0);
    3830             : 
    3831             :   // Generate case for absolute integer value.
    3832             :   //
    3833             :   //    let sign = input >> 31 in
    3834             :   //    (input ^ sign) - sign
    3835             : 
    3836          83 :   Node* sign = graph()->NewNode(machine()->Word32Sar(), input,
    3837             :                                 jsgraph()->Int32Constant(31));
    3838         166 :   return graph()->NewNode(machine()->Int32Sub(),
    3839             :                           graph()->NewNode(machine()->Word32Xor(), input, sign),
    3840          83 :                           sign);
    3841             : }
    3842             : 
    3843        2998 : Node* SimplifiedLowering::Int32Div(Node* const node) {
    3844        2998 :   Int32BinopMatcher m(node);
    3845        2998 :   Node* const zero = jsgraph()->Int32Constant(0);
    3846        2998 :   Node* const minus_one = jsgraph()->Int32Constant(-1);
    3847             :   Node* const lhs = m.left().node();
    3848             :   Node* const rhs = m.right().node();
    3849             : 
    3850        2998 :   if (m.right().Is(-1)) {
    3851          30 :     return graph()->NewNode(machine()->Int32Sub(), zero, lhs);
    3852        2983 :   } else if (m.right().Is(0)) {
    3853             :     return rhs;
    3854        2983 :   } else if (machine()->Int32DivIsSafe() || m.right().HasValue()) {
    3855        4694 :     return graph()->NewNode(machine()->Int32Div(), lhs, rhs, graph()->start());
    3856             :   }
    3857             : 
    3858             :   // General case for signed integer division.
    3859             :   //
    3860             :   //    if 0 < rhs then
    3861             :   //      lhs / rhs
    3862             :   //    else
    3863             :   //      if rhs < -1 then
    3864             :   //        lhs / rhs
    3865             :   //      else if rhs == 0 then
    3866             :   //        0
    3867             :   //      else
    3868             :   //        0 - lhs
    3869             :   //
    3870             :   // Note: We do not use the Diamond helper class here, because it really hurts
    3871             :   // readability with nested diamonds.
    3872         636 :   const Operator* const merge_op = common()->Merge(2);
    3873             :   const Operator* const phi_op =
    3874         636 :       common()->Phi(MachineRepresentation::kWord32, 2);
    3875             : 
    3876         636 :   Node* check0 = graph()->NewNode(machine()->Int32LessThan(), zero, rhs);
    3877         636 :   Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kTrue), check0,
    3878             :                                    graph()->start());
    3879             : 
    3880         636 :   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
    3881         636 :   Node* true0 = graph()->NewNode(machine()->Int32Div(), lhs, rhs, if_true0);
    3882             : 
    3883         636 :   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
    3884             :   Node* false0;
    3885             :   {
    3886         636 :     Node* check1 = graph()->NewNode(machine()->Int32LessThan(), rhs, minus_one);
    3887         636 :     Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0);
    3888             : 
    3889         636 :     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
    3890         636 :     Node* true1 = graph()->NewNode(machine()->Int32Div(), lhs, rhs, if_true1);
    3891             : 
    3892         636 :     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
    3893             :     Node* false1;
    3894             :     {
    3895         636 :       Node* check2 = graph()->NewNode(machine()->Word32Equal(), rhs, zero);
    3896         636 :       Node* branch2 = graph()->NewNode(common()->Branch(), check2, if_false1);
    3897             : 
    3898         636 :       Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
    3899             :       Node* true2 = zero;
    3900             : 
    3901         636 :       Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
    3902         636 :       Node* false2 = graph()->NewNode(machine()->Int32Sub(), zero, lhs);
    3903             : 
    3904             :       if_false1 = graph()->NewNode(merge_op, if_true2, if_false2);
    3905             :       false1 = graph()->NewNode(phi_op, true2, false2, if_false1);
    3906             :     }
    3907             : 
    3908             :     if_false0 = graph()->NewNode(merge_op, if_true1, if_false1);
    3909             :     false0 = graph()->NewNode(phi_op, true1, false1, if_false0);
    3910             :   }
    3911             : 
    3912             :   Node* merge0 = graph()->NewNode(merge_op, if_true0, if_false0);
    3913         636 :   return graph()->NewNode(phi_op, true0, false0, merge0);
    3914             : }
    3915             : 
    3916        2413 : Node* SimplifiedLowering::Int32Mod(Node* const node) {
    3917        2413 :   Int32BinopMatcher m(node);
    3918        2413 :   Node* const zero = jsgraph()->Int32Constant(0);
    3919        2413 :   Node* const minus_one = jsgraph()->Int32Constant(-1);
    3920             :   Node* const lhs = m.left().node();
    3921             :   Node* const rhs = m.right().node();
    3922             : 
    3923        4818 :   if (m.right().Is(-1) || m.right().Is(0)) {
    3924             :     return zero;
    3925        2405 :   } else if (m.right().HasValue()) {
    3926        4788 :     return graph()->NewNode(machine()->Int32Mod(), lhs, rhs, graph()->start());
    3927             :   }
    3928             : 
    3929             :   // General case for signed integer modulus, with optimization for (unknown)
    3930             :   // power of 2 right hand side.
    3931             :   //
    3932             :   //   if 0 < rhs then
    3933             :   //     msk = rhs - 1
    3934             :   //     if rhs & msk != 0 then
    3935             :   //       lhs % rhs
    3936             :   //     else
    3937             :   //       if lhs < 0 then
    3938             :   //         -(-lhs & msk)
    3939             :   //       else
    3940             :   //         lhs & msk
    3941             :   //   else
    3942             :   //     if rhs < -1 then
    3943             :   //       lhs % rhs
    3944             :   //     else
    3945             :   //       zero
    3946             :   //
    3947             :   // Note: We do not use the Diamond helper class here, because it really hurts
    3948             :   // readability with nested diamonds.
    3949          11 :   const Operator* const merge_op = common()->Merge(2);
    3950             :   const Operator* const phi_op =
    3951          11 :       common()->Phi(MachineRepresentation::kWord32, 2);
    3952             : 
    3953          11 :   Node* check0 = graph()->NewNode(machine()->Int32LessThan(), zero, rhs);
    3954          11 :   Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kTrue), check0,
    3955             :                                    graph()->start());
    3956             : 
    3957          11 :   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
    3958             :   Node* true0;
    3959             :   {
    3960          11 :     Node* msk = graph()->NewNode(machine()->Int32Add(), rhs, minus_one);
    3961             : 
    3962          11 :     Node* check1 = graph()->NewNode(machine()->Word32And(), rhs, msk);
    3963          11 :     Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0);
    3964             : 
    3965          11 :     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
    3966          11 :     Node* true1 = graph()->NewNode(machine()->Int32Mod(), lhs, rhs, if_true1);
    3967             : 
    3968          11 :     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
    3969             :     Node* false1;
    3970             :     {
    3971          11 :       Node* check2 = graph()->NewNode(machine()->Int32LessThan(), lhs, zero);
    3972          11 :       Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
    3973             :                                        check2, if_false1);
    3974             : 
    3975          11 :       Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
    3976          33 :       Node* true2 = graph()->NewNode(
    3977             :           machine()->Int32Sub(), zero,
    3978             :           graph()->NewNode(machine()->Word32And(),
    3979             :                            graph()->NewNode(machine()->Int32Sub(), zero, lhs),
    3980             :                            msk));
    3981             : 
    3982          11 :       Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
    3983          11 :       Node* false2 = graph()->NewNode(machine()->Word32And(), lhs, msk);
    3984             : 
    3985             :       if_false1 = graph()->NewNode(merge_op, if_true2, if_false2);
    3986             :       false1 = graph()->NewNode(phi_op, true2, false2, if_false1);
    3987             :     }
    3988             : 
    3989             :     if_true0 = graph()->NewNode(merge_op, if_true1, if_false1);
    3990             :     true0 = graph()->NewNode(phi_op, true1, false1, if_true0);
    3991             :   }
    3992             : 
    3993          11 :   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
    3994             :   Node* false0;
    3995             :   {
    3996          11 :     Node* check1 = graph()->NewNode(machine()->Int32LessThan(), rhs, minus_one);
    3997          11 :     Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kTrue),
    3998             :                                      check1, if_false0);
    3999             : 
    4000          11 :     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
    4001          11 :     Node* true1 = graph()->NewNode(machine()->Int32Mod(), lhs, rhs, if_true1);
    4002             : 
    4003          11 :     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
    4004             :     Node* false1 = zero;
    4005             : 
    4006             :     if_false0 = graph()->NewNode(merge_op, if_true1, if_false1);
    4007             :     false0 = graph()->NewNode(phi_op, true1, false1, if_false0);
    4008             :   }
    4009             : 
    4010             :   Node* merge0 = graph()->NewNode(merge_op, if_true0, if_false0);
    4011          11 :   return graph()->NewNode(phi_op, true0, false0, merge0);
    4012             : }
    4013             : 
    4014           7 : Node* SimplifiedLowering::Int32Sign(Node* const node) {
    4015           7 :   Node* const minus_one = jsgraph()->Int32Constant(-1);
    4016           7 :   Node* const zero = jsgraph()->Int32Constant(0);
    4017           7 :   Node* const one = jsgraph()->Int32Constant(1);
    4018             : 
    4019             :   Node* const input = node->InputAt(0);
    4020             : 
    4021          28 :   return graph()->NewNode(
    4022             :       common()->Select(MachineRepresentation::kWord32),
    4023             :       graph()->NewNode(machine()->Int32LessThan(), input, zero), minus_one,
    4024             :       graph()->NewNode(
    4025             :           common()->Select(MachineRepresentation::kWord32),
    4026             :           graph()->NewNode(machine()->Int32LessThan(), zero, input), one,
    4027           7 :           zero));
    4028             : }
    4029             : 
    4030         233 : Node* SimplifiedLowering::Uint32Div(Node* const node) {
    4031         233 :   Uint32BinopMatcher m(node);
    4032         233 :   Node* const zero = jsgraph()->Uint32Constant(0);
    4033             :   Node* const lhs = m.left().node();
    4034             :   Node* const rhs = m.right().node();
    4035             : 
    4036         233 :   if (m.right().Is(0)) {
    4037             :     return zero;
    4038         226 :   } else if (machine()->Uint32DivIsSafe() || m.right().HasValue()) {
    4039         384 :     return graph()->NewNode(machine()->Uint32Div(), lhs, rhs, graph()->start());
    4040             :   }
    4041             : 
    4042          34 :   Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, zero);
    4043          34 :   Diamond d(graph(), common(), check, BranchHint::kFalse);
    4044          34 :   Node* div = graph()->NewNode(machine()->Uint32Div(), lhs, rhs, d.if_false);
    4045          34 :   return d.Phi(MachineRepresentation::kWord32, zero, div);
    4046             : }
    4047             : 
    4048         216 : Node* SimplifiedLowering::Uint32Mod(Node* const node) {
    4049         216 :   Uint32BinopMatcher m(node);
    4050         216 :   Node* const minus_one = jsgraph()->Int32Constant(-1);
    4051         216 :   Node* const zero = jsgraph()->Uint32Constant(0);
    4052             :   Node* const lhs = m.left().node();
    4053             :   Node* const rhs = m.right().node();
    4054             : 
    4055         216 :   if (m.right().Is(0)) {
    4056             :     return zero;
    4057         216 :   } else if (m.right().HasValue()) {
    4058         386 :     return graph()->NewNode(machine()->Uint32Mod(), lhs, rhs, graph()->start());
    4059             :   }
    4060             : 
    4061             :   // General case for unsigned integer modulus, with optimization for (unknown)
    4062             :   // power of 2 right hand side.
    4063             :   //
    4064             :   //   if rhs == 0 then
    4065             :   //     zero
    4066             :   //   else
    4067             :   //     msk = rhs - 1
    4068             :   //     if rhs & msk != 0 then
    4069             :   //       lhs % rhs
    4070             :   //     else
    4071             :   //       lhs & msk
    4072             :   //
    4073             :   // Note: We do not use the Diamond helper class here, because it really hurts
    4074             :   // readability with nested diamonds.
    4075          23 :   const Operator* const merge_op = common()->Merge(2);
    4076             :   const Operator* const phi_op =
    4077          23 :       common()->Phi(MachineRepresentation::kWord32, 2);
    4078             : 
    4079          23 :   Node* check0 = graph()->NewNode(machine()->Word32Equal(), rhs, zero);
    4080          23 :   Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kFalse), check0,
    4081             :                                    graph()->start());
    4082             : 
    4083          23 :   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
    4084             :   Node* true0 = zero;
    4085             : 
    4086          23 :   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
    4087             :   Node* false0;
    4088             :   {
    4089          23 :     Node* msk = graph()->NewNode(machine()->Int32Add(), rhs, minus_one);
    4090             : 
    4091          23 :     Node* check1 = graph()->NewNode(machine()->Word32And(), rhs, msk);
    4092          23 :     Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0);
    4093             : 
    4094          23 :     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
    4095          23 :     Node* true1 = graph()->NewNode(machine()->Uint32Mod(), lhs, rhs, if_true1);
    4096             : 
    4097          23 :     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
    4098          23 :     Node* false1 = graph()->NewNode(machine()->Word32And(), lhs, msk);
    4099             : 
    4100             :     if_false0 = graph()->NewNode(merge_op, if_true1, if_false1);
    4101             :     false0 = graph()->NewNode(phi_op, true1, false1, if_false0);
    4102             :   }
    4103             : 
    4104             :   Node* merge0 = graph()->NewNode(merge_op, if_true0, if_false0);
    4105          23 :   return graph()->NewNode(phi_op, true0, false0, merge0);
    4106             : }
    4107             : 
    4108        2402 : void SimplifiedLowering::DoMax(Node* node, Operator const* op,
    4109             :                                MachineRepresentation rep) {
    4110             :   Node* const lhs = node->InputAt(0);
    4111             :   Node* const rhs = node->InputAt(1);
    4112             : 
    4113        2402 :   node->ReplaceInput(0, graph()->NewNode(op, lhs, rhs));
    4114             :   DCHECK_EQ(rhs, node->InputAt(1));
    4115        2402 :   node->AppendInput(graph()->zone(), lhs);
    4116        2402 :   NodeProperties::ChangeOp(node, common()->Select(rep));
    4117        2402 : }
    4118             : 
    4119        3183 : void SimplifiedLowering::DoMin(Node* node, Operator const* op,
    4120             :                                MachineRepresentation rep) {
    4121             :   Node* const lhs = node->InputAt(0);
    4122             :   Node* const rhs = node->InputAt(1);
    4123             : 
    4124        3183 :   node->InsertInput(graph()->zone(), 0, graph()->NewNode(op, lhs, rhs));
    4125             :   DCHECK_EQ(lhs, node->InputAt(1));
    4126             :   DCHECK_EQ(rhs, node->InputAt(2));
    4127        3183 :   NodeProperties::ChangeOp(node, common()->Select(rep));
    4128        3183 : }
    4129             : 
    4130         151 : void SimplifiedLowering::DoIntegral32ToBit(Node* node) {
    4131             :   Node* const input = node->InputAt(0);
    4132         151 :   Node* const zero = jsgraph()->Int32Constant(0);
    4133         151 :   Operator const* const op = machine()->Word32Equal();
    4134             : 
    4135         151 :   node->ReplaceInput(0, graph()->NewNode(op, input, zero));
    4136         151 :   node->AppendInput(graph()->zone(), zero);
    4137         151 :   NodeProperties::ChangeOp(node, op);
    4138         151 : }
    4139             : 
    4140           0 : void SimplifiedLowering::DoOrderedNumberToBit(Node* node) {
    4141             :   Node* const input = node->InputAt(0);
    4142             : 
    4143           0 :   node->ReplaceInput(0, graph()->NewNode(machine()->Float64Equal(), input,
    4144           0 :                                          jsgraph()->Float64Constant(0.0)));
    4145           0 :   node->AppendInput(graph()->zone(), jsgraph()->Int32Constant(0));
    4146           0 :   NodeProperties::ChangeOp(node, machine()->Word32Equal());
    4147           0 : }
    4148             : 
    4149          32 : void SimplifiedLowering::DoNumberToBit(Node* node) {
    4150             :   Node* const input = node->InputAt(0);
    4151             : 
    4152          32 :   node->ReplaceInput(0, jsgraph()->Float64Constant(0.0));
    4153          32 :   node->AppendInput(graph()->zone(),
    4154          32 :                     graph()->NewNode(machine()->Float64Abs(), input));
    4155          32 :   NodeProperties::ChangeOp(node, machine()->Float64LessThan());
    4156          32 : }
    4157             : 
    4158          21 : void SimplifiedLowering::DoIntegerToUint8Clamped(Node* node) {
    4159             :   Node* const input = node->InputAt(0);
    4160          21 :   Node* const min = jsgraph()->Float64Constant(0.0);
    4161          21 :   Node* const max = jsgraph()->Float64Constant(255.0);
    4162             : 
    4163          21 :   node->ReplaceInput(
    4164          21 :       0, graph()->NewNode(machine()->Float64LessThan(), min, input));
    4165          42 :   node->AppendInput(
    4166             :       graph()->zone(),
    4167             :       graph()->NewNode(
    4168             :           common()->Select(MachineRepresentation::kFloat64),
    4169             :           graph()->NewNode(machine()->Float64LessThan(), input, max), input,
    4170          21 :           max));
    4171          21 :   node->AppendInput(graph()->zone(), min);
    4172          21 :   NodeProperties::ChangeOp(node,
    4173          21 :                            common()->Select(MachineRepresentation::kFloat64));
    4174          21 : }
    4175             : 
    4176         294 : void SimplifiedLowering::DoNumberToUint8Clamped(Node* node) {
    4177             :   Node* const input = node->InputAt(0);
    4178         294 :   Node* const min = jsgraph()->Float64Constant(0.0);
    4179         294 :   Node* const max = jsgraph()->Float64Constant(255.0);
    4180             : 
    4181        1176 :   node->ReplaceInput(
    4182             :       0, graph()->NewNode(
    4183             :              common()->Select(MachineRepresentation::kFloat64),
    4184             :              graph()->NewNode(machine()->Float64LessThan(), min, input),
    4185             :              graph()->NewNode(
    4186             :                  common()->Select(MachineRepresentation::kFloat64),
    4187             :                  graph()->NewNode(machine()->Float64LessThan(), input, max),
    4188             :                  input, max),
    4189         294 :              min));
    4190             :   NodeProperties::ChangeOp(node,
    4191         294 :                            machine()->Float64RoundTiesEven().placeholder());
    4192         294 : }
    4193             : 
    4194          64 : void SimplifiedLowering::DoSigned32ToUint8Clamped(Node* node) {
    4195             :   Node* const input = node->InputAt(0);
    4196          64 :   Node* const min = jsgraph()->Int32Constant(0);
    4197          64 :   Node* const max = jsgraph()->Int32Constant(255);
    4198             : 
    4199          64 :   node->ReplaceInput(
    4200          64 :       0, graph()->NewNode(machine()->Int32LessThanOrEqual(), input, max));
    4201         128 :   node->AppendInput(
    4202             :       graph()->zone(),
    4203             :       graph()->NewNode(common()->Select(MachineRepresentation::kWord32),
    4204             :                        graph()->NewNode(machine()->Int32LessThan(), input, min),
    4205          64 :                        min, input));
    4206          64 :   node->AppendInput(graph()->zone(), max);
    4207          64 :   NodeProperties::ChangeOp(node,
    4208          64 :                            common()->Select(MachineRepresentation::kWord32));
    4209          64 : }
    4210             : 
    4211          72 : void SimplifiedLowering::DoUnsigned32ToUint8Clamped(Node* node) {
    4212             :   Node* const input = node->InputAt(0);
    4213          72 :   Node* const max = jsgraph()->Uint32Constant(255u);
    4214             : 
    4215          72 :   node->ReplaceInput(
    4216          72 :       0, graph()->NewNode(machine()->Uint32LessThanOrEqual(), input, max));
    4217          72 :   node->AppendInput(graph()->zone(), input);
    4218          72 :   node->AppendInput(graph()->zone(), max);
    4219          72 :   NodeProperties::ChangeOp(node,
    4220          72 :                            common()->Select(MachineRepresentation::kWord32));
    4221          72 : }
    4222             : 
    4223        1424 : Node* SimplifiedLowering::ToNumberCode() {
    4224        1424 :   if (!to_number_code_.is_set()) {
    4225        1424 :     Callable callable = Builtins::CallableFor(isolate(), Builtins::kToNumber);
    4226        2848 :     to_number_code_.set(jsgraph()->HeapConstant(callable.code()));
    4227             :   }
    4228        1424 :   return to_number_code_.get();
    4229             : }
    4230             : 
    4231          64 : Node* SimplifiedLowering::ToNumberConvertBigIntCode() {
    4232          64 :   if (!to_number_convert_big_int_code_.is_set()) {
    4233             :     Callable callable =
    4234          64 :         Builtins::CallableFor(isolate(), Builtins::kToNumberConvertBigInt);
    4235         128 :     to_number_convert_big_int_code_.set(
    4236             :         jsgraph()->HeapConstant(callable.code()));
    4237             :   }
    4238          64 :   return to_number_convert_big_int_code_.get();
    4239             : }
    4240             : 
    4241           0 : Node* SimplifiedLowering::ToNumericCode() {
    4242           0 :   if (!to_numeric_code_.is_set()) {
    4243           0 :     Callable callable = Builtins::CallableFor(isolate(), Builtins::kToNumeric);
    4244           0 :     to_numeric_code_.set(jsgraph()->HeapConstant(callable.code()));
    4245             :   }
    4246           0 :   return to_numeric_code_.get();
    4247             : }
    4248             : 
    4249        1424 : Operator const* SimplifiedLowering::ToNumberOperator() {
    4250        1424 :   if (!to_number_operator_.is_set()) {
    4251        1424 :     Callable callable = Builtins::CallableFor(isolate(), Builtins::kToNumber);
    4252             :     CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState;
    4253        1424 :     auto call_descriptor = Linkage::GetStubCallDescriptor(
    4254        1424 :         graph()->zone(), callable.descriptor(),
    4255             :         callable.descriptor().GetStackParameterCount(), flags,
    4256        1424 :         Operator::kNoProperties);
    4257        1424 :     to_number_operator_.set(common()->Call(call_descriptor));
    4258             :   }
    4259        1424 :   return to_number_operator_.get();
    4260             : }
    4261             : 
    4262           0 : Operator const* SimplifiedLowering::ToNumberConvertBigIntOperator() {
    4263           0 :   if (!to_number_convert_big_int_operator_.is_set()) {
    4264             :     Callable callable =
    4265           0 :         Builtins::CallableFor(isolate(), Builtins::kToNumberConvertBigInt);
    4266             :     CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState;
    4267           0 :     auto call_descriptor = Linkage::GetStubCallDescriptor(
    4268           0 :         graph()->zone(), callable.descriptor(),
    4269             :         callable.descriptor().GetStackParameterCount(), flags,
    4270           0 :         Operator::kNoProperties);
    4271           0 :     to_number_convert_big_int_operator_.set(common()->Call(call_descriptor));
    4272             :   }
    4273           0 :   return to_number_convert_big_int_operator_.get();
    4274             : }
    4275             : 
    4276          64 : Operator const* SimplifiedLowering::ToNumericOperator() {
    4277          64 :   if (!to_numeric_operator_.is_set()) {
    4278          64 :     Callable callable = Builtins::CallableFor(isolate(), Builtins::kToNumeric);
    4279             :     CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState;
    4280          64 :     auto call_descriptor = Linkage::GetStubCallDescriptor(
    4281          64 :         graph()->zone(), callable.descriptor(),
    4282             :         callable.descriptor().GetStackParameterCount(), flags,
    4283          64 :         Operator::kNoProperties);
    4284          64 :     to_numeric_operator_.set(common()->Call(call_descriptor));
    4285             :   }
    4286          64 :   return to_numeric_operator_.get();
    4287             : }
    4288             : 
    4289             : #undef TRACE
    4290             : 
    4291             : }  // namespace compiler
    4292             : }  // namespace internal
    4293      122028 : }  // namespace v8

Generated by: LCOV version 1.10