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