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