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