LCOV - code coverage report
Current view: top level - src/compiler - simplified-lowering.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 1317 1402 93.9 %
Date: 2017-10-20 Functions: 81 83 97.6 %

          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-properties.h"
      19             : #include "src/compiler/operation-typer.h"
      20             : #include "src/compiler/operator-properties.h"
      21             : #include "src/compiler/representation-change.h"
      22             : #include "src/compiler/simplified-operator.h"
      23             : #include "src/compiler/type-cache.h"
      24             : #include "src/conversions-inl.h"
      25             : #include "src/objects.h"
      26             : 
      27             : namespace v8 {
      28             : namespace internal {
      29             : namespace compiler {
      30             : 
      31             : // Macro for outputting trace information from representation inference.
      32             : #define TRACE(...)                                      \
      33             :   do {                                                  \
      34             :     if (FLAG_trace_representation) PrintF(__VA_ARGS__); \
      35             :   } while (false)
      36             : 
      37             : // Representation selection and lowering of {Simplified} operators to machine
      38             : // operators are interwined. We use a fixpoint calculation to compute both the
      39             : // output representation and the best possible lowering for {Simplified} nodes.
      40             : // Representation change insertion ensures that all values are in the correct
      41             : // machine representation after this phase, as dictated by the machine
      42             : // operators themselves.
      43             : enum Phase {
      44             :   // 1.) PROPAGATE: Traverse the graph from the end, pushing usage information
      45             :   //     backwards from uses to definitions, around cycles in phis, according
      46             :   //     to local rules for each operator.
      47             :   //     During this phase, the usage information for a node determines the best
      48             :   //     possible lowering for each operator so far, and that in turn determines
      49             :   //     the output representation.
      50             :   //     Therefore, to be correct, this phase must iterate to a fixpoint before
      51             :   //     the next phase can begin.
      52             :   PROPAGATE,
      53             : 
      54             :   // 2.) RETYPE: Propagate types from type feedback forwards.
      55             :   RETYPE,
      56             : 
      57             :   // 3.) LOWER: perform lowering for all {Simplified} nodes by replacing some
      58             :   //     operators for some nodes, expanding some nodes to multiple nodes, or
      59             :   //     removing some (redundant) nodes.
      60             :   //     During this phase, use the {RepresentationChanger} to insert
      61             :   //     representation changes between uses that demand a particular
      62             :   //     representation and nodes that produce a different representation.
      63             :   LOWER
      64             : };
      65             : 
      66             : namespace {
      67             : 
      68       44558 : MachineRepresentation MachineRepresentationFromArrayType(
      69             :     ExternalArrayType array_type) {
      70       44558 :   switch (array_type) {
      71             :     case kExternalUint8Array:
      72             :     case kExternalUint8ClampedArray:
      73             :     case kExternalInt8Array:
      74             :       return MachineRepresentation::kWord8;
      75             :     case kExternalUint16Array:
      76             :     case kExternalInt16Array:
      77        7858 :       return MachineRepresentation::kWord16;
      78             :     case kExternalUint32Array:
      79             :     case kExternalInt32Array:
      80        9321 :       return MachineRepresentation::kWord32;
      81             :     case kExternalFloat32Array:
      82        8771 :       return MachineRepresentation::kFloat32;
      83             :     case kExternalFloat64Array:
      84        4195 :       return MachineRepresentation::kFloat64;
      85             :   }
      86           0 :   UNREACHABLE();
      87             : }
      88             : 
      89     1148239 : UseInfo CheckedUseInfoAsWord32FromHint(
      90             :     NumberOperationHint hint,
      91             :     IdentifyZeros identify_zeros = kDistinguishZeros) {
      92     1148239 :   switch (hint) {
      93             :     case NumberOperationHint::kSignedSmall:
      94             :     case NumberOperationHint::kSignedSmallInputs:
      95             :       return UseInfo::CheckedSignedSmallAsWord32(identify_zeros);
      96             :     case NumberOperationHint::kSigned32:
      97             :       return UseInfo::CheckedSigned32AsWord32(identify_zeros);
      98             :     case NumberOperationHint::kNumber:
      99             :       return UseInfo::CheckedNumberAsWord32();
     100             :     case NumberOperationHint::kNumberOrOddball:
     101             :       return UseInfo::CheckedNumberOrOddballAsWord32();
     102             :   }
     103           0 :   UNREACHABLE();
     104             : }
     105             : 
     106       57331 : UseInfo CheckedUseInfoAsFloat64FromHint(NumberOperationHint hint) {
     107       57331 :   switch (hint) {
     108             :     case NumberOperationHint::kSignedSmall:
     109             :     case NumberOperationHint::kSignedSmallInputs:
     110             :     case NumberOperationHint::kSigned32:
     111             :       // Not used currently.
     112           0 :       UNREACHABLE();
     113             :       break;
     114             :     case NumberOperationHint::kNumber:
     115             :       return UseInfo::CheckedNumberAsFloat64();
     116             :     case NumberOperationHint::kNumberOrOddball:
     117             :       return UseInfo::CheckedNumberOrOddballAsFloat64();
     118             :   }
     119           0 :   UNREACHABLE();
     120             : }
     121             : 
     122     9889969 : UseInfo TruncatingUseInfoFromRepresentation(MachineRepresentation rep) {
     123     9889969 :   switch (rep) {
     124             :     case MachineRepresentation::kTaggedSigned:
     125             :     case MachineRepresentation::kTaggedPointer:
     126             :     case MachineRepresentation::kTagged:
     127             :       return UseInfo::AnyTagged();
     128             :     case MachineRepresentation::kFloat64:
     129             :       return UseInfo::TruncatingFloat64();
     130             :     case MachineRepresentation::kFloat32:
     131             :       return UseInfo::Float32();
     132             :     case MachineRepresentation::kWord8:
     133             :     case MachineRepresentation::kWord16:
     134             :     case MachineRepresentation::kWord32:
     135             :       return UseInfo::TruncatingWord32();
     136             :     case MachineRepresentation::kWord64:
     137             :       return UseInfo::TruncatingWord64();
     138             :     case MachineRepresentation::kBit:
     139             :       return UseInfo::Bool();
     140             :     case MachineRepresentation::kSimd128:
     141             :     case MachineRepresentation::kNone:
     142             :       break;
     143             :   }
     144           0 :   UNREACHABLE();
     145             : }
     146             : 
     147     3408470 : UseInfo UseInfoForBasePointer(const FieldAccess& access) {
     148     6594635 :   return access.tag() != 0 ? UseInfo::AnyTagged() : UseInfo::PointerInt();
     149             : }
     150             : 
     151      130497 : UseInfo UseInfoForBasePointer(const ElementAccess& access) {
     152      200647 :   return access.tag() != 0 ? UseInfo::AnyTagged() : UseInfo::PointerInt();
     153             : }
     154             : 
     155      352461 : void ReplaceEffectControlUses(Node* node, Node* effect, Node* control) {
     156     2093040 :   for (Edge edge : node->use_edges()) {
     157      870284 :     if (NodeProperties::IsControlEdge(edge)) {
     158           0 :       edge.UpdateTo(control);
     159      870286 :     } else if (NodeProperties::IsEffectEdge(edge)) {
     160      439408 :       edge.UpdateTo(effect);
     161             :     } else {
     162             :       DCHECK(NodeProperties::IsValueEdge(edge) ||
     163             :              NodeProperties::IsContextEdge(edge));
     164             :     }
     165             :   }
     166      352472 : }
     167             : 
     168      801451 : void ChangeToPureOp(Node* node, const Operator* new_op) {
     169             :   DCHECK(new_op->HasProperty(Operator::kPure));
     170      717974 :   if (node->op()->EffectInputCount() > 0) {
     171             :     DCHECK_LT(0, node->op()->ControlInputCount());
     172             :     // Disconnect the node from effect and control chains.
     173      221233 :     Node* control = NodeProperties::GetControlInput(node);
     174      221231 :     Node* effect = NodeProperties::GetEffectInput(node);
     175      221225 :     ReplaceEffectControlUses(node, effect, control);
     176      221239 :     node->TrimInputCount(new_op->ValueInputCount());
     177             :   } else {
     178             :     DCHECK_EQ(0, node->op()->ControlInputCount());
     179             :   }
     180      358989 :   NodeProperties::ChangeOp(node, new_op);
     181      358983 : }
     182             : 
     183             : #ifdef DEBUG
     184             : // Helpers for monotonicity checking.
     185             : class InputUseInfos {
     186             :  public:
     187             :   explicit InputUseInfos(Zone* zone) : input_use_infos_(zone) {}
     188             : 
     189             :   void SetAndCheckInput(Node* node, int index, UseInfo use_info) {
     190             :     if (input_use_infos_.empty()) {
     191             :       input_use_infos_.resize(node->InputCount(), UseInfo::None());
     192             :     }
     193             :     // Check that the new use informatin is a super-type of the old
     194             :     // one.
     195             :     DCHECK(IsUseLessGeneral(input_use_infos_[index], use_info));
     196             :     input_use_infos_[index] = use_info;
     197             :   }
     198             : 
     199             :  private:
     200             :   ZoneVector<UseInfo> input_use_infos_;
     201             : 
     202             :   static bool IsUseLessGeneral(UseInfo use1, UseInfo use2) {
     203             :     return use1.truncation().IsLessGeneralThan(use2.truncation());
     204             :   }
     205             : };
     206             : 
     207             : #endif  // DEBUG
     208             : 
     209      342347 : bool CanOverflowSigned32(const Operator* op, Type* left, Type* right,
     210             :                          Zone* type_zone) {
     211             :   // We assume the inputs are checked Signed32 (or known statically
     212             :   // to be Signed32). Technically, theinputs could also be minus zero, but
     213             :   // that cannot cause overflow.
     214      171171 :   left = Type::Intersect(left, Type::Signed32(), type_zone);
     215      171170 :   right = Type::Intersect(right, Type::Signed32(), type_zone);
     216      342355 :   if (!left->IsInhabited() || !right->IsInhabited()) return false;
     217      171176 :   switch (op->opcode()) {
     218             :     case IrOpcode::kSpeculativeSafeIntegerAdd:
     219      132809 :       return (left->Max() + right->Max() > kMaxInt) ||
     220      132804 :              (left->Min() + right->Min() < kMinInt);
     221             : 
     222             :     case IrOpcode::kSpeculativeSafeIntegerSubtract:
     223       58416 :       return (left->Max() - right->Min() > kMaxInt) ||
     224       58416 :              (left->Min() - right->Max() < kMinInt);
     225             : 
     226             :     default:
     227           0 :       UNREACHABLE();
     228             :   }
     229             :   return true;
     230             : }
     231             : 
     232             : }  // namespace
     233             : 
     234             : class RepresentationSelector {
     235             :  public:
     236             :   // Information for each node tracked during the fixpoint.
     237      443355 :   class NodeInfo final {
     238             :    public:
     239             :     // Adds new use to the node. Returns true if something has changed
     240             :     // and the node has to be requeued.
     241    91597198 :     bool AddUse(UseInfo info) {
     242    91597198 :       Truncation old_truncation = truncation_;
     243    91597198 :       truncation_ = Truncation::Generalize(truncation_, info.truncation());
     244    91596678 :       return truncation_ != old_truncation;
     245             :     }
     246             : 
     247    34103974 :     void set_queued() { state_ = kQueued; }
     248    62653661 :     void set_visited() { state_ = kVisited; }
     249    28550176 :     void set_pushed() { state_ = kPushed; }
     250    43583434 :     void reset_state() { state_ = kUnvisited; }
     251             :     bool visited() const { return state_ == kVisited; }
     252             :     bool queued() const { return state_ == kQueued; }
     253             :     bool unvisited() const { return state_ == kUnvisited; }
     254             :     Truncation truncation() const { return truncation_; }
     255    32367015 :     void set_output(MachineRepresentation output) { representation_ = output; }
     256             : 
     257             :     MachineRepresentation representation() const { return representation_; }
     258             : 
     259             :     // Helpers for feedback typing.
     260    20386733 :     void set_feedback_type(Type* type) { feedback_type_ = type; }
     261             :     Type* feedback_type() const { return feedback_type_; }
     262      110610 :     void set_weakened() { weakened_ = true; }
     263             :     bool weakened() const { return weakened_; }
     264    28613561 :     void set_restriction_type(Type* type) { restriction_type_ = type; }
     265             :     Type* restriction_type() const { return restriction_type_; }
     266             : 
     267             :    private:
     268             :     enum State : uint8_t { kUnvisited, kPushed, kVisited, kQueued };
     269             :     State state_ = kUnvisited;
     270             :     MachineRepresentation representation_ =
     271             :         MachineRepresentation::kNone;             // Output representation.
     272             :     Truncation truncation_ = Truncation::None();  // Information about uses.
     273             : 
     274             :     Type* restriction_type_ = Type::Any();
     275             :     Type* feedback_type_ = nullptr;
     276             :     bool weakened_ = false;
     277             :   };
     278             : 
     279     1330069 :   RepresentationSelector(JSGraph* jsgraph, Zone* zone,
     280             :                          RepresentationChanger* changer,
     281      443357 :                          SourcePositionTable* source_positions)
     282             :       : jsgraph_(jsgraph),
     283             :         zone_(zone),
     284      443356 :         count_(jsgraph->graph()->NodeCount()),
     285             :         info_(count_, zone),
     286             : #ifdef DEBUG
     287             :         node_input_use_infos_(count_, InputUseInfos(zone), zone),
     288             : #endif
     289             :         nodes_(zone),
     290             :         replacements_(zone),
     291             :         phase_(PROPAGATE),
     292             :         changer_(changer),
     293             :         queue_(zone),
     294             :         typing_stack_(zone),
     295             :         source_positions_(source_positions),
     296      443359 :         type_cache_(TypeCache::Get()),
     297     2216786 :         op_typer_(jsgraph->isolate(), graph_zone()) {
     298      443358 :   }
     299             : 
     300             :   // Forward propagation of types from type feedback.
     301     1330078 :   void RunTypePropagationPhase() {
     302             :     // Run type propagation.
     303      443358 :     TRACE("--{Type propagation phase}--\n");
     304      443360 :     phase_ = RETYPE;
     305             :     ResetNodeInfoState();
     306             : 
     307             :     DCHECK(typing_stack_.empty());
     308      886720 :     typing_stack_.push({graph()->end(), 0});
     309      443360 :     GetInfo(graph()->end())->set_pushed();
     310    57099274 :     while (!typing_stack_.empty()) {
     311             :       NodeState& current = typing_stack_.top();
     312             : 
     313             :       // If there is an unvisited input, push it and continue.
     314             :       bool pushed_unvisited = false;
     315   290520064 :       while (current.input_index < current.node->InputCount()) {
     316             :         Node* input = current.node->InputAt(current.input_index);
     317    88382974 :         NodeInfo* input_info = GetInfo(input);
     318    88382974 :         current.input_index++;
     319    88382974 :         if (input_info->unvisited()) {
     320             :           input_info->set_pushed();
     321    56213729 :           typing_stack_.push({input, 0});
     322             :           pushed_unvisited = true;
     323    28106913 :           break;
     324             :         }
     325             :       }
     326    56656013 :       if (pushed_unvisited) continue;
     327             : 
     328             :       // Process the top of the stack.
     329    28550012 :       Node* node = current.node;
     330             :       typing_stack_.pop();
     331             :       NodeInfo* info = GetInfo(node);
     332             :       info->set_visited();
     333    28550012 :       bool updated = UpdateFeedbackType(node);
     334    28549847 :       TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic());
     335    28549847 :       VisitNode(node, info->truncation(), nullptr);
     336    28549894 :       TRACE("  ==> output ");
     337    28549894 :       PrintOutputInfo(info);
     338    28549906 :       TRACE("\n");
     339    28549967 :       if (updated) {
     340   165744490 :         for (Node* const user : node->uses()) {
     341    73415859 :           if (GetInfo(user)->visited()) {
     342             :             GetInfo(user)->set_queued();
     343             :             queue_.push(user);
     344             :           }
     345             :         }
     346             :       }
     347             :     }
     348             : 
     349             :     // Process the revisit queue.
     350     5007474 :     while (!queue_.empty()) {
     351     4564116 :       Node* node = queue_.front();
     352             :       queue_.pop();
     353             :       NodeInfo* info = GetInfo(node);
     354             :       info->set_visited();
     355     4564125 :       bool updated = UpdateFeedbackType(node);
     356     4564112 :       TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic());
     357     4564112 :       VisitNode(node, info->truncation(), nullptr);
     358     4564147 :       TRACE("  ==> output ");
     359     4564147 :       PrintOutputInfo(info);
     360     4564153 :       TRACE("\n");
     361     4564109 :       if (updated) {
     362    11200059 :         for (Node* const user : node->uses()) {
     363     4863038 :           if (GetInfo(user)->visited()) {
     364             :             GetInfo(user)->set_queued();
     365             :             queue_.push(user);
     366             :           }
     367             :         }
     368             :       }
     369             :     }
     370      443358 :   }
     371             : 
     372             :   void ResetNodeInfoState() {
     373             :     // Clean up for the next phase.
     374    44026794 :     for (NodeInfo& info : info_) {
     375             :       info.reset_state();
     376             :     }
     377             :   }
     378             : 
     379             :   Type* TypeOf(Node* node) {
     380    30798799 :     Type* type = GetInfo(node)->feedback_type();
     381    30798799 :     return type == nullptr ? NodeProperties::GetType(node) : type;
     382             :   }
     383             : 
     384             :   Type* FeedbackTypeOf(Node* node) {
     385     3909220 :     Type* type = GetInfo(node)->feedback_type();
     386     3909220 :     return type == nullptr ? Type::None() : type;
     387             :   }
     388             : 
     389      868114 :   Type* TypePhi(Node* node) {
     390      868114 :     int arity = node->op()->ValueInputCount();
     391             :     Type* type = FeedbackTypeOf(node->InputAt(0));
     392     2201605 :     for (int i = 1; i < arity; ++i) {
     393     1333493 :       type = op_typer_.Merge(type, FeedbackTypeOf(node->InputAt(i)));
     394             :     }
     395      868112 :     return type;
     396             :   }
     397             : 
     398       13477 :   Type* TypeSelect(Node* node) {
     399             :     return op_typer_.Merge(FeedbackTypeOf(node->InputAt(1)),
     400       13477 :                            FeedbackTypeOf(node->InputAt(2)));
     401             :   }
     402             : 
     403    35273760 :   bool UpdateFeedbackType(Node* node) {
     404    33113573 :     if (node->op()->ValueOutputCount() == 0) return false;
     405             : 
     406    24115947 :     NodeInfo* info = GetInfo(node);
     407             :     Type* type = info->feedback_type();
     408             :     Type* new_type = type;
     409             : 
     410             :     // For any non-phi node just wait until we get all inputs typed. We only
     411             :     // allow untyped inputs for phi nodes because phis are the only places
     412             :     // where cycles need to be broken.
     413    23720521 :     if (node->opcode() != IrOpcode::kPhi) {
     414   129634199 :       for (int i = 0; i < node->op()->ValueInputCount(); i++) {
     415    54377801 :         if (GetInfo(node->InputAt(i))->feedback_type() == nullptr) {
     416             :           return false;
     417             :         }
     418             :       }
     419             :     }
     420             : 
     421    22733598 :     switch (node->opcode()) {
     422             : #define DECLARE_CASE(Name)                                       \
     423             :   case IrOpcode::k##Name: {                                      \
     424             :     new_type = op_typer_.Name(FeedbackTypeOf(node->InputAt(0)),  \
     425             :                               FeedbackTypeOf(node->InputAt(1))); \
     426             :     break;                                                       \
     427             :   }
     428      411900 :       SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_CASE)
     429             : #undef DECLARE_CASE
     430             : 
     431             : #define DECLARE_CASE(Name)                                                \
     432             :   case IrOpcode::k##Name: {                                               \
     433             :     new_type =                                                            \
     434             :         Type::Intersect(op_typer_.Name(FeedbackTypeOf(node->InputAt(0)),  \
     435             :                                        FeedbackTypeOf(node->InputAt(1))), \
     436             :                         info->restriction_type(), graph_zone());          \
     437             :     break;                                                                \
     438             :   }
     439      385588 :       SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DECLARE_CASE)
     440             : #undef DECLARE_CASE
     441             : 
     442             : #define DECLARE_CASE(Name)                                       \
     443             :   case IrOpcode::k##Name: {                                      \
     444             :     new_type = op_typer_.Name(FeedbackTypeOf(node->InputAt(0))); \
     445             :     break;                                                       \
     446             :   }
     447       32278 :       SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_CASE)
     448             : #undef DECLARE_CASE
     449             : 
     450             : #define DECLARE_CASE(Name)                                                \
     451             :   case IrOpcode::k##Name: {                                               \
     452             :     new_type =                                                            \
     453             :         Type::Intersect(op_typer_.Name(FeedbackTypeOf(node->InputAt(0))), \
     454             :                         info->restriction_type(), graph_zone());          \
     455             :     break;                                                                \
     456             :   }
     457        8640 :       SIMPLIFIED_SPECULATIVE_NUMBER_UNOP_LIST(DECLARE_CASE)
     458             : #undef DECLARE_CASE
     459             : 
     460             :       case IrOpcode::kPlainPrimitiveToNumber:
     461       10773 :         new_type = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0)));
     462       10773 :         break;
     463             : 
     464             :       case IrOpcode::kCheckFloat64Hole:
     465             :         new_type = Type::Intersect(
     466             :             op_typer_.CheckFloat64Hole(FeedbackTypeOf(node->InputAt(0))),
     467         778 :             info->restriction_type(), graph_zone());
     468         778 :         break;
     469             : 
     470             :       case IrOpcode::kCheckNumber:
     471             :         new_type = Type::Intersect(
     472             :             op_typer_.CheckNumber(FeedbackTypeOf(node->InputAt(0))),
     473         420 :             info->restriction_type(), graph_zone());
     474         420 :         break;
     475             : 
     476             :       case IrOpcode::kPhi: {
     477      868116 :         new_type = TypePhi(node);
     478      868112 :         if (type != nullptr) {
     479      469893 :           new_type = Weaken(node, type, new_type);
     480             :         }
     481             :         break;
     482             :       }
     483             : 
     484             :       case IrOpcode::kConvertTaggedHoleToUndefined:
     485             :         new_type = op_typer_.ConvertTaggedHoleToUndefined(
     486        1554 :             FeedbackTypeOf(node->InputAt(0)));
     487        1554 :         break;
     488             : 
     489             :       case IrOpcode::kTypeGuard: {
     490             :         new_type = op_typer_.TypeTypeGuard(node->op(),
     491       31240 :                                            FeedbackTypeOf(node->InputAt(0)));
     492       31240 :         break;
     493             :       }
     494             : 
     495             :       case IrOpcode::kSelect: {
     496       13477 :         new_type = TypeSelect(node);
     497       13477 :         break;
     498             :       }
     499             : 
     500             :       default:
     501             :         // Shortcut for operations that we do not handle.
     502    20968834 :         if (type == nullptr) {
     503             :           GetInfo(node)->set_feedback_type(NodeProperties::GetType(node));
     504    18811521 :           return true;
     505             :         }
     506             :         return false;
     507             :     }
     508             :     // We need to guarantee that the feedback type is a subtype of the upper
     509             :     // bound. Naively that should hold, but weakening can actually produce
     510             :     // a bigger type if we are unlucky with ordering of phi typing. To be
     511             :     // really sure, just intersect the upper bound with the feedback type.
     512     1764761 :     new_type = Type::Intersect(GetUpperBound(node), new_type, graph_zone());
     513             : 
     514     2593958 :     if (type != nullptr && new_type->Is(type)) return false;
     515             :     GetInfo(node)->set_feedback_type(new_type);
     516     1575212 :     if (FLAG_trace_representation) {
     517           0 :       PrintNodeFeedbackType(node);
     518             :     }
     519             :     return true;
     520             :   }
     521             : 
     522           0 :   void PrintNodeFeedbackType(Node* n) {
     523           0 :     OFStream os(stdout);
     524           0 :     os << "#" << n->id() << ":" << *n->op() << "(";
     525             :     int j = 0;
     526           0 :     for (Node* const i : n->inputs()) {
     527           0 :       if (j++ > 0) os << ", ";
     528           0 :       os << "#" << i->id() << ":" << i->op()->mnemonic();
     529             :     }
     530           0 :     os << ")";
     531           0 :     if (NodeProperties::IsTyped(n)) {
     532           0 :       os << "  [Static type: ";
     533             :       Type* static_type = NodeProperties::GetType(n);
     534           0 :       static_type->PrintTo(os);
     535           0 :       Type* feedback_type = GetInfo(n)->feedback_type();
     536           0 :       if (feedback_type != nullptr && feedback_type != static_type) {
     537           0 :         os << ", Feedback type: ";
     538           0 :         feedback_type->PrintTo(os);
     539             :       }
     540           0 :       os << "]";
     541             :     }
     542           0 :     os << std::endl;
     543           0 :   }
     544             : 
     545     1719379 :   Type* Weaken(Node* node, Type* previous_type, Type* current_type) {
     546             :     // If the types have nothing to do with integers, return the types.
     547      469893 :     Type* const integer = type_cache_.kInteger;
     548      469893 :     if (!previous_type->Maybe(integer)) {
     549             :       return current_type;
     550             :     }
     551             :     DCHECK(current_type->Maybe(integer));
     552             : 
     553             :     Type* current_integer =
     554      418236 :         Type::Intersect(current_type, integer, graph_zone());
     555             :     Type* previous_integer =
     556      418235 :         Type::Intersect(previous_type, integer, graph_zone());
     557             : 
     558             :     // Once we start weakening a node, we should always weaken.
     559      418232 :     if (!GetInfo(node)->weakened()) {
     560             :       // Only weaken if there is range involved; we should converge quickly
     561             :       // for all other types (the exception is a union of many constants,
     562             :       // but we currently do not increase the number of constants in unions).
     563      115827 :       Type* previous = previous_integer->GetRange();
     564      115826 :       Type* current = current_integer->GetRange();
     565      115826 :       if (current == nullptr || previous == nullptr) {
     566             :         return current_type;
     567             :       }
     568             :       // Range is involved => we are weakening.
     569             :       GetInfo(node)->set_weakened();
     570             :     }
     571             : 
     572             :     return Type::Union(current_type,
     573             :                        op_typer_.WeakenRange(previous_integer, current_integer),
     574      413015 :                        graph_zone());
     575             :   }
     576             : 
     577             :   // Backward propagation of truncations.
     578      443357 :   void RunTruncationPropagationPhase() {
     579             :     // Run propagation phase to a fixpoint.
     580      443357 :     TRACE("--{Propagation phase}--\n");
     581      443357 :     phase_ = PROPAGATE;
     582      443357 :     EnqueueInitial(jsgraph_->graph()->end());
     583             :     // Process nodes from the queue until it is empty.
     584    30426172 :     while (!queue_.empty()) {
     585    29539453 :       Node* node = queue_.front();
     586             :       NodeInfo* info = GetInfo(node);
     587             :       queue_.pop();
     588             :       info->set_visited();
     589    29539524 :       TRACE(" visit #%d: %s (trunc: %s)\n", node->id(), node->op()->mnemonic(),
     590             :             info->truncation().description());
     591    29539524 :       VisitNode(node, info->truncation(), nullptr);
     592             :     }
     593      443360 :   }
     594             : 
     595      443357 :   void Run(SimplifiedLowering* lowering) {
     596      443357 :     RunTruncationPropagationPhase();
     597             : 
     598      443360 :     RunTypePropagationPhase();
     599             : 
     600             :     // Run lowering and change insertion phase.
     601      443358 :     TRACE("--{Simplified lowering phase}--\n");
     602      443375 :     phase_ = LOWER;
     603             :     // Process nodes from the collected {nodes_} vector.
     604    29436355 :     for (NodeVector::iterator i = nodes_.begin(); i != nodes_.end(); ++i) {
     605    28549620 :       Node* node = *i;
     606             :       NodeInfo* info = GetInfo(node);
     607    28549620 :       TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic());
     608             :       // Reuse {VisitNode()} so the representation rules are in one place.
     609             :       SourcePositionTable::Scope scope(
     610    28549620 :           source_positions_, source_positions_->GetSourcePosition(node));
     611    28549631 :       VisitNode(node, info->truncation(), lowering);
     612             :     }
     613             : 
     614             :     // Perform the final replacements.
     615     1066707 :     for (NodeVector::iterator i = replacements_.begin();
     616             :          i != replacements_.end(); ++i) {
     617      179987 :       Node* node = *i;
     618      179987 :       Node* replacement = *(++i);
     619      179987 :       node->ReplaceUses(replacement);
     620      179987 :       node->Kill();
     621             :       // We also need to replace the node in the rest of the vector.
     622    11882110 :       for (NodeVector::iterator j = i + 1; j != replacements_.end(); ++j) {
     623             :         ++j;
     624    11522136 :         if (*j == node) *j = replacement;
     625             :       }
     626             :     }
     627      443360 :   }
     628             : 
     629      443358 :   void EnqueueInitial(Node* node) {
     630      443358 :     NodeInfo* info = GetInfo(node);
     631             :     info->set_queued();
     632      443358 :     nodes_.push_back(node);
     633             :     queue_.push(node);
     634      443359 :   }
     635             : 
     636             :   // Enqueue {use_node}'s {index} input if the {use} contains new information
     637             :   // for that input node. Add the input to {nodes_} if this is the first time
     638             :   // it's been visited.
     639   144174880 :   void EnqueueInput(Node* use_node, int index,
     640             :                     UseInfo use_info = UseInfo::None()) {
     641   144174880 :     Node* node = use_node->InputAt(index);
     642   224857071 :     if (phase_ != PROPAGATE) return;
     643    93229924 :     NodeInfo* info = GetInfo(node);
     644             : #ifdef DEBUG
     645             :     // Check monotonicity of input requirements.
     646             :     node_input_use_infos_[use_node->id()].SetAndCheckInput(use_node, index,
     647             :                                                            use_info);
     648             : #endif  // DEBUG
     649    91599256 :     if (info->unvisited()) {
     650             :       // First visit of this node.
     651             :       info->set_queued();
     652    28106672 :       nodes_.push_back(node);
     653             :       queue_.push(node);
     654    28106671 :       TRACE("  initial #%i: ", node->id());
     655    28106671 :       info->AddUse(use_info);
     656    28106544 :       PrintTruncation(info->truncation());
     657    28106567 :       return;
     658             :     }
     659    63492584 :     TRACE("   queue #%i?: ", node->id());
     660    63492584 :     PrintTruncation(info->truncation());
     661    63492605 :     if (info->AddUse(use_info)) {
     662             :       // New usage information for the node is available.
     663     1630668 :       if (!info->queued()) {
     664             :         queue_.push(node);
     665             :         info->set_queued();
     666      989743 :         TRACE("   added: ");
     667             :       } else {
     668      640924 :         TRACE(" inqueue: ");
     669             :       }
     670     1630667 :       PrintTruncation(info->truncation());
     671             :     }
     672             :   }
     673             : 
     674             :   bool lower() const { return phase_ == LOWER; }
     675             :   bool retype() const { return phase_ == RETYPE; }
     676             :   bool propagate() const { return phase_ == PROPAGATE; }
     677             : 
     678             :   void SetOutput(Node* node, MachineRepresentation representation,
     679             :                  Type* restriction_type = Type::Any()) {
     680             :     NodeInfo* const info = GetInfo(node);
     681    88879428 :     switch (phase_) {
     682             :       case PROPAGATE:
     683             :         info->set_restriction_type(restriction_type);
     684             :         break;
     685             :       case RETYPE:
     686             :         DCHECK(info->restriction_type()->Is(restriction_type));
     687             :         DCHECK(restriction_type->Is(info->restriction_type()));
     688             :         info->set_output(representation);
     689             :         break;
     690             :       case LOWER:
     691             :         DCHECK_EQ(info->representation(), representation);
     692             :         DCHECK(info->restriction_type()->Is(restriction_type));
     693             :         DCHECK(restriction_type->Is(info->restriction_type()));
     694             :         break;
     695             :     }
     696             :   }
     697             : 
     698             :   Type* GetUpperBound(Node* node) { return NodeProperties::GetType(node); }
     699             : 
     700       78748 :   bool InputCannotBe(Node* node, Type* type) {
     701             :     DCHECK_EQ(1, node->op()->ValueInputCount());
     702       78748 :     return !GetUpperBound(node->InputAt(0))->Maybe(type);
     703             :   }
     704             : 
     705      129953 :   bool InputIs(Node* node, Type* type) {
     706             :     DCHECK_EQ(1, node->op()->ValueInputCount());
     707      129953 :     return GetUpperBound(node->InputAt(0))->Is(type);
     708             :   }
     709             : 
     710             :   bool BothInputsAreSigned32(Node* node) {
     711      115757 :     return BothInputsAre(node, Type::Signed32());
     712             :   }
     713             : 
     714             :   bool BothInputsAreUnsigned32(Node* node) {
     715      122872 :     return BothInputsAre(node, Type::Unsigned32());
     716             :   }
     717             : 
     718     1779712 :   bool BothInputsAre(Node* node, Type* type) {
     719             :     DCHECK_EQ(2, node->op()->ValueInputCount());
     720     2701069 :     return GetUpperBound(node->InputAt(0))->Is(type) &&
     721     1779695 :            GetUpperBound(node->InputAt(1))->Is(type);
     722             :   }
     723             : 
     724             :   bool IsNodeRepresentationTagged(Node* node) {
     725       38435 :     MachineRepresentation representation = GetInfo(node)->representation();
     726             :     return IsAnyTagged(representation);
     727             :   }
     728             : 
     729        1763 :   bool OneInputCannotBe(Node* node, Type* type) {
     730             :     DCHECK_EQ(2, node->op()->ValueInputCount());
     731        3526 :     return !GetUpperBound(node->InputAt(0))->Maybe(type) ||
     732        3526 :            !GetUpperBound(node->InputAt(1))->Maybe(type);
     733             :   }
     734             : 
     735             :   // Converts input {index} of {node} according to given UseInfo {use},
     736             :   // assuming the type of the input is {input_type}. If {input_type} is null,
     737             :   // it takes the input from the input node {TypeOf(node->InputAt(index))}.
     738    62737350 :   void ConvertInput(Node* node, int index, UseInfo use,
     739             :                     Type* input_type = nullptr) {
     740           0 :     Node* input = node->InputAt(index);
     741             :     // In the change phase, insert a change before the use if necessary.
     742    50038776 :     if (use.representation() == MachineRepresentation::kNone)
     743    50038722 :       return;  // No input requirement on the use.
     744             :     DCHECK_NOT_NULL(input);
     745    59927045 :     NodeInfo* input_info = GetInfo(input);
     746             :     MachineRepresentation input_rep = input_info->representation();
     747    81857548 :     if (input_rep != use.representation() ||
     748    34629068 :         use.type_check() != TypeCheckKind::kNone) {
     749             :       // Output representation doesn't match usage.
     750    12698574 :       TRACE("  change: #%d:%s(@%d #%d:%s) ", node->id(), node->op()->mnemonic(),
     751             :             index, input->id(), input->op()->mnemonic());
     752    12698573 :       TRACE(" from ");
     753    12698573 :       PrintOutputInfo(input_info);
     754    12698574 :       TRACE(" to ");
     755    12698574 :       PrintUseInfo(use);
     756    12698570 :       TRACE("\n");
     757    12698565 :       if (input_type == nullptr) {
     758             :         input_type = TypeOf(input);
     759             :       }
     760             :       Node* n = changer_->GetRepresentationFor(
     761    12698565 :           input, input_info->representation(), input_type, node, use);
     762    12698553 :       node->ReplaceInput(index, n);
     763             :     }
     764             :   }
     765             : 
     766   161854093 :   void ProcessInput(Node* node, int index, UseInfo use) {
     767   161854093 :     switch (phase_) {
     768             :       case PROPAGATE:
     769    51954896 :         EnqueueInput(node, index, use);
     770    51954471 :         break;
     771             :       case RETYPE:
     772             :         break;
     773             :       case LOWER:
     774    50019249 :         ConvertInput(node, index, use);
     775    50019101 :         break;
     776             :     }
     777   161853520 :   }
     778             : 
     779    15558103 :   void ProcessRemainingInputs(Node* node, int index) {
     780             :     DCHECK_GE(index, NodeProperties::PastValueIndex(node));
     781             :     DCHECK_GE(index, NodeProperties::PastContextIndex(node));
     782    64480192 :     for (int i = std::max(index, NodeProperties::FirstEffectIndex(node));
     783    24461049 :          i < NodeProperties::PastEffectIndex(node); ++i) {
     784     8902942 :       EnqueueInput(node, i);  // Effect inputs: just visit
     785             :     }
     786    64805885 :     for (int i = std::max(index, NodeProperties::FirstControlIndex(node));
     787    24623900 :          i < NodeProperties::PastControlIndex(node); ++i) {
     788     9065804 :       EnqueueInput(node, i);  // Control inputs: just visit
     789             :     }
     790    15558096 :   }
     791             : 
     792             :   // The default, most general visitation case. For {node}, process all value,
     793             :   // context, frame state, effect, and control inputs, assuming that value
     794             :   // inputs should have {kRepTagged} representation and can observe all output
     795             :   // values {kTypeAny}.
     796    55495203 :   void VisitInputs(Node* node) {
     797    55495203 :     int tagged_count = node->op()->ValueInputCount() +
     798             :                        OperatorProperties::GetContextInputCount(node->op()) +
     799    27747275 :                        OperatorProperties::GetFrameStateInputCount(node->op());
     800             :     // Visit value, context and frame state inputs as tagged.
     801    67575683 :     for (int i = 0; i < tagged_count; i++) {
     802    39828391 :       ProcessInput(node, i, UseInfo::AnyTagged());
     803             :     }
     804             :     // Only enqueue other inputs (effects, control).
     805   131835470 :     for (int i = tagged_count; i < node->InputCount(); i++) {
     806    52044087 :       EnqueueInput(node, i);
     807             :     }
     808    27747294 :   }
     809             : 
     810     3320073 :   void VisitReturn(Node* node) {
     811     3320073 :     int tagged_limit = node->op()->ValueInputCount() +
     812             :                        OperatorProperties::GetContextInputCount(node->op()) +
     813     1660038 :                        OperatorProperties::GetFrameStateInputCount(node->op());
     814             :     // Visit integer slot count to pop
     815     1660038 :     ProcessInput(node, 0, UseInfo::TruncatingWord32());
     816             : 
     817             :     // Visit value, context and frame state inputs as tagged.
     818     3320070 :     for (int i = 1; i < tagged_limit; i++) {
     819     1660034 :       ProcessInput(node, i, UseInfo::AnyTagged());
     820             :     }
     821             :     // Only enqueue other inputs (effects, control).
     822     8300194 :     for (int i = tagged_limit; i < node->InputCount(); i++) {
     823     3320074 :       EnqueueInput(node, i);
     824             :     }
     825     1660041 :   }
     826             : 
     827             :   // Helper for an unused node.
     828     1256973 :   void VisitUnused(Node* node) {
     829      837985 :     int value_count = node->op()->ValueInputCount() +
     830             :                       OperatorProperties::GetContextInputCount(node->op()) +
     831      418993 :                       OperatorProperties::GetFrameStateInputCount(node->op());
     832     1091852 :     for (int i = 0; i < value_count; i++) {
     833      672860 :       ProcessInput(node, i, UseInfo::None());
     834             :     }
     835      418992 :     ProcessRemainingInputs(node, value_count);
     836      418988 :     if (lower()) Kill(node);
     837      418988 :   }
     838             : 
     839             :   // Helper for no-op node.
     840         504 :   void VisitNoop(Node* node, Truncation truncation) {
     841         520 :     if (truncation.IsUnused()) return VisitUnused(node);
     842             :     MachineRepresentation representation =
     843         244 :         GetOutputInfoForPhi(node, TypeOf(node), truncation);
     844         244 :     VisitUnop(node, UseInfo(representation, truncation), representation);
     845         330 :     if (lower()) DeferReplacement(node, node->InputAt(0));
     846             :   }
     847             : 
     848             :   // Helper for binops of the R x L -> O variety.
     849     3435260 :   void VisitBinop(Node* node, UseInfo left_use, UseInfo right_use,
     850             :                   MachineRepresentation output,
     851             :                   Type* restriction_type = Type::Any()) {
     852             :     DCHECK_EQ(2, node->op()->ValueInputCount());
     853     3435260 :     ProcessInput(node, 0, left_use);
     854     3435239 :     ProcessInput(node, 1, right_use);
     855    13644648 :     for (int i = 2; i < node->InputCount(); i++) {
     856     3387028 :       EnqueueInput(node, i);
     857             :     }
     858             :     SetOutput(node, output, restriction_type);
     859     3435296 :   }
     860             : 
     861             :   // Helper for binops of the I x I -> O variety.
     862             :   void VisitBinop(Node* node, UseInfo input_use, MachineRepresentation output,
     863             :                   Type* restriction_type = Type::Any()) {
     864     2730994 :     VisitBinop(node, input_use, input_use, output, restriction_type);
     865             :   }
     866             : 
     867      106474 :   void VisitSpeculativeInt32Binop(Node* node) {
     868             :     DCHECK_EQ(2, node->op()->ValueInputCount());
     869       86517 :     if (BothInputsAre(node, Type::NumberOrOddball())) {
     870             :       return VisitBinop(node, UseInfo::TruncatingWord32(),
     871             :                         MachineRepresentation::kWord32);
     872             :     }
     873       19957 :     NumberOperationHint hint = NumberOperationHintOf(node->op());
     874             :     return VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
     875       19956 :                       MachineRepresentation::kWord32);
     876             :   }
     877             : 
     878             :   // Helper for unops of the I -> O variety.
     879    10046049 :   void VisitUnop(Node* node, UseInfo input_use, MachineRepresentation output,
     880             :                  Type* restriction_type = Type::Any()) {
     881             :     DCHECK_EQ(1, node->op()->ValueInputCount());
     882    10046049 :     ProcessInput(node, 0, input_use);
     883    10046050 :     ProcessRemainingInputs(node, 1);
     884             :     SetOutput(node, output, restriction_type);
     885    10046052 :   }
     886             : 
     887             :   // Helper for leaf nodes.
     888             :   void VisitLeaf(Node* node, MachineRepresentation output) {
     889             :     DCHECK_EQ(0, node->InputCount());
     890             :     SetOutput(node, output);
     891             :   }
     892             : 
     893             :   // Helpers for specific types of binops.
     894      634653 :   void VisitFloat64Binop(Node* node) {
     895             :     VisitBinop(node, UseInfo::TruncatingFloat64(),
     896             :                MachineRepresentation::kFloat64);
     897      634663 :   }
     898      410600 :   void VisitWord32TruncatingBinop(Node* node) {
     899             :     VisitBinop(node, UseInfo::TruncatingWord32(),
     900             :                MachineRepresentation::kWord32);
     901      410580 :   }
     902             : 
     903             :   // Infer representation for phi-like nodes.
     904             :   // The {node} parameter is only used to decide on the int64 representation.
     905             :   // Once the type system supports an external pointer type, the {node}
     906             :   // parameter can be removed.
     907     1859828 :   MachineRepresentation GetOutputInfoForPhi(Node* node, Type* type,
     908     1305584 :                                             Truncation use) {
     909             :     // Compute the representation.
     910     1859800 :     if (type->Is(Type::None())) {
     911             :       return MachineRepresentation::kNone;
     912     3290018 :     } else if (type->Is(Type::Signed32()) || type->Is(Type::Unsigned32())) {
     913             :       return MachineRepresentation::kWord32;
     914     2259232 :     } else if (type->Is(Type::NumberOrOddball()) && use.IsUsedAsWord32()) {
     915             :       return MachineRepresentation::kWord32;
     916     1451210 :     } else if (type->Is(Type::Boolean())) {
     917             :       return MachineRepresentation::kBit;
     918     2120241 :     } else if (type->Is(Type::NumberOrOddball()) && use.IsUsedAsFloat64()) {
     919             :       return MachineRepresentation::kFloat64;
     920     1305574 :     } else if (type->Is(
     921     1305584 :                    Type::Union(Type::SignedSmall(), Type::NaN(), zone()))) {
     922             :       // TODO(turbofan): For Phis that return either NaN or some Smi, it's
     923             :       // beneficial to not go all the way to double, unless the uses are
     924             :       // double uses. For tagging that just means some potentially expensive
     925             :       // allocation code; we might want to do the same for -0 as well?
     926             :       return MachineRepresentation::kTagged;
     927     1304513 :     } else if (type->Is(Type::Number())) {
     928             :       return MachineRepresentation::kFloat64;
     929      675445 :     } else if (type->Is(Type::ExternalPointer())) {
     930             :       return MachineType::PointerRepresentation();
     931             :     }
     932      675445 :     return MachineRepresentation::kTagged;
     933             :   }
     934             : 
     935             :   // Helper for handling selects.
     936       54788 :   void VisitSelect(Node* node, Truncation truncation,
     937       41311 :                    SimplifiedLowering* lowering) {
     938             :     DCHECK(TypeOf(node->InputAt(0))->Is(Type::Boolean()));
     939       41311 :     ProcessInput(node, 0, UseInfo::Bool());
     940             : 
     941             :     MachineRepresentation output =
     942       41311 :         GetOutputInfoForPhi(node, TypeOf(node), truncation);
     943             :     SetOutput(node, output);
     944             : 
     945       41311 :     if (lower()) {
     946             :       // Update the select operator.
     947       13477 :       SelectParameters p = SelectParametersOf(node->op());
     948       13477 :       if (output != p.representation()) {
     949             :         NodeProperties::ChangeOp(node,
     950        7010 :                                  lowering->common()->Select(output, p.hint()));
     951             :       }
     952             :     }
     953             :     // Convert inputs to the output representation of this phi, pass the
     954             :     // truncation truncation along.
     955             :     UseInfo input_use(output, truncation);
     956       41311 :     ProcessInput(node, 1, input_use);
     957       41311 :     ProcessInput(node, 2, input_use);
     958       41311 :   }
     959             : 
     960             :   // Helper for handling phis.
     961     3468941 :   void VisitPhi(Node* node, Truncation truncation,
     962     1734452 :                 SimplifiedLowering* lowering) {
     963             :     MachineRepresentation output =
     964     1734489 :         GetOutputInfoForPhi(node, TypeOf(node), truncation);
     965             :     // Only set the output representation if not running with type
     966             :     // feedback. (Feedback typing will set the representation.)
     967             :     SetOutput(node, output);
     968             : 
     969     1734452 :     int values = node->op()->ValueInputCount();
     970     1734452 :     if (lower()) {
     971             :       // Update the phi operator.
     972      398228 :       if (output != PhiRepresentationOf(node->op())) {
     973      197228 :         NodeProperties::ChangeOp(node, lowering->common()->Phi(output, values));
     974             :       }
     975             :     }
     976             : 
     977             :     // Convert inputs to the output representation of this phi, pass the
     978             :     // truncation along.
     979             :     UseInfo input_use(output, truncation);
     980    16047112 :     for (int i = 0; i < node->InputCount(); i++) {
     981     6289118 :       ProcessInput(node, i, i < values ? input_use : UseInfo::None());
     982             :     }
     983     1734438 :   }
     984             : 
     985      325211 :   void VisitObjectIs(Node* node, Type* type, SimplifiedLowering* lowering) {
     986             :     Type* const input_type = TypeOf(node->InputAt(0));
     987      161547 :     if (input_type->Is(type)) {
     988        5150 :       VisitUnop(node, UseInfo::None(), MachineRepresentation::kBit);
     989        5150 :       if (lower()) {
     990        1703 :         DeferReplacement(node, lowering->jsgraph()->Int32Constant(1));
     991             :       }
     992             :     } else {
     993      156397 :       VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
     994      156397 :       if (lower() && !input_type->Maybe(type)) {
     995         414 :         DeferReplacement(node, lowering->jsgraph()->Int32Constant(0));
     996             :       }
     997             :     }
     998      161547 :   }
     999             : 
    1000       17466 :   void VisitCheck(Node* node, Type* type, SimplifiedLowering* lowering) {
    1001       17085 :     if (InputIs(node, type)) {
    1002             :       VisitUnop(node, UseInfo::AnyTagged(),
    1003         381 :                 MachineRepresentation::kTaggedPointer);
    1004         476 :       if (lower()) DeferReplacement(node, node->InputAt(0));
    1005             :     } else {
    1006             :       VisitUnop(node, UseInfo::CheckedHeapObjectAsTaggedPointer(),
    1007       16704 :                 MachineRepresentation::kTaggedPointer);
    1008             :     }
    1009       17085 :     return;
    1010             :   }
    1011             : 
    1012     2079365 :   void VisitCall(Node* node, SimplifiedLowering* lowering) {
    1013     2079365 :     const CallDescriptor* desc = CallDescriptorOf(node->op());
    1014     1039683 :     int params = static_cast<int>(desc->ParameterCount());
    1015     1039683 :     int value_input_count = node->op()->ValueInputCount();
    1016             :     // Propagate representation information from call descriptor.
    1017     9443358 :     for (int i = 0; i < value_input_count; i++) {
    1018     8403673 :       if (i == 0) {
    1019             :         // The target of the call.
    1020     1039679 :         ProcessInput(node, i, UseInfo::Any());
    1021     7363994 :       } else if ((i - 1) < params) {
    1022             :         ProcessInput(node, i,
    1023             :                      TruncatingUseInfoFromRepresentation(
    1024    12657328 :                          desc->GetInputType(i).representation()));
    1025             :       } else {
    1026     1035330 :         ProcessInput(node, i, UseInfo::AnyTagged());
    1027             :       }
    1028             :     }
    1029     1039685 :     ProcessRemainingInputs(node, value_input_count);
    1030             : 
    1031     1039683 :     if (desc->ReturnCount() > 0) {
    1032             :       SetOutput(node, desc->GetReturnType(0).representation());
    1033             :     } else {
    1034             :       SetOutput(node, MachineRepresentation::kTagged);
    1035             :     }
    1036     1039683 :   }
    1037             : 
    1038      549490 :   static MachineSemantic DeoptValueSemanticOf(Type* type) {
    1039             :     // We only need signedness to do deopt correctly.
    1040      549499 :     if (type->Is(Type::Signed32())) {
    1041             :       return MachineSemantic::kInt32;
    1042      318633 :     } else if (type->Is(Type::Unsigned32())) {
    1043             :       return MachineSemantic::kUint32;
    1044             :     } else {
    1045      316794 :       return MachineSemantic::kAny;
    1046             :     }
    1047             :   }
    1048             : 
    1049     9758417 :   static MachineType DeoptMachineTypeOf(MachineRepresentation rep, Type* type) {
    1050     9758446 :     if (!type->IsInhabited()) {
    1051             :       return MachineType::None();
    1052             :     }
    1053             :     // TODO(turbofan): Special treatment for ExternalPointer here,
    1054             :     // to avoid incompatible truncations. We really need a story
    1055             :     // for the JSFunction::entry field.
    1056     9758430 :     if (type->Is(Type::ExternalPointer())) {
    1057             :       return MachineType::Pointer();
    1058             :     }
    1059             :     // Do not distinguish between various Tagged variations.
    1060     9758430 :     if (IsAnyTagged(rep)) {
    1061             :       return MachineType::AnyTagged();
    1062             :     }
    1063      549481 :     MachineType machine_type(rep, DeoptValueSemanticOf(type));
    1064             :     DCHECK(machine_type.representation() != MachineRepresentation::kWord32 ||
    1065             :            machine_type.semantic() == MachineSemantic::kInt32 ||
    1066             :            machine_type.semantic() == MachineSemantic::kUint32);
    1067             :     DCHECK(machine_type.representation() != MachineRepresentation::kBit ||
    1068             :            type->Is(Type::Boolean()));
    1069      549489 :     return machine_type;
    1070             :   }
    1071             : 
    1072    13121089 :   void VisitStateValues(Node* node) {
    1073    10189666 :     if (propagate()) {
    1074    20191345 :       for (int i = 0; i < node->InputCount(); i++) {
    1075     8629969 :         EnqueueInput(node, i, UseInfo::Any());
    1076             :       }
    1077     7258257 :     } else if (lower()) {
    1078     5862841 :       Zone* zone = jsgraph_->zone();
    1079             :       ZoneVector<MachineType>* types =
    1080             :           new (zone->New(sizeof(ZoneVector<MachineType>)))
    1081     2931422 :               ZoneVector<MachineType>(node->InputCount(), zone);
    1082    23122648 :       for (int i = 0; i < node->InputCount(); i++) {
    1083             :         Node* input = node->InputAt(i);
    1084     8629901 :         (*types)[i] =
    1085     8629901 :             DeoptMachineTypeOf(GetInfo(input)->representation(), TypeOf(input));
    1086             :       }
    1087     2931423 :       SparseInputMask mask = SparseInputMaskOf(node->op());
    1088             :       NodeProperties::ChangeOp(
    1089     5862838 :           node, jsgraph_->common()->TypedStateValues(types, mask));
    1090             :     }
    1091             :     SetOutput(node, MachineRepresentation::kTagged);
    1092    10189659 :   }
    1093             : 
    1094    30558101 :   void VisitFrameState(Node* node) {
    1095             :     DCHECK_EQ(5, node->op()->ValueInputCount());
    1096             :     DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
    1097             : 
    1098    15279041 :     ProcessInput(node, 0, UseInfo::AnyTagged());  // Parameters.
    1099    15279048 :     ProcessInput(node, 1, UseInfo::AnyTagged());  // Registers.
    1100             : 
    1101             :     // Accumulator is a special flower - we need to remember its type in
    1102             :     // a singleton typed-state-values node (as if it was a singleton
    1103             :     // state-values node).
    1104    15279060 :     if (propagate()) {
    1105     4860235 :       EnqueueInput(node, 2, UseInfo::Any());
    1106    10418825 :     } else if (lower()) {
    1107     6933593 :       Zone* zone = jsgraph_->zone();
    1108             :       Node* accumulator = node->InputAt(2);
    1109     4860237 :       if (accumulator == jsgraph_->OptimizedOutConstant()) {
    1110     3823556 :         node->ReplaceInput(2, jsgraph_->SingleDeadTypedStateValues());
    1111             :       } else {
    1112             :         ZoneVector<MachineType>* types =
    1113             :             new (zone->New(sizeof(ZoneVector<MachineType>)))
    1114     1036680 :                 ZoneVector<MachineType>(1, zone);
    1115     1036680 :         (*types)[0] = DeoptMachineTypeOf(GetInfo(accumulator)->representation(),
    1116     1036680 :                                          TypeOf(accumulator));
    1117             : 
    1118             :         node->ReplaceInput(
    1119             :             2, jsgraph_->graph()->NewNode(jsgraph_->common()->TypedStateValues(
    1120             :                                               types, SparseInputMask::Dense()),
    1121     3110038 :                                           accumulator));
    1122             :       }
    1123             :     }
    1124             : 
    1125    15279063 :     ProcessInput(node, 3, UseInfo::AnyTagged());  // Context.
    1126    15279046 :     ProcessInput(node, 4, UseInfo::AnyTagged());  // Closure.
    1127    15279042 :     ProcessInput(node, 5, UseInfo::AnyTagged());  // Outer frame state.
    1128    15279048 :     return SetOutput(node, MachineRepresentation::kTagged);
    1129             :   }
    1130             : 
    1131       76256 :   void VisitObjectState(Node* node) {
    1132       57919 :     if (propagate()) {
    1133      202039 :       for (int i = 0; i < node->InputCount(); i++) {
    1134       91851 :         EnqueueInput(node, i, UseInfo::Any());
    1135             :       }
    1136       39582 :     } else if (lower()) {
    1137       36674 :       Zone* zone = jsgraph_->zone();
    1138             :       ZoneVector<MachineType>* types =
    1139             :           new (zone->New(sizeof(ZoneVector<MachineType>)))
    1140       18337 :               ZoneVector<MachineType>(node->InputCount(), zone);
    1141      220376 :       for (int i = 0; i < node->InputCount(); i++) {
    1142             :         Node* input = node->InputAt(i);
    1143       91851 :         (*types)[i] =
    1144       91851 :             DeoptMachineTypeOf(GetInfo(input)->representation(), TypeOf(input));
    1145             :       }
    1146             :       NodeProperties::ChangeOp(node, jsgraph_->common()->TypedObjectState(
    1147       36674 :                                          ObjectIdOf(node->op()), types));
    1148             :     }
    1149             :     SetOutput(node, MachineRepresentation::kTagged);
    1150       57919 :   }
    1151             : 
    1152      218028 :   const Operator* Int32Op(Node* node) {
    1153      218028 :     return changer_->Int32OperatorFor(node->opcode());
    1154             :   }
    1155             : 
    1156      165752 :   const Operator* Int32OverflowOp(Node* node) {
    1157      165752 :     return changer_->Int32OverflowOperatorFor(node->opcode());
    1158             :   }
    1159             : 
    1160       56045 :   const Operator* Uint32Op(Node* node) {
    1161       56045 :     return changer_->Uint32OperatorFor(node->opcode());
    1162             :   }
    1163             : 
    1164         105 :   const Operator* Uint32OverflowOp(Node* node) {
    1165         105 :     return changer_->Uint32OverflowOperatorFor(node->opcode());
    1166             :   }
    1167             : 
    1168      176131 :   const Operator* Float64Op(Node* node) {
    1169      176131 :     return changer_->Float64OperatorFor(node->opcode());
    1170             :   }
    1171             : 
    1172     3202820 :   WriteBarrierKind WriteBarrierKindFor(
    1173             :       BaseTaggedness base_taggedness,
    1174             :       MachineRepresentation field_representation, Type* field_type,
    1175             :       MachineRepresentation value_representation, Node* value) {
    1176     6325762 :     if (base_taggedness == kTaggedBase &&
    1177             :         CanBeTaggedPointer(field_representation)) {
    1178             :       Type* value_type = NodeProperties::GetType(value);
    1179     4948738 :       if (field_representation == MachineRepresentation::kTaggedSigned ||
    1180     2474369 :           value_representation == MachineRepresentation::kTaggedSigned) {
    1181             :         // Write barriers are only for stores of heap objects.
    1182             :         return kNoWriteBarrier;
    1183             :       }
    1184     4948738 :       if (field_type->Is(Type::BooleanOrNullOrUndefined()) ||
    1185             :           value_type->Is(Type::BooleanOrNullOrUndefined())) {
    1186             :         // Write barriers are not necessary when storing true, false, null or
    1187             :         // undefined, because these special oddballs are always in the root set.
    1188             :         return kNoWriteBarrier;
    1189             :       }
    1190     2122750 :       if (value_type->IsHeapConstant()) {
    1191             :         Heap::RootListIndex root_index;
    1192      993334 :         Heap* heap = jsgraph_->isolate()->heap();
    1193      993334 :         if (heap->IsRootHandle(value_type->AsHeapConstant()->Value(),
    1194             :                                &root_index)) {
    1195      610860 :           if (heap->RootIsImmortalImmovable(root_index)) {
    1196             :             // Write barriers are unnecessary for immortal immovable roots.
    1197             :             return kNoWriteBarrier;
    1198             :           }
    1199             :         }
    1200             :       }
    1201     3023780 :       if (field_representation == MachineRepresentation::kTaggedPointer ||
    1202     1511890 :           value_representation == MachineRepresentation::kTaggedPointer) {
    1203             :         // Write barriers for heap objects are cheaper.
    1204             :         return kPointerWriteBarrier;
    1205             :       }
    1206             :       NumberMatcher m(value);
    1207     1073478 :       if (m.HasValue()) {
    1208        1056 :         if (IsSmiDouble(m.Value())) {
    1209             :           // Storing a smi doesn't need a write barrier.
    1210             :           return kNoWriteBarrier;
    1211             :         }
    1212             :         // The NumberConstant will be represented as HeapNumber.
    1213        1056 :         return kPointerWriteBarrier;
    1214             :       }
    1215             :       return kFullWriteBarrier;
    1216             :     }
    1217             :     return kNoWriteBarrier;
    1218             :   }
    1219             : 
    1220             :   WriteBarrierKind WriteBarrierKindFor(
    1221             :       BaseTaggedness base_taggedness,
    1222             :       MachineRepresentation field_representation, int field_offset,
    1223             :       Type* field_type, MachineRepresentation value_representation,
    1224             :       Node* value) {
    1225     6816940 :     if (base_taggedness == kTaggedBase &&
    1226     3408470 :         field_offset == HeapObject::kMapOffset) {
    1227             :       return kMapWriteBarrier;
    1228             :     }
    1229             :     return WriteBarrierKindFor(base_taggedness, field_representation,
    1230     3072323 :                                field_type, value_representation, value);
    1231             :   }
    1232             : 
    1233      886720 :   Graph* graph() const { return jsgraph_->graph(); }
    1234             :   CommonOperatorBuilder* common() const { return jsgraph_->common(); }
    1235             :   SimplifiedOperatorBuilder* simplified() const {
    1236       16306 :     return jsgraph_->simplified();
    1237             :   }
    1238             : 
    1239        6120 :   void LowerToCheckedInt32Mul(Node* node, Truncation truncation,
    1240        6120 :                               Type* input0_type, Type* input1_type) {
    1241             :     // If one of the inputs is positive and/or truncation is being applied,
    1242             :     // there is no need to return -0.
    1243             :     CheckForMinusZeroMode mz_mode =
    1244        4764 :         truncation.IdentifiesZeroAndMinusZero() ||
    1245        1788 :                 (input0_type->Is(Type::OrderedNumber()) &&
    1246        6525 :                  input0_type->Min() > 0) ||
    1247        4456 :                 (input1_type->Is(Type::OrderedNumber()) &&
    1248        4456 :                  input1_type->Min() > 0)
    1249             :             ? CheckForMinusZeroMode::kDontCheckForMinusZero
    1250        6120 :             : CheckForMinusZeroMode::kCheckForMinusZero;
    1251             : 
    1252        6120 :     NodeProperties::ChangeOp(node, simplified()->CheckedInt32Mul(mz_mode));
    1253        6120 :   }
    1254             : 
    1255      165752 :   void ChangeToInt32OverflowOp(Node* node) {
    1256      165752 :     NodeProperties::ChangeOp(node, Int32OverflowOp(node));
    1257      165749 :   }
    1258             : 
    1259         105 :   void ChangeToUint32OverflowOp(Node* node) {
    1260         105 :     NodeProperties::ChangeOp(node, Uint32OverflowOp(node));
    1261         105 :   }
    1262             : 
    1263     2168090 :   void VisitSpeculativeIntegerAdditiveOp(Node* node, Truncation truncation,
    1264     1111226 :                                          SimplifiedLowering* lowering) {
    1265             :     Type* left_upper = GetUpperBound(node->InputAt(0));
    1266             :     Type* right_upper = GetUpperBound(node->InputAt(1));
    1267             :     // Only eliminate eliminate the node if the ToNumber conversion cannot
    1268             :     // cause any observable side-effect and if we know for sure that it
    1269             :     // is a number addition (we must exclude strings).
    1270     1555409 :     if (left_upper->Is(Type::NumberOrOddball()) &&
    1271             :         right_upper->Is(Type::NumberOrOddball())) {
    1272      635330 :       if (truncation.IsUnused()) return VisitUnused(node);
    1273             :     }
    1274             : 
    1275     2116212 :     if (left_upper->Is(type_cache_.kAdditiveSafeIntegerOrMinusZero) &&
    1276      382333 :         right_upper->Is(type_cache_.kAdditiveSafeIntegerOrMinusZero)) {
    1277             :       // If we know how to interpret the result or if the users only care
    1278             :       // about the low 32-bits, we can truncate to Word32 do a wrapping
    1279             :       // addition.
    1280      479277 :       if (GetUpperBound(node)->Is(Type::Signed32()) ||
    1281      479277 :           GetUpperBound(node)->Is(Type::Unsigned32()) ||
    1282             :           truncation.IsUsedAsWord32()) {
    1283             :         // => Int32Add/Sub
    1284      278485 :         VisitWord32TruncatingBinop(node);
    1285      343684 :         if (lower()) ChangeToPureOp(node, Int32Op(node));
    1286             :         return;
    1287             :       }
    1288             :     }
    1289             : 
    1290             :     // Try to use type feedback.
    1291      588484 :     NumberOperationHint hint = NumberOperationHintOf(node->op());
    1292             : 
    1293             :     DCHECK(hint == NumberOperationHint::kSignedSmall ||
    1294             :            hint == NumberOperationHint::kSigned32);
    1295             : 
    1296             :     Type* left_feedback_type = TypeOf(node->InputAt(0));
    1297             :     Type* right_feedback_type = TypeOf(node->InputAt(1));
    1298             :     // Handle the case when no int32 checks on inputs are necessary (but
    1299             :     // an overflow check is needed on the output). Note that we do not
    1300             :     // have to do any check if at most one side can be minus zero.
    1301      689867 :     if (left_upper->Is(Type::Signed32OrMinusZero()) &&
    1302      684659 :         right_upper->Is(Type::Signed32OrMinusZero()) &&
    1303           0 :         (left_upper->Is(Type::Signed32()) ||
    1304             :          right_upper->Is(Type::Signed32()))) {
    1305             :       VisitBinop(node, UseInfo::TruncatingWord32(),
    1306             :                  MachineRepresentation::kWord32, Type::Signed32());
    1307             :     } else {
    1308             :       // If the output's truncation is identify-zeros, we can pass it
    1309             :       // along. Moreover, if the operation is addition and we know the
    1310             :       // right-hand side is not minus zero, we do not have to distinguish
    1311             :       // between 0 and -0.
    1312      492505 :       IdentifyZeros left_identify_zeros = truncation.identify_zeros();
    1313      929473 :       if (node->opcode() == IrOpcode::kSpeculativeSafeIntegerAdd &&
    1314      436902 :           !right_feedback_type->Maybe(Type::MinusZero())) {
    1315             :         left_identify_zeros = kIdentifyZeros;
    1316             :       }
    1317             :       UseInfo left_use =
    1318      492571 :           CheckedUseInfoAsWord32FromHint(hint, left_identify_zeros);
    1319             :       // For CheckedInt32Add and CheckedInt32Sub, we don't need to do
    1320             :       // a minus zero check for the right hand side, since we already
    1321             :       // know that the left hand side is a proper Signed32 value,
    1322             :       // potentially guarded by a check.
    1323      492571 :       UseInfo right_use = CheckedUseInfoAsWord32FromHint(hint, kIdentifyZeros);
    1324             :       VisitBinop(node, left_use, right_use, MachineRepresentation::kWord32,
    1325      492564 :                  Type::Signed32());
    1326             :     }
    1327      588685 :     if (lower()) {
    1328      343196 :       if (truncation.IsUsedAsWord32() ||
    1329             :           !CanOverflowSigned32(node->op(), left_feedback_type,
    1330      171170 :                                right_feedback_type, graph_zone())) {
    1331        7687 :         ChangeToPureOp(node, Int32Op(node));
    1332             : 
    1333             :       } else {
    1334      164339 :         ChangeToInt32OverflowOp(node);
    1335             :       }
    1336             :     }
    1337             :     return;
    1338             :   }
    1339             : 
    1340        6210 :   void VisitSpeculativeAdditiveOp(Node* node, Truncation truncation,
    1341        7731 :                                   SimplifiedLowering* lowering) {
    1342             :     // ToNumber(x) can throw if x is either a Receiver or a Symbol, so we can
    1343             :     // only eliminate an unused speculative number operation if we know that
    1344             :     // the inputs are PlainPrimitive, which excludes everything that's might
    1345             :     // have side effects or throws during a ToNumber conversion. We are only
    1346             :     // allowed to perform a number addition if neither input is a String, even
    1347             :     // if the value is never used, so we further limit to NumberOrOddball in
    1348             :     // order to explicitly exclude String inputs.
    1349        6210 :     if (BothInputsAre(node, Type::NumberOrOddball())) {
    1350         487 :       if (truncation.IsUnused()) return VisitUnused(node);
    1351             :     }
    1352             : 
    1353       12366 :     if (BothInputsAre(node, type_cache_.kAdditiveSafeIntegerOrMinusZero) &&
    1354          42 :         (GetUpperBound(node)->Is(Type::Signed32()) ||
    1355          42 :          GetUpperBound(node)->Is(Type::Unsigned32()) ||
    1356             :          truncation.IsUsedAsWord32())) {
    1357             :       // => Int32Add/Sub
    1358           0 :       VisitWord32TruncatingBinop(node);
    1359           0 :       if (lower()) ChangeToPureOp(node, Int32Op(node));
    1360             :       return;
    1361             :     }
    1362             : 
    1363             :     // default case => Float64Add/Sub
    1364             :     VisitBinop(node, UseInfo::CheckedNumberOrOddballAsFloat64(),
    1365             :                MachineRepresentation::kFloat64, Type::Number());
    1366        6162 :     if (lower()) {
    1367        1569 :       ChangeToPureOp(node, Float64Op(node));
    1368             :     }
    1369             :     return;
    1370             :   }
    1371             : 
    1372       20024 :   void VisitSpeculativeNumberModulus(Node* node, Truncation truncation,
    1373       13418 :                                      SimplifiedLowering* lowering) {
    1374             :     // ToNumber(x) can throw if x is either a Receiver or a Symbol, so we
    1375             :     // can only eliminate an unused speculative number operation if we know
    1376             :     // that the inputs are PlainPrimitive, which excludes everything that's
    1377             :     // might have side effects or throws during a ToNumber conversion.
    1378       13405 :     if (BothInputsAre(node, Type::PlainPrimitive())) {
    1379        8738 :       if (truncation.IsUnused()) return VisitUnused(node);
    1380             :     }
    1381       27148 :     if (BothInputsAre(node, Type::Unsigned32OrMinusZeroOrNaN()) &&
    1382         168 :         (truncation.IsUsedAsWord32() ||
    1383             :          NodeProperties::GetType(node)->Is(Type::Unsigned32()))) {
    1384             :       // => unsigned Uint32Mod
    1385         574 :       VisitWord32TruncatingBinop(node);
    1386         574 :       if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
    1387             :       return;
    1388             :     }
    1389       32828 :     if (BothInputsAre(node, Type::Signed32OrMinusZeroOrNaN()) &&
    1390        1533 :         (truncation.IsUsedAsWord32() ||
    1391             :          NodeProperties::GetType(node)->Is(Type::Signed32()))) {
    1392             :       // => signed Int32Mod
    1393        6019 :       VisitWord32TruncatingBinop(node);
    1394        6019 :       if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
    1395             :       return;
    1396             :     }
    1397             : 
    1398             :     // Try to use type feedback.
    1399        6619 :     NumberOperationHint hint = NumberOperationHintOf(node->op());
    1400             : 
    1401             :     // Handle the case when no uint32 checks on inputs are necessary
    1402             :     // (but an overflow check is needed on the output).
    1403        6619 :     if (BothInputsAreUnsigned32(node)) {
    1404         300 :       if (hint == NumberOperationHint::kSignedSmall ||
    1405         150 :           hint == NumberOperationHint::kSigned32) {
    1406             :         VisitBinop(node, UseInfo::TruncatingWord32(),
    1407             :                    MachineRepresentation::kWord32, Type::Unsigned32());
    1408         150 :         if (lower()) ChangeToUint32OverflowOp(node);
    1409             :         return;
    1410             :       }
    1411             :     }
    1412             : 
    1413             :     // Handle the case when no int32 checks on inputs are necessary
    1414             :     // (but an overflow check is needed on the output).
    1415        6469 :     if (BothInputsAre(node, Type::Signed32())) {
    1416             :       // If both the inputs the feedback are int32, use the overflow op.
    1417        2766 :       if (hint == NumberOperationHint::kSignedSmall ||
    1418        1383 :           hint == NumberOperationHint::kSigned32) {
    1419             :         VisitBinop(node, UseInfo::TruncatingWord32(),
    1420             :                    MachineRepresentation::kWord32, Type::Signed32());
    1421        1383 :         if (lower()) ChangeToInt32OverflowOp(node);
    1422             :         return;
    1423             :       }
    1424             :     }
    1425             : 
    1426       10172 :     if (hint == NumberOperationHint::kSignedSmall ||
    1427        5086 :         hint == NumberOperationHint::kSigned32) {
    1428             :       // If the result is truncated, we only need to check the inputs.
    1429        4267 :       if (truncation.IsUsedAsWord32()) {
    1430             :         VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
    1431         934 :                    MachineRepresentation::kWord32);
    1432         934 :         if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
    1433        3333 :       } else if (BothInputsAre(node, Type::Unsigned32OrMinusZeroOrNaN())) {
    1434             :         VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
    1435           0 :                    MachineRepresentation::kWord32, Type::Unsigned32());
    1436           0 :         if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
    1437             :       } else {
    1438             :         VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
    1439        3333 :                    MachineRepresentation::kWord32, Type::Signed32());
    1440        3333 :         if (lower()) ChangeToInt32OverflowOp(node);
    1441             :       }
    1442             :       return;
    1443             :     }
    1444             : 
    1445         891 :     if (TypeOf(node->InputAt(0))->Is(Type::Unsigned32()) &&
    1446         819 :         TypeOf(node->InputAt(1))->Is(Type::Unsigned32()) &&
    1447           0 :         (truncation.IsUsedAsWord32() ||
    1448             :          NodeProperties::GetType(node)->Is(Type::Unsigned32()))) {
    1449             :       // We can only promise Float64 truncation here, as the decision is
    1450             :       // based on the feedback types of the inputs.
    1451             :       VisitBinop(node,
    1452             :                  UseInfo(MachineRepresentation::kWord32, Truncation::Float64()),
    1453             :                  MachineRepresentation::kWord32, Type::Number());
    1454           0 :       if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
    1455             :       return;
    1456             :     }
    1457         971 :     if (TypeOf(node->InputAt(0))->Is(Type::Signed32()) &&
    1458         833 :         TypeOf(node->InputAt(1))->Is(Type::Signed32()) &&
    1459           0 :         (truncation.IsUsedAsWord32() ||
    1460             :          NodeProperties::GetType(node)->Is(Type::Signed32()))) {
    1461             :       // We can only promise Float64 truncation here, as the decision is
    1462             :       // based on the feedback types of the inputs.
    1463             :       VisitBinop(node,
    1464             :                  UseInfo(MachineRepresentation::kWord32, Truncation::Float64()),
    1465             :                  MachineRepresentation::kWord32, Type::Number());
    1466          14 :       if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
    1467             :       return;
    1468             :     }
    1469             :     // default case => Float64Mod
    1470             :     VisitBinop(node, UseInfo::CheckedNumberOrOddballAsFloat64(),
    1471             :                MachineRepresentation::kFloat64, Type::Number());
    1472        1011 :     if (lower()) ChangeToPureOp(node, Float64Op(node));
    1473             :     return;
    1474             :   }
    1475             : 
    1476             :   // Dispatching routine for visiting the node {node} with the usage {use}.
    1477             :   // Depending on the operator, propagate new usage info to the inputs.
    1478    91513966 :   void VisitNode(Node* node, Truncation truncation,
    1479     7080692 :                  SimplifiedLowering* lowering) {
    1480             :     // Unconditionally eliminate unused pure nodes (only relevant if there's
    1481             :     // a pure operation in between two effectful ones, where the last one
    1482             :     // is unused).
    1483             :     // Note: We must not do this for constants, as they are cached and we
    1484             :     // would thus kill the cached {node} during lowering (i.e. replace all
    1485             :     // uses with Dead), but at that point some node lowering might have
    1486             :     // already taken the constant {node} from the cache (while it was in
    1487             :     // a sane state still) and we would afterwards replace that use with
    1488             :     // Dead as well.
    1489   238148725 :     if (node->op()->ValueInputCount() > 0 &&
    1490             :         node->op()->HasProperty(Operator::kPure)) {
    1491    34855979 :       if (truncation.IsUnused()) return VisitUnused(node);
    1492             :     }
    1493    91104643 :     switch (node->opcode()) {
    1494             :       //------------------------------------------------------------------
    1495             :       // Common operators.
    1496             :       //------------------------------------------------------------------
    1497             :       case IrOpcode::kStart:
    1498             :         // We use Start as a terminator for the frame state chain, so even
    1499             :         // tho Start doesn't really produce a value, we have to say Tagged
    1500             :         // here, otherwise the input conversion will fail.
    1501             :         return VisitLeaf(node, MachineRepresentation::kTagged);
    1502             :       case IrOpcode::kParameter:
    1503             :         // TODO(titzer): use representation from linkage.
    1504     6125176 :         return VisitUnop(node, UseInfo::None(), MachineRepresentation::kTagged);
    1505             :       case IrOpcode::kInt32Constant:
    1506             :         return VisitLeaf(node, MachineRepresentation::kWord32);
    1507             :       case IrOpcode::kInt64Constant:
    1508             :         return VisitLeaf(node, MachineRepresentation::kWord64);
    1509             :       case IrOpcode::kExternalConstant:
    1510             :         return VisitLeaf(node, MachineType::PointerRepresentation());
    1511             :       case IrOpcode::kNumberConstant:
    1512             :         return VisitLeaf(node, MachineRepresentation::kTagged);
    1513             :       case IrOpcode::kHeapConstant:
    1514             :         return VisitLeaf(node, MachineRepresentation::kTaggedPointer);
    1515             :       case IrOpcode::kPointerConstant: {
    1516             :         VisitLeaf(node, MachineType::PointerRepresentation());
    1517        2682 :         if (lower()) {
    1518         894 :           intptr_t const value = OpParameter<intptr_t>(node);
    1519         894 :           DeferReplacement(node, lowering->jsgraph()->IntPtrConstant(value));
    1520             :         }
    1521             :         return;
    1522             :       }
    1523             : 
    1524             :       case IrOpcode::kBranch: {
    1525             :         DCHECK(TypeOf(node->InputAt(0))->Is(Type::Boolean()));
    1526     1878014 :         ProcessInput(node, 0, UseInfo::Bool());
    1527     1877992 :         EnqueueInput(node, NodeProperties::FirstControlIndex(node));
    1528     1877999 :         return;
    1529             :       }
    1530             :       case IrOpcode::kSwitch:
    1531       20620 :         ProcessInput(node, 0, UseInfo::TruncatingWord32());
    1532       20620 :         EnqueueInput(node, NodeProperties::FirstControlIndex(node));
    1533       20620 :         return;
    1534             :       case IrOpcode::kSelect:
    1535       41311 :         return VisitSelect(node, truncation, lowering);
    1536             :       case IrOpcode::kPhi:
    1537     1734479 :         return VisitPhi(node, truncation, lowering);
    1538             :       case IrOpcode::kCall:
    1539     1039682 :         return VisitCall(node, lowering);
    1540             : 
    1541             :       //------------------------------------------------------------------
    1542             :       // JavaScript operators.
    1543             :       //------------------------------------------------------------------
    1544             :       case IrOpcode::kToBoolean: {
    1545      180046 :         if (truncation.IsUsedAsBool()) {
    1546      178300 :           ProcessInput(node, 0, UseInfo::Bool());
    1547             :           SetOutput(node, MachineRepresentation::kBit);
    1548      235594 :           if (lower()) DeferReplacement(node, node->InputAt(0));
    1549             :         } else {
    1550        1746 :           VisitInputs(node);
    1551             :           SetOutput(node, MachineRepresentation::kTaggedPointer);
    1552             :         }
    1553             :         return;
    1554             :       }
    1555             :       case IrOpcode::kJSToNumber: {
    1556       27199 :         VisitInputs(node);
    1557             :         // TODO(bmeurer): Optimize somewhat based on input type?
    1558       27199 :         if (truncation.IsUsedAsWord32()) {
    1559             :           SetOutput(node, MachineRepresentation::kWord32);
    1560         362 :           if (lower()) lowering->DoJSToNumberTruncatesToWord32(node, this);
    1561       26837 :         } else if (truncation.IsUsedAsFloat64()) {
    1562             :           SetOutput(node, MachineRepresentation::kFloat64);
    1563        4854 :           if (lower()) lowering->DoJSToNumberTruncatesToFloat64(node, this);
    1564             :         } else {
    1565             :           SetOutput(node, MachineRepresentation::kTagged);
    1566             :         }
    1567             :         return;
    1568             :       }
    1569             : 
    1570             :       //------------------------------------------------------------------
    1571             :       // Simplified operators.
    1572             :       //------------------------------------------------------------------
    1573             :       case IrOpcode::kBooleanNot: {
    1574       20337 :         if (lower()) {
    1575        6448 :           NodeInfo* input_info = GetInfo(node->InputAt(0));
    1576        6448 :           if (input_info->representation() == MachineRepresentation::kBit) {
    1577             :             // BooleanNot(x: kRepBit) => Word32Equal(x, #0)
    1578      574191 :             node->AppendInput(jsgraph_->zone(), jsgraph_->Int32Constant(0));
    1579        5872 :             NodeProperties::ChangeOp(node, lowering->machine()->Word32Equal());
    1580         576 :           } else if (CanBeTaggedPointer(input_info->representation())) {
    1581             :             // BooleanNot(x: kRepTagged) => WordEqual(x, #false)
    1582        1138 :             node->AppendInput(jsgraph_->zone(), jsgraph_->FalseConstant());
    1583         569 :             NodeProperties::ChangeOp(node, lowering->machine()->WordEqual());
    1584             :           } else {
    1585             :             DCHECK(!TypeOf(node->InputAt(0))->IsInhabited());
    1586           7 :             DeferReplacement(node, lowering->jsgraph()->Int32Constant(0));
    1587             :           }
    1588             :         } else {
    1589             :           // No input representation requirement; adapt during lowering.
    1590       13889 :           ProcessInput(node, 0, UseInfo::AnyTruncatingToBool());
    1591             :           SetOutput(node, MachineRepresentation::kBit);
    1592             :         }
    1593             :         return;
    1594             :       }
    1595             :       case IrOpcode::kNumberEqual: {
    1596             :         Type* const lhs_type = TypeOf(node->InputAt(0));
    1597             :         Type* const rhs_type = TypeOf(node->InputAt(1));
    1598             :         // Number comparisons reduce to integer comparisons for integer inputs.
    1599      276147 :         if ((lhs_type->Is(Type::Unsigned32()) &&
    1600      309329 :              rhs_type->Is(Type::Unsigned32())) ||
    1601         859 :             (lhs_type->Is(Type::Unsigned32OrMinusZeroOrNaN()) &&
    1602         500 :              rhs_type->Is(Type::Unsigned32OrMinusZeroOrNaN()) &&
    1603         500 :              OneInputCannotBe(node, type_cache_.kZeroish))) {
    1604             :           // => unsigned Int32Cmp
    1605             :           VisitBinop(node, UseInfo::TruncatingWord32(),
    1606             :                      MachineRepresentation::kBit);
    1607      104075 :           if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node));
    1608             :           return;
    1609             :         }
    1610      168432 :         if ((lhs_type->Is(Type::Signed32()) &&
    1611      174144 :              rhs_type->Is(Type::Signed32())) ||
    1612        1404 :             (lhs_type->Is(Type::Signed32OrMinusZeroOrNaN()) &&
    1613        1263 :              rhs_type->Is(Type::Signed32OrMinusZeroOrNaN()) &&
    1614        1263 :              OneInputCannotBe(node, type_cache_.kZeroish))) {
    1615             :           // => signed Int32Cmp
    1616             :           VisitBinop(node, UseInfo::TruncatingWord32(),
    1617             :                      MachineRepresentation::kBit);
    1618       71813 :           if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
    1619             :           return;
    1620             :         }
    1621             :         // => Float64Cmp
    1622             :         VisitBinop(node, UseInfo::TruncatingFloat64(),
    1623             :                    MachineRepresentation::kBit);
    1624       68463 :         if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
    1625             :         return;
    1626             :       }
    1627             :       case IrOpcode::kNumberLessThan:
    1628             :       case IrOpcode::kNumberLessThanOrEqual: {
    1629             :         // Number comparisons reduce to integer comparisons for integer inputs.
    1630      324852 :         if (TypeOf(node->InputAt(0))->Is(Type::Unsigned32()) &&
    1631             :             TypeOf(node->InputAt(1))->Is(Type::Unsigned32())) {
    1632             :           // => unsigned Int32Cmp
    1633             :           VisitBinop(node, UseInfo::TruncatingWord32(),
    1634             :                      MachineRepresentation::kBit);
    1635      141379 :           if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node));
    1636      112435 :         } else if (TypeOf(node->InputAt(0))->Is(Type::Signed32()) &&
    1637             :                    TypeOf(node->InputAt(1))->Is(Type::Signed32())) {
    1638             :           // => signed Int32Cmp
    1639             :           VisitBinop(node, UseInfo::TruncatingWord32(),
    1640             :                      MachineRepresentation::kBit);
    1641       17251 :           if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
    1642             :         } else {
    1643             :           // => Float64Cmp
    1644             :           VisitBinop(node, UseInfo::TruncatingFloat64(),
    1645             :                      MachineRepresentation::kBit);
    1646       60825 :           if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
    1647             :         }
    1648             :         return;
    1649             :       }
    1650             : 
    1651             :       case IrOpcode::kSpeculativeSafeIntegerAdd:
    1652             :       case IrOpcode::kSpeculativeSafeIntegerSubtract:
    1653      915928 :         return VisitSpeculativeIntegerAdditiveOp(node, truncation, lowering);
    1654             : 
    1655             :       case IrOpcode::kSpeculativeNumberAdd:
    1656             :       case IrOpcode::kSpeculativeNumberSubtract:
    1657        6210 :         return VisitSpeculativeAdditiveOp(node, truncation, lowering);
    1658             : 
    1659             :       case IrOpcode::kSpeculativeNumberLessThan:
    1660             :       case IrOpcode::kSpeculativeNumberLessThanOrEqual:
    1661             :       case IrOpcode::kSpeculativeNumberEqual: {
    1662             :         // ToNumber(x) can throw if x is either a Receiver or a Symbol, so we
    1663             :         // can only eliminate an unused speculative number operation if we know
    1664             :         // that the inputs are PlainPrimitive, which excludes everything that's
    1665             :         // might have side effects or throws during a ToNumber conversion.
    1666      424337 :         if (BothInputsAre(node, Type::PlainPrimitive())) {
    1667      317376 :           if (truncation.IsUnused()) return VisitUnused(node);
    1668             :         }
    1669             :         // Number comparisons reduce to integer comparisons for integer inputs.
    1670      657242 :         if (TypeOf(node->InputAt(0))->Is(Type::Unsigned32()) &&
    1671             :             TypeOf(node->InputAt(1))->Is(Type::Unsigned32())) {
    1672             :           // => unsigned Int32Cmp
    1673             :           VisitBinop(node, UseInfo::TruncatingWord32(),
    1674             :                      MachineRepresentation::kBit);
    1675       13063 :           if (lower()) ChangeToPureOp(node, Uint32Op(node));
    1676             :           return;
    1677      647750 :         } else if (TypeOf(node->InputAt(0))->Is(Type::Signed32()) &&
    1678             :                    TypeOf(node->InputAt(1))->Is(Type::Signed32())) {
    1679             :           // => signed Int32Cmp
    1680             :           VisitBinop(node, UseInfo::TruncatingWord32(),
    1681             :                      MachineRepresentation::kBit);
    1682      250757 :           if (lower()) ChangeToPureOp(node, Int32Op(node));
    1683             :           return;
    1684             :         }
    1685             :         // Try to use type feedback.
    1686      195671 :         NumberOperationHint hint = NumberOperationHintOf(node->op());
    1687      195670 :         switch (hint) {
    1688             :           case NumberOperationHint::kSigned32:
    1689             :           case NumberOperationHint::kSignedSmall:
    1690      157029 :             if (propagate()) {
    1691             :               VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
    1692      103055 :                          MachineRepresentation::kBit);
    1693       53974 :             } else if (retype()) {
    1694             :               SetOutput(node, MachineRepresentation::kBit, Type::Any());
    1695             :             } else {
    1696             :               DCHECK(lower());
    1697             :               Node* lhs = node->InputAt(0);
    1698             :               Node* rhs = node->InputAt(1);
    1699       38435 :               if (IsNodeRepresentationTagged(lhs) &&
    1700             :                   IsNodeRepresentationTagged(rhs)) {
    1701             :                 VisitBinop(node, UseInfo::CheckedSignedSmallAsTaggedSigned(),
    1702             :                            MachineRepresentation::kBit);
    1703             :                 ChangeToPureOp(
    1704       17287 :                     node, changer_->TaggedSignedOperatorFor(node->opcode()));
    1705             : 
    1706             :               } else {
    1707             :                 VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
    1708        2996 :                            MachineRepresentation::kBit);
    1709        2996 :                 ChangeToPureOp(node, Int32Op(node));
    1710             :               }
    1711             :             }
    1712             :             return;
    1713             :           case NumberOperationHint::kSignedSmallInputs:
    1714             :             // This doesn't make sense for compare operations.
    1715           0 :             UNREACHABLE();
    1716             :           case NumberOperationHint::kNumberOrOddball:
    1717             :             // Abstract and strict equality don't perform ToNumber conversions
    1718             :             // on Oddballs, so make sure we don't accidentially sneak in a
    1719             :             // hint with Oddball feedback here.
    1720             :             DCHECK_NE(IrOpcode::kSpeculativeNumberEqual, node->opcode());
    1721             :           // Fallthrough
    1722             :           case NumberOperationHint::kNumber:
    1723             :             VisitBinop(node, CheckedUseInfoAsFloat64FromHint(hint),
    1724       38641 :                        MachineRepresentation::kBit);
    1725       48553 :             if (lower()) ChangeToPureOp(node, Float64Op(node));
    1726             :             return;
    1727             :         }
    1728           0 :         UNREACHABLE();
    1729             :         return;
    1730             :       }
    1731             : 
    1732             :       case IrOpcode::kNumberAdd:
    1733             :       case IrOpcode::kNumberSubtract: {
    1734     1458108 :         if (BothInputsAre(node, type_cache_.kAdditiveSafeIntegerOrMinusZero) &&
    1735       44889 :             (GetUpperBound(node)->Is(Type::Signed32()) ||
    1736       44361 :              GetUpperBound(node)->Is(Type::Unsigned32()) ||
    1737             :              truncation.IsUsedAsWord32())) {
    1738             :           // => Int32Add/Sub
    1739       84977 :           VisitWord32TruncatingBinop(node);
    1740      109048 :           if (lower()) ChangeToPureOp(node, Int32Op(node));
    1741             :         } else {
    1742             :           // => Float64Add/Sub
    1743      580591 :           VisitFloat64Binop(node);
    1744      673914 :           if (lower()) ChangeToPureOp(node, Float64Op(node));
    1745             :         }
    1746             :         return;
    1747             :       }
    1748             :       case IrOpcode::kSpeculativeNumberMultiply: {
    1749             :         // ToNumber(x) can throw if x is either a Receiver or a Symbol, so we
    1750             :         // can only eliminate an unused speculative number operation if we know
    1751             :         // that the inputs are PlainPrimitive, which excludes everything that's
    1752             :         // might have side effects or throws during a ToNumber conversion.
    1753       42362 :         if (BothInputsAre(node, Type::PlainPrimitive())) {
    1754       18221 :           if (truncation.IsUnused()) return VisitUnused(node);
    1755             :         }
    1756       87598 :         if (BothInputsAre(node, Type::Integral32()) &&
    1757        3042 :             (NodeProperties::GetType(node)->Is(Type::Signed32()) ||
    1758        3042 :              NodeProperties::GetType(node)->Is(Type::Unsigned32()) ||
    1759         202 :              (truncation.IsUsedAsWord32() &&
    1760             :               NodeProperties::GetType(node)->Is(
    1761         202 :                   type_cache_.kSafeIntegerOrMinusZero)))) {
    1762             :           // Multiply reduces to Int32Mul if the inputs are integers, and
    1763             :           // (a) the output is either known to be Signed32, or
    1764             :           // (b) the output is known to be Unsigned32, or
    1765             :           // (c) the uses are truncating and the result is in the safe
    1766             :           //     integer range.
    1767        1252 :           VisitWord32TruncatingBinop(node);
    1768        1562 :           if (lower()) ChangeToPureOp(node, Int32Op(node));
    1769             :           return;
    1770             :         }
    1771             :         // Try to use type feedback.
    1772       40477 :         NumberOperationHint hint = NumberOperationHintOf(node->op());
    1773             :         Type* input0_type = TypeOf(node->InputAt(0));
    1774             :         Type* input1_type = TypeOf(node->InputAt(1));
    1775             : 
    1776             :         // Handle the case when no int32 checks on inputs are necessary
    1777             :         // (but an overflow check is needed on the output).
    1778       40477 :         if (BothInputsAre(node, Type::Signed32())) {
    1779             :           // If both the inputs the feedback are int32, use the overflow op.
    1780        5776 :           if (hint == NumberOperationHint::kSignedSmall ||
    1781        2888 :               hint == NumberOperationHint::kSigned32) {
    1782             :             VisitBinop(node, UseInfo::TruncatingWord32(),
    1783             :                        MachineRepresentation::kWord32, Type::Signed32());
    1784        2888 :             if (lower()) {
    1785             :               LowerToCheckedInt32Mul(node, truncation, input0_type,
    1786         933 :                                      input1_type);
    1787             :             }
    1788             :             return;
    1789             :           }
    1790             :         }
    1791             : 
    1792       75178 :         if (hint == NumberOperationHint::kSignedSmall ||
    1793       37589 :             hint == NumberOperationHint::kSigned32) {
    1794             :           VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
    1795       17467 :                      MachineRepresentation::kWord32, Type::Signed32());
    1796       17467 :           if (lower()) {
    1797        5187 :             LowerToCheckedInt32Mul(node, truncation, input0_type, input1_type);
    1798             :           }
    1799             :           return;
    1800             :         }
    1801             : 
    1802             :         // Checked float64 x float64 => float64
    1803             :         VisitBinop(node, UseInfo::CheckedNumberOrOddballAsFloat64(),
    1804             :                    MachineRepresentation::kFloat64, Type::Number());
    1805       25810 :         if (lower()) ChangeToPureOp(node, Float64Op(node));
    1806             :         return;
    1807             :       }
    1808             :       case IrOpcode::kNumberMultiply: {
    1809       63779 :         if (BothInputsAre(node, Type::Integral32()) &&
    1810        4221 :             (NodeProperties::GetType(node)->Is(Type::Signed32()) ||
    1811        4209 :              NodeProperties::GetType(node)->Is(Type::Unsigned32()) ||
    1812         429 :              (truncation.IsUsedAsWord32() &&
    1813             :               NodeProperties::GetType(node)->Is(
    1814         429 :                   type_cache_.kSafeIntegerOrMinusZero)))) {
    1815             :           // Multiply reduces to Int32Mul if the inputs are integers, and
    1816             :           // (a) the output is either known to be Signed32, or
    1817             :           // (b) the output is known to be Unsigned32, or
    1818             :           // (c) the uses are truncating and the result is in the safe
    1819             :           //     integer range.
    1820        1676 :           VisitWord32TruncatingBinop(node);
    1821        2044 :           if (lower()) ChangeToPureOp(node, Int32Op(node));
    1822             :           return;
    1823             :         }
    1824             :         // Number x Number => Float64Mul
    1825       27310 :         VisitFloat64Binop(node);
    1826       35239 :         if (lower()) ChangeToPureOp(node, Float64Op(node));
    1827             :         return;
    1828             :       }
    1829             :       case IrOpcode::kSpeculativeNumberDivide: {
    1830             :         // ToNumber(x) can throw if x is either a Receiver or a Symbol, so we
    1831             :         // can only eliminate an unused speculative number operation if we know
    1832             :         // that the inputs are PlainPrimitive, which excludes everything that's
    1833             :         // might have side effects or throws during a ToNumber conversion.
    1834       52238 :         if (BothInputsAre(node, Type::PlainPrimitive())) {
    1835       26898 :           if (truncation.IsUnused()) return VisitUnused(node);
    1836             :         }
    1837       56466 :         if (BothInputsAreUnsigned32(node) && truncation.IsUsedAsWord32()) {
    1838             :           // => unsigned Uint32Div
    1839          24 :           VisitWord32TruncatingBinop(node);
    1840          24 :           if (lower()) DeferReplacement(node, lowering->Uint32Div(node));
    1841             :           return;
    1842             :         }
    1843       50662 :         if (BothInputsAreSigned32(node)) {
    1844       13374 :           if (NodeProperties::GetType(node)->Is(Type::Signed32())) {
    1845             :             // => signed Int32Div
    1846           0 :             VisitWord32TruncatingBinop(node);
    1847           0 :             if (lower()) DeferReplacement(node, lowering->Int32Div(node));
    1848             :             return;
    1849             :           }
    1850       13374 :           if (truncation.IsUsedAsWord32()) {
    1851             :             // => signed Int32Div
    1852        6060 :             VisitWord32TruncatingBinop(node);
    1853        6060 :             if (lower()) DeferReplacement(node, lowering->Int32Div(node));
    1854             :             return;
    1855             :           }
    1856             :         }
    1857             : 
    1858             :         // Try to use type feedback.
    1859       44602 :         NumberOperationHint hint = NumberOperationHintOf(node->op());
    1860             : 
    1861             :         // Handle the case when no uint32 checks on inputs are necessary
    1862             :         // (but an overflow check is needed on the output).
    1863       44602 :         if (BothInputsAreUnsigned32(node)) {
    1864       11514 :           if (hint == NumberOperationHint::kSignedSmall ||
    1865        5757 :               hint == NumberOperationHint::kSigned32) {
    1866             :             VisitBinop(node, UseInfo::TruncatingWord32(),
    1867             :                        MachineRepresentation::kWord32, Type::Unsigned32());
    1868         263 :             if (lower()) ChangeToUint32OverflowOp(node);
    1869             :             return;
    1870             :           }
    1871             :         }
    1872             : 
    1873             :         // Handle the case when no int32 checks on inputs are necessary
    1874             :         // (but an overflow check is needed on the output).
    1875       44339 :         if (BothInputsAreSigned32(node)) {
    1876             :           // If both the inputs the feedback are int32, use the overflow op.
    1877       14102 :           if (hint == NumberOperationHint::kSignedSmall ||
    1878        7051 :               hint == NumberOperationHint::kSigned32) {
    1879             :             VisitBinop(node, UseInfo::TruncatingWord32(),
    1880             :                        MachineRepresentation::kWord32, Type::Signed32());
    1881           0 :             if (lower()) ChangeToInt32OverflowOp(node);
    1882             :             return;
    1883             :           }
    1884             :         }
    1885             : 
    1886       88678 :         if (hint == NumberOperationHint::kSigned32 ||
    1887       87760 :             hint == NumberOperationHint::kSignedSmall ||
    1888             :             hint == NumberOperationHint::kSignedSmallInputs) {
    1889             :           // If the result is truncated, we only need to check the inputs.
    1890       35601 :           if (truncation.IsUsedAsWord32()) {
    1891             :             VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
    1892        2731 :                        MachineRepresentation::kWord32);
    1893        2731 :             if (lower()) DeferReplacement(node, lowering->Int32Div(node));
    1894             :             return;
    1895       32870 :           } else if (hint != NumberOperationHint::kSignedSmallInputs) {
    1896             :             VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
    1897         798 :                        MachineRepresentation::kWord32, Type::Signed32());
    1898         798 :             if (lower()) ChangeToInt32OverflowOp(node);
    1899             :             return;
    1900             :           }
    1901             :         }
    1902             : 
    1903             :         // default case => Float64Div
    1904             :         VisitBinop(node, UseInfo::CheckedNumberOrOddballAsFloat64(),
    1905             :                    MachineRepresentation::kFloat64, Type::Number());
    1906       52268 :         if (lower()) ChangeToPureOp(node, Float64Op(node));
    1907             :         return;
    1908             :       }
    1909             :       case IrOpcode::kNumberDivide: {
    1910       22042 :         if (BothInputsAreUnsigned32(node) && truncation.IsUsedAsWord32()) {
    1911             :           // => unsigned Uint32Div
    1912         208 :           VisitWord32TruncatingBinop(node);
    1913         208 :           if (lower()) DeferReplacement(node, lowering->Uint32Div(node));
    1914             :           return;
    1915             :         }
    1916       20757 :         if (BothInputsAreSigned32(node)) {
    1917        3215 :           if (NodeProperties::GetType(node)->Is(Type::Signed32())) {
    1918             :             // => signed Int32Div
    1919           0 :             VisitWord32TruncatingBinop(node);
    1920           0 :             if (lower()) DeferReplacement(node, lowering->Int32Div(node));
    1921             :             return;
    1922             :           }
    1923        3215 :           if (truncation.IsUsedAsWord32()) {
    1924             :             // => signed Int32Div
    1925        1119 :             VisitWord32TruncatingBinop(node);
    1926        1119 :             if (lower()) DeferReplacement(node, lowering->Int32Div(node));
    1927             :             return;
    1928             :           }
    1929             :         }
    1930             :         // Number x Number => Float64Div
    1931       19638 :         VisitFloat64Binop(node);
    1932       24708 :         if (lower()) ChangeToPureOp(node, Float64Op(node));
    1933             :         return;
    1934             :       }
    1935             :       case IrOpcode::kSpeculativeNumberModulus:
    1936       13405 :         return VisitSpeculativeNumberModulus(node, truncation, lowering);
    1937             :       case IrOpcode::kNumberModulus: {
    1938       15596 :         if (BothInputsAre(node, Type::Unsigned32OrMinusZeroOrNaN()) &&
    1939         155 :             (truncation.IsUsedAsWord32() ||
    1940             :              NodeProperties::GetType(node)->Is(Type::Unsigned32()))) {
    1941             :           // => unsigned Uint32Mod
    1942         321 :           VisitWord32TruncatingBinop(node);
    1943         321 :           if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
    1944             :           return;
    1945             :         }
    1946       16589 :         if (BothInputsAre(node, Type::Signed32OrMinusZeroOrNaN()) &&
    1947         745 :             (truncation.IsUsedAsWord32() ||
    1948             :              NodeProperties::GetType(node)->Is(Type::Signed32()))) {
    1949             :           // => signed Int32Mod
    1950        1319 :           VisitWord32TruncatingBinop(node);
    1951        1319 :           if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
    1952             :           return;
    1953             :         }
    1954        6546 :         if (TypeOf(node->InputAt(0))->Is(Type::Unsigned32()) &&
    1955        6104 :             TypeOf(node->InputAt(1))->Is(Type::Unsigned32()) &&
    1956         120 :             (truncation.IsUsedAsWord32() ||
    1957             :              NodeProperties::GetType(node)->Is(Type::Unsigned32()))) {
    1958             :           // We can only promise Float64 truncation here, as the decision is
    1959             :           // based on the feedback types of the inputs.
    1960             :           VisitBinop(node, UseInfo(MachineRepresentation::kWord32,
    1961             :                                    Truncation::Float64()),
    1962             :                      MachineRepresentation::kWord32);
    1963          24 :           if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
    1964             :           return;
    1965             :         }
    1966        7757 :         if (TypeOf(node->InputAt(0))->Is(Type::Signed32()) &&
    1967        6674 :             TypeOf(node->InputAt(1))->Is(Type::Signed32()) &&
    1968         738 :             (truncation.IsUsedAsWord32() ||
    1969             :              NodeProperties::GetType(node)->Is(Type::Signed32()))) {
    1970             :           // We can only promise Float64 truncation here, as the decision is
    1971             :           // based on the feedback types of the inputs.
    1972             :           VisitBinop(node, UseInfo(MachineRepresentation::kWord32,
    1973             :                                    Truncation::Float64()),
    1974             :                      MachineRepresentation::kWord32);
    1975           0 :           if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
    1976             :           return;
    1977             :         }
    1978             :         // default case => Float64Mod
    1979        5936 :         VisitFloat64Binop(node);
    1980        7647 :         if (lower()) ChangeToPureOp(node, Float64Op(node));
    1981             :         return;
    1982             :       }
    1983             :       case IrOpcode::kNumberBitwiseOr:
    1984             :       case IrOpcode::kNumberBitwiseXor:
    1985             :       case IrOpcode::kNumberBitwiseAnd: {
    1986       28084 :         VisitWord32TruncatingBinop(node);
    1987       37237 :         if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
    1988             :         return;
    1989             :       }
    1990             :       case IrOpcode::kSpeculativeNumberBitwiseOr:
    1991             :       case IrOpcode::kSpeculativeNumberBitwiseXor:
    1992             :       case IrOpcode::kSpeculativeNumberBitwiseAnd:
    1993       86516 :         VisitSpeculativeInt32Binop(node);
    1994       86515 :         if (lower()) {
    1995       22746 :           ChangeToPureOp(node, Int32Op(node));
    1996             :         }
    1997             :         return;
    1998             :       case IrOpcode::kNumberShiftLeft: {
    1999             :         Type* rhs_type = GetUpperBound(node->InputAt(1));
    2000             :         VisitBinop(node, UseInfo::TruncatingWord32(),
    2001        5847 :                    UseInfo::TruncatingWord32(), MachineRepresentation::kWord32);
    2002        5847 :         if (lower()) {
    2003        1898 :           lowering->DoShift(node, lowering->machine()->Word32Shl(), rhs_type);
    2004             :         }
    2005             :         return;
    2006             :       }
    2007             :       case IrOpcode::kSpeculativeNumberShiftLeft: {
    2008             :         // ToNumber(x) can throw if x is either a Receiver or a Symbol, so we
    2009             :         // can only eliminate an unused speculative number operation if we know
    2010             :         // that the inputs are PlainPrimitive, which excludes everything that's
    2011             :         // might have side effects or throws during a ToNumber conversion.
    2012        9208 :         if (BothInputsAre(node, Type::PlainPrimitive())) {
    2013        8354 :           if (truncation.IsUnused()) return VisitUnused(node);
    2014             :         }
    2015        9122 :         if (BothInputsAre(node, Type::NumberOrOddball())) {
    2016             :           Type* rhs_type = GetUpperBound(node->InputAt(1));
    2017             :           VisitBinop(node, UseInfo::TruncatingWord32(),
    2018             :                      UseInfo::TruncatingWord32(),
    2019        8244 :                      MachineRepresentation::kWord32);
    2020        8244 :           if (lower()) {
    2021        1838 :             lowering->DoShift(node, lowering->machine()->Word32Shl(), rhs_type);
    2022             :           }
    2023             :           return;
    2024             :         }
    2025         878 :         NumberOperationHint hint = NumberOperationHintOf(node->op());
    2026             :         Type* rhs_type = GetUpperBound(node->InputAt(1));
    2027             :         VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
    2028         878 :                    MachineRepresentation::kWord32, Type::Signed32());
    2029         878 :         if (lower()) {
    2030         268 :           lowering->DoShift(node, lowering->machine()->Word32Shl(), rhs_type);
    2031             :         }
    2032             :         return;
    2033             :       }
    2034             :       case IrOpcode::kNumberShiftRight: {
    2035             :         Type* rhs_type = GetUpperBound(node->InputAt(1));
    2036             :         VisitBinop(node, UseInfo::TruncatingWord32(),
    2037        5731 :                    UseInfo::TruncatingWord32(), MachineRepresentation::kWord32);
    2038        5731 :         if (lower()) {
    2039        1805 :           lowering->DoShift(node, lowering->machine()->Word32Sar(), rhs_type);
    2040             :         }
    2041             :         return;
    2042             :       }
    2043             :       case IrOpcode::kSpeculativeNumberShiftRight: {
    2044             :         // ToNumber(x) can throw if x is either a Receiver or a Symbol, so we
    2045             :         // can only eliminate an unused speculative number operation if we know
    2046             :         // that the inputs are PlainPrimitive, which excludes everything that's
    2047             :         // might have side effects or throws during a ToNumber conversion.
    2048       25132 :         if (BothInputsAre(node, Type::PlainPrimitive())) {
    2049       23709 :           if (truncation.IsUnused()) return VisitUnused(node);
    2050             :         }
    2051       25042 :         if (BothInputsAre(node, Type::NumberOrOddball())) {
    2052             :           Type* rhs_type = GetUpperBound(node->InputAt(1));
    2053             :           VisitBinop(node, UseInfo::TruncatingWord32(),
    2054             :                      UseInfo::TruncatingWord32(),
    2055       23594 :                      MachineRepresentation::kWord32);
    2056       23593 :           if (lower()) {
    2057        5119 :             lowering->DoShift(node, lowering->machine()->Word32Sar(), rhs_type);
    2058             :           }
    2059             :           return;
    2060             :         }
    2061        1448 :         NumberOperationHint hint = NumberOperationHintOf(node->op());
    2062             :         Type* rhs_type = GetUpperBound(node->InputAt(1));
    2063             :         VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
    2064        1448 :                    MachineRepresentation::kWord32, Type::Signed32());
    2065        1448 :         if (lower()) {
    2066         420 :           lowering->DoShift(node, lowering->machine()->Word32Sar(), rhs_type);
    2067             :         }
    2068             :         return;
    2069             :       }
    2070             :       case IrOpcode::kNumberShiftRightLogical: {
    2071             :         Type* rhs_type = GetUpperBound(node->InputAt(1));
    2072             :         VisitBinop(node, UseInfo::TruncatingWord32(),
    2073        4830 :                    UseInfo::TruncatingWord32(), MachineRepresentation::kWord32);
    2074        4830 :         if (lower()) {
    2075        1597 :           lowering->DoShift(node, lowering->machine()->Word32Shr(), rhs_type);
    2076             :         }
    2077             :         return;
    2078             :       }
    2079             :       case IrOpcode::kSpeculativeNumberShiftRightLogical: {
    2080             :         // ToNumber(x) can throw if x is either a Receiver or a Symbol, so we
    2081             :         // can only eliminate an unused speculative number operation if we know
    2082             :         // that the inputs are PlainPrimitive, which excludes everything that's
    2083             :         // might have side effects or throws during a ToNumber conversion.
    2084        7466 :         if (BothInputsAre(node, Type::PlainPrimitive())) {
    2085        5455 :           if (truncation.IsUnused()) return VisitUnused(node);
    2086             :         }
    2087        7014 :         NumberOperationHint hint = NumberOperationHintOf(node->op());
    2088             :         Type* rhs_type = GetUpperBound(node->InputAt(1));
    2089       17480 :         if (rhs_type->Is(type_cache_.kZeroish) &&
    2090        6904 :             (hint == NumberOperationHint::kSignedSmall ||
    2091       10997 :              hint == NumberOperationHint::kSigned32) &&
    2092             :             !truncation.IsUsedAsWord32()) {
    2093             :           // The SignedSmall or Signed32 feedback means that the results that we
    2094             :           // have seen so far were of type Unsigned31.  We speculate that this
    2095             :           // will continue to hold.  Moreover, since the RHS is 0, the result
    2096             :           // will just be the (converted) LHS.
    2097             :           VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
    2098         283 :                      MachineRepresentation::kWord32, Type::Unsigned31());
    2099         283 :           if (lower()) {
    2100          78 :             node->RemoveInput(1);
    2101             :             NodeProperties::ChangeOp(node,
    2102          78 :                                      simplified()->CheckedUint32ToInt32());
    2103             :           }
    2104             :           return;
    2105             :         }
    2106        6731 :         if (BothInputsAre(node, Type::NumberOrOddball())) {
    2107             :           VisitBinop(node, UseInfo::TruncatingWord32(),
    2108             :                      UseInfo::TruncatingWord32(),
    2109        4853 :                      MachineRepresentation::kWord32);
    2110        4853 :           if (lower()) {
    2111        1382 :             lowering->DoShift(node, lowering->machine()->Word32Shr(), rhs_type);
    2112             :           }
    2113             :           return;
    2114             :         }
    2115             :         VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
    2116        1878 :                    MachineRepresentation::kWord32, Type::Unsigned32());
    2117        1878 :         if (lower()) {
    2118         540 :           lowering->DoShift(node, lowering->machine()->Word32Shr(), rhs_type);
    2119             :         }
    2120             :         return;
    2121             :       }
    2122             :       case IrOpcode::kNumberAbs: {
    2123         351 :         if (TypeOf(node->InputAt(0))->Is(Type::Unsigned32())) {
    2124             :           VisitUnop(node, UseInfo::TruncatingWord32(),
    2125          21 :                     MachineRepresentation::kWord32);
    2126          28 :           if (lower()) DeferReplacement(node, node->InputAt(0));
    2127         330 :         } else if (TypeOf(node->InputAt(0))->Is(Type::Signed32())) {
    2128             :           VisitUnop(node, UseInfo::TruncatingWord32(),
    2129         115 :                     MachineRepresentation::kWord32);
    2130         115 :           if (lower()) DeferReplacement(node, lowering->Int32Abs(node));
    2131         215 :         } else if (TypeOf(node->InputAt(0))
    2132         215 :                        ->Is(type_cache_.kPositiveIntegerOrMinusZeroOrNaN)) {
    2133             :           VisitUnop(node, UseInfo::TruncatingFloat64(),
    2134           0 :                     MachineRepresentation::kFloat64);
    2135           0 :           if (lower()) DeferReplacement(node, node->InputAt(0));
    2136             :         } else {
    2137             :           VisitUnop(node, UseInfo::TruncatingFloat64(),
    2138         215 :                     MachineRepresentation::kFloat64);
    2139         283 :           if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
    2140             :         }
    2141             :         return;
    2142             :       }
    2143             :       case IrOpcode::kNumberClz32: {
    2144             :         VisitUnop(node, UseInfo::TruncatingWord32(),
    2145          42 :                   MachineRepresentation::kWord32);
    2146          56 :         if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node));
    2147             :         return;
    2148             :       }
    2149             :       case IrOpcode::kNumberImul: {
    2150             :         VisitBinop(node, UseInfo::TruncatingWord32(),
    2151          90 :                    UseInfo::TruncatingWord32(), MachineRepresentation::kWord32);
    2152         120 :         if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node));
    2153             :         return;
    2154             :       }
    2155             :       case IrOpcode::kNumberFround: {
    2156             :         VisitUnop(node, UseInfo::TruncatingFloat64(),
    2157        2376 :                   MachineRepresentation::kFloat32);
    2158        3132 :         if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
    2159             :         return;
    2160             :       }
    2161             :       case IrOpcode::kNumberMax: {
    2162             :         // It is safe to use the feedback types for left and right hand side
    2163             :         // here, since we can only narrow those types and thus we can only
    2164             :         // promise a more specific truncation.
    2165             :         Type* const lhs_type = TypeOf(node->InputAt(0));
    2166             :         Type* const rhs_type = TypeOf(node->InputAt(1));
    2167        1206 :         if (lhs_type->Is(Type::Unsigned32()) &&
    2168             :             rhs_type->Is(Type::Unsigned32())) {
    2169          39 :           VisitWord32TruncatingBinop(node);
    2170          39 :           if (lower()) {
    2171             :             lowering->DoMax(node, lowering->machine()->Uint32LessThan(),
    2172          13 :                             MachineRepresentation::kWord32);
    2173             :           }
    2174        1298 :         } else if (lhs_type->Is(Type::Signed32()) &&
    2175             :                    rhs_type->Is(Type::Signed32())) {
    2176         213 :           VisitWord32TruncatingBinop(node);
    2177         213 :           if (lower()) {
    2178             :             lowering->DoMax(node, lowering->machine()->Int32LessThan(),
    2179          74 :                             MachineRepresentation::kWord32);
    2180             :           }
    2181        1008 :         } else if (lhs_type->Is(Type::PlainNumber()) &&
    2182             :                    rhs_type->Is(Type::PlainNumber())) {
    2183         456 :           VisitFloat64Binop(node);
    2184         456 :           if (lower()) {
    2185             :             lowering->DoMax(node, lowering->machine()->Float64LessThan(),
    2186         149 :                             MachineRepresentation::kFloat64);
    2187             :           }
    2188             :         } else {
    2189          60 :           VisitFloat64Binop(node);
    2190          80 :           if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
    2191             :         }
    2192             :         return;
    2193             :       }
    2194             :       case IrOpcode::kNumberMin: {
    2195             :         // It is safe to use the feedback types for left and right hand side
    2196             :         // here, since we can only narrow those types and thus we can only
    2197             :         // promise a more specific truncation.
    2198             :         Type* const lhs_type = TypeOf(node->InputAt(0));
    2199             :         Type* const rhs_type = TypeOf(node->InputAt(1));
    2200        1014 :         if (lhs_type->Is(Type::Unsigned32()) &&
    2201             :             rhs_type->Is(Type::Unsigned32())) {
    2202          21 :           VisitWord32TruncatingBinop(node);
    2203          21 :           if (lower()) {
    2204             :             lowering->DoMin(node, lowering->machine()->Uint32LessThan(),
    2205           7 :                             MachineRepresentation::kWord32);
    2206             :           }
    2207        1182 :         } else if (lhs_type->Is(Type::Signed32()) &&
    2208             :                    rhs_type->Is(Type::Signed32())) {
    2209         210 :           VisitWord32TruncatingBinop(node);
    2210         210 :           if (lower()) {
    2211             :             lowering->DoMin(node, lowering->machine()->Int32LessThan(),
    2212          70 :                             MachineRepresentation::kWord32);
    2213             :           }
    2214         819 :         } else if (lhs_type->Is(Type::PlainNumber()) &&
    2215             :                    rhs_type->Is(Type::PlainNumber())) {
    2216         123 :           VisitFloat64Binop(node);
    2217         123 :           if (lower()) {
    2218             :             lowering->DoMin(node, lowering->machine()->Float64LessThan(),
    2219          41 :                             MachineRepresentation::kFloat64);
    2220             :           }
    2221             :         } else {
    2222         537 :           VisitFloat64Binop(node);
    2223         716 :           if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
    2224             :         }
    2225             :         return;
    2226             :       }
    2227             :       case IrOpcode::kNumberAtan2:
    2228             :       case IrOpcode::kNumberPow: {
    2229             :         VisitBinop(node, UseInfo::TruncatingFloat64(),
    2230             :                    MachineRepresentation::kFloat64);
    2231        3978 :         if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
    2232             :         return;
    2233             :       }
    2234             :       case IrOpcode::kNumberAcos:
    2235             :       case IrOpcode::kNumberAcosh:
    2236             :       case IrOpcode::kNumberAsin:
    2237             :       case IrOpcode::kNumberAsinh:
    2238             :       case IrOpcode::kNumberAtan:
    2239             :       case IrOpcode::kNumberAtanh:
    2240             :       case IrOpcode::kNumberCeil:
    2241             :       case IrOpcode::kNumberCos:
    2242             :       case IrOpcode::kNumberCosh:
    2243             :       case IrOpcode::kNumberExp:
    2244             :       case IrOpcode::kNumberExpm1:
    2245             :       case IrOpcode::kNumberFloor:
    2246             :       case IrOpcode::kNumberLog:
    2247             :       case IrOpcode::kNumberLog1p:
    2248             :       case IrOpcode::kNumberLog2:
    2249             :       case IrOpcode::kNumberLog10:
    2250             :       case IrOpcode::kNumberCbrt:
    2251             :       case IrOpcode::kNumberSin:
    2252             :       case IrOpcode::kNumberSinh:
    2253             :       case IrOpcode::kNumberTan:
    2254             :       case IrOpcode::kNumberTanh:
    2255             :       case IrOpcode::kNumberTrunc: {
    2256             :         VisitUnop(node, UseInfo::TruncatingFloat64(),
    2257       51476 :                   MachineRepresentation::kFloat64);
    2258       68065 :         if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
    2259             :         return;
    2260             :       }
    2261             :       case IrOpcode::kNumberRound: {
    2262             :         VisitUnop(node, UseInfo::TruncatingFloat64(),
    2263         246 :                   MachineRepresentation::kFloat64);
    2264         246 :         if (lower()) DeferReplacement(node, lowering->Float64Round(node));
    2265             :         return;
    2266             :       }
    2267             :       case IrOpcode::kNumberSign: {
    2268          63 :         if (InputIs(node, Type::Signed32())) {
    2269             :           VisitUnop(node, UseInfo::TruncatingWord32(),
    2270          21 :                     MachineRepresentation::kWord32);
    2271          21 :           if (lower()) DeferReplacement(node, lowering->Int32Sign(node));
    2272             :         } else {
    2273             :           VisitUnop(node, UseInfo::TruncatingFloat64(),
    2274          42 :                     MachineRepresentation::kFloat64);
    2275          42 :           if (lower()) DeferReplacement(node, lowering->Float64Sign(node));
    2276             :         }
    2277             :         return;
    2278             :       }
    2279             :       case IrOpcode::kNumberSqrt: {
    2280             :         VisitUnop(node, UseInfo::TruncatingFloat64(),
    2281         135 :                   MachineRepresentation::kFloat64);
    2282         180 :         if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
    2283             :         return;
    2284             :       }
    2285             :       case IrOpcode::kNumberToBoolean: {
    2286             :         Type* const input_type = TypeOf(node->InputAt(0));
    2287         898 :         if (input_type->Is(Type::Integral32())) {
    2288             :           VisitUnop(node, UseInfo::TruncatingWord32(),
    2289         287 :                     MachineRepresentation::kBit);
    2290         287 :           if (lower()) lowering->DoIntegral32ToBit(node);
    2291         611 :         } else if (input_type->Is(Type::OrderedNumber())) {
    2292             :           VisitUnop(node, UseInfo::TruncatingFloat64(),
    2293           0 :                     MachineRepresentation::kBit);
    2294           0 :           if (lower()) lowering->DoOrderedNumberToBit(node);
    2295             :         } else {
    2296             :           VisitUnop(node, UseInfo::TruncatingFloat64(),
    2297         611 :                     MachineRepresentation::kBit);
    2298         611 :           if (lower()) lowering->DoNumberToBit(node);
    2299             :         }
    2300             :         return;
    2301             :       }
    2302             :       case IrOpcode::kNumberToInt32: {
    2303             :         // Just change representation if necessary.
    2304             :         VisitUnop(node, UseInfo::TruncatingWord32(),
    2305       21261 :                   MachineRepresentation::kWord32);
    2306       28000 :         if (lower()) DeferReplacement(node, node->InputAt(0));
    2307             :         return;
    2308             :       }
    2309             :       case IrOpcode::kNumberToUint32: {
    2310             :         // Just change representation if necessary.
    2311             :         VisitUnop(node, UseInfo::TruncatingWord32(),
    2312       16241 :                   MachineRepresentation::kWord32);
    2313       21420 :         if (lower()) DeferReplacement(node, node->InputAt(0));
    2314             :         return;
    2315             :       }
    2316             :       case IrOpcode::kNumberToUint8Clamped: {
    2317             :         Type* const input_type = TypeOf(node->InputAt(0));
    2318        4512 :         if (input_type->Is(type_cache_.kUint8OrMinusZeroOrNaN)) {
    2319             :           VisitUnop(node, UseInfo::TruncatingWord32(),
    2320          51 :                     MachineRepresentation::kWord32);
    2321          68 :           if (lower()) DeferReplacement(node, node->InputAt(0));
    2322        2205 :         } else if (input_type->Is(Type::Unsigned32OrMinusZeroOrNaN())) {
    2323             :           VisitUnop(node, UseInfo::TruncatingWord32(),
    2324         582 :                     MachineRepresentation::kWord32);
    2325         582 :           if (lower()) lowering->DoUnsigned32ToUint8Clamped(node);
    2326        1623 :         } else if (input_type->Is(Type::Signed32OrMinusZeroOrNaN())) {
    2327             :           VisitUnop(node, UseInfo::TruncatingWord32(),
    2328         555 :                     MachineRepresentation::kWord32);
    2329         555 :           if (lower()) lowering->DoSigned32ToUint8Clamped(node);
    2330        2136 :         } else if (input_type->Is(type_cache_.kIntegerOrMinusZeroOrNaN)) {
    2331             :           VisitUnop(node, UseInfo::TruncatingFloat64(),
    2332          72 :                     MachineRepresentation::kFloat64);
    2333          72 :           if (lower()) lowering->DoIntegerToUint8Clamped(node);
    2334             :         } else {
    2335             :           VisitUnop(node, UseInfo::TruncatingFloat64(),
    2336         996 :                     MachineRepresentation::kFloat64);
    2337         996 :           if (lower()) lowering->DoNumberToUint8Clamped(node);
    2338             :         }
    2339             :         return;
    2340             :       }
    2341             :       case IrOpcode::kReferenceEqual: {
    2342             :         VisitBinop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
    2343      552082 :         if (lower()) {
    2344      181093 :           NodeProperties::ChangeOp(node, lowering->machine()->WordEqual());
    2345             :         }
    2346             :         return;
    2347             :       }
    2348             :       case IrOpcode::kClassOf:
    2349             :       case IrOpcode::kTypeOf: {
    2350             :         return VisitUnop(node, UseInfo::AnyTagged(),
    2351       66573 :                          MachineRepresentation::kTaggedPointer);
    2352             :       }
    2353             :       case IrOpcode::kStringEqual:
    2354             :       case IrOpcode::kStringLessThan:
    2355             :       case IrOpcode::kStringLessThanOrEqual: {
    2356             :         return VisitBinop(node, UseInfo::AnyTagged(),
    2357             :                           MachineRepresentation::kTaggedPointer);
    2358             :       }
    2359             :       case IrOpcode::kStringCharAt: {
    2360             :         VisitBinop(node, UseInfo::AnyTagged(), UseInfo::TruncatingWord32(),
    2361        1090 :                    MachineRepresentation::kTaggedPointer);
    2362        1090 :         return;
    2363             :       }
    2364             :       case IrOpcode::kStringCharCodeAt: {
    2365             :         Type* string_type = TypeOf(node->InputAt(0));
    2366        1905 :         if (string_type->Is(Type::SeqString())) {
    2367             :           VisitBinop(node, UseInfo::AnyTagged(), UseInfo::TruncatingWord32(),
    2368        1366 :                      MachineRepresentation::kWord32);
    2369        1366 :           if (lower()) {
    2370         415 :             NodeProperties::ChangeOp(node, simplified()->SeqStringCharCodeAt());
    2371             :           }
    2372             :         } else {
    2373             :           // TODO(turbofan): Allow builtins to return untagged values.
    2374             :           VisitBinop(node, UseInfo::AnyTagged(), UseInfo::TruncatingWord32(),
    2375         539 :                      MachineRepresentation::kTaggedSigned);
    2376             :         }
    2377             :         return;
    2378             :       }
    2379             :       case IrOpcode::kStringFromCharCode: {
    2380             :         VisitUnop(node, UseInfo::TruncatingWord32(),
    2381         717 :                   MachineRepresentation::kTaggedPointer);
    2382         717 :         return;
    2383             :       }
    2384             :       case IrOpcode::kStringFromCodePoint: {
    2385             :         VisitUnop(node, UseInfo::TruncatingWord32(),
    2386         143 :                   MachineRepresentation::kTaggedPointer);
    2387         143 :         return;
    2388             :       }
    2389             :       case IrOpcode::kStringIndexOf: {
    2390         593 :         ProcessInput(node, 0, UseInfo::AnyTagged());
    2391         593 :         ProcessInput(node, 1, UseInfo::AnyTagged());
    2392         593 :         ProcessInput(node, 2, UseInfo::TaggedSigned());
    2393             :         SetOutput(node, MachineRepresentation::kTaggedSigned);
    2394             :         return;
    2395             :       }
    2396             :       case IrOpcode::kStringToLowerCaseIntl:
    2397             :       case IrOpcode::kStringToUpperCaseIntl: {
    2398             :         VisitUnop(node, UseInfo::AnyTagged(),
    2399           0 :                   MachineRepresentation::kTaggedPointer);
    2400           0 :         return;
    2401             :       }
    2402             :       case IrOpcode::kCheckBounds: {
    2403             :         Type* index_type = TypeOf(node->InputAt(0));
    2404             :         Type* length_type = TypeOf(node->InputAt(1));
    2405      119579 :         if (index_type->Is(Type::Integral32OrMinusZero())) {
    2406             :           // Map -0 to 0, and the values in the [-2^31,-1] range to the
    2407             :           // [2^31,2^32-1] range, which will be considered out-of-bounds
    2408             :           // as well, because the {length_type} is limited to Unsigned31.
    2409             :           VisitBinop(node, UseInfo::TruncatingWord32(),
    2410             :                      MachineRepresentation::kWord32);
    2411       96102 :           if (lower()) {
    2412       50098 :             if (index_type->Min() >= 0.0 &&
    2413       22978 :                 index_type->Max() < length_type->Min()) {
    2414             :               // The bounds check is redundant if we already know that
    2415             :               // the index is within the bounds of [0.0, length[.
    2416        3774 :               DeferReplacement(node, node->InputAt(0));
    2417             :             }
    2418             :           }
    2419             :         } else {
    2420             :           VisitBinop(node, UseInfo::CheckedSigned32AsWord32(kIdentifyZeros),
    2421             :                      UseInfo::TruncatingWord32(),
    2422       23477 :                      MachineRepresentation::kWord32);
    2423             :         }
    2424             :         return;
    2425             :       }
    2426             :       case IrOpcode::kCheckHeapObject: {
    2427       78748 :         if (InputCannotBe(node, Type::SignedSmall())) {
    2428             :           VisitUnop(node, UseInfo::AnyTagged(),
    2429          75 :                     MachineRepresentation::kTaggedPointer);
    2430             :         } else {
    2431             :           VisitUnop(node, UseInfo::CheckedHeapObjectAsTaggedPointer(),
    2432       78673 :                     MachineRepresentation::kTaggedPointer);
    2433             :         }
    2434      103573 :         if (lower()) DeferReplacement(node, node->InputAt(0));
    2435             :         return;
    2436             :       }
    2437             :       case IrOpcode::kCheckIf: {
    2438       92079 :         ProcessInput(node, 0, UseInfo::Bool());
    2439       92079 :         ProcessRemainingInputs(node, 1);
    2440             :         SetOutput(node, MachineRepresentation::kNone);
    2441             :         return;
    2442             :       }
    2443             :       case IrOpcode::kCheckInternalizedString: {
    2444        7099 :         VisitCheck(node, Type::InternalizedString(), lowering);
    2445        7099 :         return;
    2446             :       }
    2447             :       case IrOpcode::kCheckNumber: {
    2448             :         Type* const input_type = TypeOf(node->InputAt(0));
    2449        1270 :         if (input_type->Is(Type::Number())) {
    2450          44 :           VisitNoop(node, truncation);
    2451             :         } else {
    2452        1226 :           VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged);
    2453             :         }
    2454             :         return;
    2455             :       }
    2456             :       case IrOpcode::kCheckReceiver: {
    2457        3263 :         VisitCheck(node, Type::Receiver(), lowering);
    2458        3263 :         return;
    2459             :       }
    2460             :       case IrOpcode::kCheckSmi: {
    2461      140794 :         if (SmiValuesAre32Bits() && truncation.IsUsedAsWord32()) {
    2462             :           VisitUnop(node,
    2463             :                     UseInfo::CheckedSignedSmallAsWord32(kDistinguishZeros),
    2464       28936 :                     MachineRepresentation::kWord32);
    2465             :         } else {
    2466             :           VisitUnop(node, UseInfo::CheckedSignedSmallAsTaggedSigned(),
    2467      111858 :                     MachineRepresentation::kTaggedSigned);
    2468             :         }
    2469      183901 :         if (lower()) DeferReplacement(node, node->InputAt(0));
    2470             :         return;
    2471             :       }
    2472             :       case IrOpcode::kCheckString: {
    2473        6723 :         VisitCheck(node, Type::String(), lowering);
    2474        6723 :         return;
    2475             :       }
    2476             :       case IrOpcode::kCheckSymbol: {
    2477           0 :         VisitCheck(node, Type::Symbol(), lowering);
    2478           0 :         return;
    2479             :       }
    2480             :       case IrOpcode::kCheckSeqString: {
    2481        3442 :         if (InputIs(node, Type::SeqString())) {
    2482             :           VisitUnop(node, UseInfo::AnyTagged(),
    2483           0 :                     MachineRepresentation::kTaggedPointer);
    2484           0 :           if (lower()) DeferReplacement(node, node->InputAt(0));
    2485             :         } else {
    2486             :           VisitUnop(node, UseInfo::CheckedHeapObjectAsTaggedPointer(),
    2487        3442 :                     MachineRepresentation::kTaggedPointer);
    2488             :         }
    2489             :         return;
    2490             :       }
    2491             : 
    2492             :       case IrOpcode::kAllocate: {
    2493      284340 :         ProcessInput(node, 0, UseInfo::TruncatingWord32());
    2494      284340 :         ProcessRemainingInputs(node, 1);
    2495             :         SetOutput(node, MachineRepresentation::kTaggedPointer);
    2496             :         return;
    2497             :       }
    2498             :       case IrOpcode::kLoadFieldByIndex: {
    2499        8441 :         if (truncation.IsUnused()) return VisitUnused(node);
    2500             :         VisitBinop(node, UseInfo::AnyTagged(), UseInfo::TruncatingWord32(),
    2501        8200 :                    MachineRepresentation::kTagged);
    2502        8200 :         return;
    2503             :       }
    2504             :       case IrOpcode::kLoadField: {
    2505     3393391 :         if (truncation.IsUnused()) return VisitUnused(node);
    2506     3186164 :         FieldAccess access = FieldAccessOf(node->op());
    2507             :         MachineRepresentation const representation =
    2508             :             access.machine_type.representation();
    2509     3186165 :         VisitUnop(node, UseInfoForBasePointer(access), representation);
    2510     3186164 :         return;
    2511             :       }
    2512             :       case IrOpcode::kStoreField: {
    2513     3408470 :         FieldAccess access = FieldAccessOf(node->op());
    2514             :         Node* value_node = node->InputAt(1);
    2515     3408470 :         NodeInfo* input_info = GetInfo(value_node);
    2516             :         MachineRepresentation field_representation =
    2517     3408470 :             access.machine_type.representation();
    2518             : 
    2519             :         // Make sure we convert to Smi if possible. This should help write
    2520             :         // barrier elimination.
    2521     5979053 :         if (field_representation == MachineRepresentation::kTagged &&
    2522             :             TypeOf(value_node)->Is(Type::SignedSmall())) {
    2523             :           field_representation = MachineRepresentation::kTaggedSigned;
    2524             :         }
    2525             :         WriteBarrierKind write_barrier_kind = WriteBarrierKindFor(
    2526             :             access.base_is_tagged, field_representation, access.offset,
    2527     3408470 :             access.type, input_info->representation(), value_node);
    2528             : 
    2529     3408470 :         ProcessInput(node, 0, UseInfoForBasePointer(access));
    2530             :         ProcessInput(node, 1,
    2531     3408469 :                      TruncatingUseInfoFromRepresentation(field_representation));
    2532     3408469 :         ProcessRemainingInputs(node, 2);
    2533             :         SetOutput(node, MachineRepresentation::kNone);
    2534     3408469 :         if (lower()) {
    2535     1130099 :           if (write_barrier_kind < access.write_barrier_kind) {
    2536      533810 :             access.write_barrier_kind = write_barrier_kind;
    2537             :             NodeProperties::ChangeOp(
    2538     1067620 :                 node, jsgraph_->simplified()->StoreField(access));
    2539             :           }
    2540             :         }
    2541             :         return;
    2542             :       }
    2543             :       case IrOpcode::kLoadElement: {
    2544       71860 :         if (truncation.IsUnused()) return VisitUnused(node);
    2545       70150 :         ElementAccess access = ElementAccessOf(node->op());
    2546             :         VisitBinop(node, UseInfoForBasePointer(access),
    2547             :                    UseInfo::TruncatingWord32(),
    2548       70150 :                    access.machine_type.representation());
    2549       70150 :         return;
    2550             :       }
    2551             :       case IrOpcode::kStoreElement: {
    2552      130497 :         ElementAccess access = ElementAccessOf(node->op());
    2553             :         Node* value_node = node->InputAt(2);
    2554      130497 :         NodeInfo* input_info = GetInfo(value_node);
    2555             :         MachineRepresentation element_representation =
    2556      130497 :             access.machine_type.representation();
    2557             : 
    2558             :         // Make sure we convert to Smi if possible. This should help write
    2559             :         // barrier elimination.
    2560      221945 :         if (element_representation == MachineRepresentation::kTagged &&
    2561             :             TypeOf(value_node)->Is(Type::SignedSmall())) {
    2562             :           element_representation = MachineRepresentation::kTaggedSigned;
    2563             :         }
    2564             :         WriteBarrierKind write_barrier_kind = WriteBarrierKindFor(
    2565             :             access.base_is_tagged, element_representation, access.type,
    2566      130497 :             input_info->representation(), value_node);
    2567      130497 :         ProcessInput(node, 0, UseInfoForBasePointer(access));  // base
    2568      130497 :         ProcessInput(node, 1, UseInfo::TruncatingWord32());    // index
    2569             :         ProcessInput(node, 2,
    2570             :                      TruncatingUseInfoFromRepresentation(
    2571      130497 :                          element_representation));  // value
    2572      130497 :         ProcessRemainingInputs(node, 3);
    2573             :         SetOutput(node, MachineRepresentation::kNone);
    2574      130497 :         if (lower()) {
    2575       41189 :           if (write_barrier_kind < access.write_barrier_kind) {
    2576       28562 :             access.write_barrier_kind = write_barrier_kind;
    2577             :             NodeProperties::ChangeOp(
    2578       57124 :                 node, jsgraph_->simplified()->StoreElement(access));
    2579             :           }
    2580             :         }
    2581             :         return;
    2582             :       }
    2583             :       case IrOpcode::kTransitionAndStoreElement: {
    2584             :         Type* value_type = TypeOf(node->InputAt(2));
    2585             : 
    2586         597 :         ProcessInput(node, 0, UseInfo::AnyTagged());         // array
    2587         597 :         ProcessInput(node, 1, UseInfo::TruncatingWord32());  // index
    2588             : 
    2589         597 :         if (value_type->Is(Type::SignedSmall())) {
    2590         206 :           ProcessInput(node, 2, UseInfo::TruncatingWord32());  // value
    2591         206 :           if (lower()) {
    2592             :             NodeProperties::ChangeOp(node,
    2593          61 :                                      simplified()->StoreSignedSmallElement());
    2594             :           }
    2595         391 :         } else if (value_type->Is(Type::Number())) {
    2596          73 :           ProcessInput(node, 2, UseInfo::TruncatingFloat64());  // value
    2597          73 :           if (lower()) {
    2598          20 :             Handle<Map> double_map = DoubleMapParameterOf(node->op());
    2599             :             NodeProperties::ChangeOp(
    2600             :                 node,
    2601          20 :                 simplified()->TransitionAndStoreNumberElement(double_map));
    2602             :           }
    2603         318 :         } else if (value_type->Is(Type::NonNumber())) {
    2604          24 :           ProcessInput(node, 2, UseInfo::AnyTagged());  // value
    2605          24 :           if (lower()) {
    2606           6 :             Handle<Map> fast_map = FastMapParameterOf(node->op());
    2607             :             NodeProperties::ChangeOp(
    2608             :                 node, simplified()->TransitionAndStoreNonNumberElement(
    2609           6 :                           fast_map, value_type));
    2610             :           }
    2611             :         } else {
    2612         294 :           ProcessInput(node, 2, UseInfo::AnyTagged());  // value
    2613             :         }
    2614             : 
    2615         597 :         ProcessRemainingInputs(node, 3);
    2616             :         SetOutput(node, MachineRepresentation::kNone);
    2617             :         return;
    2618             :       }
    2619             :       case IrOpcode::kLoadTypedElement: {
    2620             :         MachineRepresentation const rep =
    2621       22215 :             MachineRepresentationFromArrayType(ExternalArrayTypeOf(node->op()));
    2622       22215 :         ProcessInput(node, 0, UseInfo::AnyTagged());         // buffer
    2623       22215 :         ProcessInput(node, 1, UseInfo::AnyTagged());         // base pointer
    2624       22215 :         ProcessInput(node, 2, UseInfo::PointerInt());        // external pointer
    2625       22215 :         ProcessInput(node, 3, UseInfo::TruncatingWord32());  // index
    2626       22215 :         ProcessRemainingInputs(node, 4);
    2627             :         SetOutput(node, rep);
    2628             :         return;
    2629             :       }
    2630             :       case IrOpcode::kStoreTypedElement: {
    2631             :         MachineRepresentation const rep =
    2632       22343 :             MachineRepresentationFromArrayType(ExternalArrayTypeOf(node->op()));
    2633       22343 :         ProcessInput(node, 0, UseInfo::AnyTagged());         // buffer
    2634       22343 :         ProcessInput(node, 1, UseInfo::AnyTagged());         // base pointer
    2635       22343 :         ProcessInput(node, 2, UseInfo::PointerInt());        // external pointer
    2636       22343 :         ProcessInput(node, 3, UseInfo::TruncatingWord32());  // index
    2637             :         ProcessInput(node, 4,
    2638       22343 :                      TruncatingUseInfoFromRepresentation(rep));  // value
    2639       22343 :         ProcessRemainingInputs(node, 5);
    2640             :         SetOutput(node, MachineRepresentation::kNone);
    2641             :         return;
    2642             :       }
    2643             :       case IrOpcode::kPlainPrimitiveToNumber: {
    2644       31958 :         if (InputIs(node, Type::Boolean())) {
    2645         214 :           VisitUnop(node, UseInfo::Bool(), MachineRepresentation::kWord32);
    2646         278 :           if (lower()) DeferReplacement(node, node->InputAt(0));
    2647       31744 :         } else if (InputIs(node, Type::String())) {
    2648         579 :           VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged);
    2649         579 :           if (lower()) {
    2650         183 :             NodeProperties::ChangeOp(node, simplified()->StringToNumber());
    2651             :           }
    2652       31165 :         } else if (truncation.IsUsedAsWord32()) {
    2653         681 :           if (InputIs(node, Type::NumberOrOddball())) {
    2654             :             VisitUnop(node, UseInfo::TruncatingWord32(),
    2655          38 :                       MachineRepresentation::kWord32);
    2656          50 :             if (lower()) DeferReplacement(node, node->InputAt(0));
    2657             :           } else {
    2658             :             VisitUnop(node, UseInfo::AnyTagged(),
    2659         643 :                       MachineRepresentation::kWord32);
    2660         643 :             if (lower()) {
    2661             :               NodeProperties::ChangeOp(node,
    2662         200 :                                        simplified()->PlainPrimitiveToWord32());
    2663             :             }
    2664             :           }
    2665       30484 :         } else if (truncation.IsUsedAsFloat64()) {
    2666       30352 :           if (InputIs(node, Type::NumberOrOddball())) {
    2667             :             VisitUnop(node, UseInfo::TruncatingFloat64(),
    2668        1630 :                       MachineRepresentation::kFloat64);
    2669        2071 :             if (lower()) DeferReplacement(node, node->InputAt(0));
    2670             :           } else {
    2671             :             VisitUnop(node, UseInfo::AnyTagged(),
    2672       28722 :                       MachineRepresentation::kFloat64);
    2673       28722 :             if (lower()) {
    2674             :               NodeProperties::ChangeOp(node,
    2675        9223 :                                        simplified()->PlainPrimitiveToFloat64());
    2676             :             }
    2677             :           }
    2678             :         } else {
    2679         132 :           VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged);
    2680             :         }
    2681             :         return;
    2682             :       }
    2683             :       case IrOpcode::kSpeculativeToNumber: {
    2684       26122 :         NumberOperationHint const hint = NumberOperationHintOf(node->op());
    2685       26122 :         switch (hint) {
    2686             :           case NumberOperationHint::kSigned32:
    2687             :           case NumberOperationHint::kSignedSmall:
    2688             :           case NumberOperationHint::kSignedSmallInputs:
    2689             :             VisitUnop(node, CheckedUseInfoAsWord32FromHint(hint),
    2690        7432 :                       MachineRepresentation::kWord32, Type::Signed32());
    2691        7432 :             break;
    2692             :           case NumberOperationHint::kNumber:
    2693             :           case NumberOperationHint::kNumberOrOddball:
    2694             :             VisitUnop(node, CheckedUseInfoAsFloat64FromHint(hint),
    2695       18690 :                       MachineRepresentation::kFloat64);
    2696       18690 :             break;
    2697             :         }
    2698       34287 :         if (lower()) DeferReplacement(node, node->InputAt(0));
    2699             :         return;
    2700             :       }
    2701             :       case IrOpcode::kObjectIsArrayBufferView: {
    2702             :         // TODO(turbofan): Introduce a Type::ArrayBufferView?
    2703           0 :         VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
    2704           0 :         return;
    2705             :       }
    2706             :       case IrOpcode::kObjectIsCallable: {
    2707          54 :         VisitObjectIs(node, Type::Callable(), lowering);
    2708          54 :         return;
    2709             :       }
    2710             :       case IrOpcode::kObjectIsConstructor: {
    2711             :         // TODO(turbofan): Introduce a Type::Constructor?
    2712         480 :         VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
    2713         480 :         return;
    2714             :       }
    2715             :       case IrOpcode::kObjectIsDetectableCallable: {
    2716       35551 :         VisitObjectIs(node, Type::DetectableCallable(), lowering);
    2717       35551 :         return;
    2718             :       }
    2719             :       case IrOpcode::kObjectIsMinusZero: {
    2720             :         Type* const input_type = GetUpperBound(node->InputAt(0));
    2721          84 :         if (input_type->Is(Type::MinusZero())) {
    2722           0 :           VisitUnop(node, UseInfo::None(), MachineRepresentation::kBit);
    2723           0 :           if (lower()) {
    2724           0 :             DeferReplacement(node, lowering->jsgraph()->Int32Constant(1));
    2725             :           }
    2726          84 :         } else if (!input_type->Maybe(Type::MinusZero())) {
    2727           0 :           VisitUnop(node, UseInfo::Any(), MachineRepresentation::kBit);
    2728           0 :           if (lower()) {
    2729           0 :             DeferReplacement(node, lowering->jsgraph()->Int32Constant(0));
    2730             :           }
    2731          84 :         } else if (input_type->Is(Type::Number())) {
    2732             :           VisitUnop(node, UseInfo::TruncatingFloat64(),
    2733          42 :                     MachineRepresentation::kBit);
    2734          42 :           if (lower()) {
    2735             :             // ObjectIsMinusZero(x:kRepFloat64)
    2736             :             //   => Float64Equal(Float64Div(1.0,x),-Infinity)
    2737             :             Node* const input = node->InputAt(0);
    2738             :             node->ReplaceInput(
    2739             :                 0, jsgraph_->graph()->NewNode(
    2740             :                        lowering->machine()->Float64Div(),
    2741          42 :                        lowering->jsgraph()->Float64Constant(1.0), input));
    2742             :             node->AppendInput(jsgraph_->zone(),
    2743             :                               jsgraph_->Float64Constant(
    2744          28 :                                   -std::numeric_limits<double>::infinity()));
    2745          14 :             NodeProperties::ChangeOp(node, lowering->machine()->Float64Equal());
    2746             :           }
    2747             :         } else {
    2748          42 :           VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
    2749             :         }
    2750             :         return;
    2751             :       }
    2752             :       case IrOpcode::kObjectIsNaN: {
    2753             :         Type* const input_type = GetUpperBound(node->InputAt(0));
    2754        1827 :         if (input_type->Is(Type::NaN())) {
    2755           0 :           VisitUnop(node, UseInfo::None(), MachineRepresentation::kBit);
    2756           0 :           if (lower()) {
    2757           0 :             DeferReplacement(node, lowering->jsgraph()->Int32Constant(1));
    2758             :           }
    2759        1827 :         } else if (!input_type->Maybe(Type::NaN())) {
    2760          42 :           VisitUnop(node, UseInfo::Any(), MachineRepresentation::kBit);
    2761          42 :           if (lower()) {
    2762          14 :             DeferReplacement(node, lowering->jsgraph()->Int32Constant(0));
    2763             :           }
    2764        1785 :         } else if (input_type->Is(Type::Number())) {
    2765             :           VisitUnop(node, UseInfo::TruncatingFloat64(),
    2766         183 :                     MachineRepresentation::kBit);
    2767         183 :           if (lower()) {
    2768             :             // ObjectIsNaN(x:kRepFloat64) => Word32Equal(Float64Equal(x,x),#0)
    2769             :             Node* const input = node->InputAt(0);
    2770             :             node->ReplaceInput(
    2771             :                 0, jsgraph_->graph()->NewNode(
    2772         122 :                        lowering->machine()->Float64Equal(), input, input));
    2773         122 :             node->AppendInput(jsgraph_->zone(), jsgraph_->Int32Constant(0));
    2774          61 :             NodeProperties::ChangeOp(node, lowering->machine()->Word32Equal());
    2775             :           }
    2776             :         } else {
    2777        1602 :           VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
    2778             :         }
    2779             :         return;
    2780             :       }
    2781             :       case IrOpcode::kObjectIsNonCallable: {
    2782       16539 :         VisitObjectIs(node, Type::NonCallable(), lowering);
    2783       16539 :         return;
    2784             :       }
    2785             :       case IrOpcode::kObjectIsNumber: {
    2786       24145 :         VisitObjectIs(node, Type::Number(), lowering);
    2787       24145 :         return;
    2788             :       }
    2789             :       case IrOpcode::kObjectIsReceiver: {
    2790       60384 :         VisitObjectIs(node, Type::Receiver(), lowering);
    2791       60384 :         return;
    2792             :       }
    2793             :       case IrOpcode::kObjectIsSmi: {
    2794             :         // TODO(turbofan): Optimize based on input representation.
    2795       11083 :         VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
    2796       11083 :         return;
    2797             :       }
    2798             :       case IrOpcode::kObjectIsString: {
    2799        7440 :         VisitObjectIs(node, Type::String(), lowering);
    2800        7440 :         return;
    2801             :       }
    2802             :       case IrOpcode::kObjectIsSymbol: {
    2803         404 :         VisitObjectIs(node, Type::Symbol(), lowering);
    2804         404 :         return;
    2805             :       }
    2806             :       case IrOpcode::kObjectIsUndetectable: {
    2807       17030 :         VisitObjectIs(node, Type::Undetectable(), lowering);
    2808       17030 :         return;
    2809             :       }
    2810             :       case IrOpcode::kArgumentsFrame: {
    2811             :         SetOutput(node, MachineType::PointerRepresentation());
    2812             :         return;
    2813             :       }
    2814             :       case IrOpcode::kArgumentsLength: {
    2815             :         VisitUnop(node, UseInfo::PointerInt(),
    2816       47969 :                   MachineRepresentation::kTaggedSigned);
    2817       47969 :         return;
    2818             :       }
    2819             :       case IrOpcode::kNewDoubleElements:
    2820             :       case IrOpcode::kNewSmiOrObjectElements: {
    2821             :         VisitUnop(node, UseInfo::TruncatingWord32(),
    2822        1129 :                   MachineRepresentation::kTaggedPointer);
    2823        1129 :         return;
    2824             :       }
    2825             :       case IrOpcode::kNewArgumentsElements: {
    2826             :         VisitBinop(node, UseInfo::PointerInt(), UseInfo::TaggedSigned(),
    2827       54419 :                    MachineRepresentation::kTaggedPointer);
    2828       54419 :         return;
    2829             :       }
    2830             :       case IrOpcode::kArrayBufferWasNeutered: {
    2831        1777 :         VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
    2832        1777 :         return;
    2833             :       }
    2834             :       case IrOpcode::kCheckFloat64Hole: {
    2835             :         Type* const input_type = TypeOf(node->InputAt(0));
    2836        2448 :         if (input_type->Is(Type::Number())) {
    2837         216 :           VisitNoop(node, truncation);
    2838             :         } else {
    2839        2232 :           CheckFloat64HoleMode mode = CheckFloat64HoleModeOf(node->op());
    2840        2232 :           switch (mode) {
    2841             :             case CheckFloat64HoleMode::kAllowReturnHole:
    2842        2041 :               if (truncation.IsUnused()) return VisitUnused(node);
    2843        1929 :               if (truncation.IsUsedAsFloat64()) {
    2844             :                 VisitUnop(node, UseInfo::TruncatingFloat64(),
    2845         192 :                           MachineRepresentation::kFloat64);
    2846         256 :                 if (lower()) DeferReplacement(node, node->InputAt(0));
    2847             :               } else {
    2848             :                 VisitUnop(
    2849             :                     node,
    2850             :                     UseInfo(MachineRepresentation::kFloat64, Truncation::Any()),
    2851        1737 :                     MachineRepresentation::kFloat64, Type::Number());
    2852             :               }
    2853             :               break;
    2854             :             case CheckFloat64HoleMode::kNeverReturnHole:
    2855             :               VisitUnop(
    2856             :                   node,
    2857             :                   UseInfo(MachineRepresentation::kFloat64, Truncation::Any()),
    2858         191 :                   MachineRepresentation::kFloat64, Type::Number());
    2859         191 :               break;
    2860             :           }
    2861             :         }
    2862             :         return;
    2863             :       }
    2864             :       case IrOpcode::kCheckNotTaggedHole: {
    2865        4329 :         VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged);
    2866        4329 :         return;
    2867             :       }
    2868             :       case IrOpcode::kConvertTaggedHoleToUndefined: {
    2869        7449 :         if (InputIs(node, Type::NumberOrOddball()) &&
    2870             :             truncation.IsUsedAsWord32()) {
    2871             :           // Propagate the Word32 truncation.
    2872             :           VisitUnop(node, UseInfo::TruncatingWord32(),
    2873         672 :                     MachineRepresentation::kWord32);
    2874         842 :           if (lower()) DeferReplacement(node, node->InputAt(0));
    2875        6105 :         } else if (InputIs(node, Type::NumberOrOddball()) &&
    2876             :                    truncation.IsUsedAsFloat64()) {
    2877             :           // Propagate the Float64 truncation.
    2878             :           VisitUnop(node, UseInfo::TruncatingFloat64(),
    2879          75 :                     MachineRepresentation::kFloat64);
    2880         100 :           if (lower()) DeferReplacement(node, node->InputAt(0));
    2881        4602 :         } else if (InputIs(node, Type::NonInternal())) {
    2882         177 :           VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged);
    2883         236 :           if (lower()) DeferReplacement(node, node->InputAt(0));
    2884             :         } else {
    2885             :           // TODO(turbofan): Add a (Tagged) truncation that identifies hole
    2886             :           // and undefined, i.e. for a[i] === obj cases.
    2887        4425 :           VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged);
    2888             :         }
    2889             :         return;
    2890             :       }
    2891             :       case IrOpcode::kCheckEqualsSymbol:
    2892             :       case IrOpcode::kCheckEqualsInternalizedString:
    2893             :         return VisitBinop(node, UseInfo::AnyTagged(),
    2894             :                           MachineRepresentation::kNone);
    2895             :       case IrOpcode::kMapGuard:
    2896             :         // Eliminate MapGuard nodes here.
    2897       26554 :         return VisitUnused(node);
    2898             :       case IrOpcode::kCheckMaps:
    2899             :       case IrOpcode::kTransitionElementsKind: {
    2900      165093 :         VisitInputs(node);
    2901             :         return SetOutput(node, MachineRepresentation::kNone);
    2902             :       }
    2903             :       case IrOpcode::kCompareMaps:
    2904             :         return VisitUnop(node, UseInfo::AnyTagged(),
    2905       32171 :                          MachineRepresentation::kBit);
    2906             :       case IrOpcode::kEnsureWritableFastElements:
    2907             :         return VisitBinop(node, UseInfo::AnyTagged(),
    2908             :                           MachineRepresentation::kTaggedPointer);
    2909             :       case IrOpcode::kMaybeGrowFastElements: {
    2910        9060 :         ProcessInput(node, 0, UseInfo::AnyTagged());         // object
    2911        9060 :         ProcessInput(node, 1, UseInfo::AnyTagged());         // elements
    2912        9060 :         ProcessInput(node, 2, UseInfo::TruncatingWord32());  // index
    2913        9060 :         ProcessInput(node, 3, UseInfo::TruncatingWord32());  // length
    2914        9060 :         ProcessRemainingInputs(node, 4);
    2915             :         SetOutput(node, MachineRepresentation::kTaggedPointer);
    2916             :         return;
    2917             :       }
    2918             : 
    2919             :       case IrOpcode::kNumberSilenceNaN:
    2920             :         VisitUnop(node, UseInfo::TruncatingFloat64(),
    2921        2452 :                   MachineRepresentation::kFloat64);
    2922        3241 :         if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
    2923             :         return;
    2924             :       case IrOpcode::kFrameState:
    2925    15279044 :         return VisitFrameState(node);
    2926             :       case IrOpcode::kStateValues:
    2927    10189660 :         return VisitStateValues(node);
    2928             :       case IrOpcode::kObjectState:
    2929       57919 :         return VisitObjectState(node);
    2930             :       case IrOpcode::kObjectId:
    2931             :         return SetOutput(node, MachineRepresentation::kTaggedPointer);
    2932             :       case IrOpcode::kTypeGuard: {
    2933             :         // We just get rid of the sigma here, choosing the best representation
    2934             :         // for the sigma's type.
    2935             :         Type* type = TypeOf(node);
    2936             :         MachineRepresentation representation =
    2937       83792 :             GetOutputInfoForPhi(node, type, truncation);
    2938             : 
    2939             :         // Here we pretend that the input has the sigma's type for the
    2940             :         // conversion.
    2941             :         UseInfo use(representation, truncation);
    2942       83793 :         if (propagate()) {
    2943       23186 :           EnqueueInput(node, 0, use);
    2944       60607 :         } else if (lower()) {
    2945       19438 :           ConvertInput(node, 0, use, type);
    2946             :         }
    2947       83794 :         ProcessRemainingInputs(node, 1);
    2948             :         SetOutput(node, representation);
    2949      103231 :         if (lower()) DeferReplacement(node, node->InputAt(0));
    2950             :         return;
    2951             :       }
    2952             : 
    2953             :       case IrOpcode::kFinishRegion:
    2954      348153 :         VisitInputs(node);
    2955             :         // Assume the output is tagged pointer.
    2956             :         return SetOutput(node, MachineRepresentation::kTaggedPointer);
    2957             : 
    2958             :       case IrOpcode::kReturn:
    2959     1660035 :         VisitReturn(node);
    2960             :         // Assume the output is tagged.
    2961             :         return SetOutput(node, MachineRepresentation::kTagged);
    2962             : 
    2963             :       case IrOpcode::kFindOrderedHashMapEntry: {
    2964             :         VisitBinop(node, UseInfo::AnyTagged(),
    2965             :                    MachineRepresentation::kTaggedSigned);
    2966             :         return;
    2967             :       }
    2968             : 
    2969             :       // Operators with all inputs tagged and no or tagged output have uniform
    2970             :       // handling.
    2971             :       case IrOpcode::kEnd:
    2972             :       case IrOpcode::kIfSuccess:
    2973             :       case IrOpcode::kIfException:
    2974             :       case IrOpcode::kIfTrue:
    2975             :       case IrOpcode::kIfFalse:
    2976             :       case IrOpcode::kIfValue:
    2977             :       case IrOpcode::kIfDefault:
    2978             :       case IrOpcode::kDeoptimize:
    2979             :       case IrOpcode::kEffectPhi:
    2980             :       case IrOpcode::kTerminate:
    2981             :       case IrOpcode::kCheckpoint:
    2982             :       case IrOpcode::kLoop:
    2983             :       case IrOpcode::kMerge:
    2984             :       case IrOpcode::kThrow:
    2985             :       case IrOpcode::kBeginRegion:
    2986             :       case IrOpcode::kProjection:
    2987             :       case IrOpcode::kOsrValue:
    2988             :       case IrOpcode::kArgumentsElementsState:
    2989             :       case IrOpcode::kArgumentsLengthState:
    2990             :       case IrOpcode::kRuntimeAbort:
    2991             : // All JavaScript operators except JSToNumber have uniform handling.
    2992             : #define OPCODE_CASE(name) case IrOpcode::k##name:
    2993             :         JS_SIMPLE_BINOP_LIST(OPCODE_CASE)
    2994             :         JS_OBJECT_OP_LIST(OPCODE_CASE)
    2995             :         JS_CONTEXT_OP_LIST(OPCODE_CASE)
    2996             :         JS_OTHER_OP_LIST(OPCODE_CASE)
    2997             : #undef OPCODE_CASE
    2998             :       case IrOpcode::kJSToInteger:
    2999             :       case IrOpcode::kJSToLength:
    3000             :       case IrOpcode::kJSToName:
    3001             :       case IrOpcode::kJSToObject:
    3002             :       case IrOpcode::kJSToString:
    3003    27205390 :         VisitInputs(node);
    3004             :         // Assume the output is tagged.
    3005             :         return SetOutput(node, MachineRepresentation::kTagged);
    3006             : 
    3007             :       default:
    3008             :         V8_Fatal(
    3009             :             __FILE__, __LINE__,
    3010             :             "Representation inference: unsupported opcode %i (%s), node #%i\n.",
    3011           0 :             node->opcode(), node->op()->mnemonic(), node->id());
    3012             :         break;
    3013             :     }
    3014             :     UNREACHABLE();
    3015             :   }
    3016             : 
    3017      179987 :   void DeferReplacement(Node* node, Node* replacement) {
    3018      446380 :     TRACE("defer replacement #%d:%s with #%d:%s\n", node->id(),
    3019             :           node->op()->mnemonic(), replacement->id(),
    3020             :           replacement->op()->mnemonic());
    3021             : 
    3022             :     // Disconnect the node from effect and control chains, if necessary.
    3023      539961 :     if (node->op()->EffectInputCount() > 0) {
    3024             :       DCHECK_LT(0, node->op()->ControlInputCount());
    3025             :       // Disconnect the node from effect and control chains.
    3026       86406 :       Node* control = NodeProperties::GetControlInput(node);
    3027       86406 :       Node* effect = NodeProperties::GetEffectInput(node);
    3028      172812 :       ReplaceEffectControlUses(node, effect, control);
    3029             :     }
    3030             : 
    3031      179987 :     replacements_.push_back(node);
    3032      179987 :     replacements_.push_back(replacement);
    3033             : 
    3034      179987 :     node->NullAllInputs();  // Node is now dead.
    3035      179987 :   }
    3036             : 
    3037      134546 :   void Kill(Node* node) {
    3038       44859 :     TRACE("killing #%d:%s\n", node->id(), node->op()->mnemonic());
    3039             : 
    3040       44859 :     if (node->op()->EffectInputCount() == 1) {
    3041             :       DCHECK_LT(0, node->op()->ControlInputCount());
    3042             :       // Disconnect the node from effect and control chains.
    3043       44828 :       Node* control = NodeProperties::GetControlInput(node);
    3044       44828 :       Node* effect = NodeProperties::GetEffectInput(node);
    3045       44828 :       ReplaceEffectControlUses(node, effect, control);
    3046             :     } else {
    3047             :       DCHECK_EQ(0, node->op()->EffectInputCount());
    3048             :       DCHECK_EQ(0, node->op()->ControlOutputCount());
    3049             :       DCHECK_EQ(0, node->op()->EffectOutputCount());
    3050             :     }
    3051             : 
    3052       44859 :     node->ReplaceUses(jsgraph_->Dead());
    3053             : 
    3054       44859 :     node->NullAllInputs();  // The {node} is now dead.
    3055       44859 :   }
    3056             : 
    3057    45810837 :   void PrintOutputInfo(NodeInfo* info) {
    3058    45810837 :     if (FLAG_trace_representation) {
    3059           0 :       OFStream os(stdout);
    3060           0 :       os << info->representation();
    3061             :     }
    3062    45810837 :   }
    3063             : 
    3064             :   void PrintRepresentation(MachineRepresentation rep) {
    3065             :     if (FLAG_trace_representation) {
    3066             :       OFStream os(stdout);
    3067             :       os << rep;
    3068             :     }
    3069             :   }
    3070             : 
    3071    93227011 :   void PrintTruncation(Truncation truncation) {
    3072    93227011 :     if (FLAG_trace_representation) {
    3073           0 :       OFStream os(stdout);
    3074           0 :       os << truncation.description() << std::endl;
    3075             :     }
    3076    93227011 :   }
    3077             : 
    3078    12698570 :   void PrintUseInfo(UseInfo info) {
    3079    12698570 :     if (FLAG_trace_representation) {
    3080           0 :       OFStream os(stdout);
    3081           0 :       os << info.representation() << ":" << info.truncation().description();
    3082             :     }
    3083    12698570 :   }
    3084             : 
    3085             :  private:
    3086             :   JSGraph* jsgraph_;
    3087             :   Zone* zone_;                      // Temporary zone.
    3088             :   size_t const count_;              // number of nodes in the graph
    3089             :   ZoneVector<NodeInfo> info_;       // node id -> usage information
    3090             : #ifdef DEBUG
    3091             :   ZoneVector<InputUseInfos> node_input_use_infos_;  // Debug information about
    3092             :                                                     // requirements on inputs.
    3093             : #endif                                              // DEBUG
    3094             :   NodeVector nodes_;                // collected nodes
    3095             :   NodeVector replacements_;         // replacements to be done after lowering
    3096             :   Phase phase_;                     // current phase of algorithm
    3097             :   RepresentationChanger* changer_;  // for inserting representation changes
    3098             :   ZoneQueue<Node*> queue_;          // queue for traversing the graph
    3099             : 
    3100             :   struct NodeState {
    3101             :     Node* node;
    3102             :     int input_index;
    3103             :   };
    3104             :   ZoneStack<NodeState> typing_stack_;  // stack for graph typing.
    3105             :   // TODO(danno): RepresentationSelector shouldn't know anything about the
    3106             :   // source positions table, but must for now since there currently is no other
    3107             :   // way to pass down source position information to nodes created during
    3108             :   // lowering. Once this phase becomes a vanilla reducer, it should get source
    3109             :   // position information via the SourcePositionWrapper like all other reducers.
    3110             :   SourcePositionTable* source_positions_;
    3111             :   TypeCache const& type_cache_;
    3112             :   OperationTyper op_typer_;  // helper for the feedback typer
    3113             : 
    3114   601517912 :   NodeInfo* GetInfo(Node* node) {
    3115             :     DCHECK(node->id() < count_);
    3116   604953208 :     return &info_[node->id()];
    3117             :   }
    3118             :   Zone* zone() { return zone_; }
    3119             :   Zone* graph_zone() { return jsgraph_->zone(); }
    3120             : };
    3121             : 
    3122      443359 : SimplifiedLowering::SimplifiedLowering(JSGraph* jsgraph, Zone* zone,
    3123             :                                        SourcePositionTable* source_positions)
    3124             :     : jsgraph_(jsgraph),
    3125             :       zone_(zone),
    3126      443359 :       type_cache_(TypeCache::Get()),
    3127     1330077 :       source_positions_(source_positions) {}
    3128             : 
    3129      443356 : void SimplifiedLowering::LowerAllNodes() {
    3130      443356 :   RepresentationChanger changer(jsgraph(), jsgraph()->isolate());
    3131             :   RepresentationSelector selector(jsgraph(), zone_, &changer,
    3132      443356 :                                   source_positions_);
    3133      443358 :   selector.Run(this);
    3134      443358 : }
    3135             : 
    3136        1349 : void SimplifiedLowering::DoJSToNumberTruncatesToFloat64(
    3137             :     Node* node, RepresentationSelector* selector) {
    3138             :   DCHECK_EQ(IrOpcode::kJSToNumber, node->opcode());
    3139             :   Node* value = node->InputAt(0);
    3140             :   Node* context = node->InputAt(1);
    3141             :   Node* frame_state = node->InputAt(2);
    3142             :   Node* effect = node->InputAt(3);
    3143             :   Node* control = node->InputAt(4);
    3144             : 
    3145        1349 :   Node* check0 = graph()->NewNode(simplified()->ObjectIsSmi(), value);
    3146             :   Node* branch0 =
    3147        1349 :       graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
    3148             : 
    3149        1349 :   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
    3150             :   Node* etrue0 = effect;
    3151             :   Node* vtrue0;
    3152             :   {
    3153        1349 :     vtrue0 = graph()->NewNode(simplified()->ChangeTaggedSignedToInt32(), value);
    3154        1349 :     vtrue0 = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue0);
    3155             :   }
    3156             : 
    3157        1349 :   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
    3158             :   Node* efalse0 = effect;
    3159             :   Node* vfalse0;
    3160             :   {
    3161             :     vfalse0 = efalse0 = if_false0 =
    3162             :         graph()->NewNode(ToNumberOperator(), ToNumberCode(), value, context,
    3163        1349 :                          frame_state, efalse0, if_false0);
    3164             : 
    3165             :     // Update potential {IfException} uses of {node} to point to the above
    3166             :     // {ToNumber} stub call node instead.
    3167        1349 :     Node* on_exception = nullptr;
    3168        1349 :     if (NodeProperties::IsExceptionalCall(node, &on_exception)) {
    3169           0 :       NodeProperties::ReplaceControlInput(on_exception, vfalse0);
    3170           0 :       NodeProperties::ReplaceEffectInput(on_exception, efalse0);
    3171           0 :       if_false0 = graph()->NewNode(common()->IfSuccess(), vfalse0);
    3172             :     }
    3173             : 
    3174        1349 :     Node* check1 = graph()->NewNode(simplified()->ObjectIsSmi(), vfalse0);
    3175        1349 :     Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0);
    3176             : 
    3177        1349 :     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
    3178             :     Node* etrue1 = efalse0;
    3179             :     Node* vtrue1;
    3180             :     {
    3181             :       vtrue1 =
    3182        1349 :           graph()->NewNode(simplified()->ChangeTaggedSignedToInt32(), vfalse0);
    3183        1349 :       vtrue1 = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue1);
    3184             :     }
    3185             : 
    3186        1349 :     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
    3187             :     Node* efalse1 = efalse0;
    3188             :     Node* vfalse1;
    3189             :     {
    3190             :       vfalse1 = efalse1 = graph()->NewNode(
    3191             :           simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), efalse0,
    3192        4047 :           efalse1, if_false1);
    3193             :     }
    3194             : 
    3195        1349 :     if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
    3196             :     efalse0 =
    3197        1349 :         graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_false0);
    3198             :     vfalse0 =
    3199             :         graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
    3200        1349 :                          vtrue1, vfalse1, if_false0);
    3201             :   }
    3202             : 
    3203        1349 :   control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
    3204        1349 :   effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
    3205             :   value = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
    3206        1349 :                            vtrue0, vfalse0, control);
    3207             : 
    3208             :   // Replace effect and control uses appropriately.
    3209        9621 :   for (Edge edge : node->use_edges()) {
    3210        4136 :     if (NodeProperties::IsControlEdge(edge)) {
    3211        4083 :       if (edge.from()->opcode() == IrOpcode::kIfSuccess) {
    3212           0 :         edge.from()->ReplaceUses(control);
    3213           0 :         edge.from()->Kill();
    3214             :       } else {
    3215             :         DCHECK_NE(IrOpcode::kIfException, edge.from()->opcode());
    3216        1361 :         edge.UpdateTo(control);
    3217             :       }
    3218        2775 :     } else if (NodeProperties::IsEffectEdge(edge)) {
    3219        1378 :       edge.UpdateTo(effect);
    3220             :     }
    3221             :   }
    3222             : 
    3223        1349 :   selector->DeferReplacement(node, value);
    3224        1349 : }
    3225             : 
    3226          67 : void SimplifiedLowering::DoJSToNumberTruncatesToWord32(
    3227             :     Node* node, RepresentationSelector* selector) {
    3228             :   DCHECK_EQ(IrOpcode::kJSToNumber, node->opcode());
    3229             :   Node* value = node->InputAt(0);
    3230             :   Node* context = node->InputAt(1);
    3231             :   Node* frame_state = node->InputAt(2);
    3232             :   Node* effect = node->InputAt(3);
    3233             :   Node* control = node->InputAt(4);
    3234             : 
    3235          67 :   Node* check0 = graph()->NewNode(simplified()->ObjectIsSmi(), value);
    3236             :   Node* branch0 =
    3237          67 :       graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
    3238             : 
    3239          67 :   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
    3240             :   Node* etrue0 = effect;
    3241             :   Node* vtrue0 =
    3242          67 :       graph()->NewNode(simplified()->ChangeTaggedSignedToInt32(), value);
    3243             : 
    3244          67 :   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
    3245             :   Node* efalse0 = effect;
    3246             :   Node* vfalse0;
    3247             :   {
    3248             :     vfalse0 = efalse0 = if_false0 =
    3249             :         graph()->NewNode(ToNumberOperator(), ToNumberCode(), value, context,
    3250          67 :                          frame_state, efalse0, if_false0);
    3251             : 
    3252             :     // Update potential {IfException} uses of {node} to point to the above
    3253             :     // {ToNumber} stub call node instead.
    3254          67 :     Node* on_exception = nullptr;
    3255          67 :     if (NodeProperties::IsExceptionalCall(node, &on_exception)) {
    3256           0 :       NodeProperties::ReplaceControlInput(on_exception, vfalse0);
    3257           0 :       NodeProperties::ReplaceEffectInput(on_exception, efalse0);
    3258           0 :       if_false0 = graph()->NewNode(common()->IfSuccess(), vfalse0);
    3259             :     }
    3260             : 
    3261          67 :     Node* check1 = graph()->NewNode(simplified()->ObjectIsSmi(), vfalse0);
    3262          67 :     Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0);
    3263             : 
    3264          67 :     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
    3265             :     Node* etrue1 = efalse0;
    3266             :     Node* vtrue1 =
    3267          67 :         graph()->NewNode(simplified()->ChangeTaggedSignedToInt32(), vfalse0);
    3268             : 
    3269          67 :     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
    3270             :     Node* efalse1 = efalse0;
    3271             :     Node* vfalse1;
    3272             :     {
    3273             :       vfalse1 = efalse1 = graph()->NewNode(
    3274             :           simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), efalse0,
    3275         201 :           efalse1, if_false1);
    3276          67 :       vfalse1 = graph()->NewNode(machine()->TruncateFloat64ToWord32(), vfalse1);
    3277             :     }
    3278             : 
    3279          67 :     if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
    3280             :     efalse0 =
    3281          67 :         graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_false0);
    3282             :     vfalse0 = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
    3283          67 :                                vtrue1, vfalse1, if_false0);
    3284             :   }
    3285             : 
    3286          67 :   control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
    3287          67 :   effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
    3288             :   value = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
    3289          67 :                            vtrue0, vfalse0, control);
    3290             : 
    3291             :   // Replace effect and control uses appropriately.
    3292         371 :   for (Edge edge : node->use_edges()) {
    3293         152 :     if (NodeProperties::IsControlEdge(edge)) {
    3294         255 :       if (edge.from()->opcode() == IrOpcode::kIfSuccess) {
    3295           0 :         edge.from()->ReplaceUses(control);
    3296           0 :         edge.from()->Kill();
    3297             :       } else {
    3298             :         DCHECK_NE(IrOpcode::kIfException, edge.from()->opcode());
    3299          85 :         edge.UpdateTo(control);
    3300             :       }
    3301          67 :     } else if (NodeProperties::IsEffectEdge(edge)) {
    3302          67 :       edge.UpdateTo(effect);
    3303             :     }
    3304             :   }
    3305             : 
    3306          67 :   selector->DeferReplacement(node, value);
    3307          67 : }
    3308             : 
    3309         148 : Node* SimplifiedLowering::Float64Round(Node* const node) {
    3310          74 :   Node* const one = jsgraph()->Float64Constant(1.0);
    3311          74 :   Node* const one_half = jsgraph()->Float64Constant(0.5);
    3312             :   Node* const input = node->InputAt(0);
    3313             : 
    3314             :   // Round up towards Infinity, and adjust if the difference exceeds 0.5.
    3315             :   Node* result = graph()->NewNode(machine()->Float64RoundUp().placeholder(),
    3316         148 :                                   node->InputAt(0));
    3317             :   return graph()->NewNode(
    3318             :       common()->Select(MachineRepresentation::kFloat64),
    3319             :       graph()->NewNode(
    3320             :           machine()->Float64LessThanOrEqual(),
    3321             :           graph()->NewNode(machine()->Float64Sub(), result, one_half), input),
    3322         370 :       result, graph()->NewNode(machine()->Float64Sub(), result, one));
    3323             : }
    3324             : 
    3325          42 : Node* SimplifiedLowering::Float64Sign(Node* const node) {
    3326          14 :   Node* const minus_one = jsgraph()->Float64Constant(-1.0);
    3327          14 :   Node* const zero = jsgraph()->Float64Constant(0.0);
    3328          14 :   Node* const one = jsgraph()->Float64Constant(1.0);
    3329             : 
    3330             :   Node* const input = node->InputAt(0);
    3331             : 
    3332             :   return graph()->NewNode(
    3333             :       common()->Select(MachineRepresentation::kFloat64),
    3334             :       graph()->NewNode(machine()->Float64LessThan(), input, zero), minus_one,
    3335             :       graph()->NewNode(
    3336             :           common()->Select(MachineRepresentation::kFloat64),
    3337             :           graph()->NewNode(machine()->Float64LessThan(), zero, input), one,
    3338          70 :           input));
    3339             : }
    3340             : 
    3341          72 : Node* SimplifiedLowering::Int32Abs(Node* const node) {
    3342             :   Node* const input = node->InputAt(0);
    3343             : 
    3344             :   // Generate case for absolute integer value.
    3345             :   //
    3346             :   //    let sign = input >> 31 in
    3347             :   //    (input ^ sign) - sign
    3348             : 
    3349             :   Node* sign = graph()->NewNode(machine()->Word32Sar(), input,
    3350          72 :                                 jsgraph()->Int32Constant(31));
    3351             :   return graph()->NewNode(machine()->Int32Sub(),
    3352             :                           graph()->NewNode(machine()->Word32Xor(), input, sign),
    3353         108 :                           sign);
    3354             : }
    3355             : 
    3356        9048 : Node* SimplifiedLowering::Int32Div(Node* const node) {
    3357        3016 :   Int32BinopMatcher m(node);
    3358        3016 :   Node* const zero = jsgraph()->Int32Constant(0);
    3359        3016 :   Node* const minus_one = jsgraph()->Int32Constant(-1);
    3360             :   Node* const lhs = m.left().node();
    3361             :   Node* const rhs = m.right().node();
    3362             : 
    3363        3016 :   if (m.right().Is(-1)) {
    3364          34 :     return graph()->NewNode(machine()->Int32Sub(), zero, lhs);
    3365        2999 :   } else if (m.right().Is(0)) {
    3366             :     return rhs;
    3367        2999 :   } else if (machine()->Int32DivIsSafe() || m.right().HasValue()) {
    3368        4758 :     return graph()->NewNode(machine()->Int32Div(), lhs, rhs, graph()->start());
    3369             :   }
    3370             : 
    3371             :   // General case for signed integer division.
    3372             :   //
    3373             :   //    if 0 < rhs then
    3374             :   //      lhs / rhs
    3375             :   //    else
    3376             :   //      if rhs < -1 then
    3377             :   //        lhs / rhs
    3378             :   //      else if rhs == 0 then
    3379             :   //        0
    3380             :   //      else
    3381             :   //        0 - lhs
    3382             :   //
    3383             :   // Note: We do not use the Diamond helper class here, because it really hurts
    3384             :   // readability with nested diamonds.
    3385         620 :   const Operator* const merge_op = common()->Merge(2);
    3386             :   const Operator* const phi_op =
    3387         620 :       common()->Phi(MachineRepresentation::kWord32, 2);
    3388             : 
    3389         620 :   Node* check0 = graph()->NewNode(machine()->Int32LessThan(), zero, rhs);
    3390             :   Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kTrue), check0,
    3391        1240 :                                    graph()->start());
    3392             : 
    3393         620 :   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
    3394         620 :   Node* true0 = graph()->NewNode(machine()->Int32Div(), lhs, rhs, if_true0);
    3395             : 
    3396         620 :   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
    3397             :   Node* false0;
    3398             :   {
    3399         620 :     Node* check1 = graph()->NewNode(machine()->Int32LessThan(), rhs, minus_one);
    3400         620 :     Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0);
    3401             : 
    3402         620 :     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
    3403         620 :     Node* true1 = graph()->NewNode(machine()->Int32Div(), lhs, rhs, if_true1);
    3404             : 
    3405         620 :     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
    3406             :     Node* false1;
    3407             :     {
    3408         620 :       Node* check2 = graph()->NewNode(machine()->Word32Equal(), rhs, zero);
    3409         620 :       Node* branch2 = graph()->NewNode(common()->Branch(), check2, if_false1);
    3410             : 
    3411         620 :       Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
    3412             :       Node* true2 = zero;
    3413             : 
    3414         620 :       Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
    3415         620 :       Node* false2 = graph()->NewNode(machine()->Int32Sub(), zero, lhs);
    3416             : 
    3417             :       if_false1 = graph()->NewNode(merge_op, if_true2, if_false2);
    3418             :       false1 = graph()->NewNode(phi_op, true2, false2, if_false1);
    3419             :     }
    3420             : 
    3421             :     if_false0 = graph()->NewNode(merge_op, if_true1, if_false1);
    3422             :     false0 = graph()->NewNode(phi_op, true1, false1, if_false0);
    3423             :   }
    3424             : 
    3425             :   Node* merge0 = graph()->NewNode(merge_op, if_true0, if_false0);
    3426         620 :   return graph()->NewNode(phi_op, true0, false0, merge0);
    3427             : }
    3428             : 
    3429        7512 : Node* SimplifiedLowering::Int32Mod(Node* const node) {
    3430        2504 :   Int32BinopMatcher m(node);
    3431        2504 :   Node* const zero = jsgraph()->Int32Constant(0);
    3432        2504 :   Node* const minus_one = jsgraph()->Int32Constant(-1);
    3433             :   Node* const lhs = m.left().node();
    3434             :   Node* const rhs = m.right().node();
    3435             : 
    3436        4993 :   if (m.right().Is(-1) || m.right().Is(0)) {
    3437             :     return zero;
    3438        2489 :   } else if (m.right().HasValue()) {
    3439        7149 :     return graph()->NewNode(machine()->Int32Mod(), lhs, rhs, graph()->start());
    3440             :   }
    3441             : 
    3442             :   // General case for signed integer modulus, with optimization for (unknown)
    3443             :   // power of 2 right hand side.
    3444             :   //
    3445             :   //   if 0 < rhs then
    3446             :   //     msk = rhs - 1
    3447             :   //     if rhs & msk != 0 then
    3448             :   //       lhs % rhs
    3449             :   //     else
    3450             :   //       if lhs < 0 then
    3451             :   //         -(-lhs & msk)
    3452             :   //       else
    3453             :   //         lhs & msk
    3454             :   //   else
    3455             :   //     if rhs < -1 then
    3456             :   //       lhs % rhs
    3457             :   //     else
    3458             :   //       zero
    3459             :   //
    3460             :   // Note: We do not use the Diamond helper class here, because it really hurts
    3461             :   // readability with nested diamonds.
    3462         106 :   const Operator* const merge_op = common()->Merge(2);
    3463             :   const Operator* const phi_op =
    3464         106 :       common()->Phi(MachineRepresentation::kWord32, 2);
    3465             : 
    3466         106 :   Node* check0 = graph()->NewNode(machine()->Int32LessThan(), zero, rhs);
    3467             :   Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kTrue), check0,
    3468         212 :                                    graph()->start());
    3469             : 
    3470         106 :   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
    3471             :   Node* true0;
    3472             :   {
    3473         106 :     Node* msk = graph()->NewNode(machine()->Int32Add(), rhs, minus_one);
    3474             : 
    3475         106 :     Node* check1 = graph()->NewNode(machine()->Word32And(), rhs, msk);
    3476         106 :     Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0);
    3477             : 
    3478         106 :     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
    3479         106 :     Node* true1 = graph()->NewNode(machine()->Int32Mod(), lhs, rhs, if_true1);
    3480             : 
    3481         106 :     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
    3482             :     Node* false1;
    3483             :     {
    3484         106 :       Node* check2 = graph()->NewNode(machine()->Int32LessThan(), lhs, zero);
    3485             :       Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
    3486         106 :                                        check2, if_false1);
    3487             : 
    3488         106 :       Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
    3489             :       Node* true2 = graph()->NewNode(
    3490             :           machine()->Int32Sub(), zero,
    3491             :           graph()->NewNode(machine()->Word32And(),
    3492             :                            graph()->NewNode(machine()->Int32Sub(), zero, lhs),
    3493         318 :                            msk));
    3494             : 
    3495         106 :       Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
    3496         106 :       Node* false2 = graph()->NewNode(machine()->Word32And(), lhs, msk);
    3497             : 
    3498             :       if_false1 = graph()->NewNode(merge_op, if_true2, if_false2);
    3499             :       false1 = graph()->NewNode(phi_op, true2, false2, if_false1);
    3500             :     }
    3501             : 
    3502             :     if_true0 = graph()->NewNode(merge_op, if_true1, if_false1);
    3503             :     true0 = graph()->NewNode(phi_op, true1, false1, if_true0);
    3504             :   }
    3505             : 
    3506         106 :   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
    3507             :   Node* false0;
    3508             :   {
    3509         106 :     Node* check1 = graph()->NewNode(machine()->Int32LessThan(), rhs, minus_one);
    3510             :     Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kTrue),
    3511         106 :                                      check1, if_false0);
    3512             : 
    3513         106 :     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
    3514         106 :     Node* true1 = graph()->NewNode(machine()->Int32Mod(), lhs, rhs, if_true1);
    3515             : 
    3516         106 :     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
    3517             :     Node* false1 = zero;
    3518             : 
    3519             :     if_false0 = graph()->NewNode(merge_op, if_true1, if_false1);
    3520             :     false0 = graph()->NewNode(phi_op, true1, false1, if_false0);
    3521             :   }
    3522             : 
    3523             :   Node* merge0 = graph()->NewNode(merge_op, if_true0, if_false0);
    3524         106 :   return graph()->NewNode(phi_op, true0, false0, merge0);
    3525             : }
    3526             : 
    3527          21 : Node* SimplifiedLowering::Int32Sign(Node* const node) {
    3528           7 :   Node* const minus_one = jsgraph()->Int32Constant(-1);
    3529           7 :   Node* const zero = jsgraph()->Int32Constant(0);
    3530           7 :   Node* const one = jsgraph()->Int32Constant(1);
    3531             : 
    3532             :   Node* const input = node->InputAt(0);
    3533             : 
    3534             :   return graph()->NewNode(
    3535             :       common()->Select(MachineRepresentation::kWord32),
    3536             :       graph()->NewNode(machine()->Int32LessThan(), input, zero), minus_one,
    3537             :       graph()->NewNode(
    3538             :           common()->Select(MachineRepresentation::kWord32),
    3539             :           graph()->NewNode(machine()->Int32LessThan(), zero, input), one,
    3540          35 :           zero));
    3541             : }
    3542             : 
    3543         148 : Node* SimplifiedLowering::Uint32Div(Node* const node) {
    3544          74 :   Uint32BinopMatcher m(node);
    3545             :   Node* const zero = jsgraph()->Uint32Constant(0);
    3546             :   Node* const lhs = m.left().node();
    3547             :   Node* const rhs = m.right().node();
    3548             : 
    3549          74 :   if (m.right().Is(0)) {
    3550             :     return zero;
    3551          67 :   } else if (machine()->Uint32DivIsSafe() || m.right().HasValue()) {
    3552          52 :     return graph()->NewNode(machine()->Uint32Div(), lhs, rhs, graph()->start());
    3553             :   }
    3554             : 
    3555          41 :   Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, zero);
    3556          41 :   Diamond d(graph(), common(), check, BranchHint::kFalse);
    3557          82 :   Node* div = graph()->NewNode(machine()->Uint32Div(), lhs, rhs, d.if_false);
    3558          41 :   return d.Phi(MachineRepresentation::kWord32, zero, div);
    3559             : }
    3560             : 
    3561         759 : Node* SimplifiedLowering::Uint32Mod(Node* const node) {
    3562         253 :   Uint32BinopMatcher m(node);
    3563         253 :   Node* const minus_one = jsgraph()->Int32Constant(-1);
    3564             :   Node* const zero = jsgraph()->Uint32Constant(0);
    3565             :   Node* const lhs = m.left().node();
    3566             :   Node* const rhs = m.right().node();
    3567             : 
    3568         253 :   if (m.right().Is(0)) {
    3569             :     return zero;
    3570         253 :   } else if (m.right().HasValue()) {
    3571         663 :     return graph()->NewNode(machine()->Uint32Mod(), lhs, rhs, graph()->start());
    3572             :   }
    3573             : 
    3574             :   // General case for unsigned integer modulus, with optimization for (unknown)
    3575             :   // power of 2 right hand side.
    3576             :   //
    3577             :   //   if rhs then
    3578             :   //     msk = rhs - 1
    3579             :   //     if rhs & msk != 0 then
    3580             :   //       lhs % rhs
    3581             :   //     else
    3582             :   //       lhs & msk
    3583             :   //   else
    3584             :   //     zero
    3585             :   //
    3586             :   // Note: We do not use the Diamond helper class here, because it really hurts
    3587             :   // readability with nested diamonds.
    3588          32 :   const Operator* const merge_op = common()->Merge(2);
    3589             :   const Operator* const phi_op =
    3590          32 :       common()->Phi(MachineRepresentation::kWord32, 2);
    3591             : 
    3592             :   Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kTrue), rhs,
    3593          64 :                                    graph()->start());
    3594             : 
    3595          32 :   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
    3596             :   Node* true0;
    3597             :   {
    3598          32 :     Node* msk = graph()->NewNode(machine()->Int32Add(), rhs, minus_one);
    3599             : 
    3600          32 :     Node* check1 = graph()->NewNode(machine()->Word32And(), rhs, msk);
    3601          32 :     Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0);
    3602             : 
    3603          32 :     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
    3604          32 :     Node* true1 = graph()->NewNode(machine()->Uint32Mod(), lhs, rhs, if_true1);
    3605             : 
    3606          32 :     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
    3607          32 :     Node* false1 = graph()->NewNode(machine()->Word32And(), lhs, msk);
    3608             : 
    3609             :     if_true0 = graph()->NewNode(merge_op, if_true1, if_false1);
    3610             :     true0 = graph()->NewNode(phi_op, true1, false1, if_true0);
    3611             :   }
    3612             : 
    3613          32 :   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
    3614             :   Node* false0 = zero;
    3615             : 
    3616             :   Node* merge0 = graph()->NewNode(merge_op, if_true0, if_false0);
    3617          32 :   return graph()->NewNode(phi_op, true0, false0, merge0);
    3618             : }
    3619             : 
    3620         236 : void SimplifiedLowering::DoMax(Node* node, Operator const* op,
    3621             :                                MachineRepresentation rep) {
    3622             :   Node* const lhs = node->InputAt(0);
    3623             :   Node* const rhs = node->InputAt(1);
    3624             : 
    3625         236 :   node->ReplaceInput(0, graph()->NewNode(op, lhs, rhs));
    3626             :   DCHECK_EQ(rhs, node->InputAt(1));
    3627         236 :   node->AppendInput(graph()->zone(), lhs);
    3628         236 :   NodeProperties::ChangeOp(node, common()->Select(rep));
    3629         236 : }
    3630             : 
    3631         118 : void SimplifiedLowering::DoMin(Node* node, Operator const* op,
    3632             :                                MachineRepresentation rep) {
    3633             :   Node* const lhs = node->InputAt(0);
    3634             :   Node* const rhs = node->InputAt(1);
    3635             : 
    3636         118 :   node->InsertInput(graph()->zone(), 0, graph()->NewNode(op, lhs, rhs));
    3637             :   DCHECK_EQ(lhs, node->InputAt(1));
    3638             :   DCHECK_EQ(rhs, node->InputAt(2));
    3639         118 :   NodeProperties::ChangeOp(node, common()->Select(rep));
    3640         118 : }
    3641             : 
    3642       14865 : void SimplifiedLowering::DoShift(Node* node, Operator const* op,
    3643        4783 :                                  Type* rhs_type) {
    3644       29731 :   if (!rhs_type->Is(type_cache_.kZeroToThirtyOne)) {
    3645        4783 :     Node* const rhs = NodeProperties::GetValueInput(node, 1);
    3646             :     node->ReplaceInput(1, graph()->NewNode(machine()->Word32And(), rhs,
    3647       14349 :                                            jsgraph()->Int32Constant(0x1f)));
    3648             :   }
    3649       14866 :   ChangeToPureOp(node, op);
    3650       14867 : }
    3651             : 
    3652         286 : void SimplifiedLowering::DoIntegral32ToBit(Node* node) {
    3653             :   Node* const input = node->InputAt(0);
    3654         143 :   Node* const zero = jsgraph()->Int32Constant(0);
    3655         143 :   Operator const* const op = machine()->Word32Equal();
    3656             : 
    3657         143 :   node->ReplaceInput(0, graph()->NewNode(op, input, zero));
    3658         143 :   node->AppendInput(graph()->zone(), zero);
    3659         143 :   NodeProperties::ChangeOp(node, op);
    3660         143 : }
    3661             : 
    3662           0 : void SimplifiedLowering::DoOrderedNumberToBit(Node* node) {
    3663             :   Node* const input = node->InputAt(0);
    3664             : 
    3665             :   node->ReplaceInput(0, graph()->NewNode(machine()->Float64Equal(), input,
    3666           0 :                                          jsgraph()->Float64Constant(0.0)));
    3667           0 :   node->AppendInput(graph()->zone(), jsgraph()->Int32Constant(0));
    3668           0 :   NodeProperties::ChangeOp(node, machine()->Word32Equal());
    3669           0 : }
    3670             : 
    3671         310 : void SimplifiedLowering::DoNumberToBit(Node* node) {
    3672             :   Node* const input = node->InputAt(0);
    3673             : 
    3674         155 :   node->ReplaceInput(0, jsgraph()->Float64Constant(0.0));
    3675             :   node->AppendInput(graph()->zone(),
    3676         310 :                     graph()->NewNode(machine()->Float64Abs(), input));
    3677         155 :   NodeProperties::ChangeOp(node, machine()->Float64LessThan());
    3678         155 : }
    3679             : 
    3680          72 : void SimplifiedLowering::DoIntegerToUint8Clamped(Node* node) {
    3681             :   Node* const input = node->InputAt(0);
    3682          24 :   Node* const min = jsgraph()->Float64Constant(0.0);
    3683          24 :   Node* const max = jsgraph()->Float64Constant(255.0);
    3684             : 
    3685             :   node->ReplaceInput(
    3686          48 :       0, graph()->NewNode(machine()->Float64LessThan(), min, input));
    3687             :   node->AppendInput(
    3688             :       graph()->zone(),
    3689             :       graph()->NewNode(
    3690             :           common()->Select(MachineRepresentation::kFloat64),
    3691             :           graph()->NewNode(machine()->Float64LessThan(), input, max), input,
    3692          72 :           max));
    3693          24 :   node->AppendInput(graph()->zone(), min);
    3694             :   NodeProperties::ChangeOp(node,
    3695          24 :                            common()->Select(MachineRepresentation::kFloat64));
    3696          24 : }
    3697             : 
    3698         996 : void SimplifiedLowering::DoNumberToUint8Clamped(Node* node) {
    3699             :   Node* const input = node->InputAt(0);
    3700         332 :   Node* const min = jsgraph()->Float64Constant(0.0);
    3701         332 :   Node* const max = jsgraph()->Float64Constant(255.0);
    3702             : 
    3703             :   node->ReplaceInput(
    3704             :       0, graph()->NewNode(
    3705             :              common()->Select(MachineRepresentation::kFloat64),
    3706             :              graph()->NewNode(machine()->Float64LessThan(), min, input),
    3707             :              graph()->NewNode(
    3708             :                  common()->Select(MachineRepresentation::kFloat64),
    3709             :                  graph()->NewNode(machine()->Float64LessThan(), input, max),
    3710             :                  input, max),
    3711        1660 :              min));
    3712             :   NodeProperties::ChangeOp(node,
    3713         332 :                            machine()->Float64RoundTiesEven().placeholder());
    3714         332 : }
    3715             : 
    3716         483 : void SimplifiedLowering::DoSigned32ToUint8Clamped(Node* node) {
    3717             :   Node* const input = node->InputAt(0);
    3718         161 :   Node* const min = jsgraph()->Int32Constant(0);
    3719         161 :   Node* const max = jsgraph()->Int32Constant(255);
    3720             : 
    3721             :   node->ReplaceInput(
    3722         322 :       0, graph()->NewNode(machine()->Int32LessThanOrEqual(), input, max));
    3723             :   node->AppendInput(
    3724             :       graph()->zone(),
    3725             :       graph()->NewNode(common()->Select(MachineRepresentation::kWord32),
    3726             :                        graph()->NewNode(machine()->Int32LessThan(), input, min),
    3727         483 :                        min, input));
    3728         161 :   node->AppendInput(graph()->zone(), max);
    3729             :   NodeProperties::ChangeOp(node,
    3730         161 :                            common()->Select(MachineRepresentation::kWord32));
    3731         161 : }
    3732             : 
    3733         340 : void SimplifiedLowering::DoUnsigned32ToUint8Clamped(Node* node) {
    3734             :   Node* const input = node->InputAt(0);
    3735             :   Node* const max = jsgraph()->Uint32Constant(255u);
    3736             : 
    3737             :   node->ReplaceInput(
    3738         340 :       0, graph()->NewNode(machine()->Uint32LessThanOrEqual(), input, max));
    3739         170 :   node->AppendInput(graph()->zone(), input);
    3740         170 :   node->AppendInput(graph()->zone(), max);
    3741             :   NodeProperties::ChangeOp(node,
    3742         170 :                            common()->Select(MachineRepresentation::kWord32));
    3743         170 : }
    3744             : 
    3745        4248 : Node* SimplifiedLowering::ToNumberCode() {
    3746        1416 :   if (!to_number_code_.is_set()) {
    3747        1416 :     Callable callable = Builtins::CallableFor(isolate(), Builtins::kToNumber);
    3748        2832 :     to_number_code_.set(jsgraph()->HeapConstant(callable.code()));
    3749             :   }
    3750        1416 :   return to_number_code_.get();
    3751             : }
    3752             : 
    3753        2832 : Operator const* SimplifiedLowering::ToNumberOperator() {
    3754        1416 :   if (!to_number_operator_.is_set()) {
    3755        1416 :     Callable callable = Builtins::CallableFor(isolate(), Builtins::kToNumber);
    3756             :     CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState;
    3757             :     CallDescriptor* desc = Linkage::GetStubCallDescriptor(
    3758             :         isolate(), graph()->zone(), callable.descriptor(), 0, flags,
    3759        4248 :         Operator::kNoProperties);
    3760        1416 :     to_number_operator_.set(common()->Call(desc));
    3761             :   }
    3762        1416 :   return to_number_operator_.get();
    3763             : }
    3764             : 
    3765             : #undef TRACE
    3766             : 
    3767             : }  // namespace compiler
    3768             : }  // namespace internal
    3769             : }  // namespace v8

Generated by: LCOV version 1.10