Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(908)

Side by Side Diff: src/compiler/representation-change.cc

Issue 2177483002: [turbofan] Handle impossible types (Type::None()) in the backend. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix?? Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/representation-change.h" 5 #include "src/compiler/representation-change.h"
6 6
7 #include <sstream> 7 #include <sstream>
8 8
9 #include "src/base/bits.h" 9 #include "src/base/bits.h"
10 #include "src/code-factory.h" 10 #include "src/code-factory.h"
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 110
111 } // namespace 111 } // namespace
112 112
113 // Changes representation from {output_rep} to {use_rep}. The {truncation} 113 // Changes representation from {output_rep} to {use_rep}. The {truncation}
114 // parameter is only used for sanity checking - if the changer cannot figure 114 // parameter is only used for sanity checking - if the changer cannot figure
115 // out signedness for the word32->float64 conversion, then we check that the 115 // out signedness for the word32->float64 conversion, then we check that the
116 // uses truncate to word32 (so they do not care about signedness). 116 // uses truncate to word32 (so they do not care about signedness).
117 Node* RepresentationChanger::GetRepresentationFor( 117 Node* RepresentationChanger::GetRepresentationFor(
118 Node* node, MachineRepresentation output_rep, Type* output_type, 118 Node* node, MachineRepresentation output_rep, Type* output_type,
119 Node* use_node, UseInfo use_info) { 119 Node* use_node, UseInfo use_info) {
120 if (output_rep == MachineRepresentation::kNone) { 120 if (output_rep == MachineRepresentation::kNone &&
121 // The output representation should be set. 121 output_type->IsInhabited()) {
122 // The output representation should be set if the type is inhabited (i.e.,
123 // if the value is possible).
122 return TypeError(node, output_rep, output_type, use_info.representation()); 124 return TypeError(node, output_rep, output_type, use_info.representation());
123 } 125 }
124 126
125 // Handle the no-op shortcuts when no checking is necessary. 127 // Handle the no-op shortcuts when no checking is necessary.
126 if (use_info.type_check() == TypeCheckKind::kNone || 128 if (use_info.type_check() == TypeCheckKind::kNone ||
127 output_rep != MachineRepresentation::kWord32) { 129 output_rep != MachineRepresentation::kWord32) {
128 if (use_info.representation() == output_rep) { 130 if (use_info.representation() == output_rep) {
129 // Representations are the same. That's a no-op. 131 // Representations are the same. That's a no-op.
130 return node; 132 return node;
131 } 133 }
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 } 195 }
194 case IrOpcode::kFloat64Constant: 196 case IrOpcode::kFloat64Constant:
195 return jsgraph()->Constant(OpParameter<double>(node)); 197 return jsgraph()->Constant(OpParameter<double>(node));
196 case IrOpcode::kFloat32Constant: 198 case IrOpcode::kFloat32Constant:
197 return jsgraph()->Constant(OpParameter<float>(node)); 199 return jsgraph()->Constant(OpParameter<float>(node));
198 default: 200 default:
199 break; 201 break;
200 } 202 }
201 // Select the correct X -> Tagged operator. 203 // Select the correct X -> Tagged operator.
202 const Operator* op; 204 const Operator* op;
203 if (output_rep == MachineRepresentation::kBit) { 205 if (output_rep == MachineRepresentation::kNone) {
206 // We should only asisgn this representation if the type is empty.
207 CHECK(!output_type->IsInhabited());
208 op = machine()->ImpossibleToTagged();
209 } else if (output_rep == MachineRepresentation::kBit) {
204 if (output_type->Is(Type::Boolean())) { 210 if (output_type->Is(Type::Boolean())) {
205 op = simplified()->ChangeBitToTagged(); 211 op = simplified()->ChangeBitToTagged();
206 } else { 212 } else {
207 return TypeError(node, output_rep, output_type, 213 return TypeError(node, output_rep, output_type,
208 MachineRepresentation::kTagged); 214 MachineRepresentation::kTagged);
209 } 215 }
210 } else if (IsWord(output_rep)) { 216 } else if (IsWord(output_rep)) {
211 if (output_type->Is(Type::Signed31())) { 217 if (output_type->Is(Type::Signed31())) {
212 op = simplified()->ChangeInt31ToTaggedSigned(); 218 op = simplified()->ChangeInt31ToTaggedSigned();
213 } else if (output_type->Is(Type::Signed32())) { 219 } else if (output_type->Is(Type::Signed32())) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 int32_t value = OpParameter<int32_t>(node); 270 int32_t value = OpParameter<int32_t>(node);
265 return jsgraph()->Float32Constant(static_cast<float>(value)); 271 return jsgraph()->Float32Constant(static_cast<float>(value));
266 } 272 }
267 case IrOpcode::kFloat32Constant: 273 case IrOpcode::kFloat32Constant:
268 return node; // No change necessary. 274 return node; // No change necessary.
269 default: 275 default:
270 break; 276 break;
271 } 277 }
272 // Select the correct X -> Float32 operator. 278 // Select the correct X -> Float32 operator.
273 const Operator* op = nullptr; 279 const Operator* op = nullptr;
274 if (IsWord(output_rep)) { 280 if (output_rep == MachineRepresentation::kNone) {
281 // We should only use kNone representation if the type is empty.
282 CHECK(!output_type->IsInhabited());
283 op = machine()->ImpossibleToFloat32();
284 } else if (IsWord(output_rep)) {
275 if (output_type->Is(Type::Signed32())) { 285 if (output_type->Is(Type::Signed32())) {
276 // int32 -> float64 -> float32 286 // int32 -> float64 -> float32
277 op = machine()->ChangeInt32ToFloat64(); 287 op = machine()->ChangeInt32ToFloat64();
278 node = jsgraph()->graph()->NewNode(op, node); 288 node = jsgraph()->graph()->NewNode(op, node);
279 op = machine()->TruncateFloat64ToFloat32(); 289 op = machine()->TruncateFloat64ToFloat32();
280 } else if (output_type->Is(Type::Unsigned32()) || 290 } else if (output_type->Is(Type::Unsigned32()) ||
281 truncation.IsUsedAsWord32()) { 291 truncation.IsUsedAsWord32()) {
282 // Either the output is uint32 or the uses only care about the 292 // Either the output is uint32 or the uses only care about the
283 // low 32 bits (so we can pick uint32 safely). 293 // low 32 bits (so we can pick uint32 safely).
284 294
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
329 case IrOpcode::kFloat64Constant: 339 case IrOpcode::kFloat64Constant:
330 return node; // No change necessary. 340 return node; // No change necessary.
331 case IrOpcode::kFloat32Constant: 341 case IrOpcode::kFloat32Constant:
332 return jsgraph()->Float64Constant(OpParameter<float>(node)); 342 return jsgraph()->Float64Constant(OpParameter<float>(node));
333 default: 343 default:
334 break; 344 break;
335 } 345 }
336 } 346 }
337 // Select the correct X -> Float64 operator. 347 // Select the correct X -> Float64 operator.
338 const Operator* op = nullptr; 348 const Operator* op = nullptr;
339 if (IsWord(output_rep)) { 349 if (output_rep == MachineRepresentation::kNone) {
350 // We should only use kNone representation if the type is empty.
351 CHECK(!output_type->IsInhabited());
352 op = machine()->ImpossibleToFloat64();
353 } else if (IsWord(output_rep)) {
340 if (output_type->Is(Type::Signed32())) { 354 if (output_type->Is(Type::Signed32())) {
341 op = machine()->ChangeInt32ToFloat64(); 355 op = machine()->ChangeInt32ToFloat64();
342 } else if (output_type->Is(Type::Unsigned32()) || 356 } else if (output_type->Is(Type::Unsigned32()) ||
343 use_info.truncation().IsUsedAsWord32()) { 357 use_info.truncation().IsUsedAsWord32()) {
344 // Either the output is uint32 or the uses only care about the 358 // Either the output is uint32 or the uses only care about the
345 // low 32 bits (so we can pick uint32 safely). 359 // low 32 bits (so we can pick uint32 safely).
346 op = machine()->ChangeUint32ToFloat64(); 360 op = machine()->ChangeUint32ToFloat64();
347 } 361 }
348 } else if (output_rep == MachineRepresentation::kBit) { 362 } else if (output_rep == MachineRepresentation::kBit) {
349 op = machine()->ChangeUint32ToFloat64(); 363 op = machine()->ChangeUint32ToFloat64();
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
401 return MakeTruncatedInt32Constant(fv); 415 return MakeTruncatedInt32Constant(fv);
402 } 416 }
403 break; 417 break;
404 } 418 }
405 default: 419 default:
406 break; 420 break;
407 } 421 }
408 422
409 // Select the correct X -> Word32 operator. 423 // Select the correct X -> Word32 operator.
410 const Operator* op = nullptr; 424 const Operator* op = nullptr;
411 if (output_rep == MachineRepresentation::kBit) { 425 if (output_rep == MachineRepresentation::kNone) {
426 // We should only use kNone representation if the type is empty.
427 CHECK(!output_type->IsInhabited());
428 op = machine()->ImpossibleToWord32();
429 } else if (output_rep == MachineRepresentation::kBit) {
412 return node; // Sloppy comparison -> word32 430 return node; // Sloppy comparison -> word32
413 } else if (output_rep == MachineRepresentation::kFloat64) { 431 } else if (output_rep == MachineRepresentation::kFloat64) {
414 if (output_type->Is(Type::Unsigned32())) { 432 if (output_type->Is(Type::Unsigned32())) {
415 op = machine()->ChangeFloat64ToUint32(); 433 op = machine()->ChangeFloat64ToUint32();
416 } else if (output_type->Is(Type::Signed32())) { 434 } else if (output_type->Is(Type::Signed32())) {
417 op = machine()->ChangeFloat64ToInt32(); 435 op = machine()->ChangeFloat64ToInt32();
418 } else if (use_info.truncation().IsUsedAsWord32()) { 436 } else if (use_info.truncation().IsUsedAsWord32()) {
419 op = machine()->TruncateFloat64ToWord32(); 437 op = machine()->TruncateFloat64ToWord32();
420 } else if (use_info.type_check() == TypeCheckKind::kSigned32) { 438 } else if (use_info.type_check() == TypeCheckKind::kSigned32) {
421 op = simplified()->CheckedFloat64ToInt32(); 439 op = simplified()->CheckedFloat64ToInt32();
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
490 DCHECK(value.is_identical_to(factory()->true_value()) || 508 DCHECK(value.is_identical_to(factory()->true_value()) ||
491 value.is_identical_to(factory()->false_value())); 509 value.is_identical_to(factory()->false_value()));
492 return jsgraph()->Int32Constant( 510 return jsgraph()->Int32Constant(
493 value.is_identical_to(factory()->true_value()) ? 1 : 0); 511 value.is_identical_to(factory()->true_value()) ? 1 : 0);
494 } 512 }
495 default: 513 default:
496 break; 514 break;
497 } 515 }
498 // Select the correct X -> Bit operator. 516 // Select the correct X -> Bit operator.
499 const Operator* op; 517 const Operator* op;
500 if (output_rep == MachineRepresentation::kTagged) { 518 if (output_rep == MachineRepresentation::kNone) {
519 // We should only use kNone representation if the type is empty.
520 CHECK(!output_type->IsInhabited());
521 op = machine()->ImpossibleToBit();
522 } else if (output_rep == MachineRepresentation::kTagged) {
501 op = simplified()->ChangeTaggedToBit(); 523 op = simplified()->ChangeTaggedToBit();
502 } else { 524 } else {
503 return TypeError(node, output_rep, output_type, 525 return TypeError(node, output_rep, output_type,
504 MachineRepresentation::kBit); 526 MachineRepresentation::kBit);
505 } 527 }
506 return jsgraph()->graph()->NewNode(op, node); 528 return jsgraph()->graph()->NewNode(op, node);
507 } 529 }
508 530
509 Node* RepresentationChanger::GetWord64RepresentationFor( 531 Node* RepresentationChanger::GetWord64RepresentationFor(
510 Node* node, MachineRepresentation output_rep, Type* output_type) { 532 Node* node, MachineRepresentation output_rep, Type* output_type) {
511 if (output_rep == MachineRepresentation::kBit) { 533 if (output_rep == MachineRepresentation::kNone) {
534 // We should only use kNone representation if the type is empty.
535 CHECK(!output_type->IsInhabited());
536 return jsgraph()->graph()->NewNode(machine()->ImpossibleToFloat64(), node);
537 } else if (output_rep == MachineRepresentation::kBit) {
512 return node; // Sloppy comparison -> word64 538 return node; // Sloppy comparison -> word64
513 } 539 }
514 // Can't really convert Word64 to anything else. Purported to be internal. 540 // Can't really convert Word64 to anything else. Purported to be internal.
515 return TypeError(node, output_rep, output_type, 541 return TypeError(node, output_rep, output_type,
516 MachineRepresentation::kWord64); 542 MachineRepresentation::kWord64);
517 } 543 }
518 544
519 Node* RepresentationChanger::GetCheckedWord32RepresentationFor( 545 Node* RepresentationChanger::GetCheckedWord32RepresentationFor(
520 Node* node, MachineRepresentation output_rep, Type* output_type, 546 Node* node, MachineRepresentation output_rep, Type* output_type,
521 Node* use_node, Truncation truncation, TypeCheckKind check) { 547 Node* use_node, Truncation truncation, TypeCheckKind check) {
522 // TODO(jarin) Eagerly fold constants (or insert hard deopt if the constant 548 // TODO(jarin) Eagerly fold constants (or insert hard deopt if the constant
523 // does not pass the check). 549 // does not pass the check).
524 550
525 // If the input is already Signed32 in Word32 representation, we do not 551 // If the input is already Signed32 in Word32 representation, we do not
526 // have to do anything. (We could fold this into the big if below, but 552 // have to do anything. (We could fold this into the big if below, but
527 // it feels nicer to have the shortcut return first). 553 // it feels nicer to have the shortcut return first).
528 if (output_rep == MachineRepresentation::kWord32 || 554 if (output_rep == MachineRepresentation::kWord32 ||
529 output_type->Is(Type::Signed32())) { 555 output_type->Is(Type::Signed32())) {
530 return node; 556 return node;
531 } 557 }
532 558
533 // Select the correct X -> Word32 operator. 559 // Select the correct X -> Word32 operator.
534 const Operator* op = nullptr; 560 const Operator* op = nullptr;
535 if (output_rep == MachineRepresentation::kWord32) { 561 if (output_rep == MachineRepresentation::kNone) {
562 // We should only use kNone representation if the type is empty.
563 CHECK(!output_type->IsInhabited());
564 op = machine()->ImpossibleToWord32();
565 } else if (output_rep == MachineRepresentation::kWord32) {
536 if (output_type->Is(Type::Unsigned32())) { 566 if (output_type->Is(Type::Unsigned32())) {
537 op = simplified()->CheckedUint32ToInt32(); 567 op = simplified()->CheckedUint32ToInt32();
538 } 568 }
539 } else if (output_rep == MachineRepresentation::kBit) { 569 } else if (output_rep == MachineRepresentation::kBit) {
540 return node; // Sloppy comparison -> word32 570 return node; // Sloppy comparison -> word32
541 } else if (output_rep == MachineRepresentation::kFloat64) { 571 } else if (output_rep == MachineRepresentation::kFloat64) {
542 if (output_type->Is(Type::Unsigned32())) { 572 if (output_type->Is(Type::Unsigned32())) {
543 op = machine()->ChangeFloat64ToUint32(); 573 op = machine()->ChangeFloat64ToUint32();
544 } else if (output_type->Is(Type::Signed32())) { 574 } else if (output_type->Is(Type::Signed32())) {
545 op = machine()->ChangeFloat64ToInt32(); 575 op = machine()->ChangeFloat64ToInt32();
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
814 } 844 }
815 845
816 Node* RepresentationChanger::InsertChangeTaggedToFloat64(Node* node) { 846 Node* RepresentationChanger::InsertChangeTaggedToFloat64(Node* node) {
817 return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedToFloat64(), 847 return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedToFloat64(),
818 node); 848 node);
819 } 849 }
820 850
821 } // namespace compiler 851 } // namespace compiler
822 } // namespace internal 852 } // namespace internal
823 } // namespace v8 853 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698