representation-change.cc 43 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/compiler/representation-change.h"

#include <sstream>

#include "src/base/bits.h"
#include "src/code-factory.h"
#include "src/compiler/machine-operator.h"
12
#include "src/compiler/node-matchers.h"
13
#include "src/factory-inl.h"
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29

namespace v8 {
namespace internal {
namespace compiler {

const char* Truncation::description() const {
  switch (kind()) {
    case TruncationKind::kNone:
      return "no-value-use";
    case TruncationKind::kBool:
      return "truncate-to-bool";
    case TruncationKind::kWord32:
      return "truncate-to-word32";
    case TruncationKind::kWord64:
      return "truncate-to-word64";
    case TruncationKind::kFloat64:
30 31 32 33 34 35
      switch (identify_zeros()) {
        case kIdentifyZeros:
          return "truncate-to-float64 (identify zeros)";
        case kDistinguishZeros:
          return "truncate-to-float64 (distinguish zeros)";
      }
36
    case TruncationKind::kAny:
37 38 39 40 41 42
      switch (identify_zeros()) {
        case kIdentifyZeros:
          return "no-truncation (but identify zeros)";
        case kDistinguishZeros:
          return "no-truncation (but distinguish zeros)";
      }
43 44 45 46 47 48 49
  }
  UNREACHABLE();
}


// Partial order for truncations:
//
50 51 52 53
//  kWord64       kAny <-------+
//     ^            ^          |
//     \            |          |
//      \         kFloat64     |
54 55 56 57 58 59 60 61 62
//       \        ^            |
//        \       /            |
//         kWord32           kBool
//               ^            ^
//               \            /
//                \          /
//                 \        /
//                  \      /
//                   \    /
63
//                   kNone
64 65
//
// TODO(jarin) We might consider making kBool < kFloat64.
66 67 68 69 70 71 72 73 74 75 76

// static
Truncation::TruncationKind Truncation::Generalize(TruncationKind rep1,
                                                  TruncationKind rep2) {
  if (LessGeneral(rep1, rep2)) return rep2;
  if (LessGeneral(rep2, rep1)) return rep1;
  // Handle the generalization of float64-representable values.
  if (LessGeneral(rep1, TruncationKind::kFloat64) &&
      LessGeneral(rep2, TruncationKind::kFloat64)) {
    return TruncationKind::kFloat64;
  }
77 78 79 80 81
  // Handle the generalization of any-representable values.
  if (LessGeneral(rep1, TruncationKind::kAny) &&
      LessGeneral(rep2, TruncationKind::kAny)) {
    return TruncationKind::kAny;
  }
82
  // All other combinations are illegal.
83
  FATAL("Tried to combine incompatible truncations");
84 85 86
  return TruncationKind::kNone;
}

87 88 89 90 91 92 93 94 95
// static
IdentifyZeros Truncation::GeneralizeIdentifyZeros(IdentifyZeros i1,
                                                  IdentifyZeros i2) {
  if (i1 == i2) {
    return i1;
  } else {
    return kDistinguishZeros;
  }
}
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117

// static
bool Truncation::LessGeneral(TruncationKind rep1, TruncationKind rep2) {
  switch (rep1) {
    case TruncationKind::kNone:
      return true;
    case TruncationKind::kBool:
      return rep2 == TruncationKind::kBool || rep2 == TruncationKind::kAny;
    case TruncationKind::kWord32:
      return rep2 == TruncationKind::kWord32 ||
             rep2 == TruncationKind::kWord64 ||
             rep2 == TruncationKind::kFloat64 || rep2 == TruncationKind::kAny;
    case TruncationKind::kWord64:
      return rep2 == TruncationKind::kWord64;
    case TruncationKind::kFloat64:
      return rep2 == TruncationKind::kFloat64 || rep2 == TruncationKind::kAny;
    case TruncationKind::kAny:
      return rep2 == TruncationKind::kAny;
  }
  UNREACHABLE();
}

118 119 120 121
// static
bool Truncation::LessGeneralIdentifyZeros(IdentifyZeros i1, IdentifyZeros i2) {
  return i1 == i2 || i1 == kIdentifyZeros;
}
122 123 124

namespace {

125 126 127 128
bool IsWord(MachineRepresentation rep) {
  return rep == MachineRepresentation::kWord8 ||
         rep == MachineRepresentation::kWord16 ||
         rep == MachineRepresentation::kWord32;
129 130 131 132
}

}  // namespace

133
// Changes representation from {output_rep} to {use_rep}. The {truncation}
134 135 136
// parameter is only used for sanity checking - if the changer cannot figure
// out signedness for the word32->float64 conversion, then we check that the
// uses truncate to word32 (so they do not care about signedness).
137 138
Node* RepresentationChanger::GetRepresentationFor(
    Node* node, MachineRepresentation output_rep, Type* output_type,
139
    Node* use_node, UseInfo use_info) {
140 141 142 143
  if (output_rep == MachineRepresentation::kNone &&
      output_type->IsInhabited()) {
    // The output representation should be set if the type is inhabited (i.e.,
    // if the value is possible).
144
    return TypeError(node, output_rep, output_type, use_info.representation());
145
  }
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160

  // Handle the no-op shortcuts when no checking is necessary.
  if (use_info.type_check() == TypeCheckKind::kNone ||
      output_rep != MachineRepresentation::kWord32) {
    if (use_info.representation() == output_rep) {
      // Representations are the same. That's a no-op.
      return node;
    }
    if (IsWord(use_info.representation()) && IsWord(output_rep)) {
      // Both are words less than or equal to 32-bits.
      // Since loads of integers from memory implicitly sign or zero extend the
      // value to the full machine word size and stores implicitly truncate,
      // no representation change is necessary.
      return node;
    }
161
  }
162 163

  switch (use_info.representation()) {
164
    case MachineRepresentation::kTaggedSigned:
165 166 167 168
      DCHECK(use_info.type_check() == TypeCheckKind::kNone ||
             use_info.type_check() == TypeCheckKind::kSignedSmall);
      return GetTaggedSignedRepresentationFor(node, output_rep, output_type,
                                              use_node, use_info);
169
    case MachineRepresentation::kTaggedPointer:
170 171 172 173
      DCHECK(use_info.type_check() == TypeCheckKind::kNone ||
             use_info.type_check() == TypeCheckKind::kHeapObject);
      return GetTaggedPointerRepresentationFor(node, output_rep, output_type,
                                               use_node, use_info);
174
    case MachineRepresentation::kTagged:
175
      DCHECK_EQ(TypeCheckKind::kNone, use_info.type_check());
176 177
      return GetTaggedRepresentationFor(node, output_rep, output_type,
                                        use_info.truncation());
178
    case MachineRepresentation::kFloat32:
179
      DCHECK_EQ(TypeCheckKind::kNone, use_info.type_check());
180
      return GetFloat32RepresentationFor(node, output_rep, output_type,
181
                                         use_info.truncation());
182
    case MachineRepresentation::kFloat64:
183
      return GetFloat64RepresentationFor(node, output_rep, output_type,
184
                                         use_node, use_info);
185
    case MachineRepresentation::kBit:
186
      DCHECK_EQ(TypeCheckKind::kNone, use_info.type_check());
187
      return GetBitRepresentationFor(node, output_rep, output_type);
188 189 190
    case MachineRepresentation::kWord8:
    case MachineRepresentation::kWord16:
    case MachineRepresentation::kWord32:
191 192
      return GetWord32RepresentationFor(node, output_rep, output_type, use_node,
                                        use_info);
193
    case MachineRepresentation::kWord64:
194
      DCHECK_EQ(TypeCheckKind::kNone, use_info.type_check());
195
      return GetWord64RepresentationFor(node, output_rep, output_type);
196
    case MachineRepresentation::kSimd128:
197
    case MachineRepresentation::kNone:
198
      return node;
199
  }
200
  UNREACHABLE();
201 202
}

203
Node* RepresentationChanger::GetTaggedSignedRepresentationFor(
204 205
    Node* node, MachineRepresentation output_rep, Type* output_type,
    Node* use_node, UseInfo use_info) {
206 207
  // Eagerly fold representation changes for constants.
  switch (node->opcode()) {
208
    case IrOpcode::kNumberConstant:
209
      if (output_type->Is(Type::SignedSmall())) {
210
        return node;
211
      }
212
      break;
213 214 215 216 217
    default:
      break;
  }
  // Select the correct X -> Tagged operator.
  const Operator* op;
218
  if (output_type->Is(Type::None())) {
219
    // This is an impossible value; it should not be used at runtime.
220 221
    // We just provide a dummy value here.
    return jsgraph()->Constant(0);
222 223 224
  } else if (IsWord(output_rep)) {
    if (output_type->Is(Type::Signed31())) {
      op = simplified()->ChangeInt31ToTaggedSigned();
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272
    } else if (output_type->Is(Type::Signed32())) {
      if (SmiValuesAre32Bits()) {
        op = simplified()->ChangeInt32ToTagged();
      } else if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
        op = simplified()->CheckedInt32ToTaggedSigned();
      } else {
        return TypeError(node, output_rep, output_type,
                         MachineRepresentation::kTaggedSigned);
      }
    } else if (output_type->Is(Type::Unsigned32()) &&
               use_info.type_check() == TypeCheckKind::kSignedSmall) {
      op = simplified()->CheckedUint32ToTaggedSigned();
    } else {
      return TypeError(node, output_rep, output_type,
                       MachineRepresentation::kTaggedSigned);
    }
  } else if (output_rep == MachineRepresentation::kFloat64) {
    if (output_type->Is(Type::Signed31())) {
      // float64 -> int32 -> tagged signed
      node = InsertChangeFloat64ToInt32(node);
      op = simplified()->ChangeInt31ToTaggedSigned();
    } else if (output_type->Is(Type::Signed32())) {
      // float64 -> int32 -> tagged signed
      node = InsertChangeFloat64ToInt32(node);
      if (SmiValuesAre32Bits()) {
        op = simplified()->ChangeInt32ToTagged();
      } else if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
        op = simplified()->CheckedInt32ToTaggedSigned();
      } else {
        return TypeError(node, output_rep, output_type,
                         MachineRepresentation::kTaggedSigned);
      }
    } else if (output_type->Is(Type::Unsigned32()) &&
               use_info.type_check() == TypeCheckKind::kSignedSmall) {
      // float64 -> uint32 -> tagged signed
      node = InsertChangeFloat64ToUint32(node);
      op = simplified()->CheckedUint32ToTaggedSigned();
    } else if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
      op = simplified()->CheckedFloat64ToInt32(
          output_type->Maybe(Type::MinusZero())
              ? CheckForMinusZeroMode::kCheckForMinusZero
              : CheckForMinusZeroMode::kDontCheckForMinusZero);
      node = InsertConversion(node, op, use_node);
      if (SmiValuesAre32Bits()) {
        op = simplified()->ChangeInt32ToTagged();
      } else {
        op = simplified()->CheckedInt32ToTaggedSigned();
      }
273 274 275 276
    } else {
      return TypeError(node, output_rep, output_type,
                       MachineRepresentation::kTaggedSigned);
    }
277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294
  } else if (output_rep == MachineRepresentation::kFloat32) {
    if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
      op = machine()->ChangeFloat32ToFloat64();
      node = InsertConversion(node, op, use_node);
      op = simplified()->CheckedFloat64ToInt32(
          output_type->Maybe(Type::MinusZero())
              ? CheckForMinusZeroMode::kCheckForMinusZero
              : CheckForMinusZeroMode::kDontCheckForMinusZero);
      node = InsertConversion(node, op, use_node);
      if (SmiValuesAre32Bits()) {
        op = simplified()->ChangeInt32ToTagged();
      } else {
        op = simplified()->CheckedInt32ToTaggedSigned();
      }
    } else {
      return TypeError(node, output_rep, output_type,
                       MachineRepresentation::kTaggedSigned);
    }
295 296 297 298 299 300 301 302 303
  } else if (CanBeTaggedPointer(output_rep)) {
    if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
      op = simplified()->CheckedTaggedToTaggedSigned();
    } else if (output_type->Is(Type::SignedSmall())) {
      op = simplified()->ChangeTaggedToTaggedSigned();
    } else {
      return TypeError(node, output_rep, output_type,
                       MachineRepresentation::kTaggedSigned);
    }
304 305 306 307 308 309 310 311 312 313
  } else if (output_rep == MachineRepresentation::kBit) {
    if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
      // TODO(turbofan): Consider adding a Bailout operator that just deopts.
      // Also use that for MachineRepresentation::kPointer case above.
      node = InsertChangeBitToTagged(node);
      op = simplified()->CheckedTaggedToTaggedSigned();
    } else {
      return TypeError(node, output_rep, output_type,
                       MachineRepresentation::kTaggedSigned);
    }
314 315 316 317
  } else {
    return TypeError(node, output_rep, output_type,
                     MachineRepresentation::kTaggedSigned);
  }
318
  return InsertConversion(node, op, use_node);
319 320 321
}

Node* RepresentationChanger::GetTaggedPointerRepresentationFor(
322 323
    Node* node, MachineRepresentation output_rep, Type* output_type,
    Node* use_node, UseInfo use_info) {
324 325 326 327 328 329 330
  // Eagerly fold representation changes for constants.
  switch (node->opcode()) {
    case IrOpcode::kHeapConstant:
      return node;  // No change necessary.
    case IrOpcode::kInt32Constant:
    case IrOpcode::kFloat64Constant:
    case IrOpcode::kFloat32Constant:
331
      UNREACHABLE();
332 333 334
    default:
      break;
  }
335 336
  // Select the correct X -> TaggedPointer operator.
  Operator const* op;
337
  if (output_type->Is(Type::None())) {
338
    // This is an impossible value; it should not be used at runtime.
339 340
    // We just provide a dummy value here.
    return jsgraph()->TheHoleConstant();
341
  } else if (output_rep == MachineRepresentation::kBit) {
342 343 344 345 346 347
    if (output_type->Is(Type::Boolean())) {
      op = simplified()->ChangeBitToTagged();
    } else {
      return TypeError(node, output_rep, output_type,
                       MachineRepresentation::kTagged);
    }
348 349 350 351 352 353 354 355 356 357 358 359 360
  } else if (IsWord(output_rep)) {
    if (output_type->Is(Type::Unsigned32())) {
      // uint32 -> float64 -> tagged
      node = InsertChangeUint32ToFloat64(node);
    } else if (output_type->Is(Type::Signed32())) {
      // int32 -> float64 -> tagged
      node = InsertChangeInt32ToFloat64(node);
    } else {
      return TypeError(node, output_rep, output_type,
                       MachineRepresentation::kTaggedPointer);
    }
    op = simplified()->ChangeFloat64ToTaggedPointer();
  } else if (output_rep == MachineRepresentation::kFloat32) {
361 362 363 364 365 366 367 368
    if (output_type->Is(Type::Number())) {
      // float32 -> float64 -> tagged
      node = InsertChangeFloat32ToFloat64(node);
      op = simplified()->ChangeFloat64ToTaggedPointer();
    } else {
      return TypeError(node, output_rep, output_type,
                       MachineRepresentation::kTaggedPointer);
    }
369
  } else if (output_rep == MachineRepresentation::kFloat64) {
370 371 372 373 374 375 376
    if (output_type->Is(Type::Number())) {
      // float64 -> tagged
      op = simplified()->ChangeFloat64ToTaggedPointer();
    } else {
      return TypeError(node, output_rep, output_type,
                       MachineRepresentation::kTaggedPointer);
    }
377 378 379 380 381 382 383 384 385 386 387
  } else if (CanBeTaggedSigned(output_rep) &&
             use_info.type_check() == TypeCheckKind::kHeapObject) {
    if (!output_type->Maybe(Type::SignedSmall())) {
      return node;
    }
    // TODO(turbofan): Consider adding a Bailout operator that just deopts
    // for TaggedSigned output representation.
    op = simplified()->CheckedTaggedToTaggedPointer();
  } else {
    return TypeError(node, output_rep, output_type,
                     MachineRepresentation::kTaggedPointer);
388
  }
389
  return InsertConversion(node, op, use_node);
390 391
}

392
Node* RepresentationChanger::GetTaggedRepresentationFor(
393 394
    Node* node, MachineRepresentation output_rep, Type* output_type,
    Truncation truncation) {
395 396 397 398 399 400 401 402
  // Eagerly fold representation changes for constants.
  switch (node->opcode()) {
    case IrOpcode::kNumberConstant:
    case IrOpcode::kHeapConstant:
      return node;  // No change necessary.
    case IrOpcode::kInt32Constant:
    case IrOpcode::kFloat64Constant:
    case IrOpcode::kFloat32Constant:
403 404
      UNREACHABLE();
      break;
405 406 407
    default:
      break;
  }
408 409 410 411 412
  if (output_rep == MachineRepresentation::kTaggedSigned ||
      output_rep == MachineRepresentation::kTaggedPointer) {
    // this is a no-op.
    return node;
  }
413 414
  // Select the correct X -> Tagged operator.
  const Operator* op;
415
  if (output_type->Is(Type::None())) {
416
    // This is an impossible value; it should not be used at runtime.
417 418
    // We just provide a dummy value here.
    return jsgraph()->TheHoleConstant();
419
  } else if (output_rep == MachineRepresentation::kBit) {
420 421 422 423 424 425
    if (output_type->Is(Type::Boolean())) {
      op = simplified()->ChangeBitToTagged();
    } else {
      return TypeError(node, output_rep, output_type,
                       MachineRepresentation::kTagged);
    }
426
  } else if (IsWord(output_rep)) {
427
    if (output_type->Is(Type::Signed31())) {
428
      op = simplified()->ChangeInt31ToTaggedSigned();
429
    } else if (output_type->Is(Type::Signed32())) {
430
      op = simplified()->ChangeInt32ToTagged();
431 432 433 434
    } else if (output_type->Is(Type::Unsigned32()) ||
               truncation.IsUsedAsWord32()) {
      // Either the output is uint32 or the uses only care about the
      // low 32 bits (so we can pick uint32 safely).
435
      op = simplified()->ChangeUint32ToTagged();
436
    } else {
437 438
      return TypeError(node, output_rep, output_type,
                       MachineRepresentation::kTagged);
439
    }
440
  } else if (output_rep ==
441
             MachineRepresentation::kFloat32) {  // float32 -> float64 -> tagged
442
    node = InsertChangeFloat32ToFloat64(node);
443 444 445 446
    op = simplified()->ChangeFloat64ToTagged(
        output_type->Maybe(Type::MinusZero())
            ? CheckForMinusZeroMode::kCheckForMinusZero
            : CheckForMinusZeroMode::kDontCheckForMinusZero);
447
  } else if (output_rep == MachineRepresentation::kFloat64) {
448 449
    if (output_type->Is(Type::Signed31())) {  // float64 -> int32 -> tagged
      node = InsertChangeFloat64ToInt32(node);
450
      op = simplified()->ChangeInt31ToTaggedSigned();
451 452 453 454 455 456 457 458
    } else if (output_type->Is(
                   Type::Signed32())) {  // float64 -> int32 -> tagged
      node = InsertChangeFloat64ToInt32(node);
      op = simplified()->ChangeInt32ToTagged();
    } else if (output_type->Is(
                   Type::Unsigned32())) {  // float64 -> uint32 -> tagged
      node = InsertChangeFloat64ToUint32(node);
      op = simplified()->ChangeUint32ToTagged();
459
    } else if (output_type->Is(Type::Number())) {
460 461 462 463
      op = simplified()->ChangeFloat64ToTagged(
          output_type->Maybe(Type::MinusZero())
              ? CheckForMinusZeroMode::kCheckForMinusZero
              : CheckForMinusZeroMode::kDontCheckForMinusZero);
464 465 466
    } else {
      return TypeError(node, output_rep, output_type,
                       MachineRepresentation::kTagged);
467
    }
468
  } else {
469 470
    return TypeError(node, output_rep, output_type,
                     MachineRepresentation::kTagged);
471 472 473 474 475 476
  }
  return jsgraph()->graph()->NewNode(op, node);
}


Node* RepresentationChanger::GetFloat32RepresentationFor(
477 478
    Node* node, MachineRepresentation output_rep, Type* output_type,
    Truncation truncation) {
479 480 481 482 483 484
  // Eagerly fold representation changes for constants.
  switch (node->opcode()) {
    case IrOpcode::kNumberConstant:
      return jsgraph()->Float32Constant(
          DoubleToFloat32(OpParameter<double>(node)));
    case IrOpcode::kInt32Constant:
485
    case IrOpcode::kFloat64Constant:
486
    case IrOpcode::kFloat32Constant:
487 488
      UNREACHABLE();
      break;
489 490 491 492
    default:
      break;
  }
  // Select the correct X -> Float32 operator.
493
  const Operator* op = nullptr;
494
  if (output_type->Is(Type::None())) {
495
    // This is an impossible value; it should not be used at runtime.
496 497
    // We just provide a dummy value here.
    return jsgraph()->Float32Constant(0.0f);
498
  } else if (IsWord(output_rep)) {
499
    if (output_type->Is(Type::Signed32())) {
500
      // int32 -> float64 -> float32
501
      op = machine()->ChangeInt32ToFloat64();
502 503 504
      node = jsgraph()->graph()->NewNode(op, node);
      op = machine()->TruncateFloat64ToFloat32();
    } else if (output_type->Is(Type::Unsigned32()) ||
505
               truncation.IsUsedAsWord32()) {
506 507 508 509
      // Either the output is uint32 or the uses only care about the
      // low 32 bits (so we can pick uint32 safely).

      // uint32 -> float64 -> float32
510
      op = machine()->ChangeUint32ToFloat64();
511 512
      node = jsgraph()->graph()->NewNode(op, node);
      op = machine()->TruncateFloat64ToFloat32();
513
    }
514
  } else if (IsAnyTagged(output_rep)) {
515
    if (output_type->Is(Type::NumberOrOddball())) {
516 517 518 519 520 521
      // tagged -> float64 -> float32
      if (output_type->Is(Type::Number())) {
        op = simplified()->ChangeTaggedToFloat64();
      } else {
        op = simplified()->TruncateTaggedToFloat64();
      }
522 523 524
      node = jsgraph()->graph()->NewNode(op, node);
      op = machine()->TruncateFloat64ToFloat32();
    }
525
  } else if (output_rep == MachineRepresentation::kFloat64) {
526
    op = machine()->TruncateFloat64ToFloat32();
527 528
  }
  if (op == nullptr) {
529 530
    return TypeError(node, output_rep, output_type,
                     MachineRepresentation::kFloat32);
531 532 533 534 535
  }
  return jsgraph()->graph()->NewNode(op, node);
}

Node* RepresentationChanger::GetFloat64RepresentationFor(
536
    Node* node, MachineRepresentation output_rep, Type* output_type,
537
    Node* use_node, UseInfo use_info) {
538
  // Eagerly fold representation changes for constants.
539 540 541 542 543 544 545 546
  if ((use_info.type_check() == TypeCheckKind::kNone)) {
    // TODO(jarin) Handle checked constant conversions.
    switch (node->opcode()) {
      case IrOpcode::kNumberConstant:
        return jsgraph()->Float64Constant(OpParameter<double>(node));
      case IrOpcode::kInt32Constant:
      case IrOpcode::kFloat64Constant:
      case IrOpcode::kFloat32Constant:
547 548
        UNREACHABLE();
        break;
549 550 551
      default:
        break;
    }
552 553
  }
  // Select the correct X -> Float64 operator.
554
  const Operator* op = nullptr;
555
  if (output_type->Is(Type::None())) {
556
    // This is an impossible value; it should not be used at runtime.
557 558
    // We just provide a dummy value here.
    return jsgraph()->Float64Constant(0.0);
559
  } else if (IsWord(output_rep)) {
560 561
    if (output_type->Is(Type::Signed32())) {
      op = machine()->ChangeInt32ToFloat64();
562
    } else if (output_type->Is(Type::Unsigned32()) ||
563
               use_info.truncation().IsUsedAsWord32()) {
564 565
      // Either the output is uint32 or the uses only care about the
      // low 32 bits (so we can pick uint32 safely).
566
      op = machine()->ChangeUint32ToFloat64();
567
    }
568 569
  } else if (output_rep == MachineRepresentation::kBit) {
    op = machine()->ChangeUint32ToFloat64();
570 571 572
  } else if (output_rep == MachineRepresentation::kTagged ||
             output_rep == MachineRepresentation::kTaggedSigned ||
             output_rep == MachineRepresentation::kTaggedPointer) {
573 574 575
    if (output_type->Is(Type::Undefined())) {
      return jsgraph()->Float64Constant(
          std::numeric_limits<double>::quiet_NaN());
576 577

    } else if (output_rep == MachineRepresentation::kTaggedSigned) {
578 579
      node = InsertChangeTaggedSignedToInt32(node);
      op = machine()->ChangeInt32ToFloat64();
580
    } else if (output_type->Is(Type::Number())) {
581
      op = simplified()->ChangeTaggedToFloat64();
582
    } else if (output_type->Is(Type::NumberOrOddball())) {
583
      // TODO(jarin) Here we should check that truncation is Number.
584
      op = simplified()->TruncateTaggedToFloat64();
585 586 587 588
    } else if (use_info.type_check() == TypeCheckKind::kNumber ||
               (use_info.type_check() == TypeCheckKind::kNumberOrOddball &&
                !output_type->Maybe(Type::BooleanOrNullOrNumber()))) {
      op = simplified()->CheckedTaggedToFloat64(CheckTaggedInputMode::kNumber);
589
    } else if (use_info.type_check() == TypeCheckKind::kNumberOrOddball) {
590 591
      op = simplified()->CheckedTaggedToFloat64(
          CheckTaggedInputMode::kNumberOrOddball);
592
    }
593
  } else if (output_rep == MachineRepresentation::kFloat32) {
594
    op = machine()->ChangeFloat32ToFloat64();
595 596
  }
  if (op == nullptr) {
597 598
    return TypeError(node, output_rep, output_type,
                     MachineRepresentation::kFloat64);
599
  }
600
  return InsertConversion(node, op, use_node);
601 602 603 604 605 606 607
}

Node* RepresentationChanger::MakeTruncatedInt32Constant(double value) {
  return jsgraph()->Int32Constant(DoubleToInt32(value));
}

Node* RepresentationChanger::GetWord32RepresentationFor(
608
    Node* node, MachineRepresentation output_rep, Type* output_type,
609
    Node* use_node, UseInfo use_info) {
610
  // Eagerly fold representation changes for constants.
611 612
  switch (node->opcode()) {
    case IrOpcode::kInt32Constant:
613 614 615
    case IrOpcode::kFloat32Constant:
    case IrOpcode::kFloat64Constant:
      UNREACHABLE();
616
      break;
617
    case IrOpcode::kNumberConstant: {
618 619
      double const fv = OpParameter<double>(node);
      if (use_info.type_check() == TypeCheckKind::kNone ||
620 621
          ((use_info.type_check() == TypeCheckKind::kSignedSmall ||
            use_info.type_check() == TypeCheckKind::kSigned32) &&
622 623 624 625 626 627 628
           IsInt32Double(fv))) {
        return MakeTruncatedInt32Constant(fv);
      }
      break;
    }
    default:
      break;
629
  }
630

631
  // Select the correct X -> Word32 operator.
632
  const Operator* op = nullptr;
633
  if (output_type->Is(Type::None())) {
634
    // This is an impossible value; it should not be used at runtime.
635 636
    // We just provide a dummy value here.
    return jsgraph()->Int32Constant(0);
637
  } else if (output_rep == MachineRepresentation::kBit) {
638
    return node;  // Sloppy comparison -> word32
639
  } else if (output_rep == MachineRepresentation::kFloat64) {
640
    if (output_type->Is(Type::Signed32())) {
641
      op = machine()->ChangeFloat64ToInt32();
642 643
    } else if (use_info.type_check() == TypeCheckKind::kSignedSmall ||
               use_info.type_check() == TypeCheckKind::kSigned32) {
644 645
      op = simplified()->CheckedFloat64ToInt32(
          output_type->Maybe(Type::MinusZero())
646
              ? use_info.minus_zero_check()
647
              : CheckForMinusZeroMode::kDontCheckForMinusZero);
648 649 650 651
    } else if (output_type->Is(Type::Unsigned32())) {
      op = machine()->ChangeFloat64ToUint32();
    } else if (use_info.truncation().IsUsedAsWord32()) {
      op = machine()->TruncateFloat64ToWord32();
652 653 654
    } else {
      return TypeError(node, output_rep, output_type,
                       MachineRepresentation::kWord32);
655
    }
656
  } else if (output_rep == MachineRepresentation::kFloat32) {
657
    node = InsertChangeFloat32ToFloat64(node);  // float32 -> float64 -> int32
658
    if (output_type->Is(Type::Signed32())) {
659
      op = machine()->ChangeFloat64ToInt32();
660 661
    } else if (use_info.type_check() == TypeCheckKind::kSignedSmall ||
               use_info.type_check() == TypeCheckKind::kSigned32) {
662 663
      op = simplified()->CheckedFloat64ToInt32(
          output_type->Maybe(Type::MinusZero())
664
              ? use_info.minus_zero_check()
665
              : CheckForMinusZeroMode::kDontCheckForMinusZero);
666 667 668 669
    } else if (output_type->Is(Type::Unsigned32())) {
      op = machine()->ChangeFloat64ToUint32();
    } else if (use_info.truncation().IsUsedAsWord32()) {
      op = machine()->TruncateFloat64ToWord32();
670 671 672
    } else {
      return TypeError(node, output_rep, output_type,
                       MachineRepresentation::kWord32);
673
    }
674 675 676
  } else if (IsAnyTagged(output_rep)) {
    if (output_rep == MachineRepresentation::kTaggedSigned &&
        output_type->Is(Type::SignedSmall())) {
677
      op = simplified()->ChangeTaggedSignedToInt32();
678
    } else if (output_type->Is(Type::Signed32())) {
679
      op = simplified()->ChangeTaggedToInt32();
680 681
    } else if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
      op = simplified()->CheckedTaggedSignedToInt32();
682
    } else if (use_info.type_check() == TypeCheckKind::kSigned32) {
683 684
      op = simplified()->CheckedTaggedToInt32(
          output_type->Maybe(Type::MinusZero())
685
              ? use_info.minus_zero_check()
686
              : CheckForMinusZeroMode::kDontCheckForMinusZero);
687 688 689
    } else if (output_type->Is(Type::Unsigned32())) {
      op = simplified()->ChangeTaggedToUint32();
    } else if (use_info.truncation().IsUsedAsWord32()) {
690
      if (output_type->Is(Type::NumberOrOddball())) {
691
        op = simplified()->TruncateTaggedToWord32();
692 693 694 695 696 697
      } else if (use_info.type_check() == TypeCheckKind::kNumber) {
        op = simplified()->CheckedTruncateTaggedToWord32(
            CheckTaggedInputMode::kNumber);
      } else if (use_info.type_check() == TypeCheckKind::kNumberOrOddball) {
        op = simplified()->CheckedTruncateTaggedToWord32(
            CheckTaggedInputMode::kNumberOrOddball);
698 699 700
      } else {
        return TypeError(node, output_rep, output_type,
                         MachineRepresentation::kWord32);
701
      }
702 703 704
    } else {
      return TypeError(node, output_rep, output_type,
                       MachineRepresentation::kWord32);
705
    }
706 707 708
  } else if (output_rep == MachineRepresentation::kWord32) {
    // Only the checked case should get here, the non-checked case is
    // handled in GetRepresentationFor.
709 710
    if (use_info.type_check() == TypeCheckKind::kSignedSmall ||
        use_info.type_check() == TypeCheckKind::kSigned32) {
711 712 713 714
      if (output_type->Is(Type::Signed32())) {
        return node;
      } else if (output_type->Is(Type::Unsigned32())) {
        op = simplified()->CheckedUint32ToInt32();
715 716 717
      } else {
        return TypeError(node, output_rep, output_type,
                         MachineRepresentation::kWord32);
718
      }
719 720
    } else if (use_info.type_check() == TypeCheckKind::kNumber ||
               use_info.type_check() == TypeCheckKind::kNumberOrOddball) {
721 722 723 724
      return node;
    }
  } else if (output_rep == MachineRepresentation::kWord8 ||
             output_rep == MachineRepresentation::kWord16) {
725
    DCHECK_EQ(MachineRepresentation::kWord32, use_info.representation());
726 727
    DCHECK(use_info.type_check() == TypeCheckKind::kSignedSmall ||
           use_info.type_check() == TypeCheckKind::kSigned32);
728
    return node;
729
  }
730

731
  if (op == nullptr) {
732 733
    return TypeError(node, output_rep, output_type,
                     MachineRepresentation::kWord32);
734
  }
735 736 737 738 739 740 741
  return InsertConversion(node, op, use_node);
}

Node* RepresentationChanger::InsertConversion(Node* node, const Operator* op,
                                              Node* use_node) {
  if (op->ControlInputCount() > 0) {
    // If the operator can deoptimize (which means it has control
742
    // input), we need to connect it to the effect and control chains.
743 744
    Node* effect = NodeProperties::GetEffectInput(use_node);
    Node* control = NodeProperties::GetControlInput(use_node);
745
    Node* conversion = jsgraph()->graph()->NewNode(op, node, effect, control);
746
    NodeProperties::ReplaceEffectInput(use_node, conversion);
747 748
    return conversion;
  }
749 750 751 752
  return jsgraph()->graph()->NewNode(op, node);
}


753 754
Node* RepresentationChanger::GetBitRepresentationFor(
    Node* node, MachineRepresentation output_rep, Type* output_type) {
755 756 757
  // Eagerly fold representation changes for constants.
  switch (node->opcode()) {
    case IrOpcode::kHeapConstant: {
758 759 760 761 762 763
      HeapObjectMatcher m(node);
      if (m.Is(factory()->false_value())) {
        return jsgraph()->Int32Constant(0);
      } else if (m.Is(factory()->true_value())) {
        return jsgraph()->Int32Constant(1);
      }
764 765 766 767 768 769
    }
    default:
      break;
  }
  // Select the correct X -> Bit operator.
  const Operator* op;
770
  if (output_type->Is(Type::None())) {
771
    // This is an impossible value; it should not be used at runtime.
772 773
    // We just provide a dummy value here.
    return jsgraph()->Int32Constant(0);
774 775
  } else if (output_rep == MachineRepresentation::kTagged ||
             output_rep == MachineRepresentation::kTaggedPointer) {
776 777 778 779
    if (output_type->Is(Type::BooleanOrNullOrUndefined())) {
      // true is the only trueish Oddball.
      op = simplified()->ChangeTaggedToBit();
    } else {
780 781 782 783 784 785 786 787
      if (output_rep == MachineRepresentation::kTagged &&
          output_type->Maybe(Type::SignedSmall())) {
        op = simplified()->TruncateTaggedToBit();
      } else {
        // The {output_type} either doesn't include the Smi range,
        // or the {output_rep} is known to be TaggedPointer.
        op = simplified()->TruncateTaggedPointerToBit();
      }
788 789 790
    }
  } else if (output_rep == MachineRepresentation::kTaggedSigned) {
    node = jsgraph()->graph()->NewNode(machine()->WordEqual(), node,
791
                                       jsgraph()->IntPtrConstant(0));
792 793 794 795 796 797 798 799 800 801 802 803 804 805 806
    return jsgraph()->graph()->NewNode(machine()->Word32Equal(), node,
                                       jsgraph()->Int32Constant(0));
  } else if (IsWord(output_rep)) {
    node = jsgraph()->graph()->NewNode(machine()->Word32Equal(), node,
                                       jsgraph()->Int32Constant(0));
    return jsgraph()->graph()->NewNode(machine()->Word32Equal(), node,
                                       jsgraph()->Int32Constant(0));
  } else if (output_rep == MachineRepresentation::kFloat32) {
    node = jsgraph()->graph()->NewNode(machine()->Float32Abs(), node);
    return jsgraph()->graph()->NewNode(machine()->Float32LessThan(),
                                       jsgraph()->Float32Constant(0.0), node);
  } else if (output_rep == MachineRepresentation::kFloat64) {
    node = jsgraph()->graph()->NewNode(machine()->Float64Abs(), node);
    return jsgraph()->graph()->NewNode(machine()->Float64LessThan(),
                                       jsgraph()->Float64Constant(0.0), node);
807
  } else {
808 809
    return TypeError(node, output_rep, output_type,
                     MachineRepresentation::kBit);
810 811 812 813 814
  }
  return jsgraph()->graph()->NewNode(op, node);
}

Node* RepresentationChanger::GetWord64RepresentationFor(
815
    Node* node, MachineRepresentation output_rep, Type* output_type) {
816
  if (output_type->Is(Type::None())) {
817
    // This is an impossible value; it should not be used at runtime.
818 819
    // We just provide a dummy value here.
    return jsgraph()->Int64Constant(0);
820
  } else if (output_rep == MachineRepresentation::kBit) {
821 822 823
    return node;  // Sloppy comparison -> word64
  }
  // Can't really convert Word64 to anything else. Purported to be internal.
824 825
  return TypeError(node, output_rep, output_type,
                   MachineRepresentation::kWord64);
826 827 828 829 830
}

const Operator* RepresentationChanger::Int32OperatorFor(
    IrOpcode::Value opcode) {
  switch (opcode) {
831
    case IrOpcode::kSpeculativeNumberAdd:  // Fall through.
832
    case IrOpcode::kSpeculativeSafeIntegerAdd:
833 834
    case IrOpcode::kNumberAdd:
      return machine()->Int32Add();
835
    case IrOpcode::kSpeculativeNumberSubtract:  // Fall through.
836
    case IrOpcode::kSpeculativeSafeIntegerSubtract:
837 838
    case IrOpcode::kNumberSubtract:
      return machine()->Int32Sub();
839
    case IrOpcode::kSpeculativeNumberMultiply:
840 841
    case IrOpcode::kNumberMultiply:
      return machine()->Int32Mul();
842
    case IrOpcode::kSpeculativeNumberDivide:
843 844
    case IrOpcode::kNumberDivide:
      return machine()->Int32Div();
845
    case IrOpcode::kSpeculativeNumberModulus:
846 847
    case IrOpcode::kNumberModulus:
      return machine()->Int32Mod();
848
    case IrOpcode::kSpeculativeNumberBitwiseOr:  // Fall through.
849 850
    case IrOpcode::kNumberBitwiseOr:
      return machine()->Word32Or();
851
    case IrOpcode::kSpeculativeNumberBitwiseXor:  // Fall through.
852 853
    case IrOpcode::kNumberBitwiseXor:
      return machine()->Word32Xor();
854
    case IrOpcode::kSpeculativeNumberBitwiseAnd:  // Fall through.
855 856 857
    case IrOpcode::kNumberBitwiseAnd:
      return machine()->Word32And();
    case IrOpcode::kNumberEqual:
858
    case IrOpcode::kSpeculativeNumberEqual:
859 860
      return machine()->Word32Equal();
    case IrOpcode::kNumberLessThan:
861
    case IrOpcode::kSpeculativeNumberLessThan:
862 863
      return machine()->Int32LessThan();
    case IrOpcode::kNumberLessThanOrEqual:
864
    case IrOpcode::kSpeculativeNumberLessThanOrEqual:
865 866 867 868 869 870
      return machine()->Int32LessThanOrEqual();
    default:
      UNREACHABLE();
  }
}

871 872 873
const Operator* RepresentationChanger::Int32OverflowOperatorFor(
    IrOpcode::Value opcode) {
  switch (opcode) {
874
    case IrOpcode::kSpeculativeSafeIntegerAdd:
875
      return simplified()->CheckedInt32Add();
876
    case IrOpcode::kSpeculativeSafeIntegerSubtract:
877
      return simplified()->CheckedInt32Sub();
878 879 880 881
    case IrOpcode::kSpeculativeNumberDivide:
      return simplified()->CheckedInt32Div();
    case IrOpcode::kSpeculativeNumberModulus:
      return simplified()->CheckedInt32Mod();
882 883 884 885
    default:
      UNREACHABLE();
  }
}
886

887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903
const Operator* RepresentationChanger::TaggedSignedOperatorFor(
    IrOpcode::Value opcode) {
  switch (opcode) {
    case IrOpcode::kSpeculativeNumberLessThan:
      return machine()->Is32() ? machine()->Int32LessThan()
                               : machine()->Int64LessThan();
    case IrOpcode::kSpeculativeNumberLessThanOrEqual:
      return machine()->Is32() ? machine()->Int32LessThanOrEqual()
                               : machine()->Int64LessThanOrEqual();
    case IrOpcode::kSpeculativeNumberEqual:
      return machine()->Is32() ? machine()->Word32Equal()
                               : machine()->Word64Equal();
    default:
      UNREACHABLE();
  }
}

904 905 906 907 908 909 910
const Operator* RepresentationChanger::Uint32OperatorFor(
    IrOpcode::Value opcode) {
  switch (opcode) {
    case IrOpcode::kNumberAdd:
      return machine()->Int32Add();
    case IrOpcode::kNumberSubtract:
      return machine()->Int32Sub();
911
    case IrOpcode::kSpeculativeNumberMultiply:
912 913
    case IrOpcode::kNumberMultiply:
      return machine()->Int32Mul();
914
    case IrOpcode::kSpeculativeNumberDivide:
915 916
    case IrOpcode::kNumberDivide:
      return machine()->Uint32Div();
917
    case IrOpcode::kSpeculativeNumberModulus:
918 919 920
    case IrOpcode::kNumberModulus:
      return machine()->Uint32Mod();
    case IrOpcode::kNumberEqual:
921
    case IrOpcode::kSpeculativeNumberEqual:
922 923
      return machine()->Word32Equal();
    case IrOpcode::kNumberLessThan:
924
    case IrOpcode::kSpeculativeNumberLessThan:
925 926
      return machine()->Uint32LessThan();
    case IrOpcode::kNumberLessThanOrEqual:
927
    case IrOpcode::kSpeculativeNumberLessThanOrEqual:
928
      return machine()->Uint32LessThanOrEqual();
929 930
    case IrOpcode::kNumberClz32:
      return machine()->Word32Clz();
931 932
    case IrOpcode::kNumberImul:
      return machine()->Int32Mul();
933 934 935 936 937
    default:
      UNREACHABLE();
  }
}

938 939 940 941 942 943 944 945 946 947 948
const Operator* RepresentationChanger::Uint32OverflowOperatorFor(
    IrOpcode::Value opcode) {
  switch (opcode) {
    case IrOpcode::kSpeculativeNumberDivide:
      return simplified()->CheckedUint32Div();
    case IrOpcode::kSpeculativeNumberModulus:
      return simplified()->CheckedUint32Mod();
    default:
      UNREACHABLE();
  }
}
949 950 951 952

const Operator* RepresentationChanger::Float64OperatorFor(
    IrOpcode::Value opcode) {
  switch (opcode) {
953
    case IrOpcode::kSpeculativeNumberAdd:
954
    case IrOpcode::kSpeculativeSafeIntegerAdd:
955 956
    case IrOpcode::kNumberAdd:
      return machine()->Float64Add();
957
    case IrOpcode::kSpeculativeNumberSubtract:
958
    case IrOpcode::kSpeculativeSafeIntegerSubtract:
959 960
    case IrOpcode::kNumberSubtract:
      return machine()->Float64Sub();
961
    case IrOpcode::kSpeculativeNumberMultiply:
962 963
    case IrOpcode::kNumberMultiply:
      return machine()->Float64Mul();
964
    case IrOpcode::kSpeculativeNumberDivide:
965 966
    case IrOpcode::kNumberDivide:
      return machine()->Float64Div();
967
    case IrOpcode::kSpeculativeNumberModulus:
968 969 970
    case IrOpcode::kNumberModulus:
      return machine()->Float64Mod();
    case IrOpcode::kNumberEqual:
971
    case IrOpcode::kSpeculativeNumberEqual:
972 973
      return machine()->Float64Equal();
    case IrOpcode::kNumberLessThan:
974
    case IrOpcode::kSpeculativeNumberLessThan:
975 976
      return machine()->Float64LessThan();
    case IrOpcode::kNumberLessThanOrEqual:
977
    case IrOpcode::kSpeculativeNumberLessThanOrEqual:
978
      return machine()->Float64LessThanOrEqual();
979 980
    case IrOpcode::kNumberAbs:
      return machine()->Float64Abs();
981 982 983 984 985 986 987 988
    case IrOpcode::kNumberAcos:
      return machine()->Float64Acos();
    case IrOpcode::kNumberAcosh:
      return machine()->Float64Acosh();
    case IrOpcode::kNumberAsin:
      return machine()->Float64Asin();
    case IrOpcode::kNumberAsinh:
      return machine()->Float64Asinh();
989 990
    case IrOpcode::kNumberAtan:
      return machine()->Float64Atan();
991 992
    case IrOpcode::kNumberAtanh:
      return machine()->Float64Atanh();
993 994
    case IrOpcode::kNumberAtan2:
      return machine()->Float64Atan2();
995 996
    case IrOpcode::kNumberCbrt:
      return machine()->Float64Cbrt();
997 998
    case IrOpcode::kNumberCeil:
      return machine()->Float64RoundUp().placeholder();
999 1000
    case IrOpcode::kNumberCos:
      return machine()->Float64Cos();
1001 1002
    case IrOpcode::kNumberCosh:
      return machine()->Float64Cosh();
1003 1004
    case IrOpcode::kNumberExp:
      return machine()->Float64Exp();
1005 1006
    case IrOpcode::kNumberExpm1:
      return machine()->Float64Expm1();
1007 1008
    case IrOpcode::kNumberFloor:
      return machine()->Float64RoundDown().placeholder();
1009 1010
    case IrOpcode::kNumberFround:
      return machine()->TruncateFloat64ToFloat32();
1011 1012
    case IrOpcode::kNumberLog:
      return machine()->Float64Log();
1013 1014
    case IrOpcode::kNumberLog1p:
      return machine()->Float64Log1p();
1015 1016 1017 1018
    case IrOpcode::kNumberLog2:
      return machine()->Float64Log2();
    case IrOpcode::kNumberLog10:
      return machine()->Float64Log10();
1019 1020 1021 1022
    case IrOpcode::kNumberMax:
      return machine()->Float64Max();
    case IrOpcode::kNumberMin:
      return machine()->Float64Min();
1023 1024
    case IrOpcode::kNumberPow:
      return machine()->Float64Pow();
1025 1026
    case IrOpcode::kNumberSin:
      return machine()->Float64Sin();
1027 1028
    case IrOpcode::kNumberSinh:
      return machine()->Float64Sinh();
1029 1030
    case IrOpcode::kNumberSqrt:
      return machine()->Float64Sqrt();
1031 1032
    case IrOpcode::kNumberTan:
      return machine()->Float64Tan();
1033 1034
    case IrOpcode::kNumberTanh:
      return machine()->Float64Tanh();
1035 1036
    case IrOpcode::kNumberTrunc:
      return machine()->Float64RoundTruncate().placeholder();
1037 1038
    case IrOpcode::kNumberSilenceNaN:
      return machine()->Float64SilenceNaN();
1039 1040 1041 1042 1043 1044
    default:
      UNREACHABLE();
  }
}


1045 1046 1047
Node* RepresentationChanger::TypeError(Node* node,
                                       MachineRepresentation output_rep,
                                       Type* output_type,
1048
                                       MachineRepresentation use) {
1049 1050 1051
  type_error_ = true;
  if (!testing_type_errors_) {
    std::ostringstream out_str;
1052
    out_str << output_rep << " (";
1053
    output_type->PrintTo(out_str);
1054
    out_str << ")";
1055 1056

    std::ostringstream use_str;
1057
    use_str << use;
1058 1059 1060 1061 1062 1063 1064 1065 1066 1067

    V8_Fatal(__FILE__, __LINE__,
             "RepresentationChangerError: node #%d:%s of "
             "%s cannot be changed to %s",
             node->id(), node->op()->mnemonic(), out_str.str().c_str(),
             use_str.str().c_str());
  }
  return node;
}

1068 1069 1070
Node* RepresentationChanger::InsertChangeBitToTagged(Node* node) {
  return jsgraph()->graph()->NewNode(simplified()->ChangeBitToTagged(), node);
}
1071 1072 1073 1074 1075

Node* RepresentationChanger::InsertChangeFloat32ToFloat64(Node* node) {
  return jsgraph()->graph()->NewNode(machine()->ChangeFloat32ToFloat64(), node);
}

1076 1077 1078 1079 1080 1081 1082
Node* RepresentationChanger::InsertChangeFloat64ToUint32(Node* node) {
  return jsgraph()->graph()->NewNode(machine()->ChangeFloat64ToUint32(), node);
}

Node* RepresentationChanger::InsertChangeFloat64ToInt32(Node* node) {
  return jsgraph()->graph()->NewNode(machine()->ChangeFloat64ToInt32(), node);
}
1083

1084 1085 1086 1087
Node* RepresentationChanger::InsertChangeInt32ToFloat64(Node* node) {
  return jsgraph()->graph()->NewNode(machine()->ChangeInt32ToFloat64(), node);
}

1088 1089 1090 1091 1092
Node* RepresentationChanger::InsertChangeTaggedSignedToInt32(Node* node) {
  return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedSignedToInt32(),
                                     node);
}

1093 1094 1095 1096 1097
Node* RepresentationChanger::InsertChangeTaggedToFloat64(Node* node) {
  return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedToFloat64(),
                                     node);
}

1098 1099 1100 1101
Node* RepresentationChanger::InsertChangeUint32ToFloat64(Node* node) {
  return jsgraph()->graph()->NewNode(machine()->ChangeUint32ToFloat64(), node);
}

1102 1103 1104
}  // namespace compiler
}  // namespace internal
}  // namespace v8