LCOV - code coverage report
Current view: top level - src/compiler - representation-change.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 517 761 67.9 %
Date: 2019-04-19 Functions: 33 39 84.6 %

          Line data    Source code
       1             : // Copyright 2015 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/representation-change.h"
       6             : 
       7             : #include <sstream>
       8             : 
       9             : #include "src/base/bits.h"
      10             : #include "src/code-factory.h"
      11             : #include "src/compiler/machine-operator.h"
      12             : #include "src/compiler/node-matchers.h"
      13             : #include "src/compiler/type-cache.h"
      14             : #include "src/heap/factory-inl.h"
      15             : 
      16             : namespace v8 {
      17             : namespace internal {
      18             : namespace compiler {
      19             : 
      20           0 : const char* Truncation::description() const {
      21           0 :   switch (kind()) {
      22             :     case TruncationKind::kNone:
      23             :       return "no-value-use";
      24             :     case TruncationKind::kBool:
      25           0 :       return "truncate-to-bool";
      26             :     case TruncationKind::kWord32:
      27           0 :       return "truncate-to-word32";
      28             :     case TruncationKind::kFloat64:
      29           0 :       switch (identify_zeros()) {
      30             :         case kIdentifyZeros:
      31             :           return "truncate-to-float64 (identify zeros)";
      32             :         case kDistinguishZeros:
      33           0 :           return "truncate-to-float64 (distinguish zeros)";
      34             :       }
      35             :     case TruncationKind::kAny:
      36           0 :       switch (identify_zeros()) {
      37             :         case kIdentifyZeros:
      38             :           return "no-truncation (but identify zeros)";
      39             :         case kDistinguishZeros:
      40           0 :           return "no-truncation (but distinguish zeros)";
      41             :       }
      42             :   }
      43           0 :   UNREACHABLE();
      44             : }
      45             : 
      46             : // Partial order for truncations:
      47             : //
      48             : //          kAny <-------+
      49             : //            ^          |
      50             : //            |          |
      51             : //          kFloat64     |
      52             : //          ^            |
      53             : //          /            |
      54             : //   kWord32           kBool
      55             : //         ^            ^
      56             : //         \            /
      57             : //          \          /
      58             : //           \        /
      59             : //            \      /
      60             : //             \    /
      61             : //             kNone
      62             : //
      63             : // TODO(jarin) We might consider making kBool < kFloat64.
      64             : 
      65             : // static
      66   100077757 : Truncation::TruncationKind Truncation::Generalize(TruncationKind rep1,
      67             :                                                   TruncationKind rep2) {
      68   100077757 :   if (LessGeneral(rep1, rep2)) return rep2;
      69    11521781 :   if (LessGeneral(rep2, rep1)) return rep1;
      70             :   // Handle the generalization of float64-representable values.
      71          14 :   if (LessGeneral(rep1, TruncationKind::kFloat64) &&
      72           7 :       LessGeneral(rep2, TruncationKind::kFloat64)) {
      73             :     return TruncationKind::kFloat64;
      74             :   }
      75             :   // Handle the generalization of any-representable values.
      76          14 :   if (LessGeneral(rep1, TruncationKind::kAny) &&
      77           7 :       LessGeneral(rep2, TruncationKind::kAny)) {
      78             :     return TruncationKind::kAny;
      79             :   }
      80             :   // All other combinations are illegal.
      81           0 :   FATAL("Tried to combine incompatible truncations");
      82             :   return TruncationKind::kNone;
      83             : }
      84             : 
      85             : // static
      86   100078708 : IdentifyZeros Truncation::GeneralizeIdentifyZeros(IdentifyZeros i1,
      87             :                                                   IdentifyZeros i2) {
      88   100078708 :   if (i1 == i2) {
      89    70319720 :     return i1;
      90             :   } else {
      91             :     return kDistinguishZeros;
      92             :   }
      93             : }
      94             : 
      95             : // static
      96   114074376 : bool Truncation::LessGeneral(TruncationKind rep1, TruncationKind rep2) {
      97   114074376 :   switch (rep1) {
      98             :     case TruncationKind::kNone:
      99             :       return true;
     100             :     case TruncationKind::kBool:
     101      711345 :       return rep2 == TruncationKind::kBool || rep2 == TruncationKind::kAny;
     102             :     case TruncationKind::kWord32:
     103             :       return rep2 == TruncationKind::kWord32 ||
     104      825934 :              rep2 == TruncationKind::kFloat64 || rep2 == TruncationKind::kAny;
     105             :     case TruncationKind::kFloat64:
     106      576546 :       return rep2 == TruncationKind::kFloat64 || rep2 == TruncationKind::kAny;
     107             :     case TruncationKind::kAny:
     108    59677961 :       return rep2 == TruncationKind::kAny;
     109             :   }
     110           0 :   UNREACHABLE();
     111             : }
     112             : 
     113             : // static
     114           0 : bool Truncation::LessGeneralIdentifyZeros(IdentifyZeros i1, IdentifyZeros i2) {
     115           0 :   return i1 == i2 || i1 == kIdentifyZeros;
     116             : }
     117             : 
     118             : namespace {
     119             : 
     120             : bool IsWord(MachineRepresentation rep) {
     121             :   return rep == MachineRepresentation::kWord8 ||
     122    17571624 :          rep == MachineRepresentation::kWord16 ||
     123             :          rep == MachineRepresentation::kWord32;
     124             : }
     125             : 
     126             : }  // namespace
     127             : 
     128      464941 : RepresentationChanger::RepresentationChanger(JSGraph* jsgraph, Isolate* isolate)
     129      464941 :     : cache_(TypeCache::Get()),
     130             :       jsgraph_(jsgraph),
     131             :       isolate_(isolate),
     132             :       testing_type_errors_(false),
     133      464950 :       type_error_(false) {}
     134             : 
     135             : // Changes representation from {output_rep} to {use_rep}. The {truncation}
     136             : // parameter is only used for sanity checking - if the changer cannot figure
     137             : // out signedness for the word32->float64 conversion, then we check that the
     138             : // uses truncate to word32 (so they do not care about signedness).
     139    16063857 : Node* RepresentationChanger::GetRepresentationFor(
     140             :     Node* node, MachineRepresentation output_rep, Type output_type,
     141             :     Node* use_node, UseInfo use_info) {
     142    16064344 :   if (output_rep == MachineRepresentation::kNone && !output_type.IsNone()) {
     143             :     // The output representation should be set if the type is inhabited (i.e.,
     144             :     // if the value is possible).
     145           0 :     return TypeError(node, output_rep, output_type, use_info.representation());
     146             :   }
     147             : 
     148             :   // Handle the no-op shortcuts when no checking is necessary.
     149    16063857 :   if (use_info.type_check() == TypeCheckKind::kNone ||
     150             :       output_rep != MachineRepresentation::kWord32) {
     151    15968956 :     if (use_info.representation() == output_rep) {
     152             :       // Representations are the same. That's a no-op.
     153             :       return node;
     154             :     }
     155    17217023 :     if (IsWord(use_info.representation()) && IsWord(output_rep)) {
     156             :       // Both are words less than or equal to 32-bits.
     157             :       // Since loads of integers from memory implicitly sign or zero extend the
     158             :       // value to the full machine word size and stores implicitly truncate,
     159             :       // no representation change is necessary.
     160             :       return node;
     161             :     }
     162             :   }
     163             : 
     164    16032741 :   switch (use_info.representation()) {
     165             :     case MachineRepresentation::kTaggedSigned:
     166             :       DCHECK(use_info.type_check() == TypeCheckKind::kNone ||
     167             :              use_info.type_check() == TypeCheckKind::kSignedSmall);
     168             :       return GetTaggedSignedRepresentationFor(node, output_rep, output_type,
     169       69043 :                                               use_node, use_info);
     170             :     case MachineRepresentation::kTaggedPointer:
     171             :       DCHECK(use_info.type_check() == TypeCheckKind::kNone ||
     172             :              use_info.type_check() == TypeCheckKind::kHeapObject);
     173             :       return GetTaggedPointerRepresentationFor(node, output_rep, output_type,
     174       35185 :                                                use_node, use_info);
     175             :     case MachineRepresentation::kTagged:
     176             :       DCHECK_EQ(TypeCheckKind::kNone, use_info.type_check());
     177             :       return GetTaggedRepresentationFor(node, output_rep, output_type,
     178    13815399 :                                         use_info.truncation());
     179             :     case MachineRepresentation::kCompressedSigned:
     180             :       DCHECK(use_info.type_check() == TypeCheckKind::kNone ||
     181             :              use_info.type_check() == TypeCheckKind::kSignedSmall);
     182             :       return GetCompressedSignedRepresentationFor(node, output_rep, output_type,
     183          10 :                                                   use_node, use_info);
     184             :     case MachineRepresentation::kCompressedPointer:
     185             :       DCHECK(use_info.type_check() == TypeCheckKind::kNone ||
     186             :              use_info.type_check() == TypeCheckKind::kHeapObject);
     187             :       return GetCompressedPointerRepresentationFor(
     188           5 :           node, output_rep, output_type, use_node, use_info);
     189             :     case MachineRepresentation::kCompressed:
     190             :       DCHECK_EQ(TypeCheckKind::kNone, use_info.type_check());
     191             :       return GetCompressedRepresentationFor(node, output_rep, output_type,
     192           5 :                                             use_info.truncation());
     193             :     case MachineRepresentation::kFloat32:
     194             :       DCHECK_EQ(TypeCheckKind::kNone, use_info.type_check());
     195             :       return GetFloat32RepresentationFor(node, output_rep, output_type,
     196        1402 :                                          use_info.truncation());
     197             :     case MachineRepresentation::kFloat64:
     198             :       return GetFloat64RepresentationFor(node, output_rep, output_type,
     199      252548 :                                          use_node, use_info);
     200             :     case MachineRepresentation::kBit:
     201             :       DCHECK_EQ(TypeCheckKind::kNone, use_info.type_check());
     202      321724 :       return GetBitRepresentationFor(node, output_rep, output_type);
     203             :     case MachineRepresentation::kWord8:
     204             :     case MachineRepresentation::kWord16:
     205             :     case MachineRepresentation::kWord32:
     206             :       return GetWord32RepresentationFor(node, output_rep, output_type, use_node,
     207     1351899 :                                         use_info);
     208             :     case MachineRepresentation::kWord64:
     209             :       DCHECK(use_info.type_check() == TypeCheckKind::kNone ||
     210             :              use_info.type_check() == TypeCheckKind::kSigned64);
     211             :       return GetWord64RepresentationFor(node, output_rep, output_type, use_node,
     212      185521 :                                         use_info);
     213             :     case MachineRepresentation::kSimd128:
     214             :     case MachineRepresentation::kNone:
     215             :       return node;
     216             :   }
     217           0 :   UNREACHABLE();
     218             : }
     219             : 
     220       69043 : Node* RepresentationChanger::GetTaggedSignedRepresentationFor(
     221             :     Node* node, MachineRepresentation output_rep, Type output_type,
     222             :     Node* use_node, UseInfo use_info) {
     223             :   // Eagerly fold representation changes for constants.
     224       69043 :   switch (node->opcode()) {
     225             :     case IrOpcode::kNumberConstant:
     226           7 :       if (output_type.Is(Type::SignedSmall())) {
     227             :         return node;
     228             :       }
     229             :       break;
     230             :     default:
     231             :       break;
     232             :   }
     233             :   // Select the correct X -> Tagged operator.
     234             :   const Operator* op;
     235       69043 :   if (output_type.Is(Type::None())) {
     236             :     // This is an impossible value; it should not be used at runtime.
     237           0 :     return jsgraph()->graph()->NewNode(
     238             :         jsgraph()->common()->DeadValue(MachineRepresentation::kTaggedSigned),
     239           0 :         node);
     240       69043 :   } else if (IsWord(output_rep)) {
     241       44425 :     if (output_type.Is(Type::Signed31())) {
     242       25978 :       op = simplified()->ChangeInt31ToTaggedSigned();
     243       18447 :     } else if (output_type.Is(Type::Signed32())) {
     244             :       if (SmiValuesAre32Bits()) {
     245       18440 :         op = simplified()->ChangeInt32ToTagged();
     246             :       } else if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
     247             :         op = simplified()->CheckedInt32ToTaggedSigned(use_info.feedback());
     248             :       } else {
     249             :         return TypeError(node, output_rep, output_type,
     250             :                          MachineRepresentation::kTaggedSigned);
     251             :       }
     252           7 :     } else if (output_type.Is(Type::Unsigned32()) &&
     253             :                use_info.type_check() == TypeCheckKind::kSignedSmall) {
     254           7 :       op = simplified()->CheckedUint32ToTaggedSigned(use_info.feedback());
     255             :     } else {
     256             :       return TypeError(node, output_rep, output_type,
     257           0 :                        MachineRepresentation::kTaggedSigned);
     258             :     }
     259       24618 :   } else if (output_rep == MachineRepresentation::kWord64) {
     260         171 :     if (output_type.Is(Type::Signed31())) {
     261             :       // int64 -> int32 -> tagged signed
     262           5 :       node = InsertTruncateInt64ToInt32(node);
     263           5 :       op = simplified()->ChangeInt31ToTaggedSigned();
     264         166 :     } else if (output_type.Is(Type::Signed32()) && SmiValuesAre32Bits()) {
     265             :       // int64 -> int32 -> tagged signed
     266           5 :       node = InsertTruncateInt64ToInt32(node);
     267           5 :       op = simplified()->ChangeInt32ToTagged();
     268         161 :     } else if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
     269         322 :       if (output_type.Is(cache_->kPositiveSafeInteger)) {
     270           5 :         op = simplified()->CheckedUint64ToTaggedSigned(use_info.feedback());
     271         312 :       } else if (output_type.Is(cache_->kSafeInteger)) {
     272         156 :         op = simplified()->CheckedInt64ToTaggedSigned(use_info.feedback());
     273             :       } else {
     274             :         return TypeError(node, output_rep, output_type,
     275           0 :                          MachineRepresentation::kTaggedSigned);
     276             :       }
     277             :     } else {
     278             :       return TypeError(node, output_rep, output_type,
     279           0 :                        MachineRepresentation::kTaggedSigned);
     280             :     }
     281       24447 :   } else if (output_rep == MachineRepresentation::kFloat64) {
     282          23 :     if (output_type.Is(Type::Signed31())) {
     283             :       // float64 -> int32 -> tagged signed
     284           0 :       node = InsertChangeFloat64ToInt32(node);
     285           0 :       op = simplified()->ChangeInt31ToTaggedSigned();
     286          23 :     } else if (output_type.Is(Type::Signed32())) {
     287             :       // float64 -> int32 -> tagged signed
     288           0 :       node = InsertChangeFloat64ToInt32(node);
     289             :       if (SmiValuesAre32Bits()) {
     290           0 :         op = simplified()->ChangeInt32ToTagged();
     291             :       } else if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
     292             :         op = simplified()->CheckedInt32ToTaggedSigned(use_info.feedback());
     293             :       } else {
     294             :         return TypeError(node, output_rep, output_type,
     295             :                          MachineRepresentation::kTaggedSigned);
     296             :       }
     297          23 :     } else if (output_type.Is(Type::Unsigned32()) &&
     298             :                use_info.type_check() == TypeCheckKind::kSignedSmall) {
     299             :       // float64 -> uint32 -> tagged signed
     300           0 :       node = InsertChangeFloat64ToUint32(node);
     301           0 :       op = simplified()->CheckedUint32ToTaggedSigned(use_info.feedback());
     302          23 :     } else if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
     303          23 :       op = simplified()->CheckedFloat64ToInt32(
     304          23 :           output_type.Maybe(Type::MinusZero())
     305             :               ? CheckForMinusZeroMode::kCheckForMinusZero
     306             :               : CheckForMinusZeroMode::kDontCheckForMinusZero,
     307          23 :           use_info.feedback());
     308          23 :       node = InsertConversion(node, op, use_node);
     309             :       if (SmiValuesAre32Bits()) {
     310          23 :         op = simplified()->ChangeInt32ToTagged();
     311             :       } else {
     312             :         op = simplified()->CheckedInt32ToTaggedSigned(use_info.feedback());
     313             :       }
     314             :     } else {
     315             :       return TypeError(node, output_rep, output_type,
     316           0 :                        MachineRepresentation::kTaggedSigned);
     317             :     }
     318       24424 :   } else if (output_rep == MachineRepresentation::kFloat32) {
     319           0 :     if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
     320           0 :       op = machine()->ChangeFloat32ToFloat64();
     321           0 :       node = InsertConversion(node, op, use_node);
     322           0 :       op = simplified()->CheckedFloat64ToInt32(
     323           0 :           output_type.Maybe(Type::MinusZero())
     324             :               ? CheckForMinusZeroMode::kCheckForMinusZero
     325             :               : CheckForMinusZeroMode::kDontCheckForMinusZero,
     326           0 :           use_info.feedback());
     327           0 :       node = InsertConversion(node, op, use_node);
     328             :       if (SmiValuesAre32Bits()) {
     329           0 :         op = simplified()->ChangeInt32ToTagged();
     330             :       } else {
     331             :         op = simplified()->CheckedInt32ToTaggedSigned(use_info.feedback());
     332             :       }
     333             :     } else {
     334             :       return TypeError(node, output_rep, output_type,
     335           0 :                        MachineRepresentation::kTaggedSigned);
     336             :     }
     337       24424 :   } else if (CanBeTaggedPointer(output_rep)) {
     338       24414 :     if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
     339       24400 :       op = simplified()->CheckedTaggedToTaggedSigned(use_info.feedback());
     340          14 :     } else if (output_type.Is(Type::SignedSmall())) {
     341          14 :       op = simplified()->ChangeTaggedToTaggedSigned();
     342             :     } else {
     343             :       return TypeError(node, output_rep, output_type,
     344           0 :                        MachineRepresentation::kTaggedSigned);
     345             :     }
     346          10 :   } else if (output_rep == MachineRepresentation::kBit) {
     347           0 :     if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
     348             :       // TODO(turbofan): Consider adding a Bailout operator that just deopts.
     349             :       // Also use that for MachineRepresentation::kPointer case above.
     350           0 :       node = InsertChangeBitToTagged(node);
     351           0 :       op = simplified()->CheckedTaggedToTaggedSigned(use_info.feedback());
     352             :     } else {
     353             :       return TypeError(node, output_rep, output_type,
     354           0 :                        MachineRepresentation::kTaggedSigned);
     355             :     }
     356          10 :   } else if (output_rep == MachineRepresentation::kCompressedSigned) {
     357           5 :     op = machine()->ChangeCompressedSignedToTaggedSigned();
     358           5 :   } else if (CanBeCompressedPointer(output_rep)) {
     359           5 :     if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
     360           0 :       op = simplified()->CheckedCompressedToTaggedSigned(use_info.feedback());
     361           5 :     } else if (output_type.Is(Type::SignedSmall())) {
     362           5 :       op = simplified()->ChangeCompressedToTaggedSigned();
     363             :     } else {
     364             :       return TypeError(node, output_rep, output_type,
     365           0 :                        MachineRepresentation::kTaggedSigned);
     366             :     }
     367             :   } else {
     368             :     return TypeError(node, output_rep, output_type,
     369           0 :                      MachineRepresentation::kTaggedSigned);
     370             :   }
     371       69043 :   return InsertConversion(node, op, use_node);
     372             : }
     373             : 
     374       35185 : Node* RepresentationChanger::GetTaggedPointerRepresentationFor(
     375             :     Node* node, MachineRepresentation output_rep, Type output_type,
     376             :     Node* use_node, UseInfo use_info) {
     377             :   // Eagerly fold representation changes for constants.
     378       35185 :   switch (node->opcode()) {
     379             :     case IrOpcode::kHeapConstant:
     380             :     case IrOpcode::kDelayedStringConstant:
     381             :       return node;  // No change necessary.
     382             :     case IrOpcode::kInt32Constant:
     383             :     case IrOpcode::kFloat64Constant:
     384             :     case IrOpcode::kFloat32Constant:
     385           0 :       UNREACHABLE();
     386             :     default:
     387             :       break;
     388             :   }
     389             :   // Select the correct X -> TaggedPointer operator.
     390             :   Operator const* op;
     391       35185 :   if (output_type.Is(Type::None())) {
     392             :     // This is an impossible value; it should not be used at runtime.
     393           0 :     return jsgraph()->graph()->NewNode(
     394             :         jsgraph()->common()->DeadValue(MachineRepresentation::kTaggedPointer),
     395           0 :         node);
     396       35185 :   } else if (output_rep == MachineRepresentation::kBit) {
     397           0 :     if (output_type.Is(Type::Boolean())) {
     398           0 :       op = simplified()->ChangeBitToTagged();
     399             :     } else {
     400             :       return TypeError(node, output_rep, output_type,
     401           0 :                        MachineRepresentation::kTagged);
     402             :     }
     403       35185 :   } else if (IsWord(output_rep)) {
     404          14 :     if (output_type.Is(Type::Unsigned32())) {
     405             :       // uint32 -> float64 -> tagged
     406           0 :       node = InsertChangeUint32ToFloat64(node);
     407          14 :     } else if (output_type.Is(Type::Signed32())) {
     408             :       // int32 -> float64 -> tagged
     409          14 :       node = InsertChangeInt32ToFloat64(node);
     410             :     } else {
     411             :       return TypeError(node, output_rep, output_type,
     412           0 :                        MachineRepresentation::kTaggedPointer);
     413             :     }
     414          14 :     op = simplified()->ChangeFloat64ToTaggedPointer();
     415       35171 :   } else if (output_rep == MachineRepresentation::kWord64) {
     416          10 :     if (output_type.Is(cache_->kSafeInteger)) {
     417             :       // int64 -> float64 -> tagged pointer
     418           5 :       op = machine()->ChangeInt64ToFloat64();
     419             :       node = jsgraph()->graph()->NewNode(op, node);
     420           5 :       op = simplified()->ChangeFloat64ToTaggedPointer();
     421             :     } else {
     422             :       return TypeError(node, output_rep, output_type,
     423           0 :                        MachineRepresentation::kTaggedPointer);
     424             :     }
     425       35166 :   } else if (output_rep == MachineRepresentation::kFloat32) {
     426           0 :     if (output_type.Is(Type::Number())) {
     427             :       // float32 -> float64 -> tagged
     428           0 :       node = InsertChangeFloat32ToFloat64(node);
     429           0 :       op = simplified()->ChangeFloat64ToTaggedPointer();
     430             :     } else {
     431             :       return TypeError(node, output_rep, output_type,
     432           0 :                        MachineRepresentation::kTaggedPointer);
     433             :     }
     434       35166 :   } else if (output_rep == MachineRepresentation::kFloat64) {
     435          77 :     if (output_type.Is(Type::Number())) {
     436             :       // float64 -> tagged
     437          77 :       op = simplified()->ChangeFloat64ToTaggedPointer();
     438             :     } else {
     439             :       return TypeError(node, output_rep, output_type,
     440           0 :                        MachineRepresentation::kTaggedPointer);
     441             :     }
     442       35089 :   } else if (CanBeTaggedSigned(output_rep) &&
     443             :              use_info.type_check() == TypeCheckKind::kHeapObject) {
     444       35084 :     if (!output_type.Maybe(Type::SignedSmall())) {
     445             :       return node;
     446             :     }
     447             :     // TODO(turbofan): Consider adding a Bailout operator that just deopts
     448             :     // for TaggedSigned output representation.
     449       34745 :     op = simplified()->CheckedTaggedToTaggedPointer(use_info.feedback());
     450           5 :   } else if (output_rep == MachineRepresentation::kCompressedPointer) {
     451           5 :     op = machine()->ChangeCompressedPointerToTaggedPointer();
     452           0 :   } else if (CanBeCompressedSigned(output_rep) &&
     453             :              use_info.type_check() == TypeCheckKind::kHeapObject) {
     454           0 :     if (!output_type.Maybe(Type::SignedSmall())) {
     455             :       return node;
     456             :     }
     457             :     // TODO(turbofan): Consider adding a Bailout operator that just deopts
     458             :     // for CompressedSigned output representation.
     459           0 :     op = simplified()->CheckedCompressedToTaggedPointer(use_info.feedback());
     460             :   } else {
     461             :     return TypeError(node, output_rep, output_type,
     462           0 :                      MachineRepresentation::kTaggedPointer);
     463             :   }
     464       34846 :   return InsertConversion(node, op, use_node);
     465             : }
     466             : 
     467    13815392 : Node* RepresentationChanger::GetTaggedRepresentationFor(
     468             :     Node* node, MachineRepresentation output_rep, Type output_type,
     469             :     Truncation truncation) {
     470             :   // Eagerly fold representation changes for constants.
     471    13815392 :   switch (node->opcode()) {
     472             :     case IrOpcode::kNumberConstant:
     473             :     case IrOpcode::kHeapConstant:
     474             :     case IrOpcode::kDelayedStringConstant:
     475             :       return node;  // No change necessary.
     476             :     case IrOpcode::kInt32Constant:
     477             :     case IrOpcode::kFloat64Constant:
     478             :     case IrOpcode::kFloat32Constant:
     479           0 :       UNREACHABLE();
     480             :       break;
     481             :     default:
     482             :       break;
     483             :   }
     484     3202855 :   if (output_rep == MachineRepresentation::kTaggedSigned ||
     485             :       output_rep == MachineRepresentation::kTaggedPointer) {
     486             :     // this is a no-op.
     487             :     return node;
     488             :   }
     489             :   // Select the correct X -> Tagged operator.
     490             :   const Operator* op;
     491      118276 :   if (output_type.Is(Type::None())) {
     492             :     // This is an impossible value; it should not be used at runtime.
     493         252 :     return jsgraph()->graph()->NewNode(
     494         252 :         jsgraph()->common()->DeadValue(MachineRepresentation::kTagged), node);
     495      118024 :   } else if (output_rep == MachineRepresentation::kBit) {
     496       10548 :     if (output_type.Is(Type::Boolean())) {
     497       10548 :       op = simplified()->ChangeBitToTagged();
     498             :     } else {
     499             :       return TypeError(node, output_rep, output_type,
     500           0 :                        MachineRepresentation::kTagged);
     501             :     }
     502      107476 :   } else if (IsWord(output_rep)) {
     503       35242 :     if (output_type.Is(Type::Signed31())) {
     504       16292 :       op = simplified()->ChangeInt31ToTaggedSigned();
     505       38629 :     } else if (output_type.Is(Type::Signed32()) ||
     506           7 :                (output_type.Is(Type::Signed32OrMinusZero()) &&
     507             :                 truncation.IdentifiesZeroAndMinusZero())) {
     508       18228 :       op = simplified()->ChangeInt32ToTagged();
     509         729 :     } else if (output_type.Is(Type::Unsigned32()) ||
     510           0 :                (output_type.Is(Type::Unsigned32OrMinusZero()) &&
     511         729 :                 truncation.IdentifiesZeroAndMinusZero()) ||
     512             :                truncation.IsUsedAsWord32()) {
     513             :       // Either the output is uint32 or the uses only care about the
     514             :       // low 32 bits (so we can pick uint32 safely).
     515         722 :       op = simplified()->ChangeUint32ToTagged();
     516             :     } else {
     517             :       return TypeError(node, output_rep, output_type,
     518           0 :                        MachineRepresentation::kTagged);
     519             :     }
     520       72234 :   } else if (output_rep == MachineRepresentation::kWord64) {
     521         143 :     if (output_type.Is(Type::Signed31())) {
     522             :       // int64 -> int32 -> tagged signed
     523           5 :       node = InsertTruncateInt64ToInt32(node);
     524           5 :       op = simplified()->ChangeInt31ToTaggedSigned();
     525         138 :     } else if (output_type.Is(Type::Signed32())) {
     526             :       // int64 -> int32 -> tagged
     527           5 :       node = InsertTruncateInt64ToInt32(node);
     528           5 :       op = simplified()->ChangeInt32ToTagged();
     529         133 :     } else if (output_type.Is(Type::Unsigned32())) {
     530             :       // int64 -> uint32 -> tagged
     531          12 :       node = InsertTruncateInt64ToInt32(node);
     532          12 :       op = simplified()->ChangeUint32ToTagged();
     533         242 :     } else if (output_type.Is(cache_->kPositiveSafeInteger)) {
     534             :       // uint64 -> tagged
     535          58 :       op = simplified()->ChangeUint64ToTagged();
     536         126 :     } else if (output_type.Is(cache_->kSafeInteger)) {
     537             :       // int64 -> tagged
     538          58 :       op = simplified()->ChangeInt64ToTagged();
     539             :     } else {
     540             :       return TypeError(node, output_rep, output_type,
     541           5 :                        MachineRepresentation::kTagged);
     542             :     }
     543       72091 :   } else if (output_rep ==
     544             :              MachineRepresentation::kFloat32) {  // float32 -> float64 -> tagged
     545         382 :     node = InsertChangeFloat32ToFloat64(node);
     546         382 :     op = simplified()->ChangeFloat64ToTagged(
     547         382 :         output_type.Maybe(Type::MinusZero())
     548             :             ? CheckForMinusZeroMode::kCheckForMinusZero
     549         382 :             : CheckForMinusZeroMode::kDontCheckForMinusZero);
     550       71709 :   } else if (output_rep == MachineRepresentation::kFloat64) {
     551       71704 :     if (output_type.Is(Type::Signed31())) {  // float64 -> int32 -> tagged
     552          28 :       node = InsertChangeFloat64ToInt32(node);
     553          28 :       op = simplified()->ChangeInt31ToTaggedSigned();
     554       71676 :     } else if (output_type.Is(
     555             :                    Type::Signed32())) {  // float64 -> int32 -> tagged
     556         779 :       node = InsertChangeFloat64ToInt32(node);
     557         779 :       op = simplified()->ChangeInt32ToTagged();
     558       70897 :     } else if (output_type.Is(
     559             :                    Type::Unsigned32())) {  // float64 -> uint32 -> tagged
     560          20 :       node = InsertChangeFloat64ToUint32(node);
     561          20 :       op = simplified()->ChangeUint32ToTagged();
     562      141768 :     } else if (output_type.Is(Type::Number()) ||
     563          14 :                (output_type.Is(Type::NumberOrOddball()) &&
     564             :                 truncation.IsUsedAsFloat64())) {
     565       70877 :       op = simplified()->ChangeFloat64ToTagged(
     566       70877 :           output_type.Maybe(Type::MinusZero())
     567             :               ? CheckForMinusZeroMode::kCheckForMinusZero
     568       70877 :               : CheckForMinusZeroMode::kDontCheckForMinusZero);
     569             :     } else {
     570             :       return TypeError(node, output_rep, output_type,
     571           0 :                        MachineRepresentation::kTagged);
     572             :     }
     573           5 :   } else if (IsAnyCompressed(output_rep)) {
     574           5 :     op = machine()->ChangeCompressedToTagged();
     575             :   } else {
     576             :     return TypeError(node, output_rep, output_type,
     577           0 :                      MachineRepresentation::kTagged);
     578             :   }
     579      118019 :   return jsgraph()->graph()->NewNode(op, node);
     580             : }
     581             : 
     582          10 : Node* RepresentationChanger::GetCompressedSignedRepresentationFor(
     583             :     Node* node, MachineRepresentation output_rep, Type output_type,
     584             :     Node* use_node, UseInfo use_info) {
     585             :   // Select the correct X -> Compressed operator.
     586             :   const Operator* op;
     587          10 :   if (output_type.Is(Type::None())) {
     588             :     // This is an impossible value; it should not be used at runtime.
     589           0 :     return jsgraph()->graph()->NewNode(
     590             :         jsgraph()->common()->DeadValue(
     591             :             MachineRepresentation::kCompressedSigned),
     592           0 :         node);
     593          10 :   } else if (output_rep == MachineRepresentation::kTaggedSigned) {
     594           5 :     op = machine()->ChangeTaggedSignedToCompressedSigned();
     595           5 :   } else if (output_rep == MachineRepresentation::kTagged) {
     596           5 :     if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
     597           0 :       op = simplified()->CheckedTaggedToCompressedSigned(use_info.feedback());
     598           5 :     } else if (output_type.Is(Type::SignedSmall())) {
     599           5 :       op = simplified()->ChangeTaggedToCompressedSigned();
     600             :     } else {
     601             :       return TypeError(node, output_rep, output_type,
     602           0 :                        MachineRepresentation::kTaggedSigned);
     603             :     }
     604           0 :   } else if (output_rep == MachineRepresentation::kBit) {
     605             :     // TODO(v8:8977): specialize here and below
     606             :     node = GetTaggedSignedRepresentationFor(node, output_rep, output_type,
     607           0 :                                             use_node, use_info);
     608           0 :     op = machine()->ChangeTaggedSignedToCompressedSigned();
     609           0 :   } else if (IsWord(output_rep)) {
     610             :     node = GetTaggedSignedRepresentationFor(node, output_rep, output_type,
     611           0 :                                             use_node, use_info);
     612           0 :     op = machine()->ChangeTaggedSignedToCompressedSigned();
     613           0 :   } else if (output_rep == MachineRepresentation::kWord64) {
     614             :     node = GetTaggedSignedRepresentationFor(node, output_rep, output_type,
     615           0 :                                             use_node, use_info);
     616           0 :     op = machine()->ChangeTaggedSignedToCompressedSigned();
     617           0 :   } else if (output_rep == MachineRepresentation::kFloat32) {
     618             :     node = GetTaggedSignedRepresentationFor(node, output_rep, output_type,
     619           0 :                                             use_node, use_info);
     620           0 :     op = machine()->ChangeTaggedSignedToCompressedSigned();
     621           0 :   } else if (output_rep == MachineRepresentation::kFloat64) {
     622             :     node = GetTaggedSignedRepresentationFor(node, output_rep, output_type,
     623           0 :                                             use_node, use_info);
     624           0 :     op = machine()->ChangeTaggedSignedToCompressedSigned();
     625             :   } else {
     626             :     return TypeError(node, output_rep, output_type,
     627           0 :                      MachineRepresentation::kCompressedSigned);
     628             :   }
     629          10 :   return InsertConversion(node, op, use_node);
     630             : }
     631             : 
     632           5 : Node* RepresentationChanger::GetCompressedPointerRepresentationFor(
     633             :     Node* node, MachineRepresentation output_rep, Type output_type,
     634             :     Node* use_node, UseInfo use_info) {
     635             :   // Select the correct X -> CompressedPointer operator.
     636             :   Operator const* op;
     637           5 :   if (output_type.Is(Type::None())) {
     638             :     // This is an impossible value; it should not be used at runtime.
     639           0 :     return jsgraph()->graph()->NewNode(
     640             :         jsgraph()->common()->DeadValue(
     641             :             MachineRepresentation::kCompressedPointer),
     642           0 :         node);
     643           5 :   } else if (output_rep == MachineRepresentation::kTaggedPointer) {
     644           5 :     op = machine()->ChangeTaggedPointerToCompressedPointer();
     645           0 :   } else if (output_rep == MachineRepresentation::kTagged &&
     646             :              use_info.type_check() == TypeCheckKind::kHeapObject) {
     647           0 :     if (!output_type.Maybe(Type::SignedSmall())) {
     648             :       return node;
     649             :     }
     650             :     // TODO(turbofan): Consider adding a Bailout operator that just deopts
     651             :     // for TaggedSigned output representation.
     652           0 :     op = simplified()->CheckedTaggedToCompressedPointer(use_info.feedback());
     653             :     return TypeError(node, output_rep, output_type,
     654           0 :                      MachineRepresentation::kCompressedPointer);
     655           0 :   } else if (output_rep == MachineRepresentation::kBit) {
     656             :     // TODO(v8:8977): specialize here and below
     657             :     node = GetTaggedPointerRepresentationFor(node, output_rep, output_type,
     658           0 :                                              use_node, use_info);
     659           0 :     op = machine()->ChangeTaggedPointerToCompressedPointer();
     660           0 :   } else if (IsWord(output_rep)) {
     661             :     node = GetTaggedPointerRepresentationFor(node, output_rep, output_type,
     662           0 :                                              use_node, use_info);
     663           0 :     op = machine()->ChangeTaggedPointerToCompressedPointer();
     664           0 :   } else if (output_rep == MachineRepresentation::kWord64) {
     665             :     node = GetTaggedPointerRepresentationFor(node, output_rep, output_type,
     666           0 :                                              use_node, use_info);
     667           0 :     op = machine()->ChangeTaggedPointerToCompressedPointer();
     668           0 :   } else if (output_rep == MachineRepresentation::kFloat32) {
     669             :     node = GetTaggedPointerRepresentationFor(node, output_rep, output_type,
     670           0 :                                              use_node, use_info);
     671           0 :     op = machine()->ChangeTaggedPointerToCompressedPointer();
     672           0 :   } else if (output_rep == MachineRepresentation::kFloat64) {
     673             :     node = GetTaggedPointerRepresentationFor(node, output_rep, output_type,
     674           0 :                                              use_node, use_info);
     675           0 :     op = machine()->ChangeTaggedPointerToCompressedPointer();
     676             :   } else {
     677             :     return TypeError(node, output_rep, output_type,
     678           0 :                      MachineRepresentation::kCompressedPointer);
     679             :   }
     680           5 :   return InsertConversion(node, op, use_node);
     681             : }
     682             : 
     683           5 : Node* RepresentationChanger::GetCompressedRepresentationFor(
     684             :     Node* node, MachineRepresentation output_rep, Type output_type,
     685             :     Truncation truncation) {
     686           5 :   if (output_rep == MachineRepresentation::kCompressedSigned ||
     687             :       output_rep == MachineRepresentation::kCompressedPointer) {
     688             :     // this is a no-op.
     689             :     return node;
     690             :   }
     691             :   // Select the correct X -> Compressed operator.
     692             :   const Operator* op;
     693           5 :   if (output_type.Is(Type::None())) {
     694             :     // This is an impossible value; it should not be used at runtime.
     695           0 :     return jsgraph()->graph()->NewNode(
     696             :         jsgraph()->common()->DeadValue(MachineRepresentation::kCompressed),
     697           0 :         node);
     698           5 :   } else if (output_rep == MachineRepresentation::kBit) {
     699             :     // TODO(v8:8977): specialize here and below
     700             :     node =
     701           0 :         GetTaggedRepresentationFor(node, output_rep, output_type, truncation);
     702           0 :     op = machine()->ChangeTaggedToCompressed();
     703           5 :   } else if (IsWord(output_rep)) {
     704             :     node =
     705           0 :         GetTaggedRepresentationFor(node, output_rep, output_type, truncation);
     706           0 :     op = machine()->ChangeTaggedToCompressed();
     707           5 :   } else if (output_rep == MachineRepresentation::kWord64) {
     708             :     node =
     709           0 :         GetTaggedRepresentationFor(node, output_rep, output_type, truncation);
     710           0 :     op = machine()->ChangeTaggedToCompressed();
     711           5 :   } else if (output_rep == MachineRepresentation::kFloat32) {
     712             :     node =
     713           0 :         GetTaggedRepresentationFor(node, output_rep, output_type, truncation);
     714           0 :     op = machine()->ChangeTaggedToCompressed();
     715           5 :   } else if (output_rep == MachineRepresentation::kFloat64) {
     716             :     node =
     717           0 :         GetTaggedRepresentationFor(node, output_rep, output_type, truncation);
     718           0 :     op = machine()->ChangeTaggedToCompressed();
     719           5 :   } else if (IsAnyTagged(output_rep)) {
     720           5 :     op = machine()->ChangeTaggedToCompressed();
     721             :   } else {
     722             :     return TypeError(node, output_rep, output_type,
     723           0 :                      MachineRepresentation::kCompressed);
     724             :   }
     725           5 :   return jsgraph()->graph()->NewNode(op, node);
     726             : }
     727             : 
     728        1402 : Node* RepresentationChanger::GetFloat32RepresentationFor(
     729             :     Node* node, MachineRepresentation output_rep, Type output_type,
     730             :     Truncation truncation) {
     731             :   // Eagerly fold representation changes for constants.
     732        1402 :   switch (node->opcode()) {
     733             :     case IrOpcode::kNumberConstant:
     734        2308 :       return jsgraph()->Float32Constant(
     735        1154 :           DoubleToFloat32(OpParameter<double>(node->op())));
     736             :     case IrOpcode::kInt32Constant:
     737             :     case IrOpcode::kFloat64Constant:
     738             :     case IrOpcode::kFloat32Constant:
     739           0 :       UNREACHABLE();
     740             :       break;
     741             :     default:
     742             :       break;
     743             :   }
     744             :   // Select the correct X -> Float32 operator.
     745             :   const Operator* op = nullptr;
     746         248 :   if (output_type.Is(Type::None())) {
     747             :     // This is an impossible value; it should not be used at runtime.
     748           0 :     return jsgraph()->graph()->NewNode(
     749           0 :         jsgraph()->common()->DeadValue(MachineRepresentation::kFloat32), node);
     750         248 :   } else if (IsWord(output_rep)) {
     751          31 :     if (output_type.Is(Type::Signed32())) {
     752             :       // int32 -> float64 -> float32
     753          26 :       op = machine()->ChangeInt32ToFloat64();
     754             :       node = jsgraph()->graph()->NewNode(op, node);
     755          26 :       op = machine()->TruncateFloat64ToFloat32();
     756           5 :     } else if (output_type.Is(Type::Unsigned32()) ||
     757             :                truncation.IsUsedAsWord32()) {
     758             :       // Either the output is uint32 or the uses only care about the
     759             :       // low 32 bits (so we can pick uint32 safely).
     760             : 
     761             :       // uint32 -> float64 -> float32
     762           5 :       op = machine()->ChangeUint32ToFloat64();
     763             :       node = jsgraph()->graph()->NewNode(op, node);
     764           5 :       op = machine()->TruncateFloat64ToFloat32();
     765             :     }
     766         217 :   } else if (IsAnyTagged(output_rep)) {
     767           5 :     if (output_type.Is(Type::NumberOrOddball())) {
     768             :       // tagged -> float64 -> float32
     769           5 :       if (output_type.Is(Type::Number())) {
     770           5 :         op = simplified()->ChangeTaggedToFloat64();
     771             :       } else {
     772           0 :         op = simplified()->TruncateTaggedToFloat64();
     773             :       }
     774             :       node = jsgraph()->graph()->NewNode(op, node);
     775           5 :       op = machine()->TruncateFloat64ToFloat32();
     776             :     }
     777         212 :   } else if (output_rep == MachineRepresentation::kCompressed) {
     778             :     // TODO(v8:8977): Specialise here
     779           0 :     op = machine()->ChangeCompressedToTagged();
     780             :     node = jsgraph()->graph()->NewNode(op, node);
     781             :     return GetFloat32RepresentationFor(node, MachineRepresentation::kTagged,
     782           0 :                                        output_type, truncation);
     783         212 :   } else if (output_rep == MachineRepresentation::kCompressedSigned) {
     784             :     // TODO(v8:8977): Specialise here
     785           0 :     op = machine()->ChangeCompressedSignedToTaggedSigned();
     786             :     node = jsgraph()->graph()->NewNode(op, node);
     787             :     return GetFloat32RepresentationFor(
     788           0 :         node, MachineRepresentation::kTaggedSigned, output_type, truncation);
     789         212 :   } else if (output_rep == MachineRepresentation::kCompressedPointer) {
     790             :     // TODO(v8:8977): Specialise here
     791           0 :     op = machine()->ChangeCompressedPointerToTaggedPointer();
     792             :     node = jsgraph()->graph()->NewNode(op, node);
     793             :     return GetFloat32RepresentationFor(
     794           0 :         node, MachineRepresentation::kTaggedPointer, output_type, truncation);
     795         212 :   } else if (output_rep == MachineRepresentation::kFloat64) {
     796         197 :     op = machine()->TruncateFloat64ToFloat32();
     797          15 :   } else if (output_rep == MachineRepresentation::kWord64) {
     798          10 :     if (output_type.Is(cache_->kSafeInteger)) {
     799             :       // int64 -> float64 -> float32
     800           5 :       op = machine()->ChangeInt64ToFloat64();
     801             :       node = jsgraph()->graph()->NewNode(op, node);
     802           5 :       op = machine()->TruncateFloat64ToFloat32();
     803             :     }
     804             :   }
     805         248 :   if (op == nullptr) {
     806             :     return TypeError(node, output_rep, output_type,
     807          10 :                      MachineRepresentation::kFloat32);
     808             :   }
     809         238 :   return jsgraph()->graph()->NewNode(op, node);
     810             : }
     811             : 
     812      252548 : Node* RepresentationChanger::GetFloat64RepresentationFor(
     813             :     Node* node, MachineRepresentation output_rep, Type output_type,
     814             :     Node* use_node, UseInfo use_info) {
     815             :   NumberMatcher m(node);
     816      252548 :   if (m.HasValue()) {
     817             :     switch (use_info.type_check()) {
     818             :       case TypeCheckKind::kNone:
     819             :       case TypeCheckKind::kNumber:
     820             :       case TypeCheckKind::kNumberOrOddball:
     821      145744 :         return jsgraph()->Float64Constant(m.Value());
     822             :       case TypeCheckKind::kHeapObject:
     823             :       case TypeCheckKind::kSigned32:
     824             :       case TypeCheckKind::kSigned64:
     825             :       case TypeCheckKind::kSignedSmall:
     826             :         break;
     827             :     }
     828             :   }
     829             :   // Select the correct X -> Float64 operator.
     830             :   const Operator* op = nullptr;
     831      106803 :   if (output_type.Is(Type::None())) {
     832             :     // This is an impossible value; it should not be used at runtime.
     833           0 :     return jsgraph()->graph()->NewNode(
     834           0 :         jsgraph()->common()->DeadValue(MachineRepresentation::kFloat64), node);
     835      106803 :   } else if (IsWord(output_rep)) {
     836       71541 :     if (output_type.Is(Type::Signed32()) ||
     837          12 :         (output_type.Is(Type::Signed32OrMinusZero()) &&
     838             :          use_info.truncation().IdentifiesZeroAndMinusZero())) {
     839       35640 :       op = machine()->ChangeInt32ToFloat64();
     840          83 :     } else if (output_type.Is(Type::Unsigned32()) ||
     841             :                use_info.truncation().IsUsedAsWord32()) {
     842             :       // Either the output is uint32 or the uses only care about the
     843             :       // low 32 bits (so we can pick uint32 safely).
     844          83 :       op = machine()->ChangeUint32ToFloat64();
     845             :     }
     846       71081 :   } else if (output_rep == MachineRepresentation::kBit) {
     847           0 :     CHECK(output_type.Is(Type::Boolean()));
     848           0 :     if (use_info.truncation().IsUsedAsFloat64()) {
     849           0 :       op = machine()->ChangeUint32ToFloat64();
     850             :     } else {
     851           0 :       CHECK_NE(use_info.type_check(), TypeCheckKind::kNone);
     852             :       Node* unreachable =
     853           0 :           InsertUnconditionalDeopt(use_node, DeoptimizeReason::kNotAHeapNumber);
     854           0 :       return jsgraph()->graph()->NewNode(
     855             :           jsgraph()->common()->DeadValue(MachineRepresentation::kFloat64),
     856           0 :           unreachable);
     857             :     }
     858      142162 :   } else if (output_rep == MachineRepresentation::kTagged ||
     859       75440 :              output_rep == MachineRepresentation::kTaggedSigned ||
     860             :              output_rep == MachineRepresentation::kTaggedPointer) {
     861       68798 :     if (output_type.Is(Type::Undefined())) {
     862         244 :       return jsgraph()->Float64Constant(
     863         244 :           std::numeric_limits<double>::quiet_NaN());
     864             : 
     865       68554 :     } else if (output_rep == MachineRepresentation::kTaggedSigned) {
     866        1315 :       node = InsertChangeTaggedSignedToInt32(node);
     867        1315 :       op = machine()->ChangeInt32ToFloat64();
     868       67239 :     } else if (output_type.Is(Type::Number())) {
     869       11480 :       op = simplified()->ChangeTaggedToFloat64();
     870       55759 :     } else if (output_type.Is(Type::NumberOrOddball())) {
     871             :       // TODO(jarin) Here we should check that truncation is Number.
     872        1455 :       op = simplified()->TruncateTaggedToFloat64();
     873      108608 :     } else if (use_info.type_check() == TypeCheckKind::kNumber ||
     874       46469 :                (use_info.type_check() == TypeCheckKind::kNumberOrOddball &&
     875       46469 :                 !output_type.Maybe(Type::BooleanOrNullOrNumber()))) {
     876             :       op = simplified()->CheckedTaggedToFloat64(CheckTaggedInputMode::kNumber,
     877        8302 :                                                 use_info.feedback());
     878       46002 :     } else if (use_info.type_check() == TypeCheckKind::kNumberOrOddball) {
     879             :       op = simplified()->CheckedTaggedToFloat64(
     880       46002 :           CheckTaggedInputMode::kNumberOrOddball, use_info.feedback());
     881             :     }
     882        2283 :   } else if (output_rep == MachineRepresentation::kCompressed) {
     883             :     // TODO(v8:8977): Specialise here
     884           0 :     op = machine()->ChangeCompressedToTagged();
     885             :     node = jsgraph()->graph()->NewNode(op, node);
     886             :     return GetFloat64RepresentationFor(node, MachineRepresentation::kTagged,
     887           0 :                                        output_type, use_node, use_info);
     888        2283 :   } else if (output_rep == MachineRepresentation::kCompressedSigned) {
     889             :     // TODO(v8:8977): Specialise here
     890           0 :     op = machine()->ChangeCompressedSignedToTaggedSigned();
     891             :     node = jsgraph()->graph()->NewNode(op, node);
     892             :     return GetFloat64RepresentationFor(node,
     893             :                                        MachineRepresentation::kTaggedSigned,
     894           0 :                                        output_type, use_node, use_info);
     895        2283 :   } else if (output_rep == MachineRepresentation::kCompressedPointer) {
     896             :     // TODO(v8:8977): Specialise here
     897           0 :     op = machine()->ChangeCompressedPointerToTaggedPointer();
     898             :     node = jsgraph()->graph()->NewNode(op, node);
     899             :     return GetFloat64RepresentationFor(node,
     900             :                                        MachineRepresentation::kTaggedPointer,
     901           0 :                                        output_type, use_node, use_info);
     902        2283 :   } else if (output_rep == MachineRepresentation::kFloat32) {
     903        2198 :     op = machine()->ChangeFloat32ToFloat64();
     904          85 :   } else if (output_rep == MachineRepresentation::kWord64) {
     905         170 :     if (output_type.Is(cache_->kSafeInteger)) {
     906          85 :       op = machine()->ChangeInt64ToFloat64();
     907             :     }
     908             :   }
     909      106560 :   if (op == nullptr) {
     910             :     return TypeError(node, output_rep, output_type,
     911           0 :                      MachineRepresentation::kFloat64);
     912             :   }
     913      106560 :   return InsertConversion(node, op, use_node);
     914             : }
     915             : 
     916           0 : Node* RepresentationChanger::MakeTruncatedInt32Constant(double value) {
     917     1036657 :   return jsgraph()->Int32Constant(DoubleToInt32(value));
     918             : }
     919             : 
     920           7 : Node* RepresentationChanger::InsertUnconditionalDeopt(Node* node,
     921             :                                                       DeoptimizeReason reason) {
     922           7 :   Node* effect = NodeProperties::GetEffectInput(node);
     923           7 :   Node* control = NodeProperties::GetControlInput(node);
     924             :   effect =
     925          14 :       jsgraph()->graph()->NewNode(simplified()->CheckIf(reason),
     926             :                                   jsgraph()->Int32Constant(0), effect, control);
     927           7 :   Node* unreachable = effect = jsgraph()->graph()->NewNode(
     928             :       jsgraph()->common()->Unreachable(), effect, control);
     929           7 :   NodeProperties::ReplaceEffectInput(node, effect);
     930           7 :   return unreachable;
     931             : }
     932             : 
     933     1351933 : Node* RepresentationChanger::GetWord32RepresentationFor(
     934             :     Node* node, MachineRepresentation output_rep, Type output_type,
     935             :     Node* use_node, UseInfo use_info) {
     936             :   // Eagerly fold representation changes for constants.
     937     1351933 :   switch (node->opcode()) {
     938             :     case IrOpcode::kInt32Constant:
     939             :     case IrOpcode::kInt64Constant:
     940             :     case IrOpcode::kFloat32Constant:
     941             :     case IrOpcode::kFloat64Constant:
     942           0 :       UNREACHABLE();
     943             :       break;
     944             :     case IrOpcode::kNumberConstant: {
     945     1036789 :       double const fv = OpParameter<double>(node->op());
     946     2073578 :       if (use_info.type_check() == TypeCheckKind::kNone ||
     947        1001 :           ((use_info.type_check() == TypeCheckKind::kSignedSmall ||
     948         950 :             use_info.type_check() == TypeCheckKind::kSigned32 ||
     949         270 :             use_info.type_check() == TypeCheckKind::kNumber ||
     950       85133 :             use_info.type_check() == TypeCheckKind::kNumberOrOddball) &&
     951             :            IsInt32Double(fv))) {
     952     1036631 :         return MakeTruncatedInt32Constant(fv);
     953             :       }
     954             :       break;
     955             :     }
     956             :     default:
     957             :       break;
     958             :   }
     959             : 
     960             :   // Select the correct X -> Word32 operator.
     961             :   const Operator* op = nullptr;
     962      315259 :   if (output_type.Is(Type::None())) {
     963             :     // This is an impossible value; it should not be used at runtime.
     964          21 :     return jsgraph()->graph()->NewNode(
     965          21 :         jsgraph()->common()->DeadValue(MachineRepresentation::kWord32), node);
     966      315238 :   } else if (output_rep == MachineRepresentation::kBit) {
     967          59 :     CHECK(output_type.Is(Type::Boolean()));
     968          59 :     if (use_info.truncation().IsUsedAsWord32()) {
     969             :       return node;
     970             :     } else {
     971           0 :       CHECK(Truncation::Any(kIdentifyZeros)
     972             :                 .IsLessGeneralThan(use_info.truncation()));
     973           0 :       CHECK_NE(use_info.type_check(), TypeCheckKind::kNone);
     974             :       Node* unreachable =
     975           0 :           InsertUnconditionalDeopt(use_node, DeoptimizeReason::kNotASmi);
     976           0 :       return jsgraph()->graph()->NewNode(
     977             :           jsgraph()->common()->DeadValue(MachineRepresentation::kWord32),
     978           0 :           unreachable);
     979             :     }
     980      315179 :   } else if (output_rep == MachineRepresentation::kFloat64) {
     981        8876 :     if (output_type.Is(Type::Signed32())) {
     982         804 :       op = machine()->ChangeFloat64ToInt32();
     983        8072 :     } else if (use_info.type_check() == TypeCheckKind::kSignedSmall ||
     984             :                use_info.type_check() == TypeCheckKind::kSigned32) {
     985        2427 :       op = simplified()->CheckedFloat64ToInt32(
     986        2427 :           output_type.Maybe(Type::MinusZero())
     987             :               ? use_info.minus_zero_check()
     988             :               : CheckForMinusZeroMode::kDontCheckForMinusZero,
     989        2427 :           use_info.feedback());
     990        5645 :     } else if (output_type.Is(Type::Unsigned32())) {
     991           6 :       op = machine()->ChangeFloat64ToUint32();
     992        5639 :     } else if (use_info.truncation().IsUsedAsWord32()) {
     993        5639 :       op = machine()->TruncateFloat64ToWord32();
     994             :     } else {
     995             :       return TypeError(node, output_rep, output_type,
     996           0 :                        MachineRepresentation::kWord32);
     997             :     }
     998      306303 :   } else if (output_rep == MachineRepresentation::kFloat32) {
     999          15 :     node = InsertChangeFloat32ToFloat64(node);  // float32 -> float64 -> int32
    1000          15 :     if (output_type.Is(Type::Signed32())) {
    1001           5 :       op = machine()->ChangeFloat64ToInt32();
    1002          10 :     } else if (use_info.type_check() == TypeCheckKind::kSignedSmall ||
    1003             :                use_info.type_check() == TypeCheckKind::kSigned32) {
    1004           0 :       op = simplified()->CheckedFloat64ToInt32(
    1005           0 :           output_type.Maybe(Type::MinusZero())
    1006             :               ? use_info.minus_zero_check()
    1007             :               : CheckForMinusZeroMode::kDontCheckForMinusZero,
    1008           0 :           use_info.feedback());
    1009          10 :     } else if (output_type.Is(Type::Unsigned32())) {
    1010           5 :       op = machine()->ChangeFloat64ToUint32();
    1011           5 :     } else if (use_info.truncation().IsUsedAsWord32()) {
    1012           5 :       op = machine()->TruncateFloat64ToWord32();
    1013             :     } else {
    1014             :       return TypeError(node, output_rep, output_type,
    1015           0 :                        MachineRepresentation::kWord32);
    1016             :     }
    1017      306288 :   } else if (IsAnyTagged(output_rep)) {
    1018      306161 :     if (output_rep == MachineRepresentation::kTaggedSigned &&
    1019             :         output_type.Is(Type::SignedSmall())) {
    1020       78017 :       op = simplified()->ChangeTaggedSignedToInt32();
    1021      150117 :     } else if (output_type.Is(Type::Signed32())) {
    1022        2357 :       op = simplified()->ChangeTaggedToInt32();
    1023      147760 :     } else if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
    1024      142775 :       op = simplified()->CheckedTaggedSignedToInt32(use_info.feedback());
    1025        4985 :     } else if (use_info.type_check() == TypeCheckKind::kSigned32) {
    1026        2518 :       op = simplified()->CheckedTaggedToInt32(
    1027        2518 :           output_type.Maybe(Type::MinusZero())
    1028             :               ? use_info.minus_zero_check()
    1029             :               : CheckForMinusZeroMode::kDontCheckForMinusZero,
    1030        2518 :           use_info.feedback());
    1031        2467 :     } else if (output_type.Is(Type::Unsigned32())) {
    1032         518 :       op = simplified()->ChangeTaggedToUint32();
    1033        1949 :     } else if (use_info.truncation().IsUsedAsWord32()) {
    1034        1949 :       if (output_type.Is(Type::NumberOrOddball())) {
    1035         612 :         op = simplified()->TruncateTaggedToWord32();
    1036        1337 :       } else if (use_info.type_check() == TypeCheckKind::kNumber) {
    1037             :         op = simplified()->CheckedTruncateTaggedToWord32(
    1038         870 :             CheckTaggedInputMode::kNumber, use_info.feedback());
    1039         467 :       } else if (use_info.type_check() == TypeCheckKind::kNumberOrOddball) {
    1040             :         op = simplified()->CheckedTruncateTaggedToWord32(
    1041         467 :             CheckTaggedInputMode::kNumberOrOddball, use_info.feedback());
    1042             :       } else {
    1043             :         return TypeError(node, output_rep, output_type,
    1044           0 :                          MachineRepresentation::kWord32);
    1045             :       }
    1046             :     } else {
    1047             :       return TypeError(node, output_rep, output_type,
    1048           0 :                        MachineRepresentation::kWord32);
    1049             :     }
    1050       78144 :   } else if (output_rep == MachineRepresentation::kCompressed) {
    1051             :     // TODO(v8:8977): Specialise here
    1052           0 :     op = machine()->ChangeCompressedToTagged();
    1053             :     node = jsgraph()->graph()->NewNode(op, node);
    1054             :     return GetWord32RepresentationFor(node, MachineRepresentation::kTagged,
    1055           0 :                                       output_type, use_node, use_info);
    1056       78144 :   } else if (output_rep == MachineRepresentation::kCompressedSigned) {
    1057             :     // TODO(v8:8977): Specialise here
    1058           0 :     op = machine()->ChangeCompressedSignedToTaggedSigned();
    1059             :     node = jsgraph()->graph()->NewNode(op, node);
    1060             :     return GetWord32RepresentationFor(node,
    1061             :                                       MachineRepresentation::kTaggedSigned,
    1062           0 :                                       output_type, use_node, use_info);
    1063       78144 :   } else if (output_rep == MachineRepresentation::kCompressedPointer) {
    1064             :     // TODO(v8:8977): Specialise here
    1065           0 :     op = machine()->ChangeCompressedPointerToTaggedPointer();
    1066             :     node = jsgraph()->graph()->NewNode(op, node);
    1067             :     return GetWord32RepresentationFor(node,
    1068             :                                       MachineRepresentation::kTaggedPointer,
    1069           0 :                                       output_type, use_node, use_info);
    1070       78144 :   } else if (output_rep == MachineRepresentation::kWord32) {
    1071             :     // Only the checked case should get here, the non-checked case is
    1072             :     // handled in GetRepresentationFor.
    1073       78075 :     if (use_info.type_check() == TypeCheckKind::kSignedSmall ||
    1074             :         use_info.type_check() == TypeCheckKind::kSigned32) {
    1075             :       bool indentify_zeros = use_info.truncation().IdentifiesZeroAndMinusZero();
    1076      156078 :       if (output_type.Is(Type::Signed32()) ||
    1077         278 :           (indentify_zeros && output_type.Is(Type::Signed32OrMinusZero()))) {
    1078             :         return node;
    1079         838 :       } else if (output_type.Is(Type::Unsigned32()) ||
    1080           0 :                  (indentify_zeros &&
    1081             :                   output_type.Is(Type::Unsigned32OrMinusZero()))) {
    1082         419 :         op = simplified()->CheckedUint32ToInt32(use_info.feedback());
    1083             :       } else {
    1084             :         return TypeError(node, output_rep, output_type,
    1085           0 :                          MachineRepresentation::kWord32);
    1086             :       }
    1087          36 :     } else if (use_info.type_check() == TypeCheckKind::kNumber ||
    1088             :                use_info.type_check() == TypeCheckKind::kNumberOrOddball) {
    1089             :       return node;
    1090             :     }
    1091          69 :   } else if (output_rep == MachineRepresentation::kWord8 ||
    1092             :              output_rep == MachineRepresentation::kWord16) {
    1093             :     DCHECK_EQ(MachineRepresentation::kWord32, use_info.representation());
    1094             :     DCHECK(use_info.type_check() == TypeCheckKind::kSignedSmall ||
    1095             :            use_info.type_check() == TypeCheckKind::kSigned32);
    1096             :     return node;
    1097          69 :   } else if (output_rep == MachineRepresentation::kWord64) {
    1098         109 :     if (output_type.Is(Type::Signed32()) ||
    1099             :         output_type.Is(Type::Unsigned32())) {
    1100          40 :       op = machine()->TruncateInt64ToInt32();
    1101          82 :     } else if (output_type.Is(cache_->kSafeInteger) &&
    1102             :                use_info.truncation().IsUsedAsWord32()) {
    1103           5 :       op = machine()->TruncateInt64ToInt32();
    1104          24 :     } else if (use_info.type_check() == TypeCheckKind::kSignedSmall ||
    1105             :                use_info.type_check() == TypeCheckKind::kSigned32) {
    1106          38 :       if (output_type.Is(cache_->kPositiveSafeInteger)) {
    1107           5 :         op = simplified()->CheckedUint64ToInt32(use_info.feedback());
    1108          28 :       } else if (output_type.Is(cache_->kSafeInteger)) {
    1109          14 :         op = simplified()->CheckedInt64ToInt32(use_info.feedback());
    1110             :       } else {
    1111             :         return TypeError(node, output_rep, output_type,
    1112           0 :                          MachineRepresentation::kWord32);
    1113             :       }
    1114             :     } else {
    1115             :       return TypeError(node, output_rep, output_type,
    1116           5 :                        MachineRepresentation::kWord32);
    1117             :     }
    1118             :   }
    1119             : 
    1120      237510 :   if (op == nullptr) {
    1121             :     return TypeError(node, output_rep, output_type,
    1122           0 :                      MachineRepresentation::kWord32);
    1123             :   }
    1124      237510 :   return InsertConversion(node, op, use_node);
    1125             : }
    1126             : 
    1127      483806 : Node* RepresentationChanger::InsertConversion(Node* node, const Operator* op,
    1128             :                                               Node* use_node) {
    1129      483806 :   if (op->ControlInputCount() > 0) {
    1130             :     // If the operator can deoptimize (which means it has control
    1131             :     // input), we need to connect it to the effect and control chains.
    1132      263257 :     Node* effect = NodeProperties::GetEffectInput(use_node);
    1133      263257 :     Node* control = NodeProperties::GetControlInput(use_node);
    1134             :     Node* conversion = jsgraph()->graph()->NewNode(op, node, effect, control);
    1135      263280 :     NodeProperties::ReplaceEffectInput(use_node, conversion);
    1136      263264 :     return conversion;
    1137             :   }
    1138      220549 :   return jsgraph()->graph()->NewNode(op, node);
    1139             : }
    1140             : 
    1141      321724 : Node* RepresentationChanger::GetBitRepresentationFor(
    1142             :     Node* node, MachineRepresentation output_rep, Type output_type) {
    1143             :   // Eagerly fold representation changes for constants.
    1144      321724 :   switch (node->opcode()) {
    1145             :     case IrOpcode::kHeapConstant: {
    1146             :       HeapObjectMatcher m(node);
    1147      132219 :       if (m.Is(factory()->false_value())) {
    1148       90773 :         return jsgraph()->Int32Constant(0);
    1149       41446 :       } else if (m.Is(factory()->true_value())) {
    1150       41446 :         return jsgraph()->Int32Constant(1);
    1151             :       }
    1152             :       break;
    1153             :     }
    1154             :     default:
    1155             :       break;
    1156             :   }
    1157             :   // Select the correct X -> Bit operator.
    1158             :   const Operator* op;
    1159      189505 :   if (output_type.Is(Type::None())) {
    1160             :     // This is an impossible value; it should not be used at runtime.
    1161         221 :     return jsgraph()->graph()->NewNode(
    1162         221 :         jsgraph()->common()->DeadValue(MachineRepresentation::kBit), node);
    1163      189284 :   } else if (output_rep == MachineRepresentation::kTagged ||
    1164             :              output_rep == MachineRepresentation::kTaggedPointer) {
    1165      189270 :     if (output_type.Is(Type::BooleanOrNullOrUndefined())) {
    1166             :       // true is the only trueish Oddball.
    1167      140928 :       op = simplified()->ChangeTaggedToBit();
    1168             :     } else {
    1169       96316 :       if (output_rep == MachineRepresentation::kTagged &&
    1170       47974 :           output_type.Maybe(Type::SignedSmall())) {
    1171       47952 :         op = simplified()->TruncateTaggedToBit();
    1172             :       } else {
    1173             :         // The {output_type} either doesn't include the Smi range,
    1174             :         // or the {output_rep} is known to be TaggedPointer.
    1175         390 :         op = simplified()->TruncateTaggedPointerToBit();
    1176             :       }
    1177             :     }
    1178          14 :   } else if (output_rep == MachineRepresentation::kTaggedSigned) {
    1179           0 :     node = jsgraph()->graph()->NewNode(machine()->WordEqual(), node,
    1180             :                                        jsgraph()->IntPtrConstant(0));
    1181           0 :     return jsgraph()->graph()->NewNode(machine()->Word32Equal(), node,
    1182           0 :                                        jsgraph()->Int32Constant(0));
    1183          14 :   } else if (output_rep == MachineRepresentation::kCompressed) {
    1184             :     // TODO(v8:8977): Specialise here
    1185           0 :     op = machine()->ChangeCompressedToTagged();
    1186             :     node = jsgraph()->graph()->NewNode(op, node);
    1187             :     return GetBitRepresentationFor(node, MachineRepresentation::kTagged,
    1188           0 :                                    output_type);
    1189          14 :   } else if (output_rep == MachineRepresentation::kCompressedSigned) {
    1190             :     // TODO(v8:8977): Specialise here
    1191           0 :     op = machine()->ChangeCompressedSignedToTaggedSigned();
    1192             :     node = jsgraph()->graph()->NewNode(op, node);
    1193             :     return GetBitRepresentationFor(node, MachineRepresentation::kTaggedSigned,
    1194           0 :                                    output_type);
    1195          14 :   } else if (output_rep == MachineRepresentation::kCompressedPointer) {
    1196             :     // TODO(v8:8977): Specialise here
    1197           0 :     op = machine()->ChangeCompressedPointerToTaggedPointer();
    1198             :     node = jsgraph()->graph()->NewNode(op, node);
    1199             :     return GetBitRepresentationFor(node, MachineRepresentation::kTaggedPointer,
    1200           0 :                                    output_type);
    1201          14 :   } else if (IsWord(output_rep)) {
    1202           0 :     node = jsgraph()->graph()->NewNode(machine()->Word32Equal(), node,
    1203             :                                        jsgraph()->Int32Constant(0));
    1204           0 :     return jsgraph()->graph()->NewNode(machine()->Word32Equal(), node,
    1205           0 :                                        jsgraph()->Int32Constant(0));
    1206          14 :   } else if (output_rep == MachineRepresentation::kWord64) {
    1207           0 :     node = jsgraph()->graph()->NewNode(machine()->Word64Equal(), node,
    1208             :                                        jsgraph()->Int64Constant(0));
    1209           0 :     return jsgraph()->graph()->NewNode(machine()->Word32Equal(), node,
    1210           0 :                                        jsgraph()->Int32Constant(0));
    1211          14 :   } else if (output_rep == MachineRepresentation::kFloat32) {
    1212           0 :     node = jsgraph()->graph()->NewNode(machine()->Float32Abs(), node);
    1213           0 :     return jsgraph()->graph()->NewNode(machine()->Float32LessThan(),
    1214           0 :                                        jsgraph()->Float32Constant(0.0), node);
    1215          14 :   } else if (output_rep == MachineRepresentation::kFloat64) {
    1216          14 :     node = jsgraph()->graph()->NewNode(machine()->Float64Abs(), node);
    1217          14 :     return jsgraph()->graph()->NewNode(machine()->Float64LessThan(),
    1218          14 :                                        jsgraph()->Float64Constant(0.0), node);
    1219             :   } else {
    1220             :     return TypeError(node, output_rep, output_type,
    1221           0 :                      MachineRepresentation::kBit);
    1222             :   }
    1223      189270 :   return jsgraph()->graph()->NewNode(op, node);
    1224             : }
    1225             : 
    1226      185521 : Node* RepresentationChanger::GetWord64RepresentationFor(
    1227             :     Node* node, MachineRepresentation output_rep, Type output_type,
    1228             :     Node* use_node, UseInfo use_info) {
    1229             :   // Eagerly fold representation changes for constants.
    1230      185521 :   switch (node->opcode()) {
    1231             :     case IrOpcode::kInt32Constant:
    1232             :     case IrOpcode::kInt64Constant:
    1233             :     case IrOpcode::kFloat32Constant:
    1234             :     case IrOpcode::kFloat64Constant:
    1235           0 :       UNREACHABLE();
    1236             :       break;
    1237             :     case IrOpcode::kNumberConstant: {
    1238      149605 :       double const fv = OpParameter<double>(node->op());
    1239             :       using limits = std::numeric_limits<int64_t>;
    1240      149605 :       if (fv <= limits::max() && fv >= limits::min()) {
    1241      149598 :         int64_t const iv = static_cast<int64_t>(fv);
    1242      149598 :         if (static_cast<double>(iv) == fv) {
    1243      149598 :           return jsgraph()->Int64Constant(iv);
    1244             :         }
    1245             :       }
    1246             :       break;
    1247             :     }
    1248             :     default:
    1249             :       break;
    1250             :   }
    1251             : 
    1252             :   // Select the correct X -> Word64 operator.
    1253             :   const Operator* op;
    1254       35923 :   if (output_type.Is(Type::None())) {
    1255             :     // This is an impossible value; it should not be used at runtime.
    1256          89 :     return jsgraph()->graph()->NewNode(
    1257          89 :         jsgraph()->common()->DeadValue(MachineRepresentation::kWord64), node);
    1258       35834 :   } else if (output_rep == MachineRepresentation::kBit) {
    1259           7 :     CHECK(output_type.Is(Type::Boolean()));
    1260           7 :     CHECK_NE(use_info.type_check(), TypeCheckKind::kNone);
    1261             :     Node* unreachable =
    1262           7 :         InsertUnconditionalDeopt(use_node, DeoptimizeReason::kNotASmi);
    1263           7 :     return jsgraph()->graph()->NewNode(
    1264             :         jsgraph()->common()->DeadValue(MachineRepresentation::kWord64),
    1265           7 :         unreachable);
    1266       35827 :   } else if (IsWord(output_rep)) {
    1267       35295 :     if (output_type.Is(Type::Unsigned32())) {
    1268       34489 :       op = machine()->ChangeUint32ToUint64();
    1269         806 :     } else if (output_type.Is(Type::Signed32())) {
    1270         801 :       op = machine()->ChangeInt32ToInt64();
    1271             :     } else {
    1272             :       return TypeError(node, output_rep, output_type,
    1273           5 :                        MachineRepresentation::kWord64);
    1274             :     }
    1275         532 :   } else if (output_rep == MachineRepresentation::kFloat32) {
    1276          66 :     if (output_type.Is(cache_->kInt64)) {
    1277             :       // float32 -> float64 -> int64
    1278          15 :       node = InsertChangeFloat32ToFloat64(node);
    1279          15 :       op = machine()->ChangeFloat64ToInt64();
    1280          36 :     } else if (output_type.Is(cache_->kUint64)) {
    1281             :       // float32 -> float64 -> uint64
    1282           5 :       node = InsertChangeFloat32ToFloat64(node);
    1283           5 :       op = machine()->ChangeFloat64ToUint64();
    1284          13 :     } else if (use_info.type_check() == TypeCheckKind::kSigned64) {
    1285             :       // float32 -> float64 -> int64
    1286          13 :       node = InsertChangeFloat32ToFloat64(node);
    1287          13 :       op = simplified()->CheckedFloat64ToInt64(
    1288          13 :           output_type.Maybe(Type::MinusZero())
    1289             :               ? use_info.minus_zero_check()
    1290             :               : CheckForMinusZeroMode::kDontCheckForMinusZero,
    1291          13 :           use_info.feedback());
    1292             :     } else {
    1293             :       return TypeError(node, output_rep, output_type,
    1294           0 :                        MachineRepresentation::kWord64);
    1295             :     }
    1296         499 :   } else if (output_rep == MachineRepresentation::kFloat64) {
    1297         118 :     if (output_type.Is(cache_->kInt64)) {
    1298          41 :       op = machine()->ChangeFloat64ToInt64();
    1299          36 :     } else if (output_type.Is(cache_->kUint64)) {
    1300           5 :       op = machine()->ChangeFloat64ToUint64();
    1301          13 :     } else if (use_info.type_check() == TypeCheckKind::kSigned64) {
    1302          13 :       op = simplified()->CheckedFloat64ToInt64(
    1303          13 :           output_type.Maybe(Type::MinusZero())
    1304             :               ? use_info.minus_zero_check()
    1305             :               : CheckForMinusZeroMode::kDontCheckForMinusZero,
    1306          13 :           use_info.feedback());
    1307             :     } else {
    1308             :       return TypeError(node, output_rep, output_type,
    1309           0 :                        MachineRepresentation::kWord64);
    1310             :     }
    1311         440 :   } else if (output_rep == MachineRepresentation::kTaggedSigned) {
    1312         310 :     if (output_type.Is(Type::SignedSmall())) {
    1313         310 :       op = simplified()->ChangeTaggedSignedToInt64();
    1314             :     } else {
    1315             :       return TypeError(node, output_rep, output_type,
    1316           0 :                        MachineRepresentation::kWord64);
    1317             :     }
    1318         130 :   } else if (CanBeTaggedPointer(output_rep)) {
    1319         260 :     if (output_type.Is(cache_->kInt64)) {
    1320          23 :       op = simplified()->ChangeTaggedToInt64();
    1321         107 :     } else if (use_info.type_check() == TypeCheckKind::kSigned64) {
    1322          97 :       op = simplified()->CheckedTaggedToInt64(
    1323          97 :           output_type.Maybe(Type::MinusZero())
    1324             :               ? use_info.minus_zero_check()
    1325             :               : CheckForMinusZeroMode::kDontCheckForMinusZero,
    1326          97 :           use_info.feedback());
    1327             :     } else {
    1328             :       return TypeError(node, output_rep, output_type,
    1329          10 :                        MachineRepresentation::kWord64);
    1330             :     }
    1331           0 :   } else if (output_rep == MachineRepresentation::kCompressed) {
    1332             :     // TODO(v8:8977): Specialise here
    1333           0 :     op = machine()->ChangeCompressedToTagged();
    1334             :     node = jsgraph()->graph()->NewNode(op, node);
    1335             :     return GetWord64RepresentationFor(node, MachineRepresentation::kTagged,
    1336           0 :                                       output_type, use_node, use_info);
    1337           0 :   } else if (output_rep == MachineRepresentation::kCompressedSigned) {
    1338             :     // TODO(v8:8977): Specialise here
    1339           0 :     op = machine()->ChangeCompressedSignedToTaggedSigned();
    1340             :     node = jsgraph()->graph()->NewNode(op, node);
    1341             :     return GetWord64RepresentationFor(node,
    1342             :                                       MachineRepresentation::kTaggedSigned,
    1343           0 :                                       output_type, use_node, use_info);
    1344           0 :   } else if (output_rep == MachineRepresentation::kCompressedPointer) {
    1345             :     // TODO(v8:8977): Specialise here
    1346           0 :     op = machine()->ChangeCompressedPointerToTaggedPointer();
    1347             :     node = jsgraph()->graph()->NewNode(op, node);
    1348             :     return GetWord64RepresentationFor(node,
    1349             :                                       MachineRepresentation::kTaggedPointer,
    1350           0 :                                       output_type, use_node, use_info);
    1351             :   } else {
    1352             :     return TypeError(node, output_rep, output_type,
    1353           0 :                      MachineRepresentation::kWord64);
    1354             :   }
    1355       35812 :   return InsertConversion(node, op, use_node);
    1356             : }
    1357             : 
    1358      213002 : const Operator* RepresentationChanger::Int32OperatorFor(
    1359             :     IrOpcode::Value opcode) {
    1360      213002 :   switch (opcode) {
    1361             :     case IrOpcode::kSpeculativeNumberAdd:  // Fall through.
    1362             :     case IrOpcode::kSpeculativeSafeIntegerAdd:
    1363             :     case IrOpcode::kNumberAdd:
    1364      102945 :       return machine()->Int32Add();
    1365             :     case IrOpcode::kSpeculativeNumberSubtract:  // Fall through.
    1366             :     case IrOpcode::kSpeculativeSafeIntegerSubtract:
    1367             :     case IrOpcode::kNumberSubtract:
    1368        4731 :       return machine()->Int32Sub();
    1369             :     case IrOpcode::kSpeculativeNumberMultiply:
    1370             :     case IrOpcode::kNumberMultiply:
    1371         995 :       return machine()->Int32Mul();
    1372             :     case IrOpcode::kSpeculativeNumberDivide:
    1373             :     case IrOpcode::kNumberDivide:
    1374           0 :       return machine()->Int32Div();
    1375             :     case IrOpcode::kSpeculativeNumberModulus:
    1376             :     case IrOpcode::kNumberModulus:
    1377           0 :       return machine()->Int32Mod();
    1378             :     case IrOpcode::kSpeculativeNumberBitwiseOr:  // Fall through.
    1379             :     case IrOpcode::kNumberBitwiseOr:
    1380       19040 :       return machine()->Word32Or();
    1381             :     case IrOpcode::kSpeculativeNumberBitwiseXor:  // Fall through.
    1382             :     case IrOpcode::kNumberBitwiseXor:
    1383        1124 :       return machine()->Word32Xor();
    1384             :     case IrOpcode::kSpeculativeNumberBitwiseAnd:  // Fall through.
    1385             :     case IrOpcode::kNumberBitwiseAnd:
    1386        8839 :       return machine()->Word32And();
    1387             :     case IrOpcode::kNumberEqual:
    1388             :     case IrOpcode::kSpeculativeNumberEqual:
    1389        9750 :       return machine()->Word32Equal();
    1390             :     case IrOpcode::kNumberLessThan:
    1391             :     case IrOpcode::kSpeculativeNumberLessThan:
    1392       64101 :       return machine()->Int32LessThan();
    1393             :     case IrOpcode::kNumberLessThanOrEqual:
    1394             :     case IrOpcode::kSpeculativeNumberLessThanOrEqual:
    1395        1477 :       return machine()->Int32LessThanOrEqual();
    1396             :     default:
    1397           0 :       UNREACHABLE();
    1398             :   }
    1399             : }
    1400             : 
    1401      151269 : const Operator* RepresentationChanger::Int32OverflowOperatorFor(
    1402             :     IrOpcode::Value opcode) {
    1403      151269 :   switch (opcode) {
    1404             :     case IrOpcode::kSpeculativeSafeIntegerAdd:
    1405      142224 :       return simplified()->CheckedInt32Add();
    1406             :     case IrOpcode::kSpeculativeSafeIntegerSubtract:
    1407        7710 :       return simplified()->CheckedInt32Sub();
    1408             :     case IrOpcode::kSpeculativeNumberDivide:
    1409         244 :       return simplified()->CheckedInt32Div();
    1410             :     case IrOpcode::kSpeculativeNumberModulus:
    1411        1091 :       return simplified()->CheckedInt32Mod();
    1412             :     default:
    1413           0 :       UNREACHABLE();
    1414             :   }
    1415             : }
    1416             : 
    1417         481 : const Operator* RepresentationChanger::Int64OperatorFor(
    1418             :     IrOpcode::Value opcode) {
    1419             :   switch (opcode) {
    1420             :     case IrOpcode::kSpeculativeNumberAdd:  // Fall through.
    1421             :     case IrOpcode::kSpeculativeSafeIntegerAdd:
    1422             :     case IrOpcode::kNumberAdd:
    1423         260 :       return machine()->Int64Add();
    1424             :     case IrOpcode::kSpeculativeNumberSubtract:  // Fall through.
    1425             :     case IrOpcode::kSpeculativeSafeIntegerSubtract:
    1426             :     case IrOpcode::kNumberSubtract:
    1427         221 :       return machine()->Int64Sub();
    1428             :     default:
    1429           0 :       UNREACHABLE();
    1430             :   }
    1431             : }
    1432             : 
    1433       14412 : const Operator* RepresentationChanger::TaggedSignedOperatorFor(
    1434             :     IrOpcode::Value opcode) {
    1435       14412 :   switch (opcode) {
    1436             :     case IrOpcode::kSpeculativeNumberLessThan:
    1437             :       return machine()->Is32() ? machine()->Int32LessThan()
    1438        5237 :                                : machine()->Int64LessThan();
    1439             :     case IrOpcode::kSpeculativeNumberLessThanOrEqual:
    1440             :       return machine()->Is32() ? machine()->Int32LessThanOrEqual()
    1441         239 :                                : machine()->Int64LessThanOrEqual();
    1442             :     case IrOpcode::kSpeculativeNumberEqual:
    1443             :       return machine()->Is32() ? machine()->Word32Equal()
    1444        8936 :                                : machine()->Word64Equal();
    1445             :     default:
    1446           0 :       UNREACHABLE();
    1447             :   }
    1448             : }
    1449             : 
    1450       34266 : const Operator* RepresentationChanger::Uint32OperatorFor(
    1451             :     IrOpcode::Value opcode) {
    1452       34266 :   switch (opcode) {
    1453             :     case IrOpcode::kNumberAdd:
    1454           0 :       return machine()->Int32Add();
    1455             :     case IrOpcode::kNumberSubtract:
    1456           0 :       return machine()->Int32Sub();
    1457             :     case IrOpcode::kSpeculativeNumberMultiply:
    1458             :     case IrOpcode::kNumberMultiply:
    1459           0 :       return machine()->Int32Mul();
    1460             :     case IrOpcode::kSpeculativeNumberDivide:
    1461             :     case IrOpcode::kNumberDivide:
    1462           0 :       return machine()->Uint32Div();
    1463             :     case IrOpcode::kSpeculativeNumberModulus:
    1464             :     case IrOpcode::kNumberModulus:
    1465           0 :       return machine()->Uint32Mod();
    1466             :     case IrOpcode::kNumberEqual:
    1467             :     case IrOpcode::kSpeculativeNumberEqual:
    1468       12972 :       return machine()->Word32Equal();
    1469             :     case IrOpcode::kNumberLessThan:
    1470             :     case IrOpcode::kSpeculativeNumberLessThan:
    1471       18814 :       return machine()->Uint32LessThan();
    1472             :     case IrOpcode::kNumberLessThanOrEqual:
    1473             :     case IrOpcode::kSpeculativeNumberLessThanOrEqual:
    1474        1578 :       return machine()->Uint32LessThanOrEqual();
    1475             :     case IrOpcode::kNumberClz32:
    1476          30 :       return machine()->Word32Clz();
    1477             :     case IrOpcode::kNumberImul:
    1478         872 :       return machine()->Int32Mul();
    1479             :     default:
    1480           0 :       UNREACHABLE();
    1481             :   }
    1482             : }
    1483             : 
    1484         113 : const Operator* RepresentationChanger::Uint32OverflowOperatorFor(
    1485             :     IrOpcode::Value opcode) {
    1486         113 :   switch (opcode) {
    1487             :     case IrOpcode::kSpeculativeNumberDivide:
    1488          69 :       return simplified()->CheckedUint32Div();
    1489             :     case IrOpcode::kSpeculativeNumberModulus:
    1490          44 :       return simplified()->CheckedUint32Mod();
    1491             :     default:
    1492           0 :       UNREACHABLE();
    1493             :   }
    1494             : }
    1495             : 
    1496      168306 : const Operator* RepresentationChanger::Float64OperatorFor(
    1497             :     IrOpcode::Value opcode) {
    1498      168306 :   switch (opcode) {
    1499             :     case IrOpcode::kSpeculativeNumberAdd:
    1500             :     case IrOpcode::kSpeculativeSafeIntegerAdd:
    1501             :     case IrOpcode::kNumberAdd:
    1502       73515 :       return machine()->Float64Add();
    1503             :     case IrOpcode::kSpeculativeNumberSubtract:
    1504             :     case IrOpcode::kSpeculativeSafeIntegerSubtract:
    1505             :     case IrOpcode::kNumberSubtract:
    1506        1195 :       return machine()->Float64Sub();
    1507             :     case IrOpcode::kSpeculativeNumberMultiply:
    1508             :     case IrOpcode::kNumberMultiply:
    1509       11596 :       return machine()->Float64Mul();
    1510             :     case IrOpcode::kSpeculativeNumberDivide:
    1511             :     case IrOpcode::kNumberDivide:
    1512       15295 :       return machine()->Float64Div();
    1513             :     case IrOpcode::kSpeculativeNumberModulus:
    1514             :     case IrOpcode::kNumberModulus:
    1515         562 :       return machine()->Float64Mod();
    1516             :     case IrOpcode::kNumberEqual:
    1517             :     case IrOpcode::kSpeculativeNumberEqual:
    1518       16986 :       return machine()->Float64Equal();
    1519             :     case IrOpcode::kNumberLessThan:
    1520             :     case IrOpcode::kSpeculativeNumberLessThan:
    1521        3762 :       return machine()->Float64LessThan();
    1522             :     case IrOpcode::kNumberLessThanOrEqual:
    1523             :     case IrOpcode::kSpeculativeNumberLessThanOrEqual:
    1524         266 :       return machine()->Float64LessThanOrEqual();
    1525             :     case IrOpcode::kNumberAbs:
    1526         190 :       return machine()->Float64Abs();
    1527             :     case IrOpcode::kNumberAcos:
    1528           0 :       return machine()->Float64Acos();
    1529             :     case IrOpcode::kNumberAcosh:
    1530           0 :       return machine()->Float64Acosh();
    1531             :     case IrOpcode::kNumberAsin:
    1532           7 :       return machine()->Float64Asin();
    1533             :     case IrOpcode::kNumberAsinh:
    1534           0 :       return machine()->Float64Asinh();
    1535             :     case IrOpcode::kNumberAtan:
    1536           0 :       return machine()->Float64Atan();
    1537             :     case IrOpcode::kNumberAtanh:
    1538           0 :       return machine()->Float64Atanh();
    1539             :     case IrOpcode::kNumberAtan2:
    1540           0 :       return machine()->Float64Atan2();
    1541             :     case IrOpcode::kNumberCbrt:
    1542           0 :       return machine()->Float64Cbrt();
    1543             :     case IrOpcode::kNumberCeil:
    1544        6675 :       return machine()->Float64RoundUp().placeholder();
    1545             :     case IrOpcode::kNumberCos:
    1546          14 :       return machine()->Float64Cos();
    1547             :     case IrOpcode::kNumberCosh:
    1548           7 :       return machine()->Float64Cosh();
    1549             :     case IrOpcode::kNumberExp:
    1550          32 :       return machine()->Float64Exp();
    1551             :     case IrOpcode::kNumberExpm1:
    1552          14 :       return machine()->Float64Expm1();
    1553             :     case IrOpcode::kNumberFloor:
    1554       27873 :       return machine()->Float64RoundDown().placeholder();
    1555             :     case IrOpcode::kNumberFround:
    1556        1287 :       return machine()->TruncateFloat64ToFloat32();
    1557             :     case IrOpcode::kNumberLog:
    1558         131 :       return machine()->Float64Log();
    1559             :     case IrOpcode::kNumberLog1p:
    1560           0 :       return machine()->Float64Log1p();
    1561             :     case IrOpcode::kNumberLog2:
    1562           0 :       return machine()->Float64Log2();
    1563             :     case IrOpcode::kNumberLog10:
    1564           0 :       return machine()->Float64Log10();
    1565             :     case IrOpcode::kNumberMax:
    1566          72 :       return machine()->Float64Max();
    1567             :     case IrOpcode::kNumberMin:
    1568         148 :       return machine()->Float64Min();
    1569             :     case IrOpcode::kNumberPow:
    1570         909 :       return machine()->Float64Pow();
    1571             :     case IrOpcode::kNumberSin:
    1572          31 :       return machine()->Float64Sin();
    1573             :     case IrOpcode::kNumberSinh:
    1574           7 :       return machine()->Float64Sinh();
    1575             :     case IrOpcode::kNumberSqrt:
    1576          51 :       return machine()->Float64Sqrt();
    1577             :     case IrOpcode::kNumberTan:
    1578          28 :       return machine()->Float64Tan();
    1579             :     case IrOpcode::kNumberTanh:
    1580           7 :       return machine()->Float64Tanh();
    1581             :     case IrOpcode::kNumberTrunc:
    1582        6914 :       return machine()->Float64RoundTruncate().placeholder();
    1583             :     case IrOpcode::kNumberSilenceNaN:
    1584         732 :       return machine()->Float64SilenceNaN();
    1585             :     default:
    1586           0 :       UNREACHABLE();
    1587             :   }
    1588             : }
    1589             : 
    1590          35 : Node* RepresentationChanger::TypeError(Node* node,
    1591             :                                        MachineRepresentation output_rep,
    1592             :                                        Type output_type,
    1593             :                                        MachineRepresentation use) {
    1594          35 :   type_error_ = true;
    1595          35 :   if (!testing_type_errors_) {
    1596           0 :     std::ostringstream out_str;
    1597           0 :     out_str << output_rep << " (";
    1598           0 :     output_type.PrintTo(out_str);
    1599           0 :     out_str << ")";
    1600             : 
    1601           0 :     std::ostringstream use_str;
    1602           0 :     use_str << use;
    1603             : 
    1604             :     FATAL(
    1605             :         "RepresentationChangerError: node #%d:%s of "
    1606             :         "%s cannot be changed to %s",
    1607             :         node->id(), node->op()->mnemonic(), out_str.str().c_str(),
    1608           0 :         use_str.str().c_str());
    1609             :   }
    1610          35 :   return node;
    1611             : }
    1612             : 
    1613           0 : Node* RepresentationChanger::InsertChangeBitToTagged(Node* node) {
    1614           0 :   return jsgraph()->graph()->NewNode(simplified()->ChangeBitToTagged(), node);
    1615             : }
    1616             : 
    1617         430 : Node* RepresentationChanger::InsertChangeFloat32ToFloat64(Node* node) {
    1618         860 :   return jsgraph()->graph()->NewNode(machine()->ChangeFloat32ToFloat64(), node);
    1619             : }
    1620             : 
    1621          20 : Node* RepresentationChanger::InsertChangeFloat64ToUint32(Node* node) {
    1622          40 :   return jsgraph()->graph()->NewNode(machine()->ChangeFloat64ToUint32(), node);
    1623             : }
    1624             : 
    1625         807 : Node* RepresentationChanger::InsertChangeFloat64ToInt32(Node* node) {
    1626        1614 :   return jsgraph()->graph()->NewNode(machine()->ChangeFloat64ToInt32(), node);
    1627             : }
    1628             : 
    1629          14 : Node* RepresentationChanger::InsertChangeInt32ToFloat64(Node* node) {
    1630          28 :   return jsgraph()->graph()->NewNode(machine()->ChangeInt32ToFloat64(), node);
    1631             : }
    1632             : 
    1633        1315 : Node* RepresentationChanger::InsertChangeTaggedSignedToInt32(Node* node) {
    1634        1315 :   return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedSignedToInt32(),
    1635        1315 :                                      node);
    1636             : }
    1637             : 
    1638           0 : Node* RepresentationChanger::InsertChangeTaggedToFloat64(Node* node) {
    1639           0 :   return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedToFloat64(),
    1640           0 :                                      node);
    1641             : }
    1642             : 
    1643           0 : Node* RepresentationChanger::InsertChangeUint32ToFloat64(Node* node) {
    1644           0 :   return jsgraph()->graph()->NewNode(machine()->ChangeUint32ToFloat64(), node);
    1645             : }
    1646             : 
    1647          32 : Node* RepresentationChanger::InsertTruncateInt64ToInt32(Node* node) {
    1648          64 :   return jsgraph()->graph()->NewNode(machine()->TruncateInt64ToInt32(), node);
    1649             : }
    1650             : 
    1651             : }  // namespace compiler
    1652             : }  // namespace internal
    1653      122036 : }  // namespace v8

Generated by: LCOV version 1.10