LCOV - code coverage report
Current view: top level - src/compiler - simplified-lowering.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 1284 1372 93.6 %
Date: 2017-04-26 Functions: 82 84 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       23207 : MachineRepresentation MachineRepresentationFromArrayType(
      69             :     ExternalArrayType array_type) {
      70       23207 :   switch (array_type) {
      71             :     case kExternalUint8Array:
      72             :     case kExternalUint8ClampedArray:
      73             :     case kExternalInt8Array:
      74             :       return MachineRepresentation::kWord8;
      75             :     case kExternalUint16Array:
      76             :     case kExternalInt16Array:
      77        3171 :       return MachineRepresentation::kWord16;
      78             :     case kExternalUint32Array:
      79             :     case kExternalInt32Array:
      80        4129 :       return MachineRepresentation::kWord32;
      81             :     case kExternalFloat32Array:
      82        6664 :       return MachineRepresentation::kFloat32;
      83             :     case kExternalFloat64Array:
      84        2083 :       return MachineRepresentation::kFloat64;
      85             :   }
      86           0 :   UNREACHABLE();
      87             :   return MachineRepresentation::kNone;
      88             : }
      89             : 
      90     1151120 : UseInfo CheckedUseInfoAsWord32FromHint(
      91             :     NumberOperationHint hint,
      92             :     IdentifyZeros identify_zeros = kDistinguishZeros) {
      93     1151120 :   switch (hint) {
      94             :     case NumberOperationHint::kSignedSmall:
      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             :   return UseInfo::None();
     105             : }
     106             : 
     107       36140 : UseInfo CheckedUseInfoAsFloat64FromHint(NumberOperationHint hint) {
     108       36140 :   switch (hint) {
     109             :     case NumberOperationHint::kSignedSmall:
     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             :   return UseInfo::None();
     121             : }
     122             : 
     123    18735578 : UseInfo TruncatingUseInfoFromRepresentation(MachineRepresentation rep) {
     124    18735578 :   switch (rep) {
     125             :     case MachineRepresentation::kTaggedSigned:
     126             :     case MachineRepresentation::kTaggedPointer:
     127             :     case MachineRepresentation::kTagged:
     128             :       return UseInfo::AnyTagged();
     129             :     case MachineRepresentation::kFloat64:
     130             :       return UseInfo::TruncatingFloat64();
     131             :     case MachineRepresentation::kFloat32:
     132             :       return UseInfo::Float32();
     133             :     case MachineRepresentation::kWord64:
     134             :       return UseInfo::TruncatingWord64();
     135             :     case MachineRepresentation::kWord8:
     136             :     case MachineRepresentation::kWord16:
     137             :     case MachineRepresentation::kWord32:
     138             :       return UseInfo::TruncatingWord32();
     139             :     case MachineRepresentation::kBit:
     140             :       return UseInfo::Bool();
     141             :     case MachineRepresentation::kSimd128:
     142             :     case MachineRepresentation::kSimd1x4:
     143             :     case MachineRepresentation::kSimd1x8:
     144             :     case MachineRepresentation::kSimd1x16:
     145             :     case MachineRepresentation::kNone:
     146             :       break;
     147             :   }
     148           0 :   UNREACHABLE();
     149             :   return UseInfo::None();
     150             : }
     151             : 
     152             : 
     153     2760848 : UseInfo UseInfoForBasePointer(const FieldAccess& access) {
     154     5596812 :   return access.tag() != 0 ? UseInfo::AnyTagged() : UseInfo::PointerInt();
     155             : }
     156             : 
     157             : 
     158      494916 : UseInfo UseInfoForBasePointer(const ElementAccess& access) {
     159      606839 :   return access.tag() != 0 ? UseInfo::AnyTagged() : UseInfo::PointerInt();
     160             : }
     161             : 
     162      365091 : void ReplaceEffectControlUses(Node* node, Node* effect, Node* control) {
     163     2357476 :   for (Edge edge : node->use_edges()) {
     164      996192 :     if (NodeProperties::IsControlEdge(edge)) {
     165           0 :       edge.UpdateTo(control);
     166      996197 :     } else if (NodeProperties::IsEffectEdge(edge)) {
     167      441166 :       edge.UpdateTo(effect);
     168             :     } else {
     169             :       DCHECK(NodeProperties::IsValueEdge(edge) ||
     170             :              NodeProperties::IsContextEdge(edge));
     171             :     }
     172             :   }
     173      365092 : }
     174             : 
     175      831483 : void ChangeToPureOp(Node* node, const Operator* new_op) {
     176             :   DCHECK(new_op->HasProperty(Operator::kPure));
     177      784956 :   if (node->op()->EffectInputCount() > 0) {
     178             :     DCHECK_LT(0, node->op()->ControlInputCount());
     179             :     // Disconnect the node from effect and control chains.
     180      219499 :     Node* control = NodeProperties::GetControlInput(node);
     181      219501 :     Node* effect = NodeProperties::GetEffectInput(node);
     182      219498 :     ReplaceEffectControlUses(node, effect, control);
     183      219507 :     node->TrimInputCount(new_op->ValueInputCount());
     184             :   } else {
     185             :     DCHECK_EQ(0, node->op()->ControlInputCount());
     186             :   }
     187      392488 :   NodeProperties::ChangeOp(node, new_op);
     188      392491 : }
     189             : 
     190             : #ifdef DEBUG
     191             : // Helpers for monotonicity checking.
     192             : class InputUseInfos {
     193             :  public:
     194             :   explicit InputUseInfos(Zone* zone) : input_use_infos_(zone) {}
     195             : 
     196             :   void SetAndCheckInput(Node* node, int index, UseInfo use_info) {
     197             :     if (input_use_infos_.empty()) {
     198             :       input_use_infos_.resize(node->InputCount(), UseInfo::None());
     199             :     }
     200             :     // Check that the new use informatin is a super-type of the old
     201             :     // one.
     202             :     CHECK(IsUseLessGeneral(input_use_infos_[index], use_info));
     203             :     input_use_infos_[index] = use_info;
     204             :   }
     205             : 
     206             :  private:
     207             :   ZoneVector<UseInfo> input_use_infos_;
     208             : 
     209             :   static bool IsUseLessGeneral(UseInfo use1, UseInfo use2) {
     210             :     return use1.truncation().IsLessGeneralThan(use2.truncation());
     211             :   }
     212             : };
     213             : 
     214             : #endif  // DEBUG
     215             : 
     216      308489 : bool CanOverflowSigned32(const Operator* op, Type* left, Type* right,
     217             :                          Zone* type_zone) {
     218             :   // We assume the inputs are checked Signed32 (or known statically
     219             :   // to be Signed32). Technically, theinputs could also be minus zero, but
     220             :   // that cannot cause overflow.
     221      154247 :   left = Type::Intersect(left, Type::Signed32(), type_zone);
     222      154246 :   right = Type::Intersect(right, Type::Signed32(), type_zone);
     223      308493 :   if (!left->IsInhabited() || !right->IsInhabited()) return false;
     224      154242 :   switch (op->opcode()) {
     225             :     case IrOpcode::kSpeculativeNumberAdd:
     226      133525 :       return (left->Max() + right->Max() > kMaxInt) ||
     227      133525 :              (left->Min() + right->Min() < kMinInt);
     228             : 
     229             :     case IrOpcode::kSpeculativeNumberSubtract:
     230       30562 :       return (left->Max() - right->Min() > kMaxInt) ||
     231       30562 :              (left->Min() - right->Max() < kMinInt);
     232             : 
     233             :     default:
     234           0 :       UNREACHABLE();
     235             :   }
     236             :   return true;
     237             : }
     238             : 
     239             : }  // namespace
     240             : 
     241             : class RepresentationSelector {
     242             :  public:
     243             :   // Information for each node tracked during the fixpoint.
     244      394593 :   class NodeInfo final {
     245             :    public:
     246             :     // Adds new use to the node. Returns true if something has changed
     247             :     // and the node has to be requeued.
     248    87720780 :     bool AddUse(UseInfo info) {
     249    87720780 :       Truncation old_truncation = truncation_;
     250    87720780 :       truncation_ = Truncation::Generalize(truncation_, info.truncation());
     251    87718469 :       return truncation_ != old_truncation;
     252             :     }
     253             : 
     254    35819996 :     void set_queued() { state_ = kQueued; }
     255    64499146 :     void set_visited() { state_ = kVisited; }
     256    28679945 :     void set_pushed() { state_ = kPushed; }
     257    47374320 :     void reset_state() { state_ = kUnvisited; }
     258             :     bool visited() const { return state_ == kVisited; }
     259             :     bool queued() const { return state_ == kQueued; }
     260             :     bool unvisited() const { return state_ == kUnvisited; }
     261             :     Truncation truncation() const { return truncation_; }
     262    33664315 :     void set_output(MachineRepresentation output) { representation_ = output; }
     263             : 
     264             :     MachineRepresentation representation() const { return representation_; }
     265             : 
     266             :     // Helpers for feedback typing.
     267    20702598 :     void set_feedback_type(Type* type) { feedback_type_ = type; }
     268             :     Type* feedback_type() const { return feedback_type_; }
     269      110866 :     void set_weakened() { weakened_ = true; }
     270             :     bool weakened() const { return weakened_; }
     271    28709927 :     void set_restriction_type(Type* type) { restriction_type_ = type; }
     272             :     Type* restriction_type() const { return restriction_type_; }
     273             : 
     274             :    private:
     275             :     enum State : uint8_t { kUnvisited, kPushed, kVisited, kQueued };
     276             :     State state_ = kUnvisited;
     277             :     MachineRepresentation representation_ =
     278             :         MachineRepresentation::kNone;             // Output representation.
     279             :     Truncation truncation_ = Truncation::None();  // Information about uses.
     280             : 
     281             :     Type* restriction_type_ = Type::Any();
     282             :     Type* feedback_type_ = nullptr;
     283             :     bool weakened_ = false;
     284             :   };
     285             : 
     286     1183780 :   RepresentationSelector(JSGraph* jsgraph, Zone* zone,
     287             :                          RepresentationChanger* changer,
     288      394594 :                          SourcePositionTable* source_positions)
     289             :       : jsgraph_(jsgraph),
     290             :         zone_(zone),
     291      394593 :         count_(jsgraph->graph()->NodeCount()),
     292             :         info_(count_, zone),
     293             : #ifdef DEBUG
     294             :         node_input_use_infos_(count_, InputUseInfos(zone), zone),
     295             : #endif
     296             :         nodes_(zone),
     297             :         replacements_(zone),
     298             :         phase_(PROPAGATE),
     299             :         changer_(changer),
     300             :         queue_(zone),
     301             :         typing_stack_(zone),
     302             :         source_positions_(source_positions),
     303      394593 :         type_cache_(TypeCache::Get()),
     304     1972967 :         op_typer_(jsgraph->isolate(), graph_zone()) {
     305      394593 :   }
     306             : 
     307             :   // Forward propagation of types from type feedback.
     308     1183762 :   void RunTypePropagationPhase() {
     309             :     // Run type propagation.
     310      394594 :     TRACE("--{Type propagation phase}--\n");
     311      394594 :     phase_ = RETYPE;
     312             :     ResetNodeInfoState();
     313             : 
     314             :     DCHECK(typing_stack_.empty());
     315      789168 :     typing_stack_.push({graph()->end(), 0});
     316      394574 :     GetInfo(graph()->end())->set_pushed();
     317    57357181 :     while (!typing_stack_.empty()) {
     318             :       NodeState& current = typing_stack_.top();
     319             : 
     320             :       // If there is an unvisited input, push it and continue.
     321             :       bool pushed_unvisited = false;
     322   280807297 :       while (current.input_index < current.node->InputCount()) {
     323             :         Node* input = current.node->InputAt(current.input_index);
     324    83245139 :         NodeInfo* input_info = GetInfo(input);
     325    83245139 :         current.input_index++;
     326    83245139 :         if (input_info->unvisited()) {
     327             :           input_info->set_pushed();
     328    56570998 :           typing_stack_.push({input, 0});
     329             :           pushed_unvisited = true;
     330    28285627 :           break;
     331             :         }
     332             :       }
     333    56962843 :       if (pushed_unvisited) continue;
     334             : 
     335             :       // Process the top of the stack.
     336    28679697 :       Node* node = current.node;
     337             :       typing_stack_.pop();
     338             :       NodeInfo* info = GetInfo(node);
     339             :       info->set_visited();
     340    28679697 :       bool updated = UpdateFeedbackType(node);
     341    28679697 :       TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic());
     342    28679697 :       VisitNode(node, info->truncation(), nullptr);
     343    28679274 :       TRACE("  ==> output ");
     344    28679274 :       PrintOutputInfo(info);
     345    28679334 :       TRACE("\n");
     346    28679548 :       if (updated) {
     347   154530776 :         for (Node* const user : node->uses()) {
     348    67809123 :           if (GetInfo(user)->visited()) {
     349             :             GetInfo(user)->set_queued();
     350             :             queue_.push(user);
     351             :           }
     352             :         }
     353             :       }
     354             :     }
     355             : 
     356             :     // Process the revisit queue.
     357     6298236 :     while (!queue_.empty()) {
     358     5903643 :       Node* node = queue_.front();
     359             :       queue_.pop();
     360             :       NodeInfo* info = GetInfo(node);
     361             :       info->set_visited();
     362     5903647 :       bool updated = UpdateFeedbackType(node);
     363     5903665 :       TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic());
     364     5903665 :       VisitNode(node, info->truncation(), nullptr);
     365     5903653 :       TRACE("  ==> output ");
     366     5903653 :       PrintOutputInfo(info);
     367     5903654 :       TRACE("\n");
     368     5903646 :       if (updated) {
     369    14434580 :         for (Node* const user : node->uses()) {
     370     6322428 :           if (GetInfo(user)->visited()) {
     371             :             GetInfo(user)->set_queued();
     372             :             queue_.push(user);
     373             :           }
     374             :         }
     375             :       }
     376             :     }
     377      394593 :   }
     378             : 
     379             :   void ResetNodeInfoState() {
     380             :     // Clean up for the next phase.
     381    47768914 :     for (NodeInfo& info : info_) {
     382             :       info.reset_state();
     383             :     }
     384             :   }
     385             : 
     386             :   Type* TypeOf(Node* node) {
     387    28400307 :     Type* type = GetInfo(node)->feedback_type();
     388    28400307 :     return type == nullptr ? NodeProperties::GetType(node) : type;
     389             :   }
     390             : 
     391             :   Type* FeedbackTypeOf(Node* node) {
     392     4434236 :     Type* type = GetInfo(node)->feedback_type();
     393     4434236 :     return type == nullptr ? Type::None() : type;
     394             :   }
     395             : 
     396     1036140 :   Type* TypePhi(Node* node) {
     397     1036140 :     int arity = node->op()->ValueInputCount();
     398             :     Type* type = FeedbackTypeOf(node->InputAt(0));
     399     2633050 :     for (int i = 1; i < arity; ++i) {
     400     1596920 :       type = op_typer_.Merge(type, FeedbackTypeOf(node->InputAt(i)));
     401             :     }
     402     1036130 :     return type;
     403             :   }
     404             : 
     405       10462 :   Type* TypeSelect(Node* node) {
     406             :     return op_typer_.Merge(FeedbackTypeOf(node->InputAt(1)),
     407       10462 :                            FeedbackTypeOf(node->InputAt(2)));
     408             :   }
     409             : 
     410    36936492 :   bool UpdateFeedbackType(Node* node) {
     411    34583014 :     if (node->op()->ValueOutputCount() == 0) return false;
     412             : 
     413    25504989 :     NodeInfo* info = GetInfo(node);
     414             :     Type* type = info->feedback_type();
     415             :     Type* new_type = type;
     416             : 
     417             :     // For any non-phi node just wait until we get all inputs typed. We only
     418             :     // allow untyped inputs for phi nodes because phis are the only places
     419             :     // where cycles need to be broken.
     420    25143483 :     if (node->opcode() != IrOpcode::kPhi) {
     421   133468416 :       for (int i = 0; i < node->op()->ValueInputCount(); i++) {
     422    56116064 :         if (GetInfo(node->InputAt(i))->feedback_type() == nullptr) {
     423             :           return false;
     424             :         }
     425             :       }
     426             :     }
     427             : 
     428    23708022 :     switch (node->opcode()) {
     429             : #define DECLARE_CASE(Name)                                       \
     430             :   case IrOpcode::k##Name: {                                      \
     431             :     new_type = op_typer_.Name(FeedbackTypeOf(node->InputAt(0)),  \
     432             :                               FeedbackTypeOf(node->InputAt(1))); \
     433             :     break;                                                       \
     434             :   }
     435      476107 :       SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_CASE)
     436             : #undef DECLARE_CASE
     437             : 
     438             : #define DECLARE_CASE(Name)                                                \
     439             :   case IrOpcode::k##Name: {                                               \
     440             :     new_type =                                                            \
     441             :         Type::Intersect(op_typer_.Name(FeedbackTypeOf(node->InputAt(0)),  \
     442             :                                        FeedbackTypeOf(node->InputAt(1))), \
     443             :                         info->restriction_type(), graph_zone());          \
     444             :     break;                                                                \
     445             :   }
     446      358759 :       SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DECLARE_CASE)
     447             : #undef DECLARE_CASE
     448             : 
     449             : #define DECLARE_CASE(Name)                                       \
     450             :   case IrOpcode::k##Name: {                                      \
     451             :     new_type = op_typer_.Name(FeedbackTypeOf(node->InputAt(0))); \
     452             :     break;                                                       \
     453             :   }
     454       67492 :       SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_CASE)
     455             : #undef DECLARE_CASE
     456             : 
     457             : #define DECLARE_CASE(Name)                                                \
     458             :   case IrOpcode::k##Name: {                                               \
     459             :     new_type =                                                            \
     460             :         Type::Intersect(op_typer_.Name(FeedbackTypeOf(node->InputAt(0))), \
     461             :                         info->restriction_type(), graph_zone());          \
     462             :     break;                                                                \
     463             :   }
     464        1469 :       SIMPLIFIED_SPECULATIVE_NUMBER_UNOP_LIST(DECLARE_CASE)
     465             : #undef DECLARE_CASE
     466             : 
     467             :       case IrOpcode::kPlainPrimitiveToNumber:
     468       16401 :         new_type = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0)));
     469       16401 :         break;
     470             : 
     471             :       case IrOpcode::kCheckFloat64Hole:
     472             :         new_type = Type::Intersect(
     473             :             op_typer_.CheckFloat64Hole(FeedbackTypeOf(node->InputAt(0))),
     474         780 :             info->restriction_type(), graph_zone());
     475         780 :         break;
     476             : 
     477             :       case IrOpcode::kCheckNumber:
     478             :         new_type = Type::Intersect(
     479             :             op_typer_.CheckNumber(FeedbackTypeOf(node->InputAt(0))),
     480         498 :             info->restriction_type(), graph_zone());
     481         498 :         break;
     482             : 
     483             :       case IrOpcode::kPhi: {
     484     1036139 :         new_type = TypePhi(node);
     485     1036130 :         if (type != nullptr) {
     486      475727 :           new_type = Weaken(node, type, new_type);
     487             :         }
     488             :         break;
     489             :       }
     490             : 
     491             :       case IrOpcode::kTypeGuard: {
     492             :         new_type = op_typer_.TypeTypeGuard(node->op(),
     493       23880 :                                            FeedbackTypeOf(node->InputAt(0)));
     494       23880 :         break;
     495             :       }
     496             : 
     497             :       case IrOpcode::kSelect: {
     498       10462 :         new_type = TypeSelect(node);
     499       10462 :         break;
     500             :       }
     501             : 
     502             :       default:
     503             :         // Shortcut for operations that we do not handle.
     504    21716035 :         if (type == nullptr) {
     505             :           GetInfo(node)->set_feedback_type(NodeProperties::GetType(node));
     506    18908654 :           return true;
     507             :         }
     508             :         return false;
     509             :     }
     510             :     // We need to guarantee that the feedback type is a subtype of the upper
     511             :     // bound. Naively that should hold, but weakening can actually produce
     512             :     // a bigger type if we are unlucky with ordering of phi typing. To be
     513             :     // really sure, just intersect the upper bound with the feedback type.
     514     1991972 :     new_type = Type::Intersect(GetUpperBound(node), new_type, graph_zone());
     515             : 
     516     2818957 :     if (type != nullptr && new_type->Is(type)) return false;
     517             :     GetInfo(node)->set_feedback_type(new_type);
     518     1793944 :     if (FLAG_trace_representation) {
     519           0 :       PrintNodeFeedbackType(node);
     520             :     }
     521             :     return true;
     522             :   }
     523             : 
     524           0 :   void PrintNodeFeedbackType(Node* n) {
     525           0 :     OFStream os(stdout);
     526           0 :     os << "#" << n->id() << ":" << *n->op() << "(";
     527             :     int j = 0;
     528           0 :     for (Node* const i : n->inputs()) {
     529           0 :       if (j++ > 0) os << ", ";
     530           0 :       os << "#" << i->id() << ":" << i->op()->mnemonic();
     531             :     }
     532           0 :     os << ")";
     533           0 :     if (NodeProperties::IsTyped(n)) {
     534           0 :       os << "  [Static type: ";
     535             :       Type* static_type = NodeProperties::GetType(n);
     536           0 :       static_type->PrintTo(os);
     537           0 :       Type* feedback_type = GetInfo(n)->feedback_type();
     538           0 :       if (feedback_type != nullptr && feedback_type != static_type) {
     539           0 :         os << ", Feedback type: ";
     540           0 :         feedback_type->PrintTo(os);
     541             :       }
     542           0 :       os << "]";
     543             :     }
     544           0 :     os << std::endl;
     545           0 :   }
     546             : 
     547     1704366 :   Type* Weaken(Node* node, Type* previous_type, Type* current_type) {
     548             :     // If the types have nothing to do with integers, return the types.
     549      475726 :     Type* const integer = type_cache_.kInteger;
     550      475726 :     if (!previous_type->Maybe(integer)) {
     551             :       return current_type;
     552             :     }
     553             :     DCHECK(current_type->Maybe(integer));
     554             : 
     555             :     Type* current_integer =
     556      411614 :         Type::Intersect(current_type, integer, graph_zone());
     557             :     Type* previous_integer =
     558      411615 :         Type::Intersect(previous_type, integer, graph_zone());
     559             : 
     560             :     // Once we start weakening a node, we should always weaken.
     561      411613 :     if (!GetInfo(node)->weakened()) {
     562             :       // Only weaken if there is range involved; we should converge quickly
     563             :       // for all other types (the exception is a union of many constants,
     564             :       // but we currently do not increase the number of constants in unions).
     565      117068 :       Type* previous = previous_integer->GetRange();
     566      117068 :       Type* current = current_integer->GetRange();
     567      117068 :       if (current == nullptr || previous == nullptr) {
     568             :         return current_type;
     569             :       }
     570             :       // Range is involved => we are weakening.
     571             :       GetInfo(node)->set_weakened();
     572             :     }
     573             : 
     574             :     return Type::Union(current_type,
     575             :                        op_typer_.WeakenRange(previous_integer, current_integer),
     576      405411 :                        graph_zone());
     577             :   }
     578             : 
     579             :   // Backward propagation of truncations.
     580      394593 :   void RunTruncationPropagationPhase() {
     581             :     // Run propagation phase to a fixpoint.
     582      394593 :     TRACE("--{Propagation phase}--\n");
     583      394593 :     phase_ = PROPAGATE;
     584      394593 :     EnqueueInitial(jsgraph_->graph()->end());
     585             :     // Process nodes from the queue until it is empty.
     586    30704908 :     while (!queue_.empty()) {
     587    29915723 :       Node* node = queue_.front();
     588             :       NodeInfo* info = GetInfo(node);
     589             :       queue_.pop();
     590             :       info->set_visited();
     591    29915802 :       TRACE(" visit #%d: %s (trunc: %s)\n", node->id(), node->op()->mnemonic(),
     592             :             info->truncation().description());
     593    29915802 :       VisitNode(node, info->truncation(), nullptr);
     594             :     }
     595      394594 :   }
     596             : 
     597      394593 :   void Run(SimplifiedLowering* lowering) {
     598      394593 :     RunTruncationPropagationPhase();
     599             : 
     600      394594 :     RunTypePropagationPhase();
     601             : 
     602             :     // Run lowering and change insertion phase.
     603      394594 :     TRACE("--{Simplified lowering phase}--\n");
     604      394617 :     phase_ = LOWER;
     605             :     // Process nodes from the collected {nodes_} vector.
     606    29469524 :     for (NodeVector::iterator i = nodes_.begin(); i != nodes_.end(); ++i) {
     607    28680313 :       Node* node = *i;
     608             :       NodeInfo* info = GetInfo(node);
     609    28680313 :       TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic());
     610             :       // Reuse {VisitNode()} so the representation rules are in one place.
     611             :       SourcePositionTable::Scope scope(
     612    28680313 :           source_positions_, source_positions_->GetSourcePosition(node));
     613    28680312 :       VisitNode(node, info->truncation(), lowering);
     614             :     }
     615             : 
     616             :     // Perform the final replacements.
     617     1039808 :     for (NodeVector::iterator i = replacements_.begin();
     618             :          i != replacements_.end(); ++i) {
     619      250620 :       Node* node = *i;
     620      250620 :       Node* replacement = *(++i);
     621      250620 :       node->ReplaceUses(replacement);
     622      250620 :       node->Kill();
     623             :       // We also need to replace the node in the rest of the vector.
     624    16608306 :       for (NodeVector::iterator j = i + 1; j != replacements_.end(); ++j) {
     625             :         ++j;
     626    16107066 :         if (*j == node) *j = replacement;
     627             :       }
     628             :     }
     629      394594 :   }
     630             : 
     631      394593 :   void EnqueueInitial(Node* node) {
     632      394593 :     NodeInfo* info = GetInfo(node);
     633             :     info->set_queued();
     634      394593 :     nodes_.push_back(node);
     635             :     queue_.push(node);
     636      394591 :   }
     637             : 
     638             :   // Enqueue {use_node}'s {index} input if the {use} contains new information
     639             :   // for that input node. Add the input to {nodes_} if this is the first time
     640             :   // it's been visited.
     641   139044269 :   void EnqueueInput(Node* use_node, int index,
     642             :                     UseInfo use_info = UseInfo::None()) {
     643   139044269 :     Node* node = use_node->InputAt(index);
     644   218647550 :     if (phase_ != PROPAGATE) return;
     645    89610724 :     NodeInfo* info = GetInfo(node);
     646             : #ifdef DEBUG
     647             :     // Check monotonicity of input requirements.
     648             :     node_input_use_infos_[use_node->id()].SetAndCheckInput(use_node, index,
     649             :                                                            use_info);
     650             : #endif  // DEBUG
     651    87726509 :     if (info->unvisited()) {
     652             :       // First visit of this node.
     653             :       info->set_queued();
     654    28285567 :       nodes_.push_back(node);
     655             :       queue_.push(node);
     656    28285547 :       TRACE("  initial #%i: ", node->id());
     657    28285547 :       info->AddUse(use_info);
     658    28285504 :       PrintTruncation(info->truncation());
     659    28285521 :       return;
     660             :     }
     661    59440942 :     TRACE("   queue #%i?: ", node->id());
     662    59440942 :     PrintTruncation(info->truncation());
     663    59440913 :     if (info->AddUse(use_info)) {
     664             :       // New usage information for the node is available.
     665     1884215 :       if (!info->queued()) {
     666             :         queue_.push(node);
     667             :         info->set_queued();
     668     1236105 :         TRACE("   added: ");
     669             :       } else {
     670      648108 :         TRACE(" inqueue: ");
     671             :       }
     672     1884213 :       PrintTruncation(info->truncation());
     673             :     }
     674             :   }
     675             : 
     676             :   bool lower() const { return phase_ == LOWER; }
     677             :   bool retype() const { return phase_ == RETYPE; }
     678             :   bool propagate() const { return phase_ == PROPAGATE; }
     679             : 
     680             :   void SetOutput(Node* node, MachineRepresentation representation,
     681             :                  Type* restriction_type = Type::Any()) {
     682             :     NodeInfo* const info = GetInfo(node);
     683    90252732 :     switch (phase_) {
     684             :       case PROPAGATE:
     685             :         info->set_restriction_type(restriction_type);
     686             :         break;
     687             :       case RETYPE:
     688             :         DCHECK(info->restriction_type()->Is(restriction_type));
     689             :         DCHECK(restriction_type->Is(info->restriction_type()));
     690             :         info->set_output(representation);
     691             :         break;
     692             :       case LOWER:
     693             :         DCHECK_EQ(info->representation(), representation);
     694             :         DCHECK(info->restriction_type()->Is(restriction_type));
     695             :         DCHECK(restriction_type->Is(info->restriction_type()));
     696             :         break;
     697             :     }
     698             :   }
     699             : 
     700             :   Type* GetUpperBound(Node* node) { return NodeProperties::GetType(node); }
     701             : 
     702       57639 :   bool InputCannotBe(Node* node, Type* type) {
     703             :     DCHECK_EQ(1, node->op()->ValueInputCount());
     704       57639 :     return !GetUpperBound(node->InputAt(0))->Maybe(type);
     705             :   }
     706             : 
     707      182386 :   bool InputIs(Node* node, Type* type) {
     708             :     DCHECK_EQ(1, node->op()->ValueInputCount());
     709      182386 :     return GetUpperBound(node->InputAt(0))->Is(type);
     710             :   }
     711             : 
     712             :   bool BothInputsAreSigned32(Node* node) {
     713       98910 :     return BothInputsAre(node, Type::Signed32());
     714             :   }
     715             : 
     716             :   bool BothInputsAreUnsigned32(Node* node) {
     717      107906 :     return BothInputsAre(node, Type::Unsigned32());
     718             :   }
     719             : 
     720     4464200 :   bool BothInputsAre(Node* node, Type* type) {
     721             :     DCHECK_EQ(2, node->op()->ValueInputCount());
     722     6247724 :     return GetUpperBound(node->InputAt(0))->Is(type) &&
     723     4464154 :            GetUpperBound(node->InputAt(1))->Is(type);
     724             :   }
     725             : 
     726             :   bool IsNodeRepresentationTagged(Node* node) {
     727       42882 :     MachineRepresentation representation = GetInfo(node)->representation();
     728             :     return IsAnyTagged(representation);
     729             :   }
     730             : 
     731        2883 :   bool OneInputCannotBe(Node* node, Type* type) {
     732             :     DCHECK_EQ(2, node->op()->ValueInputCount());
     733        5766 :     return !GetUpperBound(node->InputAt(0))->Maybe(type) ||
     734        5766 :            !GetUpperBound(node->InputAt(1))->Maybe(type);
     735             :   }
     736             : 
     737    64016554 :   void ConvertInput(Node* node, int index, UseInfo use) {
     738           0 :     Node* input = node->InputAt(index);
     739             :     // In the change phase, insert a change before the use if necessary.
     740    50798013 :     if (use.representation() == MachineRepresentation::kNone)
     741    50798025 :       return;  // No input requirement on the use.
     742             :     DCHECK_NOT_NULL(input);
     743    61643750 :     NodeInfo* input_info = GetInfo(input);
     744             :     MachineRepresentation input_rep = input_info->representation();
     745    83724337 :     if (input_rep != use.representation() ||
     746    35299111 :         use.type_check() != TypeCheckKind::kNone) {
     747             :       // Output representation doesn't match usage.
     748    13218543 :       TRACE("  change: #%d:%s(@%d #%d:%s) ", node->id(), node->op()->mnemonic(),
     749             :             index, input->id(), input->op()->mnemonic());
     750    13218538 :       TRACE(" from ");
     751    13218538 :       PrintOutputInfo(input_info);
     752    13218541 :       TRACE(" to ");
     753    13218541 :       PrintUseInfo(use);
     754    13218519 :       TRACE("\n");
     755             :       Node* n = changer_->GetRepresentationFor(
     756    13218524 :           input, input_info->representation(), TypeOf(input), node, use);
     757    13218556 :       node->ReplaceInput(index, n);
     758             :     }
     759             :   }
     760             : 
     761   167059102 :   void ProcessInput(Node* node, int index, UseInfo use) {
     762   167059102 :     switch (phase_) {
     763             :       case PROPAGATE:
     764    53688393 :         EnqueueInput(node, index, use);
     765    53687471 :         break;
     766             :       case RETYPE:
     767             :         break;
     768             :       case LOWER:
     769    50797820 :         ConvertInput(node, index, use);
     770    50797665 :         break;
     771             :     }
     772   167058025 :   }
     773             : 
     774    13107742 :   void ProcessRemainingInputs(Node* node, int index) {
     775             :     DCHECK_GE(index, NodeProperties::PastValueIndex(node));
     776             :     DCHECK_GE(index, NodeProperties::PastContextIndex(node));
     777    58126722 :     for (int i = std::max(index, NodeProperties::FirstEffectIndex(node));
     778    22509515 :          i < NodeProperties::PastEffectIndex(node); ++i) {
     779     9401794 :       EnqueueInput(node, i);  // Effect inputs: just visit
     780             :     }
     781    58266923 :     for (int i = std::max(index, NodeProperties::FirstControlIndex(node));
     782    22579617 :          i < NodeProperties::PastControlIndex(node); ++i) {
     783     9471966 :       EnqueueInput(node, i);  // Control inputs: just visit
     784             :     }
     785    13107695 :   }
     786             : 
     787             :   // The default, most general visitation case. For {node}, process all value,
     788             :   // context, frame state, effect, and control inputs, assuming that value
     789             :   // inputs should have {kRepTagged} representation and can observe all output
     790             :   // values {kTypeAny}.
     791    78619771 :   void VisitInputs(Node* node) {
     792    78619771 :     int tagged_count = node->op()->ValueInputCount() +
     793             :                        OperatorProperties::GetContextInputCount(node->op()) +
     794    39308707 :                        OperatorProperties::GetFrameStateInputCount(node->op());
     795             :     // Visit value, context and frame state inputs as tagged.
     796   149549339 :     for (int i = 0; i < tagged_count; i++) {
     797   110240520 :       ProcessInput(node, i, UseInfo::AnyTagged());
     798             :     }
     799             :     // Only enqueue other inputs (effects, control).
     800   136974641 :     for (int i = tagged_count; i < node->InputCount(); i++) {
     801    48832756 :       EnqueueInput(node, i);
     802             :     }
     803    39308974 :   }
     804             : 
     805     3186142 :   void VisitReturn(Node* node) {
     806     3186142 :     int tagged_limit = node->op()->ValueInputCount() +
     807             :                        OperatorProperties::GetContextInputCount(node->op()) +
     808     1593072 :                        OperatorProperties::GetFrameStateInputCount(node->op());
     809             :     // Visit integer slot count to pop
     810     1593072 :     ProcessInput(node, 0, UseInfo::TruncatingWord32());
     811             : 
     812             :     // Visit value, context and frame state inputs as tagged.
     813     3186137 :     for (int i = 1; i < tagged_limit; i++) {
     814     1593069 :       ProcessInput(node, i, UseInfo::AnyTagged());
     815             :     }
     816             :     // Only enqueue other inputs (effects, control).
     817     7965360 :     for (int i = tagged_limit; i < node->InputCount(); i++) {
     818     3186139 :       EnqueueInput(node, i);
     819             :     }
     820     1593075 :   }
     821             : 
     822             :   // Helper for an unused node.
     823     1708078 :   void VisitUnused(Node* node) {
     824     1138720 :     int value_count = node->op()->ValueInputCount() +
     825             :                       OperatorProperties::GetContextInputCount(node->op()) +
     826      569356 :                       OperatorProperties::GetFrameStateInputCount(node->op());
     827     1501477 :     for (int i = 0; i < value_count; i++) {
     828      932118 :       ProcessInput(node, i, UseInfo::None());
     829             :     }
     830      569359 :     ProcessRemainingInputs(node, value_count);
     831      569358 :     if (lower()) Kill(node);
     832      569358 :   }
     833             : 
     834             :   // Helper for no-op node.
     835         356 :   void VisitNoop(Node* node, Truncation truncation) {
     836         372 :     if (truncation.IsUnused()) return VisitUnused(node);
     837             :     MachineRepresentation representation =
     838         170 :         GetOutputInfoForPhi(node, TypeOf(node), truncation);
     839         170 :     VisitUnop(node, UseInfo(representation, truncation), representation);
     840         231 :     if (lower()) DeferReplacement(node, node->InputAt(0));
     841             :   }
     842             : 
     843             :   // Helper for binops of the R x L -> O variety.
     844     3706082 :   void VisitBinop(Node* node, UseInfo left_use, UseInfo right_use,
     845             :                   MachineRepresentation output,
     846             :                   Type* restriction_type = Type::Any()) {
     847             :     DCHECK_EQ(2, node->op()->ValueInputCount());
     848     3706082 :     ProcessInput(node, 0, left_use);
     849     3706086 :     ProcessInput(node, 1, right_use);
     850    13914844 :     for (int i = 2; i < node->InputCount(); i++) {
     851     3251357 :       EnqueueInput(node, i);
     852             :     }
     853             :     SetOutput(node, output, restriction_type);
     854     3706065 :   }
     855             : 
     856             :   // Helper for binops of the I x I -> O variety.
     857             :   void VisitBinop(Node* node, UseInfo input_use, MachineRepresentation output,
     858             :                   Type* restriction_type = Type::Any()) {
     859     2936964 :     VisitBinop(node, input_use, input_use, output, restriction_type);
     860             :   }
     861             : 
     862      104343 :   void VisitSpeculativeInt32Binop(Node* node) {
     863             :     DCHECK_EQ(2, node->op()->ValueInputCount());
     864       84022 :     if (BothInputsAre(node, Type::NumberOrOddball())) {
     865             :       return VisitBinop(node, UseInfo::TruncatingWord32(),
     866             :                         MachineRepresentation::kWord32);
     867             :     }
     868       20321 :     NumberOperationHint hint = NumberOperationHintOf(node->op());
     869             :     return VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
     870       20321 :                       MachineRepresentation::kWord32);
     871             :   }
     872             : 
     873             :   // Helper for unops of the I -> O variety.
     874     6620993 :   void VisitUnop(Node* node, UseInfo input_use, MachineRepresentation output,
     875             :                  Type* restriction_type = Type::Any()) {
     876             :     DCHECK_EQ(1, node->op()->ValueInputCount());
     877     6620993 :     ProcessInput(node, 0, input_use);
     878     6620994 :     ProcessRemainingInputs(node, 1);
     879             :     SetOutput(node, output, restriction_type);
     880     6620983 :   }
     881             : 
     882             :   // Helper for leaf nodes.
     883             :   void VisitLeaf(Node* node, MachineRepresentation output) {
     884             :     DCHECK_EQ(0, node->InputCount());
     885             :     SetOutput(node, output);
     886             :   }
     887             : 
     888             :   // Helpers for specific types of binops.
     889      665475 :   void VisitFloat64Binop(Node* node) {
     890             :     VisitBinop(node, UseInfo::TruncatingFloat64(),
     891             :                MachineRepresentation::kFloat64);
     892      665478 :   }
     893      492900 :   void VisitWord32TruncatingBinop(Node* node) {
     894             :     VisitBinop(node, UseInfo::TruncatingWord32(),
     895             :                MachineRepresentation::kWord32);
     896      492902 :   }
     897             : 
     898             :   // Infer representation for phi-like nodes.
     899             :   // The {node} parameter is only used to decide on the int64 representation.
     900             :   // Once the type system supports an external pointer type, the {node}
     901             :   // parameter can be removed.
     902     2334158 :   MachineRepresentation GetOutputInfoForPhi(Node* node, Type* type,
     903     1730263 :                                             Truncation use) {
     904             :     // Compute the representation.
     905     2334158 :     if (type->Is(Type::None())) {
     906             :       return MachineRepresentation::kNone;
     907     4218192 :     } else if (type->Is(Type::Signed32()) || type->Is(Type::Unsigned32())) {
     908             :       return MachineRepresentation::kWord32;
     909     2729617 :     } else if (type->Is(Type::NumberOrOddball()) && use.IsUsedAsWord32()) {
     910             :       return MachineRepresentation::kWord32;
     911     1912732 :     } else if (type->Is(Type::Boolean())) {
     912             :       return MachineRepresentation::kBit;
     913     2516807 :     } else if (type->Is(Type::NumberOrOddball()) && use.IsUsedAsFloat64()) {
     914             :       return MachineRepresentation::kFloat64;
     915     1730259 :     } else if (type->Is(
     916     1730263 :                    Type::Union(Type::SignedSmall(), Type::NaN(), zone()))) {
     917             :       // TODO(turbofan): For Phis that return either NaN or some Smi, it's
     918             :       // beneficial to not go all the way to double, unless the uses are
     919             :       // double uses. For tagging that just means some potentially expensive
     920             :       // allocation code; we might want to do the same for -0 as well?
     921             :       return MachineRepresentation::kTagged;
     922     1729552 :     } else if (type->Is(Type::Number())) {
     923             :       return MachineRepresentation::kFloat64;
     924     1122403 :     } else if (type->Is(Type::ExternalPointer())) {
     925             :       return MachineType::PointerRepresentation();
     926             :     }
     927     1122403 :     return MachineRepresentation::kTagged;
     928             :   }
     929             : 
     930             :   // Helper for handling selects.
     931       43055 :   void VisitSelect(Node* node, Truncation truncation,
     932       32593 :                    SimplifiedLowering* lowering) {
     933             :     DCHECK(TypeOf(node->InputAt(0))->Is(Type::Boolean()));
     934       32593 :     ProcessInput(node, 0, UseInfo::Bool());
     935             : 
     936             :     MachineRepresentation output =
     937       32593 :         GetOutputInfoForPhi(node, TypeOf(node), truncation);
     938             :     SetOutput(node, output);
     939             : 
     940       32593 :     if (lower()) {
     941             :       // Update the select operator.
     942       10462 :       SelectParameters p = SelectParametersOf(node->op());
     943       10462 :       if (output != p.representation()) {
     944             :         NodeProperties::ChangeOp(node,
     945       10452 :                                  lowering->common()->Select(output, p.hint()));
     946             :       }
     947             :     }
     948             :     // Convert inputs to the output representation of this phi, pass the
     949             :     // truncation truncation along.
     950             :     UseInfo input_use(output, truncation);
     951       32593 :     ProcessInput(node, 1, input_use);
     952       32593 :     ProcessInput(node, 2, input_use);
     953       32593 :   }
     954             : 
     955             :   // Helper for handling phis.
     956     4463892 :   void VisitPhi(Node* node, Truncation truncation,
     957     2231950 :                 SimplifiedLowering* lowering) {
     958             :     MachineRepresentation output =
     959     2231942 :         GetOutputInfoForPhi(node, TypeOf(node), truncation);
     960             :     // Only set the output representation if not running with type
     961             :     // feedback. (Feedback typing will set the representation.)
     962             :     SetOutput(node, output);
     963             : 
     964     2231950 :     int values = node->op()->ValueInputCount();
     965     2231950 :     if (lower()) {
     966             :       // Update the phi operator.
     967      560418 :       if (output != PhiRepresentationOf(node->op())) {
     968      206288 :         NodeProperties::ChangeOp(node, lowering->common()->Phi(output, values));
     969             :       }
     970             :     }
     971             : 
     972             :     // Convert inputs to the output representation of this phi, pass the
     973             :     // truncation along.
     974             :     UseInfo input_use(output, truncation);
     975    20810324 :     for (int i = 0; i < node->InputCount(); i++) {
     976     8173231 :       ProcessInput(node, i, i < values ? input_use : UseInfo::None());
     977             :     }
     978     2231931 :   }
     979             : 
     980      453825 :   void VisitObjectIs(Node* node, Type* type, SimplifiedLowering* lowering) {
     981             :     Type* const input_type = TypeOf(node->InputAt(0));
     982      226699 :     if (input_type->Is(type)) {
     983         864 :       VisitUnop(node, UseInfo::None(), MachineRepresentation::kBit);
     984         864 :       if (lower()) {
     985         237 :         DeferReplacement(node, lowering->jsgraph()->Int32Constant(1));
     986             :       }
     987             :     } else {
     988      225835 :       VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
     989      225835 :       if (lower() && !input_type->Maybe(type)) {
     990         190 :         DeferReplacement(node, lowering->jsgraph()->Int32Constant(0));
     991             :       }
     992             :     }
     993      226699 :   }
     994             : 
     995     4463222 :   void VisitCall(Node* node, SimplifiedLowering* lowering) {
     996     4463229 :     const CallDescriptor* desc = CallDescriptorOf(node->op());
     997     2231610 :     int params = static_cast<int>(desc->ParameterCount());
     998     2231610 :     int value_input_count = node->op()->ValueInputCount();
     999             :     // Propagate representation information from call descriptor.
    1000    22132370 :     for (int i = 0; i < value_input_count; i++) {
    1001    19900754 :       if (i == 0) {
    1002             :         // The target of the call.
    1003     2231577 :         ProcessInput(node, i, UseInfo::Any());
    1004    17669177 :       } else if ((i - 1) < params) {
    1005             :         ProcessInput(node, i, TruncatingUseInfoFromRepresentation(
    1006    30909090 :                                   desc->GetInputType(i).representation()));
    1007             :       } else {
    1008     2214632 :         ProcessInput(node, i, UseInfo::AnyTagged());
    1009             :       }
    1010             :     }
    1011     2231616 :     ProcessRemainingInputs(node, value_input_count);
    1012             : 
    1013     2231617 :     if (desc->ReturnCount() > 0) {
    1014             :       SetOutput(node, desc->GetReturnType(0).representation());
    1015             :     } else {
    1016             :       SetOutput(node, MachineRepresentation::kTagged);
    1017             :     }
    1018     2231617 :   }
    1019             : 
    1020      525377 :   static MachineSemantic DeoptValueSemanticOf(Type* type) {
    1021             :     // We only need signedness to do deopt correctly.
    1022      525386 :     if (type->Is(Type::Signed32())) {
    1023             :       return MachineSemantic::kInt32;
    1024      322856 :     } else if (type->Is(Type::Unsigned32())) {
    1025             :       return MachineSemantic::kUint32;
    1026             :     } else {
    1027      322079 :       return MachineSemantic::kAny;
    1028             :     }
    1029             :   }
    1030             : 
    1031     8870648 :   static MachineType DeoptMachineTypeOf(MachineRepresentation rep, Type* type) {
    1032     8870670 :     if (!type->IsInhabited()) {
    1033             :       return MachineType::None();
    1034             :     }
    1035             :     // TODO(turbofan): Special treatment for ExternalPointer here,
    1036             :     // to avoid incompatible truncations. We really need a story
    1037             :     // for the JSFunction::entry field.
    1038     8870666 :     if (type->Is(Type::ExternalPointer())) {
    1039             :       return MachineType::Pointer();
    1040             :     }
    1041             :     // Do not distinguish between various Tagged variations.
    1042     8870666 :     if (IsAnyTagged(rep)) {
    1043             :       return MachineType::AnyTagged();
    1044             :     }
    1045      525373 :     MachineType machine_type(rep, DeoptValueSemanticOf(type));
    1046             :     DCHECK(machine_type.representation() != MachineRepresentation::kWord32 ||
    1047             :            machine_type.semantic() == MachineSemantic::kInt32 ||
    1048             :            machine_type.semantic() == MachineSemantic::kUint32);
    1049             :     DCHECK(machine_type.representation() != MachineRepresentation::kBit ||
    1050             :            type->Is(Type::Boolean()));
    1051      525386 :     return machine_type;
    1052             :   }
    1053             : 
    1054    20404025 :   void VisitStateValues(Node* node) {
    1055    15883366 :     if (propagate()) {
    1056    22175816 :       for (int i = 0; i < node->InputCount(); i++) {
    1057     8827620 :         EnqueueInput(node, i, UseInfo::Any());
    1058             :       }
    1059    11362798 :     } else if (lower()) {
    1060     9041310 :       Zone* zone = jsgraph_->zone();
    1061             :       ZoneVector<MachineType>* types =
    1062             :           new (zone->New(sizeof(ZoneVector<MachineType>)))
    1063     4520654 :               ZoneVector<MachineType>(node->InputCount(), zone);
    1064    26696628 :       for (int i = 0; i < node->InputCount(); i++) {
    1065             :         Node* input = node->InputAt(i);
    1066     8827655 :         (*types)[i] =
    1067     8827655 :             DeoptMachineTypeOf(GetInfo(input)->representation(), TypeOf(input));
    1068             :       }
    1069     4520659 :       SparseInputMask mask = SparseInputMaskOf(node->op());
    1070             :       NodeProperties::ChangeOp(
    1071     9041312 :           node, jsgraph_->common()->TypedStateValues(types, mask));
    1072             :     }
    1073             :     SetOutput(node, MachineRepresentation::kTagged);
    1074    15883364 :   }
    1075             : 
    1076       28124 :   void VisitObjectState(Node* node) {
    1077       28124 :     if (propagate()) {
    1078       94884 :       for (int i = 0; i < node->InputCount(); i++) {
    1079             :         Node* input = node->InputAt(i);
    1080             :         Type* input_type = TypeOf(input);
    1081             :         // TODO(turbofan): Special treatment for ExternalPointer here,
    1082             :         // to avoid incompatible truncations. We really need a story
    1083             :         // for the JSFunction::entry field.
    1084       42991 :         UseInfo use_info = UseInfo::None();
    1085       42991 :         if (input_type->IsInhabited()) {
    1086       42991 :           if (input_type->Is(Type::ExternalPointer())) {
    1087           0 :             use_info = UseInfo::PointerInt();
    1088             :           } else {
    1089       42991 :             use_info = UseInfo::Any();
    1090             :           }
    1091             :         }
    1092       42991 :         EnqueueInput(node, i, use_info);
    1093             :       }
    1094       19222 :     } else if (lower()) {
    1095       17804 :       Zone* zone = jsgraph_->zone();
    1096             :       ZoneVector<MachineType>* types =
    1097             :           new (zone->New(sizeof(ZoneVector<MachineType>)))
    1098        8902 :               ZoneVector<MachineType>(node->InputCount(), zone);
    1099      103786 :       for (int i = 0; i < node->InputCount(); i++) {
    1100             :         Node* input = node->InputAt(i);
    1101       42991 :         (*types)[i] =
    1102       42991 :             DeoptMachineTypeOf(GetInfo(input)->representation(), TypeOf(input));
    1103             :       }
    1104             :       NodeProperties::ChangeOp(node,
    1105       17804 :                                jsgraph_->common()->TypedObjectState(types));
    1106             :     }
    1107             :     SetOutput(node, MachineRepresentation::kTagged);
    1108       28124 :   }
    1109             : 
    1110      257998 :   const Operator* Int32Op(Node* node) {
    1111      257998 :     return changer_->Int32OperatorFor(node->opcode());
    1112             :   }
    1113             : 
    1114      150668 :   const Operator* Int32OverflowOp(Node* node) {
    1115      150668 :     return changer_->Int32OverflowOperatorFor(node->opcode());
    1116             :   }
    1117             : 
    1118       69475 :   const Operator* Uint32Op(Node* node) {
    1119       69475 :     return changer_->Uint32OperatorFor(node->opcode());
    1120             :   }
    1121             : 
    1122         190 :   const Operator* Uint32OverflowOp(Node* node) {
    1123         190 :     return changer_->Uint32OverflowOperatorFor(node->opcode());
    1124             :   }
    1125             : 
    1126      183795 :   const Operator* Float64Op(Node* node) {
    1127      183795 :     return changer_->Float64OperatorFor(node->opcode());
    1128             :   }
    1129             : 
    1130     2969420 :   WriteBarrierKind WriteBarrierKindFor(
    1131             :       BaseTaggedness base_taggedness,
    1132             :       MachineRepresentation field_representation, Type* field_type,
    1133             :       MachineRepresentation value_representation, Node* value) {
    1134     5813949 :     if (base_taggedness == kTaggedBase &&
    1135             :         CanBeTaggedPointer(field_representation)) {
    1136             :       Type* value_type = NodeProperties::GetType(value);
    1137     5065960 :       if (field_representation == MachineRepresentation::kTaggedSigned ||
    1138     2532980 :           value_representation == MachineRepresentation::kTaggedSigned) {
    1139             :         // Write barriers are only for stores of heap objects.
    1140             :         return kNoWriteBarrier;
    1141             :       }
    1142     5053940 :       if (field_type->Is(Type::BooleanOrNullOrUndefined()) ||
    1143             :           value_type->Is(Type::BooleanOrNullOrUndefined())) {
    1144             :         // Write barriers are not necessary when storing true, false, null or
    1145             :         // undefined, because these special oddballs are always in the root set.
    1146             :         return kNoWriteBarrier;
    1147             :       }
    1148     2243704 :       if (value_type->IsHeapConstant()) {
    1149             :         Heap::RootListIndex root_index;
    1150      820727 :         Heap* heap = jsgraph_->isolate()->heap();
    1151      820727 :         if (heap->IsRootHandle(value_type->AsHeapConstant()->Value(),
    1152             :                                &root_index)) {
    1153      443799 :           if (heap->RootIsImmortalImmovable(root_index)) {
    1154             :             // Write barriers are unnecessary for immortal immovable roots.
    1155             :             return kNoWriteBarrier;
    1156             :           }
    1157             :         }
    1158             :       }
    1159     3599812 :       if (field_representation == MachineRepresentation::kTaggedPointer ||
    1160     1799906 :           value_representation == MachineRepresentation::kTaggedPointer) {
    1161             :         // Write barriers for heap objects are cheaper.
    1162             :         return kPointerWriteBarrier;
    1163             :       }
    1164             :       NumberMatcher m(value);
    1165     1407978 :       if (m.HasValue()) {
    1166      552168 :         if (IsSmiDouble(m.Value())) {
    1167             :           // Storing a smi doesn't need a write barrier.
    1168             :           return kNoWriteBarrier;
    1169             :         }
    1170             :         // The NumberConstant will be represented as HeapNumber.
    1171         618 :         return kPointerWriteBarrier;
    1172             :       }
    1173             :       return kFullWriteBarrier;
    1174             :     }
    1175             :     return kNoWriteBarrier;
    1176             :   }
    1177             : 
    1178             :   WriteBarrierKind WriteBarrierKindFor(
    1179             :       BaseTaggedness base_taggedness,
    1180             :       MachineRepresentation field_representation, int field_offset,
    1181             :       Type* field_type, MachineRepresentation value_representation,
    1182             :       Node* value) {
    1183     5521690 :     if (base_taggedness == kTaggedBase &&
    1184     2760845 :         field_offset == HeapObject::kMapOffset) {
    1185             :       return kMapWriteBarrier;
    1186             :     }
    1187             :     return WriteBarrierKindFor(base_taggedness, field_representation,
    1188     2474504 :                                field_type, value_representation, value);
    1189             :   }
    1190             : 
    1191      789168 :   Graph* graph() const { return jsgraph_->graph(); }
    1192             :   CommonOperatorBuilder* common() const { return jsgraph_->common(); }
    1193             :   SimplifiedOperatorBuilder* simplified() const {
    1194       15527 :     return jsgraph_->simplified();
    1195             :   }
    1196             : 
    1197        7215 :   void LowerToCheckedInt32Mul(Node* node, Truncation truncation,
    1198        7215 :                               Type* input0_type, Type* input1_type) {
    1199             :     // If one of the inputs is positive and/or truncation is being applied,
    1200             :     // there is no need to return -0.
    1201             :     CheckForMinusZeroMode mz_mode =
    1202        5515 :         truncation.IdentifiesZeroAndMinusZero() ||
    1203        1721 :                 (input0_type->Is(Type::OrderedNumber()) &&
    1204        7217 :                  input0_type->Min() > 0) ||
    1205        5396 :                 (input1_type->Is(Type::OrderedNumber()) &&
    1206        5396 :                  input1_type->Min() > 0)
    1207             :             ? CheckForMinusZeroMode::kDontCheckForMinusZero
    1208        7215 :             : CheckForMinusZeroMode::kCheckForMinusZero;
    1209             : 
    1210        7215 :     NodeProperties::ChangeOp(node, simplified()->CheckedInt32Mul(mz_mode));
    1211        7215 :   }
    1212             : 
    1213      150668 :   void ChangeToInt32OverflowOp(Node* node) {
    1214      150667 :     NodeProperties::ChangeOp(node, Int32OverflowOp(node));
    1215      150667 :   }
    1216             : 
    1217         190 :   void ChangeToUint32OverflowOp(Node* node) {
    1218         190 :     NodeProperties::ChangeOp(node, Uint32OverflowOp(node));
    1219         190 :   }
    1220             : 
    1221     2033343 :   void VisitSpeculativeAdditiveOp(Node* node, Truncation truncation,
    1222     1030972 :                                   SimplifiedLowering* lowering) {
    1223             :     // ToNumber(x) can throw if x is either a Receiver or a Symbol, so we can
    1224             :     // only eliminate an unused speculative number operation if we know that
    1225             :     // the inputs are PlainPrimitive, which excludes everything that's might
    1226             :     // have side effects or throws during a ToNumber conversion. We are only
    1227             :     // allowed to perform a number addition if neither input is a String, even
    1228             :     // if the value is never used, so we further limit to NumberOrOddball in
    1229             :     // order to explicitly exclude String inputs.
    1230      853137 :     if (BothInputsAre(node, Type::NumberOrOddball())) {
    1231      560225 :       if (truncation.IsUnused()) return VisitUnused(node);
    1232             :     }
    1233             : 
    1234     1924831 :     if (BothInputsAre(node, type_cache_.kAdditiveSafeIntegerOrMinusZero) &&
    1235       46472 :         (GetUpperBound(node)->Is(Type::Signed32()) ||
    1236       43282 :          GetUpperBound(node)->Is(Type::Unsigned32()) ||
    1237             :          truncation.IsUsedAsWord32())) {
    1238             :       // => Int32Add/Sub
    1239      272606 :       VisitWord32TruncatingBinop(node);
    1240      336646 :       if (lower()) ChangeToPureOp(node, Int32Op(node));
    1241             :       return;
    1242             :     }
    1243             : 
    1244             :     // Try to use type feedback.
    1245      533753 :     NumberOperationHint hint = NumberOperationHintOf(node->op());
    1246             : 
    1247      533756 :     if (hint == NumberOperationHint::kSignedSmall ||
    1248             :         hint == NumberOperationHint::kSigned32) {
    1249             :       Type* left_feedback_type = TypeOf(node->InputAt(0));
    1250             :       Type* right_feedback_type = TypeOf(node->InputAt(1));
    1251             :       // Handle the case when no int32 checks on inputs are necessary (but
    1252             :       // an overflow check is needed on the output).
    1253             :       // TODO(jarin) We should not look at the upper bound because the typer
    1254             :       // could have already baked in some feedback into the upper bound.
    1255     1552572 :       if (BothInputsAre(node, Type::Signed32()) ||
    1256      492204 :           (BothInputsAre(node, Type::Signed32OrMinusZero()) &&
    1257           0 :            GetUpperBound(node)->Is(type_cache_.kSafeInteger))) {
    1258             :         VisitBinop(node, UseInfo::TruncatingWord32(),
    1259             :                    MachineRepresentation::kWord32, Type::Signed32());
    1260             :       } else {
    1261             :         // If the output's truncation is identify-zeros, we can pass it
    1262             :         // along. Moreover, if the operation is addition and we know the
    1263             :         // right-hand side is not minus zero, we do not have to distinguish
    1264             :         // between 0 and -0.
    1265      492206 :         IdentifyZeros left_identify_zeros = truncation.identify_zeros();
    1266      927257 :         if (node->opcode() == IrOpcode::kSpeculativeNumberAdd &&
    1267      435037 :             !right_feedback_type->Maybe(Type::MinusZero())) {
    1268             :           left_identify_zeros = kIdentifyZeros;
    1269             :         }
    1270             :         UseInfo left_use =
    1271      492220 :             CheckedUseInfoAsWord32FromHint(hint, left_identify_zeros);
    1272             :         // For CheckedInt32Add and CheckedInt32Sub, we don't need to do
    1273             :         // a minus zero check for the right hand side, since we already
    1274             :         // know that the left hand side is a proper Signed32 value,
    1275             :         // potentially guarded by a check.
    1276             :         UseInfo right_use =
    1277      492216 :             CheckedUseInfoAsWord32FromHint(hint, kIdentifyZeros);
    1278             :         VisitBinop(node, left_use, right_use, MachineRepresentation::kWord32,
    1279      492205 :                    Type::Signed32());
    1280             :       }
    1281      530225 :       if (lower()) {
    1282      154247 :         if (CanOverflowSigned32(node->op(), left_feedback_type,
    1283             :                                 right_feedback_type, graph_zone())) {
    1284      149013 :           ChangeToInt32OverflowOp(node);
    1285             :         } else {
    1286        5239 :           ChangeToPureOp(node, Int32Op(node));
    1287             :         }
    1288             :       }
    1289             :       return;
    1290             :     }
    1291             : 
    1292             :     // default case => Float64Add/Sub
    1293             :     VisitBinop(node, UseInfo::CheckedNumberOrOddballAsFloat64(),
    1294             :                MachineRepresentation::kFloat64, Type::Number());
    1295        3575 :     if (lower()) {
    1296        1040 :       ChangeToPureOp(node, Float64Op(node));
    1297             :     }
    1298             :     return;
    1299             :   }
    1300             : 
    1301       22379 :   void VisitSpeculativeNumberModulus(Node* node, Truncation truncation,
    1302       14639 :                                      SimplifiedLowering* lowering) {
    1303             :     // ToNumber(x) can throw if x is either a Receiver or a Symbol, so we
    1304             :     // can only eliminate an unused speculative number operation if we know
    1305             :     // that the inputs are PlainPrimitive, which excludes everything that's
    1306             :     // might have side effects or throws during a ToNumber conversion.
    1307       14709 :     if (BothInputsAre(node, Type::PlainPrimitive())) {
    1308        8895 :       if (truncation.IsUnused()) return VisitUnused(node);
    1309             :     }
    1310       30031 :     if (BothInputsAre(node, Type::Unsigned32OrMinusZeroOrNaN()) &&
    1311         291 :         (truncation.IsUsedAsWord32() ||
    1312             :          NodeProperties::GetType(node)->Is(Type::Unsigned32()))) {
    1313             :       // => unsigned Uint32Mod
    1314         803 :       VisitWord32TruncatingBinop(node);
    1315         803 :       if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
    1316             :       return;
    1317             :     }
    1318       34928 :     if (BothInputsAre(node, Type::Signed32OrMinusZeroOrNaN()) &&
    1319        1570 :         (truncation.IsUsedAsWord32() ||
    1320             :          NodeProperties::GetType(node)->Is(Type::Signed32()))) {
    1321             :       // => signed Int32Mod
    1322        6006 :       VisitWord32TruncatingBinop(node);
    1323        6006 :       if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
    1324             :       return;
    1325             :     }
    1326             : 
    1327             :     // Try to use type feedback.
    1328        7670 :     NumberOperationHint hint = NumberOperationHintOf(node->op());
    1329             : 
    1330             :     // Handle the case when no uint32 checks on inputs are necessary
    1331             :     // (but an overflow check is needed on the output).
    1332        7670 :     if (BothInputsAreUnsigned32(node)) {
    1333         270 :       if (hint == NumberOperationHint::kSignedSmall ||
    1334             :           hint == NumberOperationHint::kSigned32) {
    1335             :         VisitBinop(node, UseInfo::TruncatingWord32(),
    1336             :                    MachineRepresentation::kWord32, Type::Unsigned32());
    1337         270 :         if (lower()) ChangeToUint32OverflowOp(node);
    1338             :         return;
    1339             :       }
    1340             :     }
    1341             : 
    1342             :     // Handle the case when no int32 checks on inputs are necessary
    1343             :     // (but an overflow check is needed on the output).
    1344        7400 :     if (BothInputsAre(node, Type::Signed32())) {
    1345             :       // If both the inputs the feedback are int32, use the overflow op.
    1346        1300 :       if (hint == NumberOperationHint::kSignedSmall ||
    1347             :           hint == NumberOperationHint::kSigned32) {
    1348             :         VisitBinop(node, UseInfo::TruncatingWord32(),
    1349             :                    MachineRepresentation::kWord32, Type::Signed32());
    1350        1300 :         if (lower()) ChangeToInt32OverflowOp(node);
    1351             :         return;
    1352             :       }
    1353             :     }
    1354             : 
    1355        6100 :     if (hint == NumberOperationHint::kSignedSmall ||
    1356             :         hint == NumberOperationHint::kSigned32) {
    1357             :       // If the result is truncated, we only need to check the inputs.
    1358        5458 :       if (truncation.IsUsedAsWord32()) {
    1359             :         VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
    1360        1133 :                    MachineRepresentation::kWord32);
    1361        1133 :         if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
    1362        4325 :       } else if (BothInputsAre(node, Type::Unsigned32OrMinusZeroOrNaN())) {
    1363             :         VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
    1364           0 :                    MachineRepresentation::kWord32, Type::Unsigned32());
    1365           0 :         if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
    1366             :       } else {
    1367             :         VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
    1368        4325 :                    MachineRepresentation::kWord32, Type::Signed32());
    1369        4325 :         if (lower()) ChangeToInt32OverflowOp(node);
    1370             :       }
    1371             :       return;
    1372             :     }
    1373             : 
    1374         702 :     if (TypeOf(node->InputAt(0))->Is(Type::Unsigned32()) &&
    1375         642 :         TypeOf(node->InputAt(1))->Is(Type::Unsigned32()) &&
    1376           0 :         (truncation.IsUsedAsWord32() ||
    1377             :          NodeProperties::GetType(node)->Is(Type::Unsigned32()))) {
    1378             :       // We can only promise Float64 truncation here, as the decision is
    1379             :       // based on the feedback types of the inputs.
    1380             :       VisitBinop(node,
    1381             :                  UseInfo(MachineRepresentation::kWord32, Truncation::Float64()),
    1382             :                  MachineRepresentation::kWord32, Type::Number());
    1383           0 :       if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
    1384             :       return;
    1385             :     }
    1386         770 :     if (TypeOf(node->InputAt(0))->Is(Type::Signed32()) &&
    1387         656 :         TypeOf(node->InputAt(1))->Is(Type::Signed32()) &&
    1388           0 :         (truncation.IsUsedAsWord32() ||
    1389             :          NodeProperties::GetType(node)->Is(Type::Signed32()))) {
    1390             :       // We can only promise Float64 truncation here, as the decision is
    1391             :       // based on the feedback types of the inputs.
    1392             :       VisitBinop(node,
    1393             :                  UseInfo(MachineRepresentation::kWord32, Truncation::Float64()),
    1394             :                  MachineRepresentation::kWord32, Type::Number());
    1395          14 :       if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
    1396             :       return;
    1397             :     }
    1398             :     // default case => Float64Mod
    1399             :     VisitBinop(node, UseInfo::CheckedNumberOrOddballAsFloat64(),
    1400             :                MachineRepresentation::kFloat64, Type::Number());
    1401         788 :     if (lower()) ChangeToPureOp(node, Float64Op(node));
    1402             :     return;
    1403             :   }
    1404             : 
    1405      503055 :   void VisitOsrGuard(Node* node) {
    1406      167685 :     VisitInputs(node);
    1407             : 
    1408             :     // Insert a dynamic check for the OSR value type if necessary.
    1409      167685 :     switch (OsrGuardTypeOf(node->op())) {
    1410             :       case OsrGuardType::kUninitialized:
    1411             :         // At this point, we should always have a type for the OsrValue.
    1412           0 :         UNREACHABLE();
    1413             :         break;
    1414             :       case OsrGuardType::kSignedSmall:
    1415           0 :         if (lower()) {
    1416             :           NodeProperties::ChangeOp(node,
    1417           0 :                                    simplified()->CheckedTaggedToTaggedSigned());
    1418             :         }
    1419             :         return SetOutput(node, MachineRepresentation::kTaggedSigned);
    1420             :       case OsrGuardType::kAny:  // Nothing to check.
    1421      167685 :         if (lower()) {
    1422       54052 :           DeferReplacement(node, node->InputAt(0));
    1423             :         }
    1424             :         return SetOutput(node, MachineRepresentation::kTagged);
    1425             :     }
    1426           0 :     UNREACHABLE();
    1427             :   }
    1428             : 
    1429             :   // Dispatching routine for visiting the node {node} with the usage {use}.
    1430             :   // Depending on the operator, propagate new usage info to the inputs.
    1431    93502208 :   void VisitNode(Node* node, Truncation truncation,
    1432     7241730 :                  SimplifiedLowering* lowering) {
    1433             :     // Unconditionally eliminate unused pure nodes (only relevant if there's
    1434             :     // a pure operation in between two effectful ones, where the last one
    1435             :     // is unused).
    1436             :     // Note: We must not do this for constants, as they are cached and we
    1437             :     // would thus kill the cached {node} during lowering (i.e. replace all
    1438             :     // uses with Dead), but at that point some node lowering might have
    1439             :     // already taken the constant {node} from the cache (while it was in
    1440             :     // a sane state still) and we would afterwards replace that use with
    1441             :     // Dead as well.
    1442   242650481 :     if (node->op()->ValueInputCount() > 0 &&
    1443             :         node->op()->HasProperty(Operator::kPure)) {
    1444    36017269 :       if (truncation.IsUnused()) return VisitUnused(node);
    1445             :     }
    1446    93011899 :     switch (node->opcode()) {
    1447             :       //------------------------------------------------------------------
    1448             :       // Common operators.
    1449             :       //------------------------------------------------------------------
    1450             :       case IrOpcode::kStart:
    1451             :         // We use Start as a terminator for the frame state chain, so even
    1452             :         // tho Start doesn't really produce a value, we have to say Tagged
    1453             :         // here, otherwise the input conversion will fail.
    1454             :         return VisitLeaf(node, MachineRepresentation::kTagged);
    1455             :       case IrOpcode::kParameter:
    1456             :         // TODO(titzer): use representation from linkage.
    1457     3068982 :         return VisitUnop(node, UseInfo::None(), MachineRepresentation::kTagged);
    1458             :       case IrOpcode::kInt32Constant:
    1459             :         return VisitLeaf(node, MachineRepresentation::kWord32);
    1460             :       case IrOpcode::kInt64Constant:
    1461             :         return VisitLeaf(node, MachineRepresentation::kWord64);
    1462             :       case IrOpcode::kExternalConstant:
    1463             :         return VisitLeaf(node, MachineType::PointerRepresentation());
    1464             :       case IrOpcode::kNumberConstant:
    1465             :         return VisitLeaf(node, MachineRepresentation::kTagged);
    1466             :       case IrOpcode::kHeapConstant:
    1467             :         return VisitLeaf(node, MachineRepresentation::kTaggedPointer);
    1468             :       case IrOpcode::kPointerConstant: {
    1469             :         VisitLeaf(node, MachineType::PointerRepresentation());
    1470        4266 :         if (lower()) {
    1471        1337 :           intptr_t const value = OpParameter<intptr_t>(node);
    1472        1337 :           DeferReplacement(node, lowering->jsgraph()->IntPtrConstant(value));
    1473             :         }
    1474             :         return;
    1475             :       }
    1476             : 
    1477             :       case IrOpcode::kBranch: {
    1478             :         DCHECK(TypeOf(node->InputAt(0))->Is(Type::Boolean()));
    1479     2348129 :         ProcessInput(node, 0, UseInfo::Bool());
    1480     2348125 :         EnqueueInput(node, NodeProperties::FirstControlIndex(node));
    1481     2348128 :         return;
    1482             :       }
    1483             :       case IrOpcode::kSwitch:
    1484           0 :         ProcessInput(node, 0, UseInfo::TruncatingWord32());
    1485           0 :         EnqueueInput(node, NodeProperties::FirstControlIndex(node));
    1486           0 :         return;
    1487             :       case IrOpcode::kSelect:
    1488       32593 :         return VisitSelect(node, truncation, lowering);
    1489             :       case IrOpcode::kPhi:
    1490     2231943 :         return VisitPhi(node, truncation, lowering);
    1491             :       case IrOpcode::kCall:
    1492     2231612 :         return VisitCall(node, lowering);
    1493             : 
    1494             :       //------------------------------------------------------------------
    1495             :       // JavaScript operators.
    1496             :       //------------------------------------------------------------------
    1497             :       case IrOpcode::kJSToBoolean: {
    1498      530996 :         if (truncation.IsUsedAsBool()) {
    1499      261391 :           ProcessInput(node, 0, UseInfo::Bool());
    1500      261391 :           ProcessInput(node, 1, UseInfo::None());
    1501             :           SetOutput(node, MachineRepresentation::kBit);
    1502      344147 :           if (lower()) DeferReplacement(node, node->InputAt(0));
    1503             :         } else {
    1504        4107 :           VisitInputs(node);
    1505             :           SetOutput(node, MachineRepresentation::kTaggedPointer);
    1506             :         }
    1507             :         return;
    1508             :       }
    1509             :       case IrOpcode::kJSToNumber: {
    1510       17870 :         VisitInputs(node);
    1511             :         // TODO(bmeurer): Optimize somewhat based on input type?
    1512       35740 :         if (truncation.IsUsedAsWord32()) {
    1513             :           SetOutput(node, MachineRepresentation::kWord32);
    1514        9574 :           if (lower()) lowering->DoJSToNumberTruncatesToWord32(node, this);
    1515       16592 :         } else if (truncation.IsUsedAsFloat64()) {
    1516             :           SetOutput(node, MachineRepresentation::kFloat64);
    1517         646 :           if (lower()) lowering->DoJSToNumberTruncatesToFloat64(node, this);
    1518             :         } else {
    1519             :           SetOutput(node, MachineRepresentation::kTagged);
    1520             :         }
    1521             :         return;
    1522             :       }
    1523             : 
    1524             :       //------------------------------------------------------------------
    1525             :       // Simplified operators.
    1526             :       //------------------------------------------------------------------
    1527             :       case IrOpcode::kBooleanNot: {
    1528       31527 :         if (lower()) {
    1529        9811 :           NodeInfo* input_info = GetInfo(node->InputAt(0));
    1530        9811 :           if (input_info->representation() == MachineRepresentation::kBit) {
    1531             :             // BooleanNot(x: kRepBit) => Word32Equal(x, #0)
    1532      602258 :             node->AppendInput(jsgraph_->zone(), jsgraph_->Int32Constant(0));
    1533        9123 :             NodeProperties::ChangeOp(node, lowering->machine()->Word32Equal());
    1534         688 :           } else if (CanBeTaggedPointer(input_info->representation())) {
    1535             :             // BooleanNot(x: kRepTagged) => WordEqual(x, #false)
    1536        1374 :             node->AppendInput(jsgraph_->zone(), jsgraph_->FalseConstant());
    1537         687 :             NodeProperties::ChangeOp(node, lowering->machine()->WordEqual());
    1538             :           } else {
    1539             :             DCHECK_EQ(MachineRepresentation::kNone,
    1540             :                       input_info->representation());
    1541           1 :             DeferReplacement(node, lowering->jsgraph()->Int32Constant(0));
    1542             :           }
    1543             :         } else {
    1544             :           // No input representation requirement; adapt during lowering.
    1545       21716 :           ProcessInput(node, 0, UseInfo::AnyTruncatingToBool());
    1546             :           SetOutput(node, MachineRepresentation::kBit);
    1547             :         }
    1548             :         return;
    1549             :       }
    1550             :       case IrOpcode::kNumberEqual: {
    1551             :         Type* const lhs_type = TypeOf(node->InputAt(0));
    1552             :         Type* const rhs_type = TypeOf(node->InputAt(1));
    1553             :         // Number comparisons reduce to integer comparisons for integer inputs.
    1554      412243 :         if ((lhs_type->Is(Type::Unsigned32()) &&
    1555      425017 :              rhs_type->Is(Type::Unsigned32())) ||
    1556        1264 :             (lhs_type->Is(Type::Unsigned32OrMinusZeroOrNaN()) &&
    1557         977 :              rhs_type->Is(Type::Unsigned32OrMinusZeroOrNaN()) &&
    1558         977 :              OneInputCannotBe(node, type_cache_.kZeroish))) {
    1559             :           // => unsigned Int32Cmp
    1560             :           VisitBinop(node, UseInfo::TruncatingWord32(),
    1561             :                      MachineRepresentation::kBit);
    1562      175775 :           if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node));
    1563             :           return;
    1564             :         }
    1565      250552 :         if ((lhs_type->Is(Type::Signed32()) &&
    1566      187234 :              rhs_type->Is(Type::Signed32())) ||
    1567        2040 :             (lhs_type->Is(Type::Signed32OrMinusZeroOrNaN()) &&
    1568        1906 :              rhs_type->Is(Type::Signed32OrMinusZeroOrNaN()) &&
    1569        1906 :              OneInputCannotBe(node, type_cache_.kZeroish))) {
    1570             :           // => signed Int32Cmp
    1571             :           VisitBinop(node, UseInfo::TruncatingWord32(),
    1572             :                      MachineRepresentation::kBit);
    1573      138631 :           if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
    1574             :           return;
    1575             :         }
    1576             :         // => Float64Cmp
    1577             :         VisitBinop(node, UseInfo::TruncatingFloat64(),
    1578             :                    MachineRepresentation::kBit);
    1579       52926 :         if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
    1580             :         return;
    1581             :       }
    1582             :       case IrOpcode::kNumberLessThan:
    1583             :       case IrOpcode::kNumberLessThanOrEqual: {
    1584             :         // Number comparisons reduce to integer comparisons for integer inputs.
    1585      254512 :         if (TypeOf(node->InputAt(0))->Is(Type::Unsigned32()) &&
    1586             :             TypeOf(node->InputAt(1))->Is(Type::Unsigned32())) {
    1587             :           // => unsigned Int32Cmp
    1588             :           VisitBinop(node, UseInfo::TruncatingWord32(),
    1589             :                      MachineRepresentation::kBit);
    1590      120497 :           if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node));
    1591       76286 :         } else if (TypeOf(node->InputAt(0))->Is(Type::Signed32()) &&
    1592             :                    TypeOf(node->InputAt(1))->Is(Type::Signed32())) {
    1593             :           // => signed Int32Cmp
    1594             :           VisitBinop(node, UseInfo::TruncatingWord32(),
    1595             :                      MachineRepresentation::kBit);
    1596       21192 :           if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
    1597             :         } else {
    1598             :           // => Float64Cmp
    1599             :           VisitBinop(node, UseInfo::TruncatingFloat64(),
    1600             :                      MachineRepresentation::kBit);
    1601       32035 :           if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
    1602             :         }
    1603             :         return;
    1604             :       }
    1605             : 
    1606             :       case IrOpcode::kSpeculativeNumberAdd:
    1607             :       case IrOpcode::kSpeculativeNumberSubtract:
    1608      853139 :         return VisitSpeculativeAdditiveOp(node, truncation, lowering);
    1609             : 
    1610             :       case IrOpcode::kSpeculativeNumberLessThan:
    1611             :       case IrOpcode::kSpeculativeNumberLessThanOrEqual:
    1612             :       case IrOpcode::kSpeculativeNumberEqual: {
    1613             :         // ToNumber(x) can throw if x is either a Receiver or a Symbol, so we
    1614             :         // can only eliminate an unused speculative number operation if we know
    1615             :         // that the inputs are PlainPrimitive, which excludes everything that's
    1616             :         // might have side effects or throws during a ToNumber conversion.
    1617      426024 :         if (BothInputsAre(node, Type::PlainPrimitive())) {
    1618      309900 :           if (truncation.IsUnused()) return VisitUnused(node);
    1619             :         }
    1620             :         // Number comparisons reduce to integer comparisons for integer inputs.
    1621      653583 :         if (TypeOf(node->InputAt(0))->Is(Type::Unsigned32()) &&
    1622             :             TypeOf(node->InputAt(1))->Is(Type::Unsigned32())) {
    1623             :           // => unsigned Int32Cmp
    1624             :           VisitBinop(node, UseInfo::TruncatingWord32(),
    1625             :                      MachineRepresentation::kBit);
    1626        7469 :           if (lower()) ChangeToPureOp(node, Uint32Op(node));
    1627             :           return;
    1628      654706 :         } else if (TypeOf(node->InputAt(0))->Is(Type::Signed32()) &&
    1629             :                    TypeOf(node->InputAt(1))->Is(Type::Signed32())) {
    1630             :           // => signed Int32Cmp
    1631             :           VisitBinop(node, UseInfo::TruncatingWord32(),
    1632             :                      MachineRepresentation::kBit);
    1633      252974 :           if (lower()) ChangeToPureOp(node, Int32Op(node));
    1634             :           return;
    1635             :         }
    1636             :         // Try to use type feedback.
    1637      200732 :         NumberOperationHint hint = NumberOperationHintOf(node->op());
    1638      200732 :         switch (hint) {
    1639             :           case NumberOperationHint::kSignedSmall:
    1640             :           case NumberOperationHint::kSigned32: {
    1641      164592 :             if (propagate()) {
    1642             :               VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
    1643      106926 :                          MachineRepresentation::kBit);
    1644       57666 :             } else if (retype()) {
    1645             :               SetOutput(node, MachineRepresentation::kBit, Type::Any());
    1646             :             } else {
    1647             :               DCHECK(lower());
    1648             :               Node* lhs = node->InputAt(0);
    1649             :               Node* rhs = node->InputAt(1);
    1650       42882 :               if (IsNodeRepresentationTagged(lhs) &&
    1651             :                   IsNodeRepresentationTagged(rhs)) {
    1652             :                 VisitBinop(node, UseInfo::CheckedSignedSmallAsTaggedSigned(),
    1653             :                            MachineRepresentation::kBit);
    1654             :                 ChangeToPureOp(
    1655       19616 :                     node, changer_->TaggedSignedOperatorFor(node->opcode()));
    1656             : 
    1657             :               } else {
    1658             :                 VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
    1659        2683 :                            MachineRepresentation::kBit);
    1660        2683 :                 ChangeToPureOp(node, Int32Op(node));
    1661             :               }
    1662             :             }
    1663             :             return;
    1664             :           }
    1665             :           case NumberOperationHint::kNumberOrOddball:
    1666             :             // Abstract and strict equality don't perform ToNumber conversions
    1667             :             // on Oddballs, so make sure we don't accidentially sneak in a
    1668             :             // hint with Oddball feedback here.
    1669             :             DCHECK_NE(IrOpcode::kSpeculativeNumberEqual, node->opcode());
    1670             :           // Fallthrough
    1671             :           case NumberOperationHint::kNumber:
    1672             :             VisitBinop(node, CheckedUseInfoAsFloat64FromHint(hint),
    1673       36140 :                        MachineRepresentation::kBit);
    1674       45380 :             if (lower()) ChangeToPureOp(node, Float64Op(node));
    1675             :             return;
    1676             :         }
    1677           0 :         UNREACHABLE();
    1678             :         return;
    1679             :       }
    1680             : 
    1681             :       case IrOpcode::kNumberAdd:
    1682             :       case IrOpcode::kNumberSubtract: {
    1683     1403147 :         if (BothInputsAre(node, type_cache_.kAdditiveSafeIntegerOrMinusZero) &&
    1684       90787 :             (GetUpperBound(node)->Is(Type::Signed32()) ||
    1685       90344 :              GetUpperBound(node)->Is(Type::Unsigned32()) ||
    1686       90344 :              truncation.IsUsedAsWord32())) {
    1687             :           // => Int32Add/Sub
    1688       75492 :           VisitWord32TruncatingBinop(node);
    1689       96895 :           if (lower()) ChangeToPureOp(node, Int32Op(node));
    1690             :         } else {
    1691             :           // => Float64Add/Sub
    1692      565494 :           VisitFloat64Binop(node);
    1693      656760 :           if (lower()) ChangeToPureOp(node, Float64Op(node));
    1694             :         }
    1695             :         return;
    1696             :       }
    1697             :       case IrOpcode::kSpeculativeNumberMultiply: {
    1698             :         // ToNumber(x) can throw if x is either a Receiver or a Symbol, so we
    1699             :         // can only eliminate an unused speculative number operation if we know
    1700             :         // that the inputs are PlainPrimitive, which excludes everything that's
    1701             :         // might have side effects or throws during a ToNumber conversion.
    1702       65100 :         if (BothInputsAre(node, Type::PlainPrimitive())) {
    1703       18309 :           if (truncation.IsUnused()) return VisitUnused(node);
    1704             :         }
    1705      133321 :         if (BothInputsAre(node, Type::Integral32()) &&
    1706        2273 :             (NodeProperties::GetType(node)->Is(Type::Signed32()) ||
    1707        2267 :              NodeProperties::GetType(node)->Is(Type::Unsigned32()) ||
    1708        2400 :              (truncation.IsUsedAsWord32() &&
    1709             :               NodeProperties::GetType(node)->Is(
    1710         133 :                   type_cache_.kSafeIntegerOrMinusZero)))) {
    1711             :           // Multiply reduces to Int32Mul if the inputs are integers, and
    1712             :           // (a) the output is either known to be Signed32, or
    1713             :           // (b) the output is known to be Unsigned32, or
    1714             :           // (c) the uses are truncating and the result is in the safe
    1715             :           //     integer range.
    1716        1593 :           VisitWord32TruncatingBinop(node);
    1717        2012 :           if (lower()) ChangeToPureOp(node, Int32Op(node));
    1718             :           return;
    1719             :         }
    1720             :         // Try to use type feedback.
    1721       63180 :         NumberOperationHint hint = NumberOperationHintOf(node->op());
    1722             :         Type* input0_type = TypeOf(node->InputAt(0));
    1723             :         Type* input1_type = TypeOf(node->InputAt(1));
    1724             : 
    1725             :         // Handle the case when no int32 checks on inputs are necessary
    1726             :         // (but an overflow check is needed on the output).
    1727       63180 :         if (BothInputsAre(node, Type::Signed32())) {
    1728             :           // If both the inputs the feedback are int32, use the overflow op.
    1729        2182 :           if (hint == NumberOperationHint::kSignedSmall ||
    1730             :               hint == NumberOperationHint::kSigned32) {
    1731             :             VisitBinop(node, UseInfo::TruncatingWord32(),
    1732             :                        MachineRepresentation::kWord32, Type::Signed32());
    1733        2182 :             if (lower()) {
    1734             :               LowerToCheckedInt32Mul(node, truncation, input0_type,
    1735         677 :                                      input1_type);
    1736             :             }
    1737             :             return;
    1738             :           }
    1739             :         }
    1740             : 
    1741       60998 :         if (hint == NumberOperationHint::kSignedSmall ||
    1742             :             hint == NumberOperationHint::kSigned32) {
    1743             :           VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
    1744       21365 :                      MachineRepresentation::kWord32, Type::Signed32());
    1745       21365 :           if (lower()) {
    1746        6538 :             LowerToCheckedInt32Mul(node, truncation, input0_type, input1_type);
    1747             :           }
    1748             :           return;
    1749             :         }
    1750             : 
    1751             :         // Checked float64 x float64 => float64
    1752             :         VisitBinop(node, UseInfo::CheckedNumberOrOddballAsFloat64(),
    1753             :                    MachineRepresentation::kFloat64, Type::Number());
    1754       51664 :         if (lower()) ChangeToPureOp(node, Float64Op(node));
    1755             :         return;
    1756             :       }
    1757             :       case IrOpcode::kNumberMultiply: {
    1758      135774 :         if (BothInputsAre(node, Type::Integral32()) &&
    1759       12844 :             (NodeProperties::GetType(node)->Is(Type::Signed32()) ||
    1760       12516 :              NodeProperties::GetType(node)->Is(Type::Unsigned32()) ||
    1761       19518 :              (truncation.IsUsedAsWord32() &&
    1762             :               NodeProperties::GetType(node)->Is(
    1763        7002 :                   type_cache_.kSafeIntegerOrMinusZero)))) {
    1764             :           // Multiply reduces to Int32Mul if the inputs are integers, and
    1765             :           // (a) the output is either known to be Signed32, or
    1766             :           // (b) the output is known to be Unsigned32, or
    1767             :           // (c) the uses are truncating and the result is in the safe
    1768             :           //     integer range.
    1769        7354 :           VisitWord32TruncatingBinop(node);
    1770        9268 :           if (lower()) ChangeToPureOp(node, Int32Op(node));
    1771             :           return;
    1772             :         }
    1773             :         // Number x Number => Float64Mul
    1774       53922 :         VisitFloat64Binop(node);
    1775       69370 :         if (lower()) ChangeToPureOp(node, Float64Op(node));
    1776             :         return;
    1777             :       }
    1778             :       case IrOpcode::kSpeculativeNumberDivide: {
    1779             :         // ToNumber(x) can throw if x is either a Receiver or a Symbol, so we
    1780             :         // can only eliminate an unused speculative number operation if we know
    1781             :         // that the inputs are PlainPrimitive, which excludes everything that's
    1782             :         // might have side effects or throws during a ToNumber conversion.
    1783       26360 :         if (BothInputsAre(node, Type::PlainPrimitive())) {
    1784        1373 :           if (truncation.IsUnused()) return VisitUnused(node);
    1785             :         }
    1786       26304 :         if (BothInputsAreUnsigned32(node) && truncation.IsUsedAsWord32()) {
    1787             :           // => unsigned Uint32Div
    1788           0 :           VisitWord32TruncatingBinop(node);
    1789           0 :           if (lower()) DeferReplacement(node, lowering->Uint32Div(node));
    1790             :           return;
    1791             :         }
    1792       25835 :         if (BothInputsAreSigned32(node)) {
    1793         514 :           if (NodeProperties::GetType(node)->Is(Type::Signed32())) {
    1794             :             // => signed Int32Div
    1795           0 :             VisitWord32TruncatingBinop(node);
    1796           0 :             if (lower()) DeferReplacement(node, lowering->Int32Div(node));
    1797             :             return;
    1798             :           }
    1799        1028 :           if (truncation.IsUsedAsWord32()) {
    1800             :             // => signed Int32Div
    1801          45 :             VisitWord32TruncatingBinop(node);
    1802          45 :             if (lower()) DeferReplacement(node, lowering->Int32Div(node));
    1803             :             return;
    1804             :           }
    1805             :         }
    1806             : 
    1807             :         // Try to use type feedback.
    1808       25790 :         NumberOperationHint hint = NumberOperationHintOf(node->op());
    1809             : 
    1810             :         // Handle the case when no uint32 checks on inputs are necessary
    1811             :         // (but an overflow check is needed on the output).
    1812       25790 :         if (BothInputsAreUnsigned32(node)) {
    1813         469 :           if (hint == NumberOperationHint::kSignedSmall ||
    1814             :               hint == NumberOperationHint::kSigned32) {
    1815             :             VisitBinop(node, UseInfo::TruncatingWord32(),
    1816             :                        MachineRepresentation::kWord32, Type::Unsigned32());
    1817         469 :             if (lower()) ChangeToUint32OverflowOp(node);
    1818             :             return;
    1819             :           }
    1820             :         }
    1821             : 
    1822             :         // Handle the case when no int32 checks on inputs are necessary
    1823             :         // (but an overflow check is needed on the output).
    1824       25321 :         if (BothInputsAreSigned32(node)) {
    1825             :           // If both the inputs the feedback are int32, use the overflow op.
    1826           0 :           if (hint == NumberOperationHint::kSignedSmall ||
    1827             :               hint == NumberOperationHint::kSigned32) {
    1828             :             VisitBinop(node, UseInfo::TruncatingWord32(),
    1829             :                        MachineRepresentation::kWord32, Type::Signed32());
    1830           0 :             if (lower()) ChangeToInt32OverflowOp(node);
    1831             :             return;
    1832             :           }
    1833             :         }
    1834             : 
    1835       25321 :         if (hint == NumberOperationHint::kSignedSmall ||
    1836             :             hint == NumberOperationHint::kSigned32) {
    1837             :           // If the result is truncated, we only need to check the inputs.
    1838        1714 :           if (truncation.IsUsedAsWord32()) {
    1839             :             VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
    1840         108 :                        MachineRepresentation::kWord32);
    1841         108 :             if (lower()) DeferReplacement(node, lowering->Int32Div(node));
    1842             :           } else {
    1843             :             VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
    1844         749 :                        MachineRepresentation::kWord32, Type::Signed32());
    1845         749 :             if (lower()) ChangeToInt32OverflowOp(node);
    1846             :           }
    1847             :           return;
    1848             :         }
    1849             : 
    1850             :         // default case => Float64Div
    1851             :         VisitBinop(node, UseInfo::CheckedNumberOrOddballAsFloat64(),
    1852             :                    MachineRepresentation::kFloat64, Type::Number());
    1853       31370 :         if (lower()) ChangeToPureOp(node, Float64Op(node));
    1854             :         return;
    1855             :       }
    1856             :       case IrOpcode::kNumberDivide: {
    1857       58008 :         if (BothInputsAreUnsigned32(node) && truncation.IsUsedAsWord32()) {
    1858             :           // => unsigned Uint32Div
    1859         856 :           VisitWord32TruncatingBinop(node);
    1860         856 :           if (lower()) DeferReplacement(node, lowering->Uint32Div(node));
    1861             :           return;
    1862             :         }
    1863       47755 :         if (BothInputsAreSigned32(node)) {
    1864       21358 :           if (NodeProperties::GetType(node)->Is(Type::Signed32())) {
    1865             :             // => signed Int32Div
    1866           0 :             VisitWord32TruncatingBinop(node);
    1867           0 :             if (lower()) DeferReplacement(node, lowering->Int32Div(node));
    1868             :             return;
    1869             :           }
    1870       42716 :           if (truncation.IsUsedAsWord32()) {
    1871             :             // => signed Int32Div
    1872        8159 :             VisitWord32TruncatingBinop(node);
    1873        8158 :             if (lower()) DeferReplacement(node, lowering->Int32Div(node));
    1874             :             return;
    1875             :           }
    1876             :         }
    1877             :         // Number x Number => Float64Div
    1878       39596 :         VisitFloat64Binop(node);
    1879       50775 :         if (lower()) ChangeToPureOp(node, Float64Op(node));
    1880             :         return;
    1881             :       }
    1882             :       case IrOpcode::kSpeculativeNumberModulus:
    1883       14709 :         return VisitSpeculativeNumberModulus(node, truncation, lowering);
    1884             :       case IrOpcode::kNumberModulus: {
    1885       19804 :         if (BothInputsAre(node, Type::Unsigned32OrMinusZeroOrNaN()) &&
    1886        1155 :             (truncation.IsUsedAsWord32() ||
    1887             :              NodeProperties::GetType(node)->Is(Type::Unsigned32()))) {
    1888             :           // => unsigned Uint32Mod
    1889         923 :           VisitWord32TruncatingBinop(node);
    1890         923 :           if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
    1891             :           return;
    1892             :         }
    1893       20222 :         if (BothInputsAre(node, Type::Signed32OrMinusZeroOrNaN()) &&
    1894        4030 :             (truncation.IsUsedAsWord32() ||
    1895             :              NodeProperties::GetType(node)->Is(Type::Signed32()))) {
    1896             :           // => signed Int32Mod
    1897        2521 :           VisitWord32TruncatingBinop(node);
    1898        2521 :           if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
    1899             :           return;
    1900             :         }
    1901        6522 :         if (TypeOf(node->InputAt(0))->Is(Type::Unsigned32()) &&
    1902        6101 :             TypeOf(node->InputAt(1))->Is(Type::Unsigned32()) &&
    1903         260 :             (truncation.IsUsedAsWord32() ||
    1904             :              NodeProperties::GetType(node)->Is(Type::Unsigned32()))) {
    1905             :           // We can only promise Float64 truncation here, as the decision is
    1906             :           // based on the feedback types of the inputs.
    1907             :           VisitBinop(node, UseInfo(MachineRepresentation::kWord32,
    1908             :                                    Truncation::Float64()),
    1909             :                      MachineRepresentation::kWord32);
    1910          24 :           if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
    1911             :           return;
    1912             :         }
    1913        7764 :         if (TypeOf(node->InputAt(0))->Is(Type::Signed32()) &&
    1914        6724 :             TypeOf(node->InputAt(1))->Is(Type::Signed32()) &&
    1915        1578 :             (truncation.IsUsedAsWord32() ||
    1916             :              NodeProperties::GetType(node)->Is(Type::Signed32()))) {
    1917             :           // We can only promise Float64 truncation here, as the decision is
    1918             :           // based on the feedback types of the inputs.
    1919             :           VisitBinop(node, UseInfo(MachineRepresentation::kWord32,
    1920             :                                    Truncation::Float64()),
    1921             :                      MachineRepresentation::kWord32);
    1922           0 :           if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
    1923             :           return;
    1924             :         }
    1925             :         // default case => Float64Mod
    1926        5935 :         VisitFloat64Binop(node);
    1927        7653 :         if (lower()) ChangeToPureOp(node, Float64Op(node));
    1928             :         return;
    1929             :       }
    1930             :       case IrOpcode::kNumberBitwiseOr:
    1931             :       case IrOpcode::kNumberBitwiseXor:
    1932             :       case IrOpcode::kNumberBitwiseAnd: {
    1933      116124 :         VisitWord32TruncatingBinop(node);
    1934      151867 :         if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
    1935             :         return;
    1936             :       }
    1937             :       case IrOpcode::kSpeculativeNumberBitwiseOr:
    1938             :       case IrOpcode::kSpeculativeNumberBitwiseXor:
    1939             :       case IrOpcode::kSpeculativeNumberBitwiseAnd:
    1940       84022 :         VisitSpeculativeInt32Binop(node);
    1941       84023 :         if (lower()) {
    1942       23071 :           ChangeToPureOp(node, Int32Op(node));
    1943             :         }
    1944             :         return;
    1945             :       case IrOpcode::kNumberShiftLeft: {
    1946             :         Type* rhs_type = GetUpperBound(node->InputAt(1));
    1947             :         VisitBinop(node, UseInfo::TruncatingWord32(),
    1948       42285 :                    UseInfo::TruncatingWord32(), MachineRepresentation::kWord32);
    1949       42285 :         if (lower()) {
    1950       12981 :           lowering->DoShift(node, lowering->machine()->Word32Shl(), rhs_type);
    1951             :         }
    1952             :         return;
    1953             :       }
    1954             :       case IrOpcode::kSpeculativeNumberShiftLeft: {
    1955             :         // ToNumber(x) can throw if x is either a Receiver or a Symbol, so we
    1956             :         // can only eliminate an unused speculative number operation if we know
    1957             :         // that the inputs are PlainPrimitive, which excludes everything that's
    1958             :         // might have side effects or throws during a ToNumber conversion.
    1959        8526 :         if (BothInputsAre(node, Type::PlainPrimitive())) {
    1960        7643 :           if (truncation.IsUnused()) return VisitUnused(node);
    1961             :         }
    1962        8462 :         if (BothInputsAre(node, Type::NumberOrOddball())) {
    1963             :           Type* rhs_type = GetUpperBound(node->InputAt(1));
    1964             :           VisitBinop(node, UseInfo::TruncatingWord32(),
    1965             :                      UseInfo::TruncatingWord32(),
    1966        7555 :                      MachineRepresentation::kWord32);
    1967        7555 :           if (lower()) {
    1968        1783 :             lowering->DoShift(node, lowering->machine()->Word32Shl(), rhs_type);
    1969             :           }
    1970             :           return;
    1971             :         }
    1972         907 :         NumberOperationHint hint = NumberOperationHintOf(node->op());
    1973             :         Type* rhs_type = GetUpperBound(node->InputAt(1));
    1974             :         VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
    1975         907 :                    MachineRepresentation::kWord32, Type::Signed32());
    1976         907 :         if (lower()) {
    1977         286 :           lowering->DoShift(node, lowering->machine()->Word32Shl(), rhs_type);
    1978             :         }
    1979             :         return;
    1980             :       }
    1981             :       case IrOpcode::kNumberShiftRight: {
    1982             :         Type* rhs_type = GetUpperBound(node->InputAt(1));
    1983             :         VisitBinop(node, UseInfo::TruncatingWord32(),
    1984       34869 :                    UseInfo::TruncatingWord32(), MachineRepresentation::kWord32);
    1985       34869 :         if (lower()) {
    1986       10805 :           lowering->DoShift(node, lowering->machine()->Word32Sar(), rhs_type);
    1987             :         }
    1988             :         return;
    1989             :       }
    1990             :       case IrOpcode::kSpeculativeNumberShiftRight: {
    1991             :         // ToNumber(x) can throw if x is either a Receiver or a Symbol, so we
    1992             :         // can only eliminate an unused speculative number operation if we know
    1993             :         // that the inputs are PlainPrimitive, which excludes everything that's
    1994             :         // might have side effects or throws during a ToNumber conversion.
    1995       21554 :         if (BothInputsAre(node, Type::PlainPrimitive())) {
    1996       20280 :           if (truncation.IsUnused()) return VisitUnused(node);
    1997             :         }
    1998       21409 :         if (BothInputsAre(node, Type::NumberOrOddball())) {
    1999             :           Type* rhs_type = GetUpperBound(node->InputAt(1));
    2000             :           VisitBinop(node, UseInfo::TruncatingWord32(),
    2001             :                      UseInfo::TruncatingWord32(),
    2002       20111 :                      MachineRepresentation::kWord32);
    2003       20111 :           if (lower()) {
    2004        4578 :             lowering->DoShift(node, lowering->machine()->Word32Sar(), rhs_type);
    2005             :           }
    2006             :           return;
    2007             :         }
    2008        1298 :         NumberOperationHint hint = NumberOperationHintOf(node->op());
    2009             :         Type* rhs_type = GetUpperBound(node->InputAt(1));
    2010             :         VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
    2011        1298 :                    MachineRepresentation::kWord32, Type::Signed32());
    2012        1298 :         if (lower()) {
    2013         378 :           lowering->DoShift(node, lowering->machine()->Word32Sar(), rhs_type);
    2014             :         }
    2015             :         return;
    2016             :       }
    2017             :       case IrOpcode::kNumberShiftRightLogical: {
    2018             :         Type* rhs_type = GetUpperBound(node->InputAt(1));
    2019             :         VisitBinop(node, UseInfo::TruncatingWord32(),
    2020       19491 :                    UseInfo::TruncatingWord32(), MachineRepresentation::kWord32);
    2021       19491 :         if (lower()) {
    2022        6278 :           lowering->DoShift(node, lowering->machine()->Word32Shr(), rhs_type);
    2023             :         }
    2024             :         return;
    2025             :       }
    2026             :       case IrOpcode::kSpeculativeNumberShiftRightLogical: {
    2027             :         // ToNumber(x) can throw if x is either a Receiver or a Symbol, so we
    2028             :         // can only eliminate an unused speculative number operation if we know
    2029             :         // that the inputs are PlainPrimitive, which excludes everything that's
    2030             :         // might have side effects or throws during a ToNumber conversion.
    2031        7110 :         if (BothInputsAre(node, Type::PlainPrimitive())) {
    2032        5692 :           if (truncation.IsUnused()) return VisitUnused(node);
    2033             :         }
    2034        6748 :         NumberOperationHint hint = NumberOperationHintOf(node->op());
    2035             :         Type* rhs_type = GetUpperBound(node->InputAt(1));
    2036       16275 :         if (rhs_type->Is(type_cache_.kZeroish) &&
    2037             :             (hint == NumberOperationHint::kSignedSmall ||
    2038        7272 :              hint == NumberOperationHint::kSigned32) &&
    2039         524 :             !truncation.IsUsedAsWord32()) {
    2040             :           // The SignedSmall or Signed32 feedback means that the results that we
    2041             :           // have seen so far were of type Unsigned31.  We speculate that this
    2042             :           // will continue to hold.  Moreover, since the RHS is 0, the result
    2043             :           // will just be the (converted) LHS.
    2044             :           VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
    2045         259 :                      MachineRepresentation::kWord32, Type::Unsigned31());
    2046         259 :           if (lower()) {
    2047          70 :             node->RemoveInput(1);
    2048             :             NodeProperties::ChangeOp(node,
    2049          70 :                                      simplified()->CheckedUint32ToInt32());
    2050             :           }
    2051             :           return;
    2052             :         }
    2053        6489 :         if (BothInputsAre(node, Type::NumberOrOddball())) {
    2054             :           VisitBinop(node, UseInfo::TruncatingWord32(),
    2055             :                      UseInfo::TruncatingWord32(),
    2056        5179 :                      MachineRepresentation::kWord32);
    2057        5180 :           if (lower()) {
    2058        1529 :             lowering->DoShift(node, lowering->machine()->Word32Shr(), rhs_type);
    2059             :           }
    2060             :           return;
    2061             :         }
    2062             :         VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
    2063        1309 :                    MachineRepresentation::kWord32, Type::Unsigned32());
    2064        1309 :         if (lower()) {
    2065         389 :           lowering->DoShift(node, lowering->machine()->Word32Shr(), rhs_type);
    2066             :         }
    2067             :         return;
    2068             :       }
    2069             :       case IrOpcode::kNumberAbs: {
    2070         240 :         if (TypeOf(node->InputAt(0))->Is(Type::Unsigned32())) {
    2071             :           VisitUnop(node, UseInfo::TruncatingWord32(),
    2072           0 :                     MachineRepresentation::kWord32);
    2073           0 :           if (lower()) DeferReplacement(node, node->InputAt(0));
    2074         240 :         } else if (TypeOf(node->InputAt(0))->Is(Type::Signed32())) {
    2075             :           VisitUnop(node, UseInfo::TruncatingWord32(),
    2076          99 :                     MachineRepresentation::kWord32);
    2077          99 :           if (lower()) DeferReplacement(node, lowering->Int32Abs(node));
    2078         141 :         } else if (TypeOf(node->InputAt(0))
    2079         141 :                        ->Is(type_cache_.kPositiveIntegerOrMinusZeroOrNaN)) {
    2080             :           VisitUnop(node, UseInfo::TruncatingFloat64(),
    2081           0 :                     MachineRepresentation::kFloat64);
    2082           0 :           if (lower()) DeferReplacement(node, node->InputAt(0));
    2083             :         } else {
    2084             :           VisitUnop(node, UseInfo::TruncatingFloat64(),
    2085         141 :                     MachineRepresentation::kFloat64);
    2086         184 :           if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
    2087             :         }
    2088             :         return;
    2089             :       }
    2090             :       case IrOpcode::kNumberClz32: {
    2091             :         VisitUnop(node, UseInfo::TruncatingWord32(),
    2092          78 :                   MachineRepresentation::kWord32);
    2093         104 :         if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node));
    2094             :         return;
    2095             :       }
    2096             :       case IrOpcode::kNumberImul: {
    2097             :         VisitBinop(node, UseInfo::TruncatingWord32(),
    2098         187 :                    UseInfo::TruncatingWord32(), MachineRepresentation::kWord32);
    2099         241 :         if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node));
    2100             :         return;
    2101             :       }
    2102             :       case IrOpcode::kNumberFround: {
    2103             :         VisitUnop(node, UseInfo::TruncatingFloat64(),
    2104        1989 :                   MachineRepresentation::kFloat32);
    2105        2646 :         if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
    2106             :         return;
    2107             :       }
    2108             :       case IrOpcode::kNumberMax: {
    2109             :         // It is safe to use the feedback types for left and right hand side
    2110             :         // here, since we can only narrow those types and thus we can only
    2111             :         // promise a more specific truncation.
    2112             :         Type* const lhs_type = TypeOf(node->InputAt(0));
    2113             :         Type* const rhs_type = TypeOf(node->InputAt(1));
    2114         564 :         if (lhs_type->Is(Type::Unsigned32()) &&
    2115             :             rhs_type->Is(Type::Unsigned32())) {
    2116          21 :           VisitWord32TruncatingBinop(node);
    2117          21 :           if (lower()) {
    2118             :             lowering->DoMax(node, lowering->machine()->Uint32LessThan(),
    2119           7 :                             MachineRepresentation::kWord32);
    2120             :           }
    2121         660 :         } else if (lhs_type->Is(Type::Signed32()) &&
    2122             :                    rhs_type->Is(Type::Signed32())) {
    2123         178 :           VisitWord32TruncatingBinop(node);
    2124         178 :           if (lower()) {
    2125             :             lowering->DoMax(node, lowering->machine()->Int32LessThan(),
    2126          62 :                             MachineRepresentation::kWord32);
    2127             :           }
    2128         406 :         } else if (lhs_type->Is(Type::PlainNumber()) &&
    2129             :                    rhs_type->Is(Type::PlainNumber())) {
    2130         150 :           VisitFloat64Binop(node);
    2131         150 :           if (lower()) {
    2132             :             lowering->DoMax(node, lowering->machine()->Float64LessThan(),
    2133          50 :                             MachineRepresentation::kFloat64);
    2134             :           }
    2135             :         } else {
    2136          65 :           VisitFloat64Binop(node);
    2137          84 :           if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
    2138             :         }
    2139             :         return;
    2140             :       }
    2141             :       case IrOpcode::kNumberMin: {
    2142             :         // It is safe to use the feedback types for left and right hand side
    2143             :         // here, since we can only narrow those types and thus we can only
    2144             :         // promise a more specific truncation.
    2145             :         Type* const lhs_type = TypeOf(node->InputAt(0));
    2146             :         Type* const rhs_type = TypeOf(node->InputAt(1));
    2147         668 :         if (lhs_type->Is(Type::Unsigned32()) &&
    2148             :             rhs_type->Is(Type::Unsigned32())) {
    2149          21 :           VisitWord32TruncatingBinop(node);
    2150          21 :           if (lower()) {
    2151             :             lowering->DoMin(node, lowering->machine()->Uint32LessThan(),
    2152           7 :                             MachineRepresentation::kWord32);
    2153             :           }
    2154         812 :         } else if (lhs_type->Is(Type::Signed32()) &&
    2155             :                    rhs_type->Is(Type::Signed32())) {
    2156         200 :           VisitWord32TruncatingBinop(node);
    2157         200 :           if (lower()) {
    2158             :             lowering->DoMin(node, lowering->machine()->Int32LessThan(),
    2159          69 :                             MachineRepresentation::kWord32);
    2160             :           }
    2161         472 :         } else if (lhs_type->Is(Type::PlainNumber()) &&
    2162             :                    rhs_type->Is(Type::PlainNumber())) {
    2163         126 :           VisitFloat64Binop(node);
    2164         126 :           if (lower()) {
    2165             :             lowering->DoMin(node, lowering->machine()->Float64LessThan(),
    2166          42 :                             MachineRepresentation::kFloat64);
    2167             :           }
    2168             :         } else {
    2169         187 :           VisitFloat64Binop(node);
    2170         247 :           if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
    2171             :         }
    2172             :         return;
    2173             :       }
    2174             :       case IrOpcode::kNumberAtan2:
    2175             :       case IrOpcode::kNumberPow: {
    2176             :         VisitBinop(node, UseInfo::TruncatingFloat64(),
    2177             :                    MachineRepresentation::kFloat64);
    2178        3723 :         if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
    2179             :         return;
    2180             :       }
    2181             :       case IrOpcode::kNumberAcos:
    2182             :       case IrOpcode::kNumberAcosh:
    2183             :       case IrOpcode::kNumberAsin:
    2184             :       case IrOpcode::kNumberAsinh:
    2185             :       case IrOpcode::kNumberAtan:
    2186             :       case IrOpcode::kNumberAtanh:
    2187             :       case IrOpcode::kNumberCeil:
    2188             :       case IrOpcode::kNumberCos:
    2189             :       case IrOpcode::kNumberCosh:
    2190             :       case IrOpcode::kNumberExp:
    2191             :       case IrOpcode::kNumberExpm1:
    2192             :       case IrOpcode::kNumberFloor:
    2193             :       case IrOpcode::kNumberLog:
    2194             :       case IrOpcode::kNumberLog1p:
    2195             :       case IrOpcode::kNumberLog2:
    2196             :       case IrOpcode::kNumberLog10:
    2197             :       case IrOpcode::kNumberCbrt:
    2198             :       case IrOpcode::kNumberSin:
    2199             :       case IrOpcode::kNumberSinh:
    2200             :       case IrOpcode::kNumberTan:
    2201             :       case IrOpcode::kNumberTanh:
    2202             :       case IrOpcode::kNumberTrunc: {
    2203             :         VisitUnop(node, UseInfo::TruncatingFloat64(),
    2204       50147 :                   MachineRepresentation::kFloat64);
    2205       66507 :         if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
    2206             :         return;
    2207             :       }
    2208             :       case IrOpcode::kNumberRound: {
    2209             :         VisitUnop(node, UseInfo::TruncatingFloat64(),
    2210         201 :                   MachineRepresentation::kFloat64);
    2211         201 :         if (lower()) DeferReplacement(node, lowering->Float64Round(node));
    2212             :         return;
    2213             :       }
    2214             :       case IrOpcode::kNumberSign: {
    2215          63 :         if (InputIs(node, Type::Signed32())) {
    2216             :           VisitUnop(node, UseInfo::TruncatingWord32(),
    2217          21 :                     MachineRepresentation::kWord32);
    2218          21 :           if (lower()) DeferReplacement(node, lowering->Int32Sign(node));
    2219             :         } else {
    2220             :           VisitUnop(node, UseInfo::TruncatingFloat64(),
    2221          42 :                     MachineRepresentation::kFloat64);
    2222          42 :           if (lower()) DeferReplacement(node, lowering->Float64Sign(node));
    2223             :         }
    2224             :         return;
    2225             :       }
    2226             :       case IrOpcode::kNumberSqrt: {
    2227             :         VisitUnop(node, UseInfo::TruncatingFloat64(),
    2228         180 :                   MachineRepresentation::kFloat64);
    2229         239 :         if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
    2230             :         return;
    2231             :       }
    2232             :       case IrOpcode::kNumberToBoolean: {
    2233             :         Type* const input_type = TypeOf(node->InputAt(0));
    2234        1086 :         if (input_type->Is(Type::Integral32())) {
    2235             :           VisitUnop(node, UseInfo::TruncatingWord32(),
    2236         327 :                     MachineRepresentation::kBit);
    2237         327 :           if (lower()) lowering->DoIntegral32ToBit(node);
    2238         759 :         } else if (input_type->Is(Type::OrderedNumber())) {
    2239             :           VisitUnop(node, UseInfo::TruncatingFloat64(),
    2240           0 :                     MachineRepresentation::kBit);
    2241           0 :           if (lower()) lowering->DoOrderedNumberToBit(node);
    2242             :         } else {
    2243             :           VisitUnop(node, UseInfo::TruncatingFloat64(),
    2244         759 :                     MachineRepresentation::kBit);
    2245         759 :           if (lower()) lowering->DoNumberToBit(node);
    2246             :         }
    2247             :         return;
    2248             :       }
    2249             :       case IrOpcode::kNumberToInt32: {
    2250             :         // Just change representation if necessary.
    2251             :         VisitUnop(node, UseInfo::TruncatingWord32(),
    2252      108639 :                   MachineRepresentation::kWord32);
    2253      141524 :         if (lower()) DeferReplacement(node, node->InputAt(0));
    2254             :         return;
    2255             :       }
    2256             :       case IrOpcode::kNumberToUint32: {
    2257             :         // Just change representation if necessary.
    2258             :         VisitUnop(node, UseInfo::TruncatingWord32(),
    2259       32246 :                   MachineRepresentation::kWord32);
    2260       42536 :         if (lower()) DeferReplacement(node, node->InputAt(0));
    2261             :         return;
    2262             :       }
    2263             :       case IrOpcode::kNumberToUint8Clamped: {
    2264             :         Type* const input_type = TypeOf(node->InputAt(0));
    2265        2976 :         if (input_type->Is(type_cache_.kUint8OrMinusZeroOrNaN)) {
    2266             :           VisitUnop(node, UseInfo::TruncatingWord32(),
    2267          54 :                     MachineRepresentation::kWord32);
    2268          72 :           if (lower()) DeferReplacement(node, node->InputAt(0));
    2269        1434 :         } else if (input_type->Is(Type::Unsigned32OrMinusZeroOrNaN())) {
    2270             :           VisitUnop(node, UseInfo::TruncatingWord32(),
    2271         236 :                     MachineRepresentation::kWord32);
    2272         236 :           if (lower()) lowering->DoUnsigned32ToUint8Clamped(node);
    2273        1198 :         } else if (input_type->Is(Type::Signed32OrMinusZeroOrNaN())) {
    2274             :           VisitUnop(node, UseInfo::TruncatingWord32(),
    2275         211 :                     MachineRepresentation::kWord32);
    2276         211 :           if (lower()) lowering->DoSigned32ToUint8Clamped(node);
    2277        1974 :         } else if (input_type->Is(type_cache_.kIntegerOrMinusZeroOrNaN)) {
    2278             :           VisitUnop(node, UseInfo::TruncatingFloat64(),
    2279          87 :                     MachineRepresentation::kFloat64);
    2280          87 :           if (lower()) lowering->DoIntegerToUint8Clamped(node);
    2281             :         } else {
    2282             :           VisitUnop(node, UseInfo::TruncatingFloat64(),
    2283         900 :                     MachineRepresentation::kFloat64);
    2284         900 :           if (lower()) lowering->DoNumberToUint8Clamped(node);
    2285             :         }
    2286             :         return;
    2287             :       }
    2288             :       case IrOpcode::kReferenceEqual: {
    2289             :         VisitBinop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
    2290      669825 :         if (lower()) {
    2291      219851 :           NodeProperties::ChangeOp(node, lowering->machine()->WordEqual());
    2292             :         }
    2293             :         return;
    2294             :       }
    2295             :       case IrOpcode::kStringEqual:
    2296             :       case IrOpcode::kStringLessThan:
    2297             :       case IrOpcode::kStringLessThanOrEqual: {
    2298             :         return VisitBinop(node, UseInfo::AnyTagged(),
    2299             :                           MachineRepresentation::kTaggedPointer);
    2300             :       }
    2301             :       case IrOpcode::kStringCharAt: {
    2302             :         VisitBinop(node, UseInfo::AnyTagged(), UseInfo::TruncatingWord32(),
    2303        1022 :                    MachineRepresentation::kTaggedPointer);
    2304        1022 :         return;
    2305             :       }
    2306             :       case IrOpcode::kStringCharCodeAt: {
    2307             :         // TODO(turbofan): Allow builtins to return untagged values.
    2308             :         VisitBinop(node, UseInfo::AnyTagged(), UseInfo::TruncatingWord32(),
    2309        1239 :                    MachineRepresentation::kTaggedSigned);
    2310        1239 :         return;
    2311             :       }
    2312             :       case IrOpcode::kStringFromCharCode: {
    2313             :         VisitUnop(node, UseInfo::TruncatingWord32(),
    2314        2372 :                   MachineRepresentation::kTaggedPointer);
    2315        2372 :         return;
    2316             :       }
    2317             :       case IrOpcode::kStringFromCodePoint: {
    2318             :         VisitUnop(node, UseInfo::TruncatingWord32(),
    2319         185 :                   MachineRepresentation::kTaggedPointer);
    2320         185 :         return;
    2321             :       }
    2322             :       case IrOpcode::kStringIndexOf: {
    2323         499 :         ProcessInput(node, 0, UseInfo::AnyTagged());
    2324         499 :         ProcessInput(node, 1, UseInfo::AnyTagged());
    2325         499 :         ProcessInput(node, 2, UseInfo::TaggedSigned());
    2326             :         SetOutput(node, MachineRepresentation::kTaggedSigned);
    2327             :         return;
    2328             :       }
    2329             : 
    2330             :       case IrOpcode::kCheckBounds: {
    2331             :         Type* index_type = TypeOf(node->InputAt(0));
    2332             :         Type* length_type = TypeOf(node->InputAt(1));
    2333      114535 :         if (index_type->Is(Type::Integral32OrMinusZero())) {
    2334             :           // Map -0 to 0, and the values in the [-2^31,-1] range to the
    2335             :           // [2^31,2^32-1] range, which will be considered out-of-bounds
    2336             :           // as well, because the {length_type} is limited to Unsigned31.
    2337             :           VisitBinop(node, UseInfo::TruncatingWord32(),
    2338             :                      MachineRepresentation::kWord32);
    2339       93168 :           if (lower()) {
    2340       47815 :             if (index_type->Min() >= 0.0 &&
    2341       21806 :                 index_type->Max() < length_type->Min()) {
    2342             :               // The bounds check is redundant if we already know that
    2343             :               // the index is within the bounds of [0.0, length[.
    2344        3322 :               DeferReplacement(node, node->InputAt(0));
    2345             :             }
    2346             :           }
    2347             :         } else {
    2348             :           VisitBinop(node, UseInfo::CheckedSigned32AsWord32(kIdentifyZeros),
    2349             :                      UseInfo::TruncatingWord32(),
    2350       21367 :                      MachineRepresentation::kWord32);
    2351             :         }
    2352             :         return;
    2353             :       }
    2354             :       case IrOpcode::kCheckHeapObject: {
    2355       57639 :         if (InputCannotBe(node, Type::SignedSmall())) {
    2356             :           VisitUnop(node, UseInfo::AnyTagged(),
    2357         516 :                     MachineRepresentation::kTaggedPointer);
    2358             :         } else {
    2359             :           VisitUnop(node, UseInfo::CheckedHeapObjectAsTaggedPointer(),
    2360       57123 :                     MachineRepresentation::kTaggedPointer);
    2361             :         }
    2362       75505 :         if (lower()) DeferReplacement(node, node->InputAt(0));
    2363             :         return;
    2364             :       }
    2365             :       case IrOpcode::kCheckIf: {
    2366       92035 :         ProcessInput(node, 0, UseInfo::Bool());
    2367       92035 :         ProcessRemainingInputs(node, 1);
    2368             :         SetOutput(node, MachineRepresentation::kNone);
    2369             :         return;
    2370             :       }
    2371             :       case IrOpcode::kCheckInternalizedString: {
    2372        7190 :         if (InputIs(node, Type::InternalizedString())) {
    2373             :           VisitUnop(node, UseInfo::AnyTagged(),
    2374         332 :                     MachineRepresentation::kTaggedPointer);
    2375         417 :           if (lower()) DeferReplacement(node, node->InputAt(0));
    2376             :         } else {
    2377             :           VisitUnop(node, UseInfo::CheckedHeapObjectAsTaggedPointer(),
    2378        6858 :                     MachineRepresentation::kTaggedPointer);
    2379             :         }
    2380             :         return;
    2381             :       }
    2382             :       case IrOpcode::kCheckNumber: {
    2383             :         Type* const input_type = TypeOf(node->InputAt(0));
    2384        1479 :         if (input_type->Is(Type::Number())) {
    2385          42 :           VisitNoop(node, truncation);
    2386             :         } else {
    2387        1437 :           VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged);
    2388             :         }
    2389             :         return;
    2390             :       }
    2391             :       case IrOpcode::kCheckReceiver: {
    2392        1649 :         if (InputIs(node, Type::Receiver())) {
    2393             :           VisitUnop(node, UseInfo::AnyTagged(),
    2394          12 :                     MachineRepresentation::kTaggedPointer);
    2395          16 :           if (lower()) DeferReplacement(node, node->InputAt(0));
    2396             :         } else {
    2397             :           VisitUnop(node, UseInfo::CheckedHeapObjectAsTaggedPointer(),
    2398        1637 :                     MachineRepresentation::kTaggedPointer);
    2399             :         }
    2400             :         return;
    2401             :       }
    2402             :       case IrOpcode::kCheckSmi: {
    2403       88768 :         if (SmiValuesAre32Bits() && truncation.IsUsedAsWord32()) {
    2404             :           VisitUnop(node,
    2405             :                     UseInfo::CheckedSignedSmallAsWord32(kDistinguishZeros),
    2406        1320 :                     MachineRepresentation::kWord32);
    2407             :         } else {
    2408             :           VisitUnop(node, UseInfo::CheckedSignedSmallAsTaggedSigned(),
    2409       43064 :                     MachineRepresentation::kTaggedSigned);
    2410             :         }
    2411       58078 :         if (lower()) DeferReplacement(node, node->InputAt(0));
    2412             :         return;
    2413             :       }
    2414             :       case IrOpcode::kCheckString: {
    2415        4056 :         if (InputIs(node, Type::String())) {
    2416             :           VisitUnop(node, UseInfo::AnyTagged(),
    2417           0 :                     MachineRepresentation::kTaggedPointer);
    2418           0 :           if (lower()) DeferReplacement(node, node->InputAt(0));
    2419             :         } else {
    2420             :           VisitUnop(node, UseInfo::CheckedHeapObjectAsTaggedPointer(),
    2421        4056 :                     MachineRepresentation::kTaggedPointer);
    2422             :         }
    2423             :         return;
    2424             :       }
    2425             : 
    2426             :       case IrOpcode::kAllocate: {
    2427      273628 :         ProcessInput(node, 0, UseInfo::TruncatingWord32());
    2428      273628 :         ProcessRemainingInputs(node, 1);
    2429             :         SetOutput(node, MachineRepresentation::kTaggedPointer);
    2430             :         return;
    2431             :       }
    2432             :       case IrOpcode::kLoadField: {
    2433     3146561 :         if (truncation.IsUnused()) return VisitUnused(node);
    2434     2835964 :         FieldAccess access = FieldAccessOf(node->op());
    2435             :         MachineRepresentation const representation =
    2436             :             access.machine_type.representation();
    2437     2835964 :         VisitUnop(node, UseInfoForBasePointer(access), representation);
    2438             :         return;
    2439             :       }
    2440             :       case IrOpcode::kStoreField: {
    2441     2760845 :         FieldAccess access = FieldAccessOf(node->op());
    2442     2760845 :         NodeInfo* input_info = GetInfo(node->InputAt(1));
    2443             :         WriteBarrierKind write_barrier_kind = WriteBarrierKindFor(
    2444             :             access.base_is_tagged, access.machine_type.representation(),
    2445             :             access.offset, access.type, input_info->representation(),
    2446     2760845 :             node->InputAt(1));
    2447     2760848 :         ProcessInput(node, 0, UseInfoForBasePointer(access));
    2448             :         ProcessInput(node, 1, TruncatingUseInfoFromRepresentation(
    2449     2760845 :                                   access.machine_type.representation()));
    2450     2760844 :         ProcessRemainingInputs(node, 2);
    2451             :         SetOutput(node, MachineRepresentation::kNone);
    2452     2760839 :         if (lower()) {
    2453      914431 :           if (write_barrier_kind < access.write_barrier_kind) {
    2454      436932 :             access.write_barrier_kind = write_barrier_kind;
    2455             :             NodeProperties::ChangeOp(
    2456      873864 :                 node, jsgraph_->simplified()->StoreField(access));
    2457             :           }
    2458             :         }
    2459             :         return;
    2460             :       }
    2461             :       case IrOpcode::kLoadBuffer: {
    2462       24720 :         if (truncation.IsUnused()) return VisitUnused(node);
    2463       20469 :         BufferAccess access = BufferAccessOf(node->op());
    2464       20469 :         ProcessInput(node, 0, UseInfo::PointerInt());        // buffer
    2465       20469 :         ProcessInput(node, 1, UseInfo::TruncatingWord32());  // offset
    2466       20469 :         ProcessInput(node, 2, UseInfo::TruncatingWord32());  // length
    2467       20469 :         ProcessRemainingInputs(node, 3);
    2468             : 
    2469             :         MachineRepresentation output;
    2470       20469 :         if (truncation.IdentifiesUndefinedAndNaNAndZero()) {
    2471       19674 :           if (truncation.IdentifiesNaNAndZero()) {
    2472             :             // If undefined is truncated to a non-NaN number, we can use
    2473             :             // the load's representation.
    2474       14563 :             output = access.machine_type().representation();
    2475             :           } else {
    2476             :             // If undefined is truncated to a number, but the use can
    2477             :             // observe NaN, we need to output at least the float32
    2478             :             // representation.
    2479        5111 :             if (access.machine_type().representation() ==
    2480             :                 MachineRepresentation::kFloat32) {
    2481        4678 :               output = access.machine_type().representation();
    2482             :             } else {
    2483             :               output = MachineRepresentation::kFloat64;
    2484             :             }
    2485             :           }
    2486             :         } else {
    2487             :           // If undefined is not truncated away, we need to have the tagged
    2488             :           // representation.
    2489             :           output = MachineRepresentation::kTagged;
    2490             :         }
    2491             :         SetOutput(node, output);
    2492       20469 :         if (lower()) lowering->DoLoadBuffer(node, output, changer_);
    2493             :         return;
    2494             :       }
    2495             :       case IrOpcode::kStoreBuffer: {
    2496       14228 :         BufferAccess access = BufferAccessOf(node->op());
    2497       14228 :         ProcessInput(node, 0, UseInfo::PointerInt());        // buffer
    2498       14228 :         ProcessInput(node, 1, UseInfo::TruncatingWord32());  // offset
    2499       14228 :         ProcessInput(node, 2, UseInfo::TruncatingWord32());  // length
    2500             :         ProcessInput(node, 3,
    2501             :                      TruncatingUseInfoFromRepresentation(
    2502       14228 :                          access.machine_type().representation()));  // value
    2503       14228 :         ProcessRemainingInputs(node, 4);
    2504             :         SetOutput(node, MachineRepresentation::kNone);
    2505       14227 :         if (lower()) lowering->DoStoreBuffer(node);
    2506             :         return;
    2507             :       }
    2508             :       case IrOpcode::kLoadElement: {
    2509      117119 :         if (truncation.IsUnused()) return VisitUnused(node);
    2510      111923 :         ElementAccess access = ElementAccessOf(node->op());
    2511             :         VisitBinop(node, UseInfoForBasePointer(access),
    2512             :                    UseInfo::TruncatingWord32(),
    2513      111923 :                    access.machine_type.representation());
    2514      111923 :         return;
    2515             :       }
    2516             :       case IrOpcode::kStoreElement: {
    2517      494916 :         ElementAccess access = ElementAccessOf(node->op());
    2518      494916 :         NodeInfo* input_info = GetInfo(node->InputAt(2));
    2519             :         WriteBarrierKind write_barrier_kind = WriteBarrierKindFor(
    2520             :             access.base_is_tagged, access.machine_type.representation(),
    2521      494916 :             access.type, input_info->representation(), node->InputAt(2));
    2522      494916 :         ProcessInput(node, 0, UseInfoForBasePointer(access));  // base
    2523      494916 :         ProcessInput(node, 1, UseInfo::TruncatingWord32());    // index
    2524             :         ProcessInput(node, 2,
    2525             :                      TruncatingUseInfoFromRepresentation(
    2526      494916 :                          access.machine_type.representation()));  // value
    2527      494916 :         ProcessRemainingInputs(node, 3);
    2528             :         SetOutput(node, MachineRepresentation::kNone);
    2529      494916 :         if (lower()) {
    2530      162669 :           if (write_barrier_kind < access.write_barrier_kind) {
    2531      147063 :             access.write_barrier_kind = write_barrier_kind;
    2532             :             NodeProperties::ChangeOp(
    2533      294126 :                 node, jsgraph_->simplified()->StoreElement(access));
    2534             :           }
    2535             :         }
    2536             :         return;
    2537             :       }
    2538             :       case IrOpcode::kLoadTypedElement: {
    2539             :         MachineRepresentation const rep =
    2540       12172 :             MachineRepresentationFromArrayType(ExternalArrayTypeOf(node->op()));
    2541       12172 :         ProcessInput(node, 0, UseInfo::AnyTagged());         // buffer
    2542       12172 :         ProcessInput(node, 1, UseInfo::AnyTagged());         // base pointer
    2543       12172 :         ProcessInput(node, 2, UseInfo::PointerInt());        // external pointer
    2544       12172 :         ProcessInput(node, 3, UseInfo::TruncatingWord32());  // index
    2545       12172 :         ProcessRemainingInputs(node, 4);
    2546             :         SetOutput(node, rep);
    2547             :         return;
    2548             :       }
    2549             :       case IrOpcode::kStoreTypedElement: {
    2550             :         MachineRepresentation const rep =
    2551       11035 :             MachineRepresentationFromArrayType(ExternalArrayTypeOf(node->op()));
    2552       11035 :         ProcessInput(node, 0, UseInfo::AnyTagged());         // buffer
    2553       11035 :         ProcessInput(node, 1, UseInfo::AnyTagged());         // base pointer
    2554       11035 :         ProcessInput(node, 2, UseInfo::PointerInt());        // external pointer
    2555       11035 :         ProcessInput(node, 3, UseInfo::TruncatingWord32());  // index
    2556             :         ProcessInput(node, 4,
    2557       11035 :                      TruncatingUseInfoFromRepresentation(rep));  // value
    2558       11035 :         ProcessRemainingInputs(node, 5);
    2559             :         SetOutput(node, MachineRepresentation::kNone);
    2560             :         return;
    2561             :       }
    2562             :       case IrOpcode::kPlainPrimitiveToNumber: {
    2563       51955 :         if (InputIs(node, Type::Boolean())) {
    2564        1229 :           VisitUnop(node, UseInfo::Bool(), MachineRepresentation::kWord32);
    2565        1610 :           if (lower()) DeferReplacement(node, node->InputAt(0));
    2566       50726 :         } else if (InputIs(node, Type::String())) {
    2567        1716 :           VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged);
    2568        1716 :           if (lower()) lowering->DoStringToNumber(node);
    2569       98020 :         } else if (truncation.IsUsedAsWord32()) {
    2570       35488 :           if (InputIs(node, Type::NumberOrOddball())) {
    2571             :             VisitUnop(node, UseInfo::TruncatingWord32(),
    2572       14821 :                       MachineRepresentation::kWord32);
    2573       19310 :             if (lower()) DeferReplacement(node, node->InputAt(0));
    2574             :           } else {
    2575             :             VisitUnop(node, UseInfo::AnyTagged(),
    2576       20667 :                       MachineRepresentation::kWord32);
    2577       20667 :             if (lower()) {
    2578             :               NodeProperties::ChangeOp(node,
    2579        6347 :                                        simplified()->PlainPrimitiveToWord32());
    2580             :             }
    2581             :           }
    2582       27044 :         } else if (truncation.IsUsedAsFloat64()) {
    2583       13414 :           if (InputIs(node, Type::NumberOrOddball())) {
    2584             :             VisitUnop(node, UseInfo::TruncatingFloat64(),
    2585        6188 :                       MachineRepresentation::kFloat64);
    2586        8109 :             if (lower()) DeferReplacement(node, node->InputAt(0));
    2587             :           } else {
    2588             :             VisitUnop(node, UseInfo::AnyTagged(),
    2589        7226 :                       MachineRepresentation::kFloat64);
    2590        7226 :             if (lower()) {
    2591             :               NodeProperties::ChangeOp(node,
    2592        1895 :                                        simplified()->PlainPrimitiveToFloat64());
    2593             :             }
    2594             :           }
    2595             :         } else {
    2596         108 :           VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged);
    2597             :         }
    2598             :         return;
    2599             :       }
    2600             :       case IrOpcode::kSpeculativeToNumber: {
    2601        5365 :         NumberOperationHint const hint = NumberOperationHintOf(node->op());
    2602        5365 :         switch (hint) {
    2603             :           case NumberOperationHint::kSigned32:
    2604             :           case NumberOperationHint::kSignedSmall:
    2605             :             VisitUnop(node, CheckedUseInfoAsWord32FromHint(hint),
    2606        5365 :                       MachineRepresentation::kWord32, Type::Signed32());
    2607        5365 :             break;
    2608             :           case NumberOperationHint::kNumber:
    2609             :           case NumberOperationHint::kNumberOrOddball:
    2610             :             VisitUnop(node, CheckedUseInfoAsFloat64FromHint(hint),
    2611           0 :                       MachineRepresentation::kFloat64);
    2612           0 :             break;
    2613             :         }
    2614        6813 :         if (lower()) DeferReplacement(node, node->InputAt(0));
    2615             :         return;
    2616             :       }
    2617             :       case IrOpcode::kObjectIsDetectableCallable: {
    2618       52920 :         VisitObjectIs(node, Type::DetectableCallable(), lowering);
    2619       52920 :         return;
    2620             :       }
    2621             :       case IrOpcode::kObjectIsNaN: {
    2622             :         Type* const input_type = GetUpperBound(node->InputAt(0));
    2623        8940 :         if (input_type->Is(Type::NaN())) {
    2624           0 :           VisitUnop(node, UseInfo::None(), MachineRepresentation::kBit);
    2625           0 :           if (lower()) {
    2626           0 :             DeferReplacement(node, lowering->jsgraph()->Int32Constant(1));
    2627             :           }
    2628        8940 :         } else if (!input_type->Maybe(Type::NaN())) {
    2629          24 :           VisitUnop(node, UseInfo::Any(), MachineRepresentation::kBit);
    2630          24 :           if (lower()) {
    2631           8 :             DeferReplacement(node, lowering->jsgraph()->Int32Constant(0));
    2632             :           }
    2633        8916 :         } else if (input_type->Is(Type::Number())) {
    2634             :           VisitUnop(node, UseInfo::TruncatingFloat64(),
    2635          51 :                     MachineRepresentation::kBit);
    2636          51 :           if (lower()) {
    2637             :             // ObjectIsNaN(x:kRepFloat64) => Word32Equal(Float64Equal(x,x),#0)
    2638             :             Node* const input = node->InputAt(0);
    2639             :             node->ReplaceInput(
    2640             :                 0, jsgraph_->graph()->NewNode(
    2641          34 :                        lowering->machine()->Float64Equal(), input, input));
    2642          34 :             node->AppendInput(jsgraph_->zone(), jsgraph_->Int32Constant(0));
    2643          17 :             NodeProperties::ChangeOp(node, lowering->machine()->Word32Equal());
    2644             :           }
    2645             :         } else {
    2646        8865 :           VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
    2647             :         }
    2648             :         return;
    2649             :       }
    2650             :       case IrOpcode::kObjectIsNonCallable: {
    2651       25828 :         VisitObjectIs(node, Type::NonCallable(), lowering);
    2652       25828 :         return;
    2653             :       }
    2654             :       case IrOpcode::kObjectIsNumber: {
    2655       34647 :         VisitObjectIs(node, Type::Number(), lowering);
    2656       34647 :         return;
    2657             :       }
    2658             :       case IrOpcode::kObjectIsReceiver: {
    2659       69160 :         VisitObjectIs(node, Type::Receiver(), lowering);
    2660       69160 :         return;
    2661             :       }
    2662             :       case IrOpcode::kObjectIsSmi: {
    2663             :         // TODO(turbofan): Optimize based on input representation.
    2664       10665 :         VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
    2665       10665 :         return;
    2666             :       }
    2667             :       case IrOpcode::kObjectIsString: {
    2668       14597 :         VisitObjectIs(node, Type::String(), lowering);
    2669       14597 :         return;
    2670             :       }
    2671             :       case IrOpcode::kObjectIsSymbol: {
    2672        1989 :         VisitObjectIs(node, Type::Symbol(), lowering);
    2673        1989 :         return;
    2674             :       }
    2675             :       case IrOpcode::kObjectIsUndetectable: {
    2676       27558 :         VisitObjectIs(node, Type::Undetectable(), lowering);
    2677       27558 :         return;
    2678             :       }
    2679             :       case IrOpcode::kArgumentsFrame: {
    2680             :         SetOutput(node, MachineType::PointerRepresentation());
    2681             :         return;
    2682             :       }
    2683             :       case IrOpcode::kArgumentsLength: {
    2684             :         VisitUnop(node, UseInfo::PointerInt(),
    2685       11958 :                   MachineRepresentation::kTaggedSigned);
    2686       11958 :         return;
    2687             :       }
    2688             :       case IrOpcode::kNewUnmappedArgumentsElements: {
    2689             :         VisitBinop(node, UseInfo::PointerInt(), UseInfo::TaggedSigned(),
    2690       12227 :                    MachineRepresentation::kTaggedPointer);
    2691       12227 :         return;
    2692             :       }
    2693             :       case IrOpcode::kArrayBufferWasNeutered: {
    2694        1035 :         VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
    2695        1035 :         return;
    2696             :       }
    2697             :       case IrOpcode::kCheckFloat64Hole: {
    2698             :         Type* const input_type = TypeOf(node->InputAt(0));
    2699        2442 :         if (input_type->Is(Type::Number())) {
    2700         144 :           VisitNoop(node, truncation);
    2701             :         } else {
    2702        2298 :           CheckFloat64HoleMode mode = CheckFloat64HoleModeOf(node->op());
    2703        2298 :           switch (mode) {
    2704             :             case CheckFloat64HoleMode::kAllowReturnHole:
    2705        2083 :               if (truncation.IsUnused()) return VisitUnused(node);
    2706        1970 :               if (truncation.IsUsedAsFloat64()) {
    2707             :                 VisitUnop(node, UseInfo::TruncatingFloat64(),
    2708         195 :                           MachineRepresentation::kFloat64);
    2709         260 :                 if (lower()) DeferReplacement(node, node->InputAt(0));
    2710             :               } else {
    2711             :                 VisitUnop(
    2712             :                     node,
    2713             :                     UseInfo(MachineRepresentation::kFloat64, Truncation::Any()),
    2714        1775 :                     MachineRepresentation::kFloat64, Type::Number());
    2715             :               }
    2716             :               break;
    2717             :             case CheckFloat64HoleMode::kNeverReturnHole:
    2718             :               VisitUnop(
    2719             :                   node,
    2720             :                   UseInfo(MachineRepresentation::kFloat64, Truncation::Any()),
    2721         215 :                   MachineRepresentation::kFloat64, Type::Number());
    2722         215 :               break;
    2723             :           }
    2724             :         }
    2725             :         return;
    2726             :       }
    2727             :       case IrOpcode::kCheckTaggedHole: {
    2728        3564 :         VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged);
    2729        3564 :         return;
    2730             :       }
    2731             :       case IrOpcode::kConvertTaggedHoleToUndefined: {
    2732        8240 :         if (InputIs(node, Type::NumberOrOddball()) &&
    2733        1920 :             truncation.IsUsedAsWord32()) {
    2734             :           // Propagate the Word32 truncation.
    2735             :           VisitUnop(node, UseInfo::TruncatingWord32(),
    2736         520 :                     MachineRepresentation::kWord32);
    2737         652 :           if (lower()) DeferReplacement(node, node->InputAt(0));
    2738        7200 :         } else if (InputIs(node, Type::NumberOrOddball()) &&
    2739        1400 :                    truncation.IsUsedAsFloat64()) {
    2740             :           // Propagate the Float64 truncation.
    2741             :           VisitUnop(node, UseInfo::TruncatingFloat64(),
    2742          75 :                     MachineRepresentation::kFloat64);
    2743         100 :           if (lower()) DeferReplacement(node, node->InputAt(0));
    2744        5725 :         } else if (InputIs(node, Type::NonInternal())) {
    2745          75 :           VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged);
    2746         100 :           if (lower()) DeferReplacement(node, node->InputAt(0));
    2747             :         } else {
    2748             :           // TODO(turbofan): Add a (Tagged) truncation that identifies hole
    2749             :           // and undefined, i.e. for a[i] === obj cases.
    2750        5650 :           VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged);
    2751             :         }
    2752             :         return;
    2753             :       }
    2754             :       case IrOpcode::kCheckMaps:
    2755             :       case IrOpcode::kTransitionElementsKind: {
    2756      153729 :         VisitInputs(node);
    2757             :         return SetOutput(node, MachineRepresentation::kNone);
    2758             :       }
    2759             :       case IrOpcode::kEnsureWritableFastElements:
    2760             :         return VisitBinop(node, UseInfo::AnyTagged(),
    2761             :                           MachineRepresentation::kTaggedPointer);
    2762             :       case IrOpcode::kMaybeGrowFastElements: {
    2763        6498 :         ProcessInput(node, 0, UseInfo::AnyTagged());         // object
    2764        6498 :         ProcessInput(node, 1, UseInfo::AnyTagged());         // elements
    2765        6498 :         ProcessInput(node, 2, UseInfo::TruncatingWord32());  // index
    2766        6498 :         ProcessInput(node, 3, UseInfo::TruncatingWord32());  // length
    2767        6498 :         ProcessRemainingInputs(node, 4);
    2768             :         SetOutput(node, MachineRepresentation::kTaggedPointer);
    2769             :         return;
    2770             :       }
    2771             : 
    2772             :       case IrOpcode::kNumberSilenceNaN:
    2773             :         VisitUnop(node, UseInfo::TruncatingFloat64(),
    2774        2267 :                   MachineRepresentation::kFloat64);
    2775        2995 :         if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
    2776             :         return;
    2777             :       case IrOpcode::kStateValues:
    2778    15883379 :         return VisitStateValues(node);
    2779             :       case IrOpcode::kObjectState:
    2780       28124 :         return VisitObjectState(node);
    2781             :       case IrOpcode::kTypeGuard: {
    2782             :         // We just get rid of the sigma here. In principle, it should be
    2783             :         // possible to refine the truncation and representation based on
    2784             :         // the sigma's type.
    2785             : 
    2786             :         // For now, we just handle specially the impossible case.
    2787             :         MachineRepresentation output =
    2788             :             TypeOf(node)->IsInhabited()
    2789             :                 ? GetOutputInfoForPhi(node, TypeOf(node->InputAt(0)),
    2790             :                                       truncation)
    2791      139124 :                 : MachineRepresentation::kNone;
    2792       69668 :         VisitUnop(node, UseInfo(output, truncation), output);
    2793       85948 :         if (lower()) DeferReplacement(node, node->InputAt(0));
    2794             :         return;
    2795             :       }
    2796             : 
    2797             :       case IrOpcode::kOsrGuard:
    2798      167685 :         return VisitOsrGuard(node);
    2799             : 
    2800             :       case IrOpcode::kFinishRegion:
    2801      303764 :         VisitInputs(node);
    2802             :         // Assume the output is tagged pointer.
    2803             :         return SetOutput(node, MachineRepresentation::kTaggedPointer);
    2804             : 
    2805             :       case IrOpcode::kReturn:
    2806     1593070 :         VisitReturn(node);
    2807             :         // Assume the output is tagged.
    2808             :         return SetOutput(node, MachineRepresentation::kTagged);
    2809             : 
    2810             :       // Operators with all inputs tagged and no or tagged output have uniform
    2811             :       // handling.
    2812             :       case IrOpcode::kEnd:
    2813             :       case IrOpcode::kIfSuccess:
    2814             :       case IrOpcode::kIfException:
    2815             :       case IrOpcode::kIfTrue:
    2816             :       case IrOpcode::kIfFalse:
    2817             :       case IrOpcode::kDeoptimize:
    2818             :       case IrOpcode::kEffectPhi:
    2819             :       case IrOpcode::kTerminate:
    2820             :       case IrOpcode::kFrameState:
    2821             :       case IrOpcode::kCheckpoint:
    2822             :       case IrOpcode::kLoop:
    2823             :       case IrOpcode::kMerge:
    2824             :       case IrOpcode::kThrow:
    2825             :       case IrOpcode::kBeginRegion:
    2826             :       case IrOpcode::kProjection:
    2827             :       case IrOpcode::kOsrValue:
    2828             :       case IrOpcode::kArgumentsElementsState:
    2829             :       case IrOpcode::kArgumentsLengthState:
    2830             : // All JavaScript operators except JSToNumber have uniform handling.
    2831             : #define OPCODE_CASE(name) case IrOpcode::k##name:
    2832             :         JS_SIMPLE_BINOP_LIST(OPCODE_CASE)
    2833             :         JS_OTHER_UNOP_LIST(OPCODE_CASE)
    2834             :         JS_OBJECT_OP_LIST(OPCODE_CASE)
    2835             :         JS_CONTEXT_OP_LIST(OPCODE_CASE)
    2836             :         JS_OTHER_OP_LIST(OPCODE_CASE)
    2837             : #undef OPCODE_CASE
    2838             :       case IrOpcode::kJSToInteger:
    2839             :       case IrOpcode::kJSToLength:
    2840             :       case IrOpcode::kJSToName:
    2841             :       case IrOpcode::kJSToObject:
    2842             :       case IrOpcode::kJSToString:
    2843    38662868 :         VisitInputs(node);
    2844             :         // Assume the output is tagged.
    2845             :         return SetOutput(node, MachineRepresentation::kTagged);
    2846             : 
    2847             :       default:
    2848             :         V8_Fatal(
    2849             :             __FILE__, __LINE__,
    2850             :             "Representation inference: unsupported opcode %i (%s), node #%i\n.",
    2851           0 :             node->opcode(), node->op()->mnemonic(), node->id());
    2852             :         break;
    2853             :     }
    2854             :     UNREACHABLE();
    2855             :   }
    2856             : 
    2857      250619 :   void DeferReplacement(Node* node, Node* replacement) {
    2858      596687 :     TRACE("defer replacement #%d:%s with #%d:%s\n", node->id(),
    2859             :           node->op()->mnemonic(), replacement->id(),
    2860             :           replacement->op()->mnemonic());
    2861             : 
    2862             :     // Disconnect the node from effect and control chains, if necessary.
    2863      751857 :     if (node->op()->EffectInputCount() > 0) {
    2864             :       DCHECK_LT(0, node->op()->ControlInputCount());
    2865             :       // Disconnect the node from effect and control chains.
    2866       95449 :       Node* control = NodeProperties::GetControlInput(node);
    2867       95449 :       Node* effect = NodeProperties::GetEffectInput(node);
    2868      190898 :       ReplaceEffectControlUses(node, effect, control);
    2869             :     }
    2870             : 
    2871      250619 :     replacements_.push_back(node);
    2872      250618 :     replacements_.push_back(replacement);
    2873             : 
    2874      250619 :     node->NullAllInputs();  // Node is now dead.
    2875      250620 :   }
    2876             : 
    2877      150457 :   void Kill(Node* node) {
    2878       50160 :     TRACE("killing #%d:%s\n", node->id(), node->op()->mnemonic());
    2879             : 
    2880       50160 :     if (node->op()->EffectInputCount() == 1) {
    2881             :       DCHECK_LT(0, node->op()->ControlInputCount());
    2882             :       // Disconnect the node from effect and control chains.
    2883       50137 :       Node* control = NodeProperties::GetControlInput(node);
    2884       50137 :       Node* effect = NodeProperties::GetEffectInput(node);
    2885       50137 :       ReplaceEffectControlUses(node, effect, control);
    2886             :     } else {
    2887             :       DCHECK_EQ(0, node->op()->EffectInputCount());
    2888             :       DCHECK_EQ(0, node->op()->ControlOutputCount());
    2889             :       DCHECK_EQ(0, node->op()->EffectOutputCount());
    2890             :     }
    2891             : 
    2892       50160 :     node->ReplaceUses(jsgraph_->Dead());
    2893             : 
    2894       50160 :     node->NullAllInputs();  // The {node} is now dead.
    2895       50160 :   }
    2896             : 
    2897    47798444 :   void PrintOutputInfo(NodeInfo* info) {
    2898    47798444 :     if (FLAG_trace_representation) {
    2899           0 :       OFStream os(stdout);
    2900           0 :       os << info->representation();
    2901             :     }
    2902    47798444 :   }
    2903             : 
    2904             :   void PrintRepresentation(MachineRepresentation rep) {
    2905             :     if (FLAG_trace_representation) {
    2906             :       OFStream os(stdout);
    2907             :       os << rep;
    2908             :     }
    2909             :   }
    2910             : 
    2911    89604515 :   void PrintTruncation(Truncation truncation) {
    2912    89604515 :     if (FLAG_trace_representation) {
    2913           0 :       OFStream os(stdout);
    2914           0 :       os << truncation.description() << std::endl;
    2915             :     }
    2916    89604515 :   }
    2917             : 
    2918    13218542 :   void PrintUseInfo(UseInfo info) {
    2919    13218542 :     if (FLAG_trace_representation) {
    2920           0 :       OFStream os(stdout);
    2921           0 :       os << info.representation() << ":" << info.truncation().description();
    2922             :     }
    2923    13218542 :   }
    2924             : 
    2925             :  private:
    2926             :   JSGraph* jsgraph_;
    2927             :   Zone* zone_;                      // Temporary zone.
    2928             :   size_t const count_;              // number of nodes in the graph
    2929             :   ZoneVector<NodeInfo> info_;       // node id -> usage information
    2930             : #ifdef DEBUG
    2931             :   ZoneVector<InputUseInfos> node_input_use_infos_;  // Debug information about
    2932             :                                                     // requirements on inputs.
    2933             : #endif                                              // DEBUG
    2934             :   NodeVector nodes_;                // collected nodes
    2935             :   NodeVector replacements_;         // replacements to be done after lowering
    2936             :   Phase phase_;                     // current phase of algorithm
    2937             :   RepresentationChanger* changer_;  // for inserting representation changes
    2938             :   ZoneQueue<Node*> queue_;          // queue for traversing the graph
    2939             : 
    2940             :   struct NodeState {
    2941             :     Node* node;
    2942             :     int input_index;
    2943             :   };
    2944             :   ZoneStack<NodeState> typing_stack_;  // stack for graph typing.
    2945             :   // TODO(danno): RepresentationSelector shouldn't know anything about the
    2946             :   // source positions table, but must for now since there currently is no other
    2947             :   // way to pass down source position information to nodes created during
    2948             :   // lowering. Once this phase becomes a vanilla reducer, it should get source
    2949             :   // position information via the SourcePositionWrapper like all other reducers.
    2950             :   SourcePositionTable* source_positions_;
    2951             :   TypeCache const& type_cache_;
    2952             :   OperationTyper op_typer_;  // helper for the feedback typer
    2953             : 
    2954   593762606 :   NodeInfo* GetInfo(Node* node) {
    2955             :     DCHECK(node->id() < count_);
    2956   597468671 :     return &info_[node->id()];
    2957             :   }
    2958             :   Zone* zone() { return zone_; }
    2959             :   Zone* graph_zone() { return jsgraph_->zone(); }
    2960             : };
    2961             : 
    2962      394594 : SimplifiedLowering::SimplifiedLowering(JSGraph* jsgraph, Zone* zone,
    2963             :                                        SourcePositionTable* source_positions)
    2964             :     : jsgraph_(jsgraph),
    2965             :       zone_(zone),
    2966      394594 :       type_cache_(TypeCache::Get()),
    2967     1183782 :       source_positions_(source_positions) {}
    2968             : 
    2969      394593 : void SimplifiedLowering::LowerAllNodes() {
    2970      394593 :   RepresentationChanger changer(jsgraph(), jsgraph()->isolate());
    2971             :   RepresentationSelector selector(jsgraph(), zone_, &changer,
    2972      394593 :                                   source_positions_);
    2973      394593 :   selector.Run(this);
    2974      394594 : }
    2975             : 
    2976         162 : void SimplifiedLowering::DoJSToNumberTruncatesToFloat64(
    2977             :     Node* node, RepresentationSelector* selector) {
    2978             :   DCHECK_EQ(IrOpcode::kJSToNumber, node->opcode());
    2979             :   Node* value = node->InputAt(0);
    2980             :   Node* context = node->InputAt(1);
    2981             :   Node* frame_state = node->InputAt(2);
    2982             :   Node* effect = node->InputAt(3);
    2983             :   Node* control = node->InputAt(4);
    2984             : 
    2985         162 :   Node* check0 = graph()->NewNode(simplified()->ObjectIsSmi(), value);
    2986             :   Node* branch0 =
    2987         162 :       graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
    2988             : 
    2989         162 :   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
    2990             :   Node* etrue0 = effect;
    2991             :   Node* vtrue0;
    2992             :   {
    2993         162 :     vtrue0 = graph()->NewNode(simplified()->ChangeTaggedSignedToInt32(), value);
    2994         162 :     vtrue0 = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue0);
    2995             :   }
    2996             : 
    2997         162 :   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
    2998             :   Node* efalse0 = effect;
    2999             :   Node* vfalse0;
    3000             :   {
    3001             :     vfalse0 = efalse0 = if_false0 =
    3002             :         graph()->NewNode(ToNumberOperator(), ToNumberCode(), value, context,
    3003         162 :                          frame_state, efalse0, if_false0);
    3004             : 
    3005             :     // Update potential {IfException} uses of {node} to point to the above
    3006             :     // {ToNumber} stub call node instead.
    3007         162 :     Node* on_exception = nullptr;
    3008         162 :     if (NodeProperties::IsExceptionalCall(node, &on_exception)) {
    3009           0 :       NodeProperties::ReplaceControlInput(on_exception, vfalse0);
    3010           0 :       NodeProperties::ReplaceEffectInput(on_exception, efalse0);
    3011           0 :       if_false0 = graph()->NewNode(common()->IfSuccess(), vfalse0);
    3012             :     }
    3013             : 
    3014         162 :     Node* check1 = graph()->NewNode(simplified()->ObjectIsSmi(), vfalse0);
    3015         162 :     Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0);
    3016             : 
    3017         162 :     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
    3018             :     Node* etrue1 = efalse0;
    3019             :     Node* vtrue1;
    3020             :     {
    3021             :       vtrue1 =
    3022         162 :           graph()->NewNode(simplified()->ChangeTaggedSignedToInt32(), vfalse0);
    3023         162 :       vtrue1 = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue1);
    3024             :     }
    3025             : 
    3026         162 :     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
    3027             :     Node* efalse1 = efalse0;
    3028             :     Node* vfalse1;
    3029             :     {
    3030             :       vfalse1 = efalse1 = graph()->NewNode(
    3031             :           simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), efalse0,
    3032         486 :           efalse1, if_false1);
    3033             :     }
    3034             : 
    3035         162 :     if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
    3036             :     efalse0 =
    3037         162 :         graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_false0);
    3038             :     vfalse0 =
    3039             :         graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
    3040         162 :                          vtrue1, vfalse1, if_false0);
    3041             :   }
    3042             : 
    3043         162 :   control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
    3044         162 :   effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
    3045             :   value = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
    3046         162 :                            vtrue0, vfalse0, control);
    3047             : 
    3048             :   // Replace effect and control uses appropriately.
    3049        1740 :   for (Edge edge : node->use_edges()) {
    3050         789 :     if (NodeProperties::IsControlEdge(edge)) {
    3051        1077 :       if (edge.from()->opcode() == IrOpcode::kIfSuccess) {
    3052           0 :         edge.from()->ReplaceUses(control);
    3053           0 :         edge.from()->Kill();
    3054             :       } else {
    3055             :         DCHECK(edge.from()->opcode() != IrOpcode::kIfException);
    3056         359 :         edge.UpdateTo(control);
    3057             :       }
    3058         430 :     } else if (NodeProperties::IsEffectEdge(edge)) {
    3059         238 :       edge.UpdateTo(effect);
    3060             :     }
    3061             :   }
    3062             : 
    3063         162 :   selector->DeferReplacement(node, value);
    3064         162 : }
    3065             : 
    3066        2362 : void SimplifiedLowering::DoJSToNumberTruncatesToWord32(
    3067             :     Node* node, RepresentationSelector* selector) {
    3068             :   DCHECK_EQ(IrOpcode::kJSToNumber, node->opcode());
    3069             :   Node* value = node->InputAt(0);
    3070             :   Node* context = node->InputAt(1);
    3071             :   Node* frame_state = node->InputAt(2);
    3072             :   Node* effect = node->InputAt(3);
    3073             :   Node* control = node->InputAt(4);
    3074             : 
    3075        2362 :   Node* check0 = graph()->NewNode(simplified()->ObjectIsSmi(), value);
    3076             :   Node* branch0 =
    3077        2362 :       graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
    3078             : 
    3079        2362 :   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
    3080             :   Node* etrue0 = effect;
    3081             :   Node* vtrue0 =
    3082        2362 :       graph()->NewNode(simplified()->ChangeTaggedSignedToInt32(), value);
    3083             : 
    3084        2362 :   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
    3085             :   Node* efalse0 = effect;
    3086             :   Node* vfalse0;
    3087             :   {
    3088             :     vfalse0 = efalse0 = if_false0 =
    3089             :         graph()->NewNode(ToNumberOperator(), ToNumberCode(), value, context,
    3090        2362 :                          frame_state, efalse0, if_false0);
    3091             : 
    3092             :     // Update potential {IfException} uses of {node} to point to the above
    3093             :     // {ToNumber} stub call node instead.
    3094        2362 :     Node* on_exception = nullptr;
    3095        2362 :     if (NodeProperties::IsExceptionalCall(node, &on_exception)) {
    3096           0 :       NodeProperties::ReplaceControlInput(on_exception, vfalse0);
    3097           0 :       NodeProperties::ReplaceEffectInput(on_exception, efalse0);
    3098           0 :       if_false0 = graph()->NewNode(common()->IfSuccess(), vfalse0);
    3099             :     }
    3100             : 
    3101        2362 :     Node* check1 = graph()->NewNode(simplified()->ObjectIsSmi(), vfalse0);
    3102        2362 :     Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0);
    3103             : 
    3104        2362 :     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
    3105             :     Node* etrue1 = efalse0;
    3106             :     Node* vtrue1 =
    3107        2362 :         graph()->NewNode(simplified()->ChangeTaggedSignedToInt32(), vfalse0);
    3108             : 
    3109        2362 :     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
    3110             :     Node* efalse1 = efalse0;
    3111             :     Node* vfalse1;
    3112             :     {
    3113             :       vfalse1 = efalse1 = graph()->NewNode(
    3114             :           simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), efalse0,
    3115        7086 :           efalse1, if_false1);
    3116        2362 :       vfalse1 = graph()->NewNode(machine()->TruncateFloat64ToWord32(), vfalse1);
    3117             :     }
    3118             : 
    3119        2362 :     if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
    3120             :     efalse0 =
    3121        2362 :         graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_false0);
    3122             :     vfalse0 = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
    3123        2362 :                                vtrue1, vfalse1, if_false0);
    3124             :   }
    3125             : 
    3126        2362 :   control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
    3127        2362 :   effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
    3128             :   value = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
    3129        2362 :                            vtrue0, vfalse0, control);
    3130             : 
    3131             :   // Replace effect and control uses appropriately.
    3132       25970 :   for (Edge edge : node->use_edges()) {
    3133       11804 :     if (NodeProperties::IsControlEdge(edge)) {
    3134       17457 :       if (edge.from()->opcode() == IrOpcode::kIfSuccess) {
    3135           0 :         edge.from()->ReplaceUses(control);
    3136           0 :         edge.from()->Kill();
    3137             :       } else {
    3138             :         DCHECK(edge.from()->opcode() != IrOpcode::kIfException);
    3139        5819 :         edge.UpdateTo(control);
    3140             :       }
    3141        5985 :     } else if (NodeProperties::IsEffectEdge(edge)) {
    3142        3746 :       edge.UpdateTo(effect);
    3143             :     }
    3144             :   }
    3145             : 
    3146        2362 :   selector->DeferReplacement(node, value);
    3147        2362 : }
    3148             : 
    3149        5938 : void SimplifiedLowering::DoLoadBuffer(Node* node,
    3150             :                                       MachineRepresentation output_rep,
    3151         616 :                                       RepresentationChanger* changer) {
    3152             :   DCHECK_EQ(IrOpcode::kLoadBuffer, node->opcode());
    3153             :   DCHECK_NE(MachineRepresentation::kNone, output_rep);
    3154        5938 :   MachineType const access_type = BufferAccessOf(node->op()).machine_type();
    3155        5938 :   if (output_rep != access_type.representation()) {
    3156             :     Node* const buffer = node->InputAt(0);
    3157             :     Node* const offset = node->InputAt(1);
    3158             :     Node* const length = node->InputAt(2);
    3159             :     Node* const effect = node->InputAt(3);
    3160             :     Node* const control = node->InputAt(4);
    3161             :     Node* const index =
    3162             :         machine()->Is64()
    3163         308 :             ? graph()->NewNode(machine()->ChangeUint32ToUint64(), offset)
    3164         308 :             : offset;
    3165             : 
    3166         308 :     Node* check = graph()->NewNode(machine()->Uint32LessThan(), offset, length);
    3167             :     Node* branch =
    3168         308 :         graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
    3169             : 
    3170         308 :     Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
    3171             :     Node* etrue = graph()->NewNode(machine()->Load(access_type), buffer, index,
    3172         308 :                                    effect, if_true);
    3173             :     Type* element_type =
    3174         308 :         Type::Intersect(NodeProperties::GetType(node), Type::Number(), zone());
    3175             :     Node* vtrue = changer->GetRepresentationFor(
    3176             :         etrue, access_type.representation(), element_type, node,
    3177         308 :         UseInfo(output_rep, Truncation::None()));
    3178             : 
    3179         308 :     Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
    3180             :     Node* efalse = effect;
    3181             :     Node* vfalse;
    3182         308 :     if (output_rep == MachineRepresentation::kTagged) {
    3183         206 :       vfalse = jsgraph()->UndefinedConstant();
    3184         102 :     } else if (output_rep == MachineRepresentation::kFloat64) {
    3185             :       vfalse =
    3186         102 :           jsgraph()->Float64Constant(std::numeric_limits<double>::quiet_NaN());
    3187           0 :     } else if (output_rep == MachineRepresentation::kFloat32) {
    3188             :       vfalse =
    3189           0 :           jsgraph()->Float32Constant(std::numeric_limits<float>::quiet_NaN());
    3190             :     } else {
    3191           0 :       vfalse = jsgraph()->Int32Constant(0);
    3192             :     }
    3193             : 
    3194         308 :     Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
    3195         308 :     Node* ephi = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, merge);
    3196             : 
    3197             :     // Replace effect uses of {node} with the {ephi}.
    3198         308 :     NodeProperties::ReplaceUses(node, node, ephi);
    3199             : 
    3200             :     // Turn the {node} into a Phi.
    3201         308 :     node->ReplaceInput(0, vtrue);
    3202         308 :     node->ReplaceInput(1, vfalse);
    3203         308 :     node->ReplaceInput(2, merge);
    3204         308 :     node->TrimInputCount(3);
    3205         308 :     NodeProperties::ChangeOp(node, common()->Phi(output_rep, 2));
    3206             :   } else {
    3207        5630 :     NodeProperties::ChangeOp(node, machine()->CheckedLoad(access_type));
    3208             :   }
    3209        5938 : }
    3210             : 
    3211             : 
    3212        4113 : void SimplifiedLowering::DoStoreBuffer(Node* node) {
    3213             :   DCHECK_EQ(IrOpcode::kStoreBuffer, node->opcode());
    3214             :   MachineRepresentation const rep =
    3215        4113 :       BufferAccessOf(node->op()).machine_type().representation();
    3216        4113 :   NodeProperties::ChangeOp(node, machine()->CheckedStore(rep));
    3217        4113 : }
    3218             : 
    3219         124 : Node* SimplifiedLowering::Float64Round(Node* const node) {
    3220          62 :   Node* const one = jsgraph()->Float64Constant(1.0);
    3221          62 :   Node* const one_half = jsgraph()->Float64Constant(0.5);
    3222             :   Node* const input = node->InputAt(0);
    3223             : 
    3224             :   // Round up towards Infinity, and adjust if the difference exceeds 0.5.
    3225             :   Node* result = graph()->NewNode(machine()->Float64RoundUp().placeholder(),
    3226         124 :                                   node->InputAt(0));
    3227             :   return graph()->NewNode(
    3228             :       common()->Select(MachineRepresentation::kFloat64),
    3229             :       graph()->NewNode(
    3230             :           machine()->Float64LessThanOrEqual(),
    3231             :           graph()->NewNode(machine()->Float64Sub(), result, one_half), input),
    3232         310 :       result, graph()->NewNode(machine()->Float64Sub(), result, one));
    3233             : }
    3234             : 
    3235          42 : Node* SimplifiedLowering::Float64Sign(Node* const node) {
    3236          14 :   Node* const minus_one = jsgraph()->Float64Constant(-1.0);
    3237          14 :   Node* const zero = jsgraph()->Float64Constant(0.0);
    3238          14 :   Node* const one = jsgraph()->Float64Constant(1.0);
    3239             : 
    3240             :   Node* const input = node->InputAt(0);
    3241             : 
    3242             :   return graph()->NewNode(
    3243             :       common()->Select(MachineRepresentation::kFloat64),
    3244             :       graph()->NewNode(machine()->Float64LessThan(), input, zero), minus_one,
    3245             :       graph()->NewNode(
    3246             :           common()->Select(MachineRepresentation::kFloat64),
    3247             :           graph()->NewNode(machine()->Float64LessThan(), zero, input), one,
    3248          70 :           input));
    3249             : }
    3250             : 
    3251          66 : Node* SimplifiedLowering::Int32Abs(Node* const node) {
    3252             :   Node* const input = node->InputAt(0);
    3253             : 
    3254             :   // Generate case for absolute integer value.
    3255             :   //
    3256             :   //    let sign = input >> 31 in
    3257             :   //    (input ^ sign) - sign
    3258             : 
    3259             :   Node* sign = graph()->NewNode(machine()->Word32Sar(), input,
    3260          66 :                                 jsgraph()->Int32Constant(31));
    3261             :   return graph()->NewNode(machine()->Int32Sub(),
    3262             :                           graph()->NewNode(machine()->Word32Xor(), input, sign),
    3263          99 :                           sign);
    3264             : }
    3265             : 
    3266        8298 : Node* SimplifiedLowering::Int32Div(Node* const node) {
    3267        2766 :   Int32BinopMatcher m(node);
    3268        2766 :   Node* const zero = jsgraph()->Int32Constant(0);
    3269        2766 :   Node* const minus_one = jsgraph()->Int32Constant(-1);
    3270             :   Node* const lhs = m.left().node();
    3271             :   Node* const rhs = m.right().node();
    3272             : 
    3273        2766 :   if (m.right().Is(-1)) {
    3274          44 :     return graph()->NewNode(machine()->Int32Sub(), zero, lhs);
    3275        2744 :   } else if (m.right().Is(0)) {
    3276             :     return rhs;
    3277        2731 :   } else if (machine()->Int32DivIsSafe() || m.right().HasValue()) {
    3278        5272 :     return graph()->NewNode(machine()->Int32Div(), lhs, rhs, graph()->start());
    3279             :   }
    3280             : 
    3281             :   // General case for signed integer division.
    3282             :   //
    3283             :   //    if 0 < rhs then
    3284             :   //      lhs / rhs
    3285             :   //    else
    3286             :   //      if rhs < -1 then
    3287             :   //        lhs / rhs
    3288             :   //      else if rhs == 0 then
    3289             :   //        0
    3290             :   //      else
    3291             :   //        0 - lhs
    3292             :   //
    3293             :   // Note: We do not use the Diamond helper class here, because it really hurts
    3294             :   // readability with nested diamonds.
    3295          95 :   const Operator* const merge_op = common()->Merge(2);
    3296             :   const Operator* const phi_op =
    3297          95 :       common()->Phi(MachineRepresentation::kWord32, 2);
    3298             : 
    3299          95 :   Node* check0 = graph()->NewNode(machine()->Int32LessThan(), zero, rhs);
    3300             :   Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kTrue), check0,
    3301         190 :                                    graph()->start());
    3302             : 
    3303          95 :   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
    3304          95 :   Node* true0 = graph()->NewNode(machine()->Int32Div(), lhs, rhs, if_true0);
    3305             : 
    3306          95 :   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
    3307             :   Node* false0;
    3308             :   {
    3309          95 :     Node* check1 = graph()->NewNode(machine()->Int32LessThan(), rhs, minus_one);
    3310          95 :     Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0);
    3311             : 
    3312          95 :     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
    3313          95 :     Node* true1 = graph()->NewNode(machine()->Int32Div(), lhs, rhs, if_true1);
    3314             : 
    3315          95 :     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
    3316             :     Node* false1;
    3317             :     {
    3318          95 :       Node* check2 = graph()->NewNode(machine()->Word32Equal(), rhs, zero);
    3319          95 :       Node* branch2 = graph()->NewNode(common()->Branch(), check2, if_false1);
    3320             : 
    3321          95 :       Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
    3322             :       Node* true2 = zero;
    3323             : 
    3324          95 :       Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
    3325          95 :       Node* false2 = graph()->NewNode(machine()->Int32Sub(), zero, lhs);
    3326             : 
    3327             :       if_false1 = graph()->NewNode(merge_op, if_true2, if_false2);
    3328             :       false1 = graph()->NewNode(phi_op, true2, false2, if_false1);
    3329             :     }
    3330             : 
    3331             :     if_false0 = graph()->NewNode(merge_op, if_true1, if_false1);
    3332             :     false0 = graph()->NewNode(phi_op, true1, false1, if_false0);
    3333             :   }
    3334             : 
    3335             :   Node* merge0 = graph()->NewNode(merge_op, if_true0, if_false0);
    3336          95 :   return graph()->NewNode(phi_op, true0, false0, merge0);
    3337             : }
    3338             : 
    3339             : 
    3340        8556 : Node* SimplifiedLowering::Int32Mod(Node* const node) {
    3341        2852 :   Int32BinopMatcher m(node);
    3342        2852 :   Node* const zero = jsgraph()->Int32Constant(0);
    3343        2852 :   Node* const minus_one = jsgraph()->Int32Constant(-1);
    3344             :   Node* const lhs = m.left().node();
    3345             :   Node* const rhs = m.right().node();
    3346             : 
    3347        5689 :   if (m.right().Is(-1) || m.right().Is(0)) {
    3348             :     return zero;
    3349        2837 :   } else if (m.right().HasValue()) {
    3350        8124 :     return graph()->NewNode(machine()->Int32Mod(), lhs, rhs, graph()->start());
    3351             :   }
    3352             : 
    3353             :   // General case for signed integer modulus, with optimization for (unknown)
    3354             :   // power of 2 right hand side.
    3355             :   //
    3356             :   //   if 0 < rhs then
    3357             :   //     msk = rhs - 1
    3358             :   //     if rhs & msk != 0 then
    3359             :   //       lhs % rhs
    3360             :   //     else
    3361             :   //       if lhs < 0 then
    3362             :   //         -(-lhs & msk)
    3363             :   //       else
    3364             :   //         lhs & msk
    3365             :   //   else
    3366             :   //     if rhs < -1 then
    3367             :   //       lhs % rhs
    3368             :   //     else
    3369             :   //       zero
    3370             :   //
    3371             :   // Note: We do not use the Diamond helper class here, because it really hurts
    3372             :   // readability with nested diamonds.
    3373         129 :   const Operator* const merge_op = common()->Merge(2);
    3374             :   const Operator* const phi_op =
    3375         129 :       common()->Phi(MachineRepresentation::kWord32, 2);
    3376             : 
    3377         129 :   Node* check0 = graph()->NewNode(machine()->Int32LessThan(), zero, rhs);
    3378             :   Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kTrue), check0,
    3379         258 :                                    graph()->start());
    3380             : 
    3381         129 :   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
    3382             :   Node* true0;
    3383             :   {
    3384         129 :     Node* msk = graph()->NewNode(machine()->Int32Add(), rhs, minus_one);
    3385             : 
    3386         129 :     Node* check1 = graph()->NewNode(machine()->Word32And(), rhs, msk);
    3387         129 :     Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0);
    3388             : 
    3389         129 :     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
    3390         129 :     Node* true1 = graph()->NewNode(machine()->Int32Mod(), lhs, rhs, if_true1);
    3391             : 
    3392         129 :     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
    3393             :     Node* false1;
    3394             :     {
    3395         129 :       Node* check2 = graph()->NewNode(machine()->Int32LessThan(), lhs, zero);
    3396             :       Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
    3397         129 :                                        check2, if_false1);
    3398             : 
    3399         129 :       Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
    3400             :       Node* true2 = graph()->NewNode(
    3401             :           machine()->Int32Sub(), zero,
    3402             :           graph()->NewNode(machine()->Word32And(),
    3403             :                            graph()->NewNode(machine()->Int32Sub(), zero, lhs),
    3404         387 :                            msk));
    3405             : 
    3406         129 :       Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
    3407         129 :       Node* false2 = graph()->NewNode(machine()->Word32And(), lhs, msk);
    3408             : 
    3409             :       if_false1 = graph()->NewNode(merge_op, if_true2, if_false2);
    3410             :       false1 = graph()->NewNode(phi_op, true2, false2, if_false1);
    3411             :     }
    3412             : 
    3413             :     if_true0 = graph()->NewNode(merge_op, if_true1, if_false1);
    3414             :     true0 = graph()->NewNode(phi_op, true1, false1, if_true0);
    3415             :   }
    3416             : 
    3417         129 :   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
    3418             :   Node* false0;
    3419             :   {
    3420         129 :     Node* check1 = graph()->NewNode(machine()->Int32LessThan(), rhs, minus_one);
    3421             :     Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kTrue),
    3422         129 :                                      check1, if_false0);
    3423             : 
    3424         129 :     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
    3425         129 :     Node* true1 = graph()->NewNode(machine()->Int32Mod(), lhs, rhs, if_true1);
    3426             : 
    3427         129 :     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
    3428             :     Node* false1 = zero;
    3429             : 
    3430             :     if_false0 = graph()->NewNode(merge_op, if_true1, if_false1);
    3431             :     false0 = graph()->NewNode(phi_op, true1, false1, if_false0);
    3432             :   }
    3433             : 
    3434             :   Node* merge0 = graph()->NewNode(merge_op, if_true0, if_false0);
    3435         129 :   return graph()->NewNode(phi_op, true0, false0, merge0);
    3436             : }
    3437             : 
    3438          21 : Node* SimplifiedLowering::Int32Sign(Node* const node) {
    3439           7 :   Node* const minus_one = jsgraph()->Int32Constant(-1);
    3440           7 :   Node* const zero = jsgraph()->Int32Constant(0);
    3441           7 :   Node* const one = jsgraph()->Int32Constant(1);
    3442             : 
    3443             :   Node* const input = node->InputAt(0);
    3444             : 
    3445             :   return graph()->NewNode(
    3446             :       common()->Select(MachineRepresentation::kWord32),
    3447             :       graph()->NewNode(machine()->Int32LessThan(), input, zero), minus_one,
    3448             :       graph()->NewNode(
    3449             :           common()->Select(MachineRepresentation::kWord32),
    3450             :           graph()->NewNode(machine()->Int32LessThan(), zero, input), one,
    3451          35 :           zero));
    3452             : }
    3453             : 
    3454         562 : Node* SimplifiedLowering::Uint32Div(Node* const node) {
    3455         281 :   Uint32BinopMatcher m(node);
    3456             :   Node* const zero = jsgraph()->Uint32Constant(0);
    3457             :   Node* const lhs = m.left().node();
    3458             :   Node* const rhs = m.right().node();
    3459             : 
    3460         281 :   if (m.right().Is(0)) {
    3461             :     return zero;
    3462         261 :   } else if (machine()->Uint32DivIsSafe() || m.right().HasValue()) {
    3463         420 :     return graph()->NewNode(machine()->Uint32Div(), lhs, rhs, graph()->start());
    3464             :   }
    3465             : 
    3466          51 :   Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, zero);
    3467          51 :   Diamond d(graph(), common(), check, BranchHint::kFalse);
    3468         102 :   Node* div = graph()->NewNode(machine()->Uint32Div(), lhs, rhs, d.if_false);
    3469          51 :   return d.Phi(MachineRepresentation::kWord32, zero, div);
    3470             : }
    3471             : 
    3472             : 
    3473        1527 : Node* SimplifiedLowering::Uint32Mod(Node* const node) {
    3474         509 :   Uint32BinopMatcher m(node);
    3475         509 :   Node* const minus_one = jsgraph()->Int32Constant(-1);
    3476             :   Node* const zero = jsgraph()->Uint32Constant(0);
    3477             :   Node* const lhs = m.left().node();
    3478             :   Node* const rhs = m.right().node();
    3479             : 
    3480         509 :   if (m.right().Is(0)) {
    3481             :     return zero;
    3482         509 :   } else if (m.right().HasValue()) {
    3483        1374 :     return graph()->NewNode(machine()->Uint32Mod(), lhs, rhs, graph()->start());
    3484             :   }
    3485             : 
    3486             :   // General case for unsigned integer modulus, with optimization for (unknown)
    3487             :   // power of 2 right hand side.
    3488             :   //
    3489             :   //   if rhs then
    3490             :   //     msk = rhs - 1
    3491             :   //     if rhs & msk != 0 then
    3492             :   //       lhs % rhs
    3493             :   //     else
    3494             :   //       lhs & msk
    3495             :   //   else
    3496             :   //     zero
    3497             :   //
    3498             :   // Note: We do not use the Diamond helper class here, because it really hurts
    3499             :   // readability with nested diamonds.
    3500          51 :   const Operator* const merge_op = common()->Merge(2);
    3501             :   const Operator* const phi_op =
    3502          51 :       common()->Phi(MachineRepresentation::kWord32, 2);
    3503             : 
    3504             :   Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kTrue), rhs,
    3505         102 :                                    graph()->start());
    3506             : 
    3507          51 :   Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
    3508             :   Node* true0;
    3509             :   {
    3510          51 :     Node* msk = graph()->NewNode(machine()->Int32Add(), rhs, minus_one);
    3511             : 
    3512          51 :     Node* check1 = graph()->NewNode(machine()->Word32And(), rhs, msk);
    3513          51 :     Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0);
    3514             : 
    3515          51 :     Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
    3516          51 :     Node* true1 = graph()->NewNode(machine()->Uint32Mod(), lhs, rhs, if_true1);
    3517             : 
    3518          51 :     Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
    3519          51 :     Node* false1 = graph()->NewNode(machine()->Word32And(), lhs, msk);
    3520             : 
    3521             :     if_true0 = graph()->NewNode(merge_op, if_true1, if_false1);
    3522             :     true0 = graph()->NewNode(phi_op, true1, false1, if_true0);
    3523             :   }
    3524             : 
    3525          51 :   Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
    3526             :   Node* false0 = zero;
    3527             : 
    3528             :   Node* merge0 = graph()->NewNode(merge_op, if_true0, if_false0);
    3529          51 :   return graph()->NewNode(phi_op, true0, false0, merge0);
    3530             : }
    3531             : 
    3532         119 : void SimplifiedLowering::DoMax(Node* node, Operator const* op,
    3533             :                                MachineRepresentation rep) {
    3534             :   Node* const lhs = node->InputAt(0);
    3535             :   Node* const rhs = node->InputAt(1);
    3536             : 
    3537         119 :   node->ReplaceInput(0, graph()->NewNode(op, lhs, rhs));
    3538             :   DCHECK_EQ(rhs, node->InputAt(1));
    3539         119 :   node->AppendInput(graph()->zone(), lhs);
    3540         119 :   NodeProperties::ChangeOp(node, common()->Select(rep));
    3541         119 : }
    3542             : 
    3543         118 : void SimplifiedLowering::DoMin(Node* node, Operator const* op,
    3544             :                                MachineRepresentation rep) {
    3545             :   Node* const lhs = node->InputAt(0);
    3546             :   Node* const rhs = node->InputAt(1);
    3547             : 
    3548         118 :   node->InsertInput(graph()->zone(), 0, graph()->NewNode(op, lhs, rhs));
    3549             :   DCHECK_EQ(lhs, node->InputAt(1));
    3550             :   DCHECK_EQ(rhs, node->InputAt(2));
    3551         118 :   NodeProperties::ChangeOp(node, common()->Select(rep));
    3552         118 : }
    3553             : 
    3554       39005 : void SimplifiedLowering::DoShift(Node* node, Operator const* op,
    3555        5074 :                                  Type* rhs_type) {
    3556       78009 :   if (!rhs_type->Is(type_cache_.kZeroToThirtyOne)) {
    3557        5074 :     Node* const rhs = NodeProperties::GetValueInput(node, 1);
    3558             :     node->ReplaceInput(1, graph()->NewNode(machine()->Word32And(), rhs,
    3559       15222 :                                            jsgraph()->Int32Constant(0x1f)));
    3560             :   }
    3561       39004 :   ChangeToPureOp(node, op);
    3562       39005 : }
    3563             : 
    3564        2244 : void SimplifiedLowering::DoStringToNumber(Node* node) {
    3565             :   Operator::Properties properties = Operator::kEliminatable;
    3566         561 :   Callable callable = CodeFactory::StringToNumber(isolate());
    3567             :   CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
    3568             :   CallDescriptor* desc = Linkage::GetStubCallDescriptor(
    3569        1683 :       isolate(), graph()->zone(), callable.descriptor(), 0, flags, properties);
    3570             :   node->InsertInput(graph()->zone(), 0,
    3571        1122 :                     jsgraph()->HeapConstant(callable.code()));
    3572         561 :   node->AppendInput(graph()->zone(), jsgraph()->NoContextConstant());
    3573         561 :   node->AppendInput(graph()->zone(), graph()->start());
    3574         561 :   NodeProperties::ChangeOp(node, common()->Call(desc));
    3575         561 : }
    3576             : 
    3577         326 : void SimplifiedLowering::DoIntegral32ToBit(Node* node) {
    3578             :   Node* const input = node->InputAt(0);
    3579         163 :   Node* const zero = jsgraph()->Int32Constant(0);
    3580         163 :   Operator const* const op = machine()->Word32Equal();
    3581             : 
    3582         163 :   node->ReplaceInput(0, graph()->NewNode(op, input, zero));
    3583         163 :   node->AppendInput(graph()->zone(), zero);
    3584         163 :   NodeProperties::ChangeOp(node, op);
    3585         163 : }
    3586             : 
    3587           0 : void SimplifiedLowering::DoOrderedNumberToBit(Node* node) {
    3588             :   Node* const input = node->InputAt(0);
    3589             : 
    3590             :   node->ReplaceInput(0, graph()->NewNode(machine()->Float64Equal(), input,
    3591           0 :                                          jsgraph()->Float64Constant(0.0)));
    3592           0 :   node->AppendInput(graph()->zone(), jsgraph()->Int32Constant(0));
    3593           0 :   NodeProperties::ChangeOp(node, machine()->Word32Equal());
    3594           0 : }
    3595             : 
    3596         394 : void SimplifiedLowering::DoNumberToBit(Node* node) {
    3597             :   Node* const input = node->InputAt(0);
    3598             : 
    3599         197 :   node->ReplaceInput(0, jsgraph()->Float64Constant(0.0));
    3600             :   node->AppendInput(graph()->zone(),
    3601         394 :                     graph()->NewNode(machine()->Float64Abs(), input));
    3602         197 :   NodeProperties::ChangeOp(node, machine()->Float64LessThan());
    3603         197 : }
    3604             : 
    3605          72 : void SimplifiedLowering::DoIntegerToUint8Clamped(Node* node) {
    3606             :   Node* const input = node->InputAt(0);
    3607          24 :   Node* const min = jsgraph()->Float64Constant(0.0);
    3608          24 :   Node* const max = jsgraph()->Float64Constant(255.0);
    3609             : 
    3610             :   node->ReplaceInput(
    3611          48 :       0, graph()->NewNode(machine()->Float64LessThan(), min, input));
    3612             :   node->AppendInput(
    3613             :       graph()->zone(),
    3614             :       graph()->NewNode(
    3615             :           common()->Select(MachineRepresentation::kFloat64),
    3616             :           graph()->NewNode(machine()->Float64LessThan(), input, max), input,
    3617          72 :           max));
    3618          24 :   node->AppendInput(graph()->zone(), min);
    3619             :   NodeProperties::ChangeOp(node,
    3620          24 :                            common()->Select(MachineRepresentation::kFloat64));
    3621          24 : }
    3622             : 
    3623         900 : void SimplifiedLowering::DoNumberToUint8Clamped(Node* node) {
    3624             :   Node* const input = node->InputAt(0);
    3625         300 :   Node* const min = jsgraph()->Float64Constant(0.0);
    3626         300 :   Node* const max = jsgraph()->Float64Constant(255.0);
    3627             : 
    3628             :   node->ReplaceInput(
    3629             :       0, graph()->NewNode(
    3630             :              common()->Select(MachineRepresentation::kFloat64),
    3631             :              graph()->NewNode(machine()->Float64LessThan(), min, input),
    3632             :              graph()->NewNode(
    3633             :                  common()->Select(MachineRepresentation::kFloat64),
    3634             :                  graph()->NewNode(machine()->Float64LessThan(), input, max),
    3635             :                  input, max),
    3636        1500 :              min));
    3637             :   NodeProperties::ChangeOp(node,
    3638         300 :                            machine()->Float64RoundTiesEven().placeholder());
    3639         300 : }
    3640             : 
    3641         186 : void SimplifiedLowering::DoSigned32ToUint8Clamped(Node* node) {
    3642             :   Node* const input = node->InputAt(0);
    3643          62 :   Node* const min = jsgraph()->Int32Constant(0);
    3644          62 :   Node* const max = jsgraph()->Int32Constant(255);
    3645             : 
    3646             :   node->ReplaceInput(
    3647         124 :       0, graph()->NewNode(machine()->Int32LessThanOrEqual(), input, max));
    3648             :   node->AppendInput(
    3649             :       graph()->zone(),
    3650             :       graph()->NewNode(common()->Select(MachineRepresentation::kWord32),
    3651             :                        graph()->NewNode(machine()->Int32LessThan(), input, min),
    3652         186 :                        min, input));
    3653          62 :   node->AppendInput(graph()->zone(), max);
    3654             :   NodeProperties::ChangeOp(node,
    3655          62 :                            common()->Select(MachineRepresentation::kWord32));
    3656          62 : }
    3657             : 
    3658         144 : void SimplifiedLowering::DoUnsigned32ToUint8Clamped(Node* node) {
    3659             :   Node* const input = node->InputAt(0);
    3660             :   Node* const max = jsgraph()->Uint32Constant(255u);
    3661             : 
    3662             :   node->ReplaceInput(
    3663         144 :       0, graph()->NewNode(machine()->Uint32LessThanOrEqual(), input, max));
    3664          72 :   node->AppendInput(graph()->zone(), input);
    3665          72 :   node->AppendInput(graph()->zone(), max);
    3666             :   NodeProperties::ChangeOp(node,
    3667          72 :                            common()->Select(MachineRepresentation::kWord32));
    3668          72 : }
    3669             : 
    3670        5914 : Node* SimplifiedLowering::ToNumberCode() {
    3671        2524 :   if (!to_number_code_.is_set()) {
    3672        1695 :     Callable callable = CodeFactory::ToNumber(isolate());
    3673        3390 :     to_number_code_.set(jsgraph()->HeapConstant(callable.code()));
    3674             :   }
    3675        2524 :   return to_number_code_.get();
    3676             : }
    3677             : 
    3678        4219 : Operator const* SimplifiedLowering::ToNumberOperator() {
    3679        2524 :   if (!to_number_operator_.is_set()) {
    3680        1695 :     Callable callable = CodeFactory::ToNumber(isolate());
    3681             :     CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState;
    3682             :     CallDescriptor* desc = Linkage::GetStubCallDescriptor(
    3683             :         isolate(), graph()->zone(), callable.descriptor(), 0, flags,
    3684        5085 :         Operator::kNoProperties);
    3685        1695 :     to_number_operator_.set(common()->Call(desc));
    3686             :   }
    3687        2524 :   return to_number_operator_.get();
    3688             : }
    3689             : 
    3690             : }  // namespace compiler
    3691             : }  // namespace internal
    3692             : }  // namespace v8

Generated by: LCOV version 1.10