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