Home | History | Annotate | Download | only in compiler
      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/objects-inl.h"
     14 
     15 namespace v8 {
     16 namespace internal {
     17 namespace compiler {
     18 
     19 const char* Truncation::description() const {
     20   switch (kind()) {
     21     case TruncationKind::kNone:
     22       return "no-value-use";
     23     case TruncationKind::kBool:
     24       return "truncate-to-bool";
     25     case TruncationKind::kWord32:
     26       return "truncate-to-word32";
     27     case TruncationKind::kWord64:
     28       return "truncate-to-word64";
     29     case TruncationKind::kFloat64:
     30       return "truncate-to-float64";
     31     case TruncationKind::kAny:
     32       return "no-truncation";
     33   }
     34   UNREACHABLE();
     35   return nullptr;
     36 }
     37 
     38 
     39 // Partial order for truncations:
     40 //
     41 //  kWord64       kAny
     42 //     ^            ^
     43 //     \            |
     44 //      \         kFloat64  <--+
     45 //       \        ^            |
     46 //        \       /            |
     47 //         kWord32           kBool
     48 //               ^            ^
     49 //               \            /
     50 //                \          /
     51 //                 \        /
     52 //                  \      /
     53 //                   \    /
     54 //                   kNone
     55 
     56 // static
     57 Truncation::TruncationKind Truncation::Generalize(TruncationKind rep1,
     58                                                   TruncationKind rep2) {
     59   if (LessGeneral(rep1, rep2)) return rep2;
     60   if (LessGeneral(rep2, rep1)) return rep1;
     61   // Handle the generalization of float64-representable values.
     62   if (LessGeneral(rep1, TruncationKind::kFloat64) &&
     63       LessGeneral(rep2, TruncationKind::kFloat64)) {
     64     return TruncationKind::kFloat64;
     65   }
     66   // Handle the generalization of any-representable values.
     67   if (LessGeneral(rep1, TruncationKind::kAny) &&
     68       LessGeneral(rep2, TruncationKind::kAny)) {
     69     return TruncationKind::kAny;
     70   }
     71   // All other combinations are illegal.
     72   FATAL("Tried to combine incompatible truncations");
     73   return TruncationKind::kNone;
     74 }
     75 
     76 
     77 // static
     78 bool Truncation::LessGeneral(TruncationKind rep1, TruncationKind rep2) {
     79   switch (rep1) {
     80     case TruncationKind::kNone:
     81       return true;
     82     case TruncationKind::kBool:
     83       return rep2 == TruncationKind::kBool || rep2 == TruncationKind::kAny;
     84     case TruncationKind::kWord32:
     85       return rep2 == TruncationKind::kWord32 ||
     86              rep2 == TruncationKind::kWord64 ||
     87              rep2 == TruncationKind::kFloat64 || rep2 == TruncationKind::kAny;
     88     case TruncationKind::kWord64:
     89       return rep2 == TruncationKind::kWord64;
     90     case TruncationKind::kFloat64:
     91       return rep2 == TruncationKind::kFloat64 || rep2 == TruncationKind::kAny;
     92     case TruncationKind::kAny:
     93       return rep2 == TruncationKind::kAny;
     94   }
     95   UNREACHABLE();
     96   return false;
     97 }
     98 
     99 
    100 namespace {
    101 
    102 bool IsWord(MachineRepresentation rep) {
    103   return rep == MachineRepresentation::kWord8 ||
    104          rep == MachineRepresentation::kWord16 ||
    105          rep == MachineRepresentation::kWord32;
    106 }
    107 
    108 }  // namespace
    109 
    110 // Changes representation from {output_rep} to {use_rep}. The {truncation}
    111 // parameter is only used for sanity checking - if the changer cannot figure
    112 // out signedness for the word32->float64 conversion, then we check that the
    113 // uses truncate to word32 (so they do not care about signedness).
    114 Node* RepresentationChanger::GetRepresentationFor(
    115     Node* node, MachineRepresentation output_rep, Type* output_type,
    116     Node* use_node, UseInfo use_info) {
    117   if (output_rep == MachineRepresentation::kNone &&
    118       output_type->IsInhabited()) {
    119     // The output representation should be set if the type is inhabited (i.e.,
    120     // if the value is possible).
    121     return TypeError(node, output_rep, output_type, use_info.representation());
    122   }
    123 
    124   // Handle the no-op shortcuts when no checking is necessary.
    125   if (use_info.type_check() == TypeCheckKind::kNone ||
    126       output_rep != MachineRepresentation::kWord32) {
    127     if (use_info.representation() == output_rep) {
    128       // Representations are the same. That's a no-op.
    129       return node;
    130     }
    131     if (IsWord(use_info.representation()) && IsWord(output_rep)) {
    132       // Both are words less than or equal to 32-bits.
    133       // Since loads of integers from memory implicitly sign or zero extend the
    134       // value to the full machine word size and stores implicitly truncate,
    135       // no representation change is necessary.
    136       return node;
    137     }
    138   }
    139 
    140   switch (use_info.representation()) {
    141     case MachineRepresentation::kTaggedSigned:
    142       DCHECK(use_info.type_check() == TypeCheckKind::kNone ||
    143              use_info.type_check() == TypeCheckKind::kSignedSmall);
    144       return GetTaggedSignedRepresentationFor(node, output_rep, output_type,
    145                                               use_node, use_info);
    146     case MachineRepresentation::kTaggedPointer:
    147       DCHECK(use_info.type_check() == TypeCheckKind::kNone ||
    148              use_info.type_check() == TypeCheckKind::kHeapObject);
    149       return GetTaggedPointerRepresentationFor(node, output_rep, output_type,
    150                                                use_node, use_info);
    151     case MachineRepresentation::kTagged:
    152       DCHECK(use_info.type_check() == TypeCheckKind::kNone);
    153       return GetTaggedRepresentationFor(node, output_rep, output_type,
    154                                         use_info.truncation());
    155     case MachineRepresentation::kFloat32:
    156       DCHECK(use_info.type_check() == TypeCheckKind::kNone);
    157       return GetFloat32RepresentationFor(node, output_rep, output_type,
    158                                          use_info.truncation());
    159     case MachineRepresentation::kFloat64:
    160       return GetFloat64RepresentationFor(node, output_rep, output_type,
    161                                          use_node, use_info);
    162     case MachineRepresentation::kBit:
    163       DCHECK(use_info.type_check() == TypeCheckKind::kNone);
    164       return GetBitRepresentationFor(node, output_rep, output_type);
    165     case MachineRepresentation::kWord8:
    166     case MachineRepresentation::kWord16:
    167     case MachineRepresentation::kWord32:
    168       return GetWord32RepresentationFor(node, output_rep, output_type, use_node,
    169                                         use_info);
    170     case MachineRepresentation::kWord64:
    171       DCHECK(use_info.type_check() == TypeCheckKind::kNone);
    172       return GetWord64RepresentationFor(node, output_rep, output_type);
    173     case MachineRepresentation::kSimd128:
    174     case MachineRepresentation::kSimd1x4:
    175     case MachineRepresentation::kSimd1x8:
    176     case MachineRepresentation::kSimd1x16:
    177     case MachineRepresentation::kNone:
    178       return node;
    179   }
    180   UNREACHABLE();
    181   return nullptr;
    182 }
    183 
    184 Node* RepresentationChanger::GetTaggedSignedRepresentationFor(
    185     Node* node, MachineRepresentation output_rep, Type* output_type,
    186     Node* use_node, UseInfo use_info) {
    187   // Eagerly fold representation changes for constants.
    188   switch (node->opcode()) {
    189     case IrOpcode::kNumberConstant:
    190       if (output_type->Is(Type::SignedSmall())) {
    191         return node;
    192       }
    193       break;
    194     default:
    195       break;
    196   }
    197   // Select the correct X -> Tagged operator.
    198   const Operator* op;
    199   if (output_type->Is(Type::None())) {
    200     // This is an impossible value; it should not be used at runtime.
    201     // We just provide a dummy value here.
    202     return jsgraph()->Constant(0);
    203   } else if (IsWord(output_rep)) {
    204     if (output_type->Is(Type::Signed31())) {
    205       op = simplified()->ChangeInt31ToTaggedSigned();
    206     } else if (output_type->Is(Type::Signed32())) {
    207       if (SmiValuesAre32Bits()) {
    208         op = simplified()->ChangeInt32ToTagged();
    209       } else if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
    210         op = simplified()->CheckedInt32ToTaggedSigned();
    211       } else {
    212         return TypeError(node, output_rep, output_type,
    213                          MachineRepresentation::kTaggedSigned);
    214       }
    215     } else if (output_type->Is(Type::Unsigned32()) &&
    216                use_info.type_check() == TypeCheckKind::kSignedSmall) {
    217       op = simplified()->CheckedUint32ToTaggedSigned();
    218     } else {
    219       return TypeError(node, output_rep, output_type,
    220                        MachineRepresentation::kTaggedSigned);
    221     }
    222   } else if (output_rep == MachineRepresentation::kFloat64) {
    223     if (output_type->Is(Type::Signed31())) {
    224       // float64 -> int32 -> tagged signed
    225       node = InsertChangeFloat64ToInt32(node);
    226       op = simplified()->ChangeInt31ToTaggedSigned();
    227     } else if (output_type->Is(Type::Signed32())) {
    228       // float64 -> int32 -> tagged signed
    229       node = InsertChangeFloat64ToInt32(node);
    230       if (SmiValuesAre32Bits()) {
    231         op = simplified()->ChangeInt32ToTagged();
    232       } else if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
    233         op = simplified()->CheckedInt32ToTaggedSigned();
    234       } else {
    235         return TypeError(node, output_rep, output_type,
    236                          MachineRepresentation::kTaggedSigned);
    237       }
    238     } else if (output_type->Is(Type::Unsigned32()) &&
    239                use_info.type_check() == TypeCheckKind::kSignedSmall) {
    240       // float64 -> uint32 -> tagged signed
    241       node = InsertChangeFloat64ToUint32(node);
    242       op = simplified()->CheckedUint32ToTaggedSigned();
    243     } else if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
    244       op = simplified()->CheckedFloat64ToInt32(
    245           output_type->Maybe(Type::MinusZero())
    246               ? CheckForMinusZeroMode::kCheckForMinusZero
    247               : CheckForMinusZeroMode::kDontCheckForMinusZero);
    248       node = InsertConversion(node, op, use_node);
    249       if (SmiValuesAre32Bits()) {
    250         op = simplified()->ChangeInt32ToTagged();
    251       } else {
    252         op = simplified()->CheckedInt32ToTaggedSigned();
    253       }
    254     } else {
    255       return TypeError(node, output_rep, output_type,
    256                        MachineRepresentation::kTaggedSigned);
    257     }
    258   } else if (output_rep == MachineRepresentation::kFloat32) {
    259     if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
    260       op = machine()->ChangeFloat32ToFloat64();
    261       node = InsertConversion(node, op, use_node);
    262       op = simplified()->CheckedFloat64ToInt32(
    263           output_type->Maybe(Type::MinusZero())
    264               ? CheckForMinusZeroMode::kCheckForMinusZero
    265               : CheckForMinusZeroMode::kDontCheckForMinusZero);
    266       node = InsertConversion(node, op, use_node);
    267       if (SmiValuesAre32Bits()) {
    268         op = simplified()->ChangeInt32ToTagged();
    269       } else {
    270         op = simplified()->CheckedInt32ToTaggedSigned();
    271       }
    272     } else {
    273       return TypeError(node, output_rep, output_type,
    274                        MachineRepresentation::kTaggedSigned);
    275     }
    276   } else if (CanBeTaggedPointer(output_rep)) {
    277     if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
    278       op = simplified()->CheckedTaggedToTaggedSigned();
    279     } else if (output_type->Is(Type::SignedSmall())) {
    280       op = simplified()->ChangeTaggedToTaggedSigned();
    281     } else {
    282       return TypeError(node, output_rep, output_type,
    283                        MachineRepresentation::kTaggedSigned);
    284     }
    285   } else if (output_rep == MachineRepresentation::kBit &&
    286              use_info.type_check() == TypeCheckKind::kSignedSmall) {
    287     // TODO(turbofan): Consider adding a Bailout operator that just deopts.
    288     // Also use that for MachineRepresentation::kPointer case above.
    289     node = InsertChangeBitToTagged(node);
    290     op = simplified()->CheckedTaggedToTaggedSigned();
    291   } else {
    292     return TypeError(node, output_rep, output_type,
    293                      MachineRepresentation::kTaggedSigned);
    294   }
    295   return InsertConversion(node, op, use_node);
    296 }
    297 
    298 Node* RepresentationChanger::GetTaggedPointerRepresentationFor(
    299     Node* node, MachineRepresentation output_rep, Type* output_type,
    300     Node* use_node, UseInfo use_info) {
    301   // Eagerly fold representation changes for constants.
    302   switch (node->opcode()) {
    303     case IrOpcode::kHeapConstant:
    304       return node;  // No change necessary.
    305     case IrOpcode::kInt32Constant:
    306     case IrOpcode::kFloat64Constant:
    307     case IrOpcode::kFloat32Constant:
    308       UNREACHABLE();
    309     default:
    310       break;
    311   }
    312   // Select the correct X -> TaggedPointer operator.
    313   Operator const* op;
    314   if (output_type->Is(Type::None())) {
    315     // This is an impossible value; it should not be used at runtime.
    316     // We just provide a dummy value here.
    317     return jsgraph()->TheHoleConstant();
    318   } else if (output_rep == MachineRepresentation::kBit) {
    319     if (output_type->Is(Type::Boolean())) {
    320       op = simplified()->ChangeBitToTagged();
    321     } else {
    322       return TypeError(node, output_rep, output_type,
    323                        MachineRepresentation::kTagged);
    324     }
    325   } else if (IsWord(output_rep)) {
    326     if (output_type->Is(Type::Unsigned32())) {
    327       // uint32 -> float64 -> tagged
    328       node = InsertChangeUint32ToFloat64(node);
    329     } else if (output_type->Is(Type::Signed32())) {
    330       // int32 -> float64 -> tagged
    331       node = InsertChangeInt32ToFloat64(node);
    332     } else {
    333       return TypeError(node, output_rep, output_type,
    334                        MachineRepresentation::kTaggedPointer);
    335     }
    336     op = simplified()->ChangeFloat64ToTaggedPointer();
    337   } else if (output_rep == MachineRepresentation::kFloat32) {
    338     // float32 -> float64 -> tagged
    339     node = InsertChangeFloat32ToFloat64(node);
    340     op = simplified()->ChangeFloat64ToTaggedPointer();
    341   } else if (output_rep == MachineRepresentation::kFloat64) {
    342     // float64 -> tagged
    343     op = simplified()->ChangeFloat64ToTaggedPointer();
    344   } else if (CanBeTaggedSigned(output_rep) &&
    345              use_info.type_check() == TypeCheckKind::kHeapObject) {
    346     if (!output_type->Maybe(Type::SignedSmall())) {
    347       return node;
    348     }
    349     // TODO(turbofan): Consider adding a Bailout operator that just deopts
    350     // for TaggedSigned output representation.
    351     op = simplified()->CheckedTaggedToTaggedPointer();
    352   } else {
    353     return TypeError(node, output_rep, output_type,
    354                      MachineRepresentation::kTaggedPointer);
    355   }
    356   return InsertConversion(node, op, use_node);
    357 }
    358 
    359 Node* RepresentationChanger::GetTaggedRepresentationFor(
    360     Node* node, MachineRepresentation output_rep, Type* output_type,
    361     Truncation truncation) {
    362   // Eagerly fold representation changes for constants.
    363   switch (node->opcode()) {
    364     case IrOpcode::kNumberConstant:
    365     case IrOpcode::kHeapConstant:
    366       return node;  // No change necessary.
    367     case IrOpcode::kInt32Constant:
    368     case IrOpcode::kFloat64Constant:
    369     case IrOpcode::kFloat32Constant:
    370       UNREACHABLE();
    371       break;
    372     default:
    373       break;
    374   }
    375   if (output_rep == MachineRepresentation::kTaggedSigned ||
    376       output_rep == MachineRepresentation::kTaggedPointer) {
    377     // this is a no-op.
    378     return node;
    379   }
    380   // Select the correct X -> Tagged operator.
    381   const Operator* op;
    382   if (output_type->Is(Type::None())) {
    383     // This is an impossible value; it should not be used at runtime.
    384     // We just provide a dummy value here.
    385     return jsgraph()->TheHoleConstant();
    386   } else if (output_rep == MachineRepresentation::kBit) {
    387     if (output_type->Is(Type::Boolean())) {
    388       op = simplified()->ChangeBitToTagged();
    389     } else {
    390       return TypeError(node, output_rep, output_type,
    391                        MachineRepresentation::kTagged);
    392     }
    393   } else if (IsWord(output_rep)) {
    394     if (output_type->Is(Type::Signed31())) {
    395       op = simplified()->ChangeInt31ToTaggedSigned();
    396     } else if (output_type->Is(Type::Signed32())) {
    397       op = simplified()->ChangeInt32ToTagged();
    398     } else if (output_type->Is(Type::Unsigned32()) ||
    399                truncation.IsUsedAsWord32()) {
    400       // Either the output is uint32 or the uses only care about the
    401       // low 32 bits (so we can pick uint32 safely).
    402       op = simplified()->ChangeUint32ToTagged();
    403     } else {
    404       return TypeError(node, output_rep, output_type,
    405                        MachineRepresentation::kTagged);
    406     }
    407   } else if (output_rep ==
    408              MachineRepresentation::kFloat32) {  // float32 -> float64 -> tagged
    409     node = InsertChangeFloat32ToFloat64(node);
    410     op = simplified()->ChangeFloat64ToTagged();
    411   } else if (output_rep == MachineRepresentation::kFloat64) {
    412     if (output_type->Is(Type::Signed31())) {  // float64 -> int32 -> tagged
    413       node = InsertChangeFloat64ToInt32(node);
    414       op = simplified()->ChangeInt31ToTaggedSigned();
    415     } else if (output_type->Is(
    416                    Type::Signed32())) {  // float64 -> int32 -> tagged
    417       node = InsertChangeFloat64ToInt32(node);
    418       op = simplified()->ChangeInt32ToTagged();
    419     } else if (output_type->Is(
    420                    Type::Unsigned32())) {  // float64 -> uint32 -> tagged
    421       node = InsertChangeFloat64ToUint32(node);
    422       op = simplified()->ChangeUint32ToTagged();
    423     } else {
    424       op = simplified()->ChangeFloat64ToTagged();
    425     }
    426   } else {
    427     return TypeError(node, output_rep, output_type,
    428                      MachineRepresentation::kTagged);
    429   }
    430   return jsgraph()->graph()->NewNode(op, node);
    431 }
    432 
    433 
    434 Node* RepresentationChanger::GetFloat32RepresentationFor(
    435     Node* node, MachineRepresentation output_rep, Type* output_type,
    436     Truncation truncation) {
    437   // Eagerly fold representation changes for constants.
    438   switch (node->opcode()) {
    439     case IrOpcode::kNumberConstant:
    440       return jsgraph()->Float32Constant(
    441           DoubleToFloat32(OpParameter<double>(node)));
    442     case IrOpcode::kInt32Constant:
    443     case IrOpcode::kFloat64Constant:
    444     case IrOpcode::kFloat32Constant:
    445       UNREACHABLE();
    446       break;
    447     default:
    448       break;
    449   }
    450   // Select the correct X -> Float32 operator.
    451   const Operator* op = nullptr;
    452   if (output_type->Is(Type::None())) {
    453     // This is an impossible value; it should not be used at runtime.
    454     // We just provide a dummy value here.
    455     return jsgraph()->Float32Constant(0.0f);
    456   } else if (IsWord(output_rep)) {
    457     if (output_type->Is(Type::Signed32())) {
    458       // int32 -> float64 -> float32
    459       op = machine()->ChangeInt32ToFloat64();
    460       node = jsgraph()->graph()->NewNode(op, node);
    461       op = machine()->TruncateFloat64ToFloat32();
    462     } else if (output_type->Is(Type::Unsigned32()) ||
    463                truncation.IsUsedAsWord32()) {
    464       // Either the output is uint32 or the uses only care about the
    465       // low 32 bits (so we can pick uint32 safely).
    466 
    467       // uint32 -> float64 -> float32
    468       op = machine()->ChangeUint32ToFloat64();
    469       node = jsgraph()->graph()->NewNode(op, node);
    470       op = machine()->TruncateFloat64ToFloat32();
    471     }
    472   } else if (output_rep == MachineRepresentation::kTagged ||
    473              output_rep == MachineRepresentation::kTaggedPointer) {
    474     if (output_type->Is(Type::NumberOrOddball())) {
    475       // tagged -> float64 -> float32
    476       if (output_type->Is(Type::Number())) {
    477         op = simplified()->ChangeTaggedToFloat64();
    478       } else {
    479         op = simplified()->TruncateTaggedToFloat64();
    480       }
    481       node = jsgraph()->graph()->NewNode(op, node);
    482       op = machine()->TruncateFloat64ToFloat32();
    483     }
    484   } else if (output_rep == MachineRepresentation::kFloat64) {
    485     op = machine()->TruncateFloat64ToFloat32();
    486   }
    487   if (op == nullptr) {
    488     return TypeError(node, output_rep, output_type,
    489                      MachineRepresentation::kFloat32);
    490   }
    491   return jsgraph()->graph()->NewNode(op, node);
    492 }
    493 
    494 Node* RepresentationChanger::GetFloat64RepresentationFor(
    495     Node* node, MachineRepresentation output_rep, Type* output_type,
    496     Node* use_node, UseInfo use_info) {
    497   // Eagerly fold representation changes for constants.
    498   if ((use_info.type_check() == TypeCheckKind::kNone)) {
    499     // TODO(jarin) Handle checked constant conversions.
    500     switch (node->opcode()) {
    501       case IrOpcode::kNumberConstant:
    502         return jsgraph()->Float64Constant(OpParameter<double>(node));
    503       case IrOpcode::kInt32Constant:
    504       case IrOpcode::kFloat64Constant:
    505       case IrOpcode::kFloat32Constant:
    506         UNREACHABLE();
    507         break;
    508       default:
    509         break;
    510     }
    511   }
    512   // Select the correct X -> Float64 operator.
    513   const Operator* op = nullptr;
    514   if (output_type->Is(Type::None())) {
    515     // This is an impossible value; it should not be used at runtime.
    516     // We just provide a dummy value here.
    517     return jsgraph()->Float64Constant(0.0);
    518   } else if (IsWord(output_rep)) {
    519     if (output_type->Is(Type::Signed32())) {
    520       op = machine()->ChangeInt32ToFloat64();
    521     } else if (output_type->Is(Type::Unsigned32()) ||
    522                use_info.truncation().IsUsedAsWord32()) {
    523       // Either the output is uint32 or the uses only care about the
    524       // low 32 bits (so we can pick uint32 safely).
    525       op = machine()->ChangeUint32ToFloat64();
    526     }
    527   } else if (output_rep == MachineRepresentation::kBit) {
    528     op = machine()->ChangeUint32ToFloat64();
    529   } else if (output_rep == MachineRepresentation::kTagged ||
    530              output_rep == MachineRepresentation::kTaggedSigned ||
    531              output_rep == MachineRepresentation::kTaggedPointer) {
    532     if (output_type->Is(Type::Undefined())) {
    533       return jsgraph()->Float64Constant(
    534           std::numeric_limits<double>::quiet_NaN());
    535 
    536     } else if (output_rep == MachineRepresentation::kTaggedSigned) {
    537       node = InsertChangeTaggedSignedToInt32(node);
    538       op = machine()->ChangeInt32ToFloat64();
    539     } else if (output_type->Is(Type::Number())) {
    540       op = simplified()->ChangeTaggedToFloat64();
    541     } else if (output_type->Is(Type::NumberOrOddball())) {
    542       // TODO(jarin) Here we should check that truncation is Number.
    543       op = simplified()->TruncateTaggedToFloat64();
    544     } else if (use_info.type_check() == TypeCheckKind::kNumber ||
    545                (use_info.type_check() == TypeCheckKind::kNumberOrOddball &&
    546                 !output_type->Maybe(Type::BooleanOrNullOrNumber()))) {
    547       op = simplified()->CheckedTaggedToFloat64(CheckTaggedInputMode::kNumber);
    548     } else if (use_info.type_check() == TypeCheckKind::kNumberOrOddball) {
    549       op = simplified()->CheckedTaggedToFloat64(
    550           CheckTaggedInputMode::kNumberOrOddball);
    551     }
    552   } else if (output_rep == MachineRepresentation::kFloat32) {
    553     op = machine()->ChangeFloat32ToFloat64();
    554   }
    555   if (op == nullptr) {
    556     return TypeError(node, output_rep, output_type,
    557                      MachineRepresentation::kFloat64);
    558   }
    559   return InsertConversion(node, op, use_node);
    560 }
    561 
    562 Node* RepresentationChanger::MakeTruncatedInt32Constant(double value) {
    563   return jsgraph()->Int32Constant(DoubleToInt32(value));
    564 }
    565 
    566 Node* RepresentationChanger::GetWord32RepresentationFor(
    567     Node* node, MachineRepresentation output_rep, Type* output_type,
    568     Node* use_node, UseInfo use_info) {
    569   // Eagerly fold representation changes for constants.
    570   switch (node->opcode()) {
    571     case IrOpcode::kInt32Constant:
    572     case IrOpcode::kFloat32Constant:
    573     case IrOpcode::kFloat64Constant:
    574       UNREACHABLE();
    575       break;
    576     case IrOpcode::kNumberConstant: {
    577       double const fv = OpParameter<double>(node);
    578       if (use_info.type_check() == TypeCheckKind::kNone ||
    579           ((use_info.type_check() == TypeCheckKind::kSignedSmall ||
    580             use_info.type_check() == TypeCheckKind::kSigned32) &&
    581            IsInt32Double(fv))) {
    582         return MakeTruncatedInt32Constant(fv);
    583       }
    584       break;
    585     }
    586     default:
    587       break;
    588   }
    589 
    590   // Select the correct X -> Word32 operator.
    591   const Operator* op = nullptr;
    592   if (output_type->Is(Type::None())) {
    593     // This is an impossible value; it should not be used at runtime.
    594     // We just provide a dummy value here.
    595     return jsgraph()->Int32Constant(0);
    596   } else if (output_rep == MachineRepresentation::kBit) {
    597     return node;  // Sloppy comparison -> word32
    598   } else if (output_rep == MachineRepresentation::kFloat64) {
    599     if (output_type->Is(Type::Signed32())) {
    600       op = machine()->ChangeFloat64ToInt32();
    601     } else if (use_info.type_check() == TypeCheckKind::kSignedSmall ||
    602                use_info.type_check() == TypeCheckKind::kSigned32) {
    603       op = simplified()->CheckedFloat64ToInt32(
    604           output_type->Maybe(Type::MinusZero())
    605               ? use_info.minus_zero_check()
    606               : CheckForMinusZeroMode::kDontCheckForMinusZero);
    607     } else if (output_type->Is(Type::Unsigned32())) {
    608       op = machine()->ChangeFloat64ToUint32();
    609     } else if (use_info.truncation().IsUsedAsWord32()) {
    610       op = machine()->TruncateFloat64ToWord32();
    611     }
    612   } else if (output_rep == MachineRepresentation::kFloat32) {
    613     node = InsertChangeFloat32ToFloat64(node);  // float32 -> float64 -> int32
    614     if (output_type->Is(Type::Signed32())) {
    615       op = machine()->ChangeFloat64ToInt32();
    616     } else if (use_info.type_check() == TypeCheckKind::kSignedSmall ||
    617                use_info.type_check() == TypeCheckKind::kSigned32) {
    618       op = simplified()->CheckedFloat64ToInt32(
    619           output_type->Maybe(Type::MinusZero())
    620               ? CheckForMinusZeroMode::kCheckForMinusZero
    621               : CheckForMinusZeroMode::kDontCheckForMinusZero);
    622     } else if (output_type->Is(Type::Unsigned32())) {
    623       op = machine()->ChangeFloat64ToUint32();
    624     } else if (use_info.truncation().IsUsedAsWord32()) {
    625       op = machine()->TruncateFloat64ToWord32();
    626     }
    627   } else if (output_rep == MachineRepresentation::kTaggedSigned) {
    628     if (output_type->Is(Type::Signed32())) {
    629       op = simplified()->ChangeTaggedSignedToInt32();
    630     } else if (use_info.truncation().IsUsedAsWord32()) {
    631       if (use_info.type_check() != TypeCheckKind::kNone) {
    632         op = simplified()->CheckedTruncateTaggedToWord32();
    633       } else {
    634         op = simplified()->TruncateTaggedToWord32();
    635       }
    636     }
    637   } else if (output_rep == MachineRepresentation::kTagged ||
    638              output_rep == MachineRepresentation::kTaggedPointer) {
    639     if (output_type->Is(Type::Signed32())) {
    640       op = simplified()->ChangeTaggedToInt32();
    641     } else if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
    642       op = simplified()->CheckedTaggedSignedToInt32();
    643     } else if (use_info.type_check() == TypeCheckKind::kSigned32) {
    644       op = simplified()->CheckedTaggedToInt32(
    645           output_type->Maybe(Type::MinusZero())
    646               ? CheckForMinusZeroMode::kCheckForMinusZero
    647               : CheckForMinusZeroMode::kDontCheckForMinusZero);
    648     } else if (output_type->Is(Type::Unsigned32())) {
    649       op = simplified()->ChangeTaggedToUint32();
    650     } else if (use_info.truncation().IsUsedAsWord32()) {
    651       if (output_type->Is(Type::NumberOrOddball())) {
    652         op = simplified()->TruncateTaggedToWord32();
    653       } else if (use_info.type_check() != TypeCheckKind::kNone) {
    654         op = simplified()->CheckedTruncateTaggedToWord32();
    655       }
    656     }
    657   } else if (output_rep == MachineRepresentation::kWord32) {
    658     // Only the checked case should get here, the non-checked case is
    659     // handled in GetRepresentationFor.
    660     if (use_info.type_check() == TypeCheckKind::kSignedSmall ||
    661         use_info.type_check() == TypeCheckKind::kSigned32) {
    662       if (output_type->Is(Type::Signed32())) {
    663         return node;
    664       } else if (output_type->Is(Type::Unsigned32())) {
    665         op = simplified()->CheckedUint32ToInt32();
    666       }
    667     } else {
    668       DCHECK_EQ(TypeCheckKind::kNumberOrOddball, use_info.type_check());
    669       return node;
    670     }
    671   } else if (output_rep == MachineRepresentation::kWord8 ||
    672              output_rep == MachineRepresentation::kWord16) {
    673     DCHECK(use_info.representation() == MachineRepresentation::kWord32);
    674     DCHECK(use_info.type_check() == TypeCheckKind::kSignedSmall ||
    675            use_info.type_check() == TypeCheckKind::kSigned32);
    676     return node;
    677   }
    678 
    679   if (op == nullptr) {
    680     return TypeError(node, output_rep, output_type,
    681                      MachineRepresentation::kWord32);
    682   }
    683   return InsertConversion(node, op, use_node);
    684 }
    685 
    686 Node* RepresentationChanger::InsertConversion(Node* node, const Operator* op,
    687                                               Node* use_node) {
    688   if (op->ControlInputCount() > 0) {
    689     // If the operator can deoptimize (which means it has control
    690     // input), we need to connect it to the effect and control chains.
    691     Node* effect = NodeProperties::GetEffectInput(use_node);
    692     Node* control = NodeProperties::GetControlInput(use_node);
    693     Node* conversion = jsgraph()->graph()->NewNode(op, node, effect, control);
    694     NodeProperties::ReplaceEffectInput(use_node, conversion);
    695     return conversion;
    696   }
    697   return jsgraph()->graph()->NewNode(op, node);
    698 }
    699 
    700 
    701 Node* RepresentationChanger::GetBitRepresentationFor(
    702     Node* node, MachineRepresentation output_rep, Type* output_type) {
    703   // Eagerly fold representation changes for constants.
    704   switch (node->opcode()) {
    705     case IrOpcode::kHeapConstant: {
    706       HeapObjectMatcher m(node);
    707       if (m.Is(factory()->false_value())) {
    708         return jsgraph()->Int32Constant(0);
    709       } else if (m.Is(factory()->true_value())) {
    710         return jsgraph()->Int32Constant(1);
    711       }
    712     }
    713     default:
    714       break;
    715   }
    716   // Select the correct X -> Bit operator.
    717   const Operator* op;
    718   if (output_type->Is(Type::None())) {
    719     // This is an impossible value; it should not be used at runtime.
    720     // We just provide a dummy value here.
    721     return jsgraph()->Int32Constant(0);
    722   } else if (output_rep == MachineRepresentation::kTagged ||
    723              output_rep == MachineRepresentation::kTaggedPointer) {
    724     if (output_type->Is(Type::BooleanOrNullOrUndefined())) {
    725       // true is the only trueish Oddball.
    726       op = simplified()->ChangeTaggedToBit();
    727     } else {
    728       op = simplified()->TruncateTaggedToBit();
    729     }
    730   } else if (output_rep == MachineRepresentation::kTaggedSigned) {
    731     node = jsgraph()->graph()->NewNode(machine()->WordEqual(), node,
    732                                        jsgraph()->IntPtrConstant(0));
    733     return jsgraph()->graph()->NewNode(machine()->Word32Equal(), node,
    734                                        jsgraph()->Int32Constant(0));
    735   } else if (IsWord(output_rep)) {
    736     node = jsgraph()->graph()->NewNode(machine()->Word32Equal(), node,
    737                                        jsgraph()->Int32Constant(0));
    738     return jsgraph()->graph()->NewNode(machine()->Word32Equal(), node,
    739                                        jsgraph()->Int32Constant(0));
    740   } else if (output_rep == MachineRepresentation::kFloat32) {
    741     node = jsgraph()->graph()->NewNode(machine()->Float32Abs(), node);
    742     return jsgraph()->graph()->NewNode(machine()->Float32LessThan(),
    743                                        jsgraph()->Float32Constant(0.0), node);
    744   } else if (output_rep == MachineRepresentation::kFloat64) {
    745     node = jsgraph()->graph()->NewNode(machine()->Float64Abs(), node);
    746     return jsgraph()->graph()->NewNode(machine()->Float64LessThan(),
    747                                        jsgraph()->Float64Constant(0.0), node);
    748   } else {
    749     return TypeError(node, output_rep, output_type,
    750                      MachineRepresentation::kBit);
    751   }
    752   return jsgraph()->graph()->NewNode(op, node);
    753 }
    754 
    755 Node* RepresentationChanger::GetWord64RepresentationFor(
    756     Node* node, MachineRepresentation output_rep, Type* output_type) {
    757   if (output_type->Is(Type::None())) {
    758     // This is an impossible value; it should not be used at runtime.
    759     // We just provide a dummy value here.
    760     return jsgraph()->Int64Constant(0);
    761   } else if (output_rep == MachineRepresentation::kBit) {
    762     return node;  // Sloppy comparison -> word64
    763   }
    764   // Can't really convert Word64 to anything else. Purported to be internal.
    765   return TypeError(node, output_rep, output_type,
    766                    MachineRepresentation::kWord64);
    767 }
    768 
    769 const Operator* RepresentationChanger::Int32OperatorFor(
    770     IrOpcode::Value opcode) {
    771   switch (opcode) {
    772     case IrOpcode::kSpeculativeNumberAdd:  // Fall through.
    773     case IrOpcode::kNumberAdd:
    774       return machine()->Int32Add();
    775     case IrOpcode::kSpeculativeNumberSubtract:  // Fall through.
    776     case IrOpcode::kNumberSubtract:
    777       return machine()->Int32Sub();
    778     case IrOpcode::kSpeculativeNumberMultiply:
    779     case IrOpcode::kNumberMultiply:
    780       return machine()->Int32Mul();
    781     case IrOpcode::kSpeculativeNumberDivide:
    782     case IrOpcode::kNumberDivide:
    783       return machine()->Int32Div();
    784     case IrOpcode::kSpeculativeNumberModulus:
    785     case IrOpcode::kNumberModulus:
    786       return machine()->Int32Mod();
    787     case IrOpcode::kSpeculativeNumberBitwiseOr:  // Fall through.
    788     case IrOpcode::kNumberBitwiseOr:
    789       return machine()->Word32Or();
    790     case IrOpcode::kSpeculativeNumberBitwiseXor:  // Fall through.
    791     case IrOpcode::kNumberBitwiseXor:
    792       return machine()->Word32Xor();
    793     case IrOpcode::kSpeculativeNumberBitwiseAnd:  // Fall through.
    794     case IrOpcode::kNumberBitwiseAnd:
    795       return machine()->Word32And();
    796     case IrOpcode::kNumberEqual:
    797     case IrOpcode::kSpeculativeNumberEqual:
    798       return machine()->Word32Equal();
    799     case IrOpcode::kNumberLessThan:
    800     case IrOpcode::kSpeculativeNumberLessThan:
    801       return machine()->Int32LessThan();
    802     case IrOpcode::kNumberLessThanOrEqual:
    803     case IrOpcode::kSpeculativeNumberLessThanOrEqual:
    804       return machine()->Int32LessThanOrEqual();
    805     default:
    806       UNREACHABLE();
    807       return nullptr;
    808   }
    809 }
    810 
    811 const Operator* RepresentationChanger::Int32OverflowOperatorFor(
    812     IrOpcode::Value opcode) {
    813   switch (opcode) {
    814     case IrOpcode::kSpeculativeNumberAdd:
    815       return simplified()->CheckedInt32Add();
    816     case IrOpcode::kSpeculativeNumberSubtract:
    817       return simplified()->CheckedInt32Sub();
    818     case IrOpcode::kSpeculativeNumberDivide:
    819       return simplified()->CheckedInt32Div();
    820     case IrOpcode::kSpeculativeNumberModulus:
    821       return simplified()->CheckedInt32Mod();
    822     default:
    823       UNREACHABLE();
    824       return nullptr;
    825   }
    826 }
    827 
    828 const Operator* RepresentationChanger::TaggedSignedOperatorFor(
    829     IrOpcode::Value opcode) {
    830   switch (opcode) {
    831     case IrOpcode::kSpeculativeNumberLessThan:
    832       return machine()->Is32() ? machine()->Int32LessThan()
    833                                : machine()->Int64LessThan();
    834     case IrOpcode::kSpeculativeNumberLessThanOrEqual:
    835       return machine()->Is32() ? machine()->Int32LessThanOrEqual()
    836                                : machine()->Int64LessThanOrEqual();
    837     case IrOpcode::kSpeculativeNumberEqual:
    838       return machine()->Is32() ? machine()->Word32Equal()
    839                                : machine()->Word64Equal();
    840     default:
    841       UNREACHABLE();
    842       return nullptr;
    843   }
    844 }
    845 
    846 const Operator* RepresentationChanger::Uint32OperatorFor(
    847     IrOpcode::Value opcode) {
    848   switch (opcode) {
    849     case IrOpcode::kNumberAdd:
    850       return machine()->Int32Add();
    851     case IrOpcode::kNumberSubtract:
    852       return machine()->Int32Sub();
    853     case IrOpcode::kSpeculativeNumberMultiply:
    854     case IrOpcode::kNumberMultiply:
    855       return machine()->Int32Mul();
    856     case IrOpcode::kSpeculativeNumberDivide:
    857     case IrOpcode::kNumberDivide:
    858       return machine()->Uint32Div();
    859     case IrOpcode::kSpeculativeNumberModulus:
    860     case IrOpcode::kNumberModulus:
    861       return machine()->Uint32Mod();
    862     case IrOpcode::kNumberEqual:
    863     case IrOpcode::kSpeculativeNumberEqual:
    864       return machine()->Word32Equal();
    865     case IrOpcode::kNumberLessThan:
    866     case IrOpcode::kSpeculativeNumberLessThan:
    867       return machine()->Uint32LessThan();
    868     case IrOpcode::kNumberLessThanOrEqual:
    869     case IrOpcode::kSpeculativeNumberLessThanOrEqual:
    870       return machine()->Uint32LessThanOrEqual();
    871     case IrOpcode::kNumberClz32:
    872       return machine()->Word32Clz();
    873     case IrOpcode::kNumberImul:
    874       return machine()->Int32Mul();
    875     default:
    876       UNREACHABLE();
    877       return nullptr;
    878   }
    879 }
    880 
    881 const Operator* RepresentationChanger::Uint32OverflowOperatorFor(
    882     IrOpcode::Value opcode) {
    883   switch (opcode) {
    884     case IrOpcode::kSpeculativeNumberDivide:
    885       return simplified()->CheckedUint32Div();
    886     case IrOpcode::kSpeculativeNumberModulus:
    887       return simplified()->CheckedUint32Mod();
    888     default:
    889       UNREACHABLE();
    890       return nullptr;
    891   }
    892 }
    893 
    894 const Operator* RepresentationChanger::Float64OperatorFor(
    895     IrOpcode::Value opcode) {
    896   switch (opcode) {
    897     case IrOpcode::kSpeculativeNumberAdd:
    898     case IrOpcode::kNumberAdd:
    899       return machine()->Float64Add();
    900     case IrOpcode::kSpeculativeNumberSubtract:
    901     case IrOpcode::kNumberSubtract:
    902       return machine()->Float64Sub();
    903     case IrOpcode::kSpeculativeNumberMultiply:
    904     case IrOpcode::kNumberMultiply:
    905       return machine()->Float64Mul();
    906     case IrOpcode::kSpeculativeNumberDivide:
    907     case IrOpcode::kNumberDivide:
    908       return machine()->Float64Div();
    909     case IrOpcode::kSpeculativeNumberModulus:
    910     case IrOpcode::kNumberModulus:
    911       return machine()->Float64Mod();
    912     case IrOpcode::kNumberEqual:
    913     case IrOpcode::kSpeculativeNumberEqual:
    914       return machine()->Float64Equal();
    915     case IrOpcode::kNumberLessThan:
    916     case IrOpcode::kSpeculativeNumberLessThan:
    917       return machine()->Float64LessThan();
    918     case IrOpcode::kNumberLessThanOrEqual:
    919     case IrOpcode::kSpeculativeNumberLessThanOrEqual:
    920       return machine()->Float64LessThanOrEqual();
    921     case IrOpcode::kNumberAbs:
    922       return machine()->Float64Abs();
    923     case IrOpcode::kNumberAcos:
    924       return machine()->Float64Acos();
    925     case IrOpcode::kNumberAcosh:
    926       return machine()->Float64Acosh();
    927     case IrOpcode::kNumberAsin:
    928       return machine()->Float64Asin();
    929     case IrOpcode::kNumberAsinh:
    930       return machine()->Float64Asinh();
    931     case IrOpcode::kNumberAtan:
    932       return machine()->Float64Atan();
    933     case IrOpcode::kNumberAtanh:
    934       return machine()->Float64Atanh();
    935     case IrOpcode::kNumberAtan2:
    936       return machine()->Float64Atan2();
    937     case IrOpcode::kNumberCbrt:
    938       return machine()->Float64Cbrt();
    939     case IrOpcode::kNumberCeil:
    940       return machine()->Float64RoundUp().placeholder();
    941     case IrOpcode::kNumberCos:
    942       return machine()->Float64Cos();
    943     case IrOpcode::kNumberCosh:
    944       return machine()->Float64Cosh();
    945     case IrOpcode::kNumberExp:
    946       return machine()->Float64Exp();
    947     case IrOpcode::kNumberExpm1:
    948       return machine()->Float64Expm1();
    949     case IrOpcode::kNumberFloor:
    950       return machine()->Float64RoundDown().placeholder();
    951     case IrOpcode::kNumberFround:
    952       return machine()->TruncateFloat64ToFloat32();
    953     case IrOpcode::kNumberLog:
    954       return machine()->Float64Log();
    955     case IrOpcode::kNumberLog1p:
    956       return machine()->Float64Log1p();
    957     case IrOpcode::kNumberLog2:
    958       return machine()->Float64Log2();
    959     case IrOpcode::kNumberLog10:
    960       return machine()->Float64Log10();
    961     case IrOpcode::kNumberMax:
    962       return machine()->Float64Max();
    963     case IrOpcode::kNumberMin:
    964       return machine()->Float64Min();
    965     case IrOpcode::kNumberPow:
    966       return machine()->Float64Pow();
    967     case IrOpcode::kNumberSin:
    968       return machine()->Float64Sin();
    969     case IrOpcode::kNumberSinh:
    970       return machine()->Float64Sinh();
    971     case IrOpcode::kNumberSqrt:
    972       return machine()->Float64Sqrt();
    973     case IrOpcode::kNumberTan:
    974       return machine()->Float64Tan();
    975     case IrOpcode::kNumberTanh:
    976       return machine()->Float64Tanh();
    977     case IrOpcode::kNumberTrunc:
    978       return machine()->Float64RoundTruncate().placeholder();
    979     case IrOpcode::kNumberSilenceNaN:
    980       return machine()->Float64SilenceNaN();
    981     default:
    982       UNREACHABLE();
    983       return nullptr;
    984   }
    985 }
    986 
    987 
    988 Node* RepresentationChanger::TypeError(Node* node,
    989                                        MachineRepresentation output_rep,
    990                                        Type* output_type,
    991                                        MachineRepresentation use) {
    992   type_error_ = true;
    993   if (!testing_type_errors_) {
    994     std::ostringstream out_str;
    995     out_str << output_rep << " (";
    996     output_type->PrintTo(out_str);
    997     out_str << ")";
    998 
    999     std::ostringstream use_str;
   1000     use_str << use;
   1001 
   1002     V8_Fatal(__FILE__, __LINE__,
   1003              "RepresentationChangerError: node #%d:%s of "
   1004              "%s cannot be changed to %s",
   1005              node->id(), node->op()->mnemonic(), out_str.str().c_str(),
   1006              use_str.str().c_str());
   1007   }
   1008   return node;
   1009 }
   1010 
   1011 Node* RepresentationChanger::InsertChangeBitToTagged(Node* node) {
   1012   return jsgraph()->graph()->NewNode(simplified()->ChangeBitToTagged(), node);
   1013 }
   1014 
   1015 Node* RepresentationChanger::InsertChangeFloat32ToFloat64(Node* node) {
   1016   return jsgraph()->graph()->NewNode(machine()->ChangeFloat32ToFloat64(), node);
   1017 }
   1018 
   1019 Node* RepresentationChanger::InsertChangeFloat64ToUint32(Node* node) {
   1020   return jsgraph()->graph()->NewNode(machine()->ChangeFloat64ToUint32(), node);
   1021 }
   1022 
   1023 Node* RepresentationChanger::InsertChangeFloat64ToInt32(Node* node) {
   1024   return jsgraph()->graph()->NewNode(machine()->ChangeFloat64ToInt32(), node);
   1025 }
   1026 
   1027 Node* RepresentationChanger::InsertChangeInt32ToFloat64(Node* node) {
   1028   return jsgraph()->graph()->NewNode(machine()->ChangeInt32ToFloat64(), node);
   1029 }
   1030 
   1031 Node* RepresentationChanger::InsertChangeTaggedSignedToInt32(Node* node) {
   1032   return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedSignedToInt32(),
   1033                                      node);
   1034 }
   1035 
   1036 Node* RepresentationChanger::InsertChangeTaggedToFloat64(Node* node) {
   1037   return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedToFloat64(),
   1038                                      node);
   1039 }
   1040 
   1041 Node* RepresentationChanger::InsertChangeUint32ToFloat64(Node* node) {
   1042   return jsgraph()->graph()->NewNode(machine()->ChangeUint32ToFloat64(), node);
   1043 }
   1044 
   1045 }  // namespace compiler
   1046 }  // namespace internal
   1047 }  // namespace v8
   1048