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