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