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