OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/simplified-lowering.h" | 5 #include "src/compiler/simplified-lowering.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "src/address-map.h" | 9 #include "src/address-map.h" |
10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 }; | 176 }; |
177 | 177 |
178 #endif // DEBUG | 178 #endif // DEBUG |
179 | 179 |
180 } // namespace | 180 } // namespace |
181 | 181 |
182 | 182 |
183 class RepresentationSelector { | 183 class RepresentationSelector { |
184 public: | 184 public: |
185 // Information for each node tracked during the fixpoint. | 185 // Information for each node tracked during the fixpoint. |
186 class NodeInfo { | 186 class NodeInfo final { |
187 public: | 187 public: |
188 // Adds new use to the node. Returns true if something has changed | 188 // Adds new use to the node. Returns true if something has changed |
189 // and the node has to be requeued. | 189 // and the node has to be requeued. |
190 bool AddUse(UseInfo info) { | 190 bool AddUse(UseInfo info) { |
191 Truncation old_truncation = truncation_; | 191 Truncation old_truncation = truncation_; |
192 truncation_ = Truncation::Generalize(truncation_, info.truncation()); | 192 truncation_ = Truncation::Generalize(truncation_, info.truncation()); |
193 return truncation_ != old_truncation; | 193 return truncation_ != old_truncation; |
194 } | 194 } |
195 | 195 |
196 void set_queued() { state_ = kQueued; } | 196 void set_queued() { state_ = kQueued; } |
197 void set_visited() { state_ = kVisited; } | 197 void set_visited() { state_ = kVisited; } |
198 void set_pushed() { state_ = kPushed; } | 198 void set_pushed() { state_ = kPushed; } |
199 void reset_state() { state_ = kUnvisited; } | 199 void reset_state() { state_ = kUnvisited; } |
200 bool visited() const { return state_ == kVisited; } | 200 bool visited() const { return state_ == kVisited; } |
201 bool queued() const { return state_ == kQueued; } | 201 bool queued() const { return state_ == kQueued; } |
202 bool unvisited() const { return state_ == kUnvisited; } | 202 bool unvisited() const { return state_ == kUnvisited; } |
203 Truncation truncation() const { return truncation_; } | 203 Truncation truncation() const { return truncation_; } |
204 void set_output(MachineRepresentation output) { representation_ = output; } | 204 void set_output(MachineRepresentation output) { representation_ = output; } |
205 | 205 |
206 MachineRepresentation representation() const { return representation_; } | 206 MachineRepresentation representation() const { return representation_; } |
207 | 207 |
208 // Helpers for feedback typing. | 208 // Helpers for feedback typing. |
209 void set_feedback_type(Type* type) { feedback_type_ = type; } | 209 void set_feedback_type(Type* type) { feedback_type_ = type; } |
210 Type* feedback_type() { return feedback_type_; } | 210 Type* feedback_type() const { return feedback_type_; } |
211 void set_weakened() { weakened_ = true; } | 211 void set_weakened() { weakened_ = true; } |
212 bool weakened() { return weakened_; } | 212 bool weakened() const { return weakened_; } |
213 TypeCheckKind type_check() { return type_check_; } | 213 void set_restriction_type(Type* type) { restriction_type_ = type; } |
214 void set_type_check(TypeCheckKind type_check) { type_check_ = type_check; } | 214 Type* restriction_type() const { return restriction_type_; } |
215 | 215 |
216 private: | 216 private: |
217 enum State : uint8_t { kUnvisited, kPushed, kVisited, kQueued }; | 217 enum State : uint8_t { kUnvisited, kPushed, kVisited, kQueued }; |
218 State state_ = kUnvisited; | 218 State state_ = kUnvisited; |
219 MachineRepresentation representation_ = | 219 MachineRepresentation representation_ = |
220 MachineRepresentation::kNone; // Output representation. | 220 MachineRepresentation::kNone; // Output representation. |
221 Truncation truncation_ = Truncation::None(); // Information about uses. | 221 Truncation truncation_ = Truncation::None(); // Information about uses. |
222 TypeCheckKind type_check_ = TypeCheckKind::kNone; // Runtime check kind. | |
223 | 222 |
| 223 Type* restriction_type_ = Type::Any(); |
224 Type* feedback_type_ = nullptr; | 224 Type* feedback_type_ = nullptr; |
225 bool weakened_ = false; | 225 bool weakened_ = false; |
226 }; | 226 }; |
227 | 227 |
228 RepresentationSelector(JSGraph* jsgraph, Zone* zone, | 228 RepresentationSelector(JSGraph* jsgraph, Zone* zone, |
229 RepresentationChanger* changer, | 229 RepresentationChanger* changer, |
230 SourcePositionTable* source_positions) | 230 SourcePositionTable* source_positions) |
231 : jsgraph_(jsgraph), | 231 : jsgraph_(jsgraph), |
232 zone_(zone), | 232 zone_(zone), |
233 count_(jsgraph->graph()->NodeCount()), | 233 count_(jsgraph->graph()->NodeCount()), |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
336 type = op_typer_.Merge(type, FeedbackTypeOf(node->InputAt(i))); | 336 type = op_typer_.Merge(type, FeedbackTypeOf(node->InputAt(i))); |
337 } | 337 } |
338 return type; | 338 return type; |
339 } | 339 } |
340 | 340 |
341 Type* TypeSelect(Node* node) { | 341 Type* TypeSelect(Node* node) { |
342 return op_typer_.Merge(FeedbackTypeOf(node->InputAt(1)), | 342 return op_typer_.Merge(FeedbackTypeOf(node->InputAt(1)), |
343 FeedbackTypeOf(node->InputAt(2))); | 343 FeedbackTypeOf(node->InputAt(2))); |
344 } | 344 } |
345 | 345 |
346 static Type* TypeOfSpeculativeOp(TypeCheckKind type_check) { | |
347 switch (type_check) { | |
348 case TypeCheckKind::kNone: | |
349 return Type::Any(); | |
350 case TypeCheckKind::kSigned32: | |
351 return Type::Signed32(); | |
352 case TypeCheckKind::kNumber: | |
353 return Type::Number(); | |
354 // Unexpected cases. | |
355 case TypeCheckKind::kNumberOrUndefined: | |
356 FATAL("Unexpected checked type."); | |
357 break; | |
358 } | |
359 UNREACHABLE(); | |
360 return nullptr; | |
361 } | |
362 | |
363 bool UpdateFeedbackType(Node* node) { | 346 bool UpdateFeedbackType(Node* node) { |
364 if (node->op()->ValueOutputCount() == 0) return false; | 347 if (node->op()->ValueOutputCount() == 0) return false; |
365 | 348 |
366 NodeInfo* info = GetInfo(node); | 349 NodeInfo* info = GetInfo(node); |
367 Type* type = info->feedback_type(); | 350 Type* type = info->feedback_type(); |
368 Type* new_type = type; | 351 Type* new_type = type; |
369 | 352 |
370 // For any non-phi node just wait until we get all inputs typed. We only | 353 // For any non-phi node just wait until we get all inputs typed. We only |
371 // allow untyped inputs for phi nodes because phis are the only places | 354 // allow untyped inputs for phi nodes because phis are the only places |
372 // where cycles need to be broken. | 355 // where cycles need to be broken. |
373 if (node->opcode() != IrOpcode::kPhi) { | 356 if (node->opcode() != IrOpcode::kPhi) { |
374 for (int i = 0; i < node->op()->ValueInputCount(); i++) { | 357 for (int i = 0; i < node->op()->ValueInputCount(); i++) { |
375 if (GetInfo(node->InputAt(i))->feedback_type() == nullptr) { | 358 if (GetInfo(node->InputAt(i))->feedback_type() == nullptr) { |
376 return false; | 359 return false; |
377 } | 360 } |
378 } | 361 } |
379 } | 362 } |
380 | 363 |
381 switch (node->opcode()) { | 364 switch (node->opcode()) { |
| 365 case IrOpcode::kNumberAdd: |
382 case IrOpcode::kSpeculativeNumberAdd: { | 366 case IrOpcode::kSpeculativeNumberAdd: { |
383 // TODO(jarin) The ToNumber conversion is too conservative here, | 367 // TODO(jarin) The ToNumber conversion is too conservative here, |
384 // e.g. it will treat true as 1 even though the number check will | 368 // e.g. it will treat true as 1 even though the number check will |
385 // fail on a boolean. OperationTyper should have a function that | 369 // fail on a boolean. OperationTyper should have a function that |
386 // computes a more precise type. | 370 // computes a more precise type. |
387 Type* lhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0))); | 371 Type* lhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0))); |
388 Type* rhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(1))); | 372 Type* rhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(1))); |
389 Type* static_type = op_typer_.NumberAdd(lhs, rhs); | 373 Type* computed_type = op_typer_.NumberAdd(lhs, rhs); |
390 if (info->type_check() == TypeCheckKind::kNone) { | 374 new_type = Type::Intersect(computed_type, info->restriction_type(), |
391 new_type = static_type; | 375 graph_zone()); |
392 } else { | |
393 Type* feedback_type = TypeOfSpeculativeOp(info->type_check()); | |
394 new_type = Type::Intersect(static_type, feedback_type, graph_zone()); | |
395 } | |
396 break; | 376 break; |
397 } | 377 } |
398 | 378 |
| 379 case IrOpcode::kNumberSubtract: |
399 case IrOpcode::kSpeculativeNumberSubtract: { | 380 case IrOpcode::kSpeculativeNumberSubtract: { |
400 // TODO(jarin) The ToNumber conversion is too conservative here, | 381 // TODO(jarin) The ToNumber conversion is too conservative here, |
401 // e.g. it will treat true as 1 even though the number check will | 382 // e.g. it will treat true as 1 even though the number check will |
402 // fail on a boolean. OperationTyper should have a function that | 383 // fail on a boolean. OperationTyper should have a function that |
403 // computes a more precise type. | 384 // computes a more precise type. |
404 Type* lhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0))); | 385 Type* lhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0))); |
405 Type* rhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(1))); | 386 Type* rhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(1))); |
406 Type* static_type = op_typer_.NumberSubtract(lhs, rhs); | 387 Type* computed_type = op_typer_.NumberSubtract(lhs, rhs); |
407 if (info->type_check() == TypeCheckKind::kNone) { | 388 new_type = Type::Intersect(computed_type, info->restriction_type(), |
408 new_type = static_type; | 389 graph_zone()); |
409 } else { | |
410 Type* feedback_type = TypeOfSpeculativeOp(info->type_check()); | |
411 new_type = Type::Intersect(static_type, feedback_type, graph_zone()); | |
412 } | |
413 break; | 390 break; |
414 } | 391 } |
415 | 392 |
| 393 case IrOpcode::kNumberMultiply: |
416 case IrOpcode::kSpeculativeNumberMultiply: { | 394 case IrOpcode::kSpeculativeNumberMultiply: { |
417 // TODO(jarin) The ToNumber conversion is too conservative here, | 395 // TODO(jarin) The ToNumber conversion is too conservative here, |
418 // e.g. it will treat true as 1 even though the number check will | 396 // e.g. it will treat true as 1 even though the number check will |
419 // fail on a boolean. OperationTyper should have a function that | 397 // fail on a boolean. OperationTyper should have a function that |
420 // computes a more precise type. | 398 // computes a more precise type. |
421 Type* lhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0))); | 399 Type* lhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0))); |
422 Type* rhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(1))); | 400 Type* rhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(1))); |
423 Type* static_type = op_typer_.NumberMultiply(lhs, rhs); | 401 Type* computed_type = op_typer_.NumberMultiply(lhs, rhs); |
424 if (info->type_check() == TypeCheckKind::kNone) { | 402 new_type = Type::Intersect(computed_type, info->restriction_type(), |
425 new_type = static_type; | 403 graph_zone()); |
426 } else { | |
427 Type* feedback_type = TypeOfSpeculativeOp(info->type_check()); | |
428 new_type = Type::Intersect(static_type, feedback_type, graph_zone()); | |
429 } | |
430 break; | 404 break; |
431 } | 405 } |
432 | 406 |
| 407 case IrOpcode::kNumberDivide: |
433 case IrOpcode::kSpeculativeNumberDivide: { | 408 case IrOpcode::kSpeculativeNumberDivide: { |
434 // TODO(jarin) The ToNumber conversion is too conservative here, | 409 // TODO(jarin) The ToNumber conversion is too conservative here, |
435 // e.g. it will treat true as 1 even though the number check will | 410 // e.g. it will treat true as 1 even though the number check will |
436 // fail on a boolean. OperationTyper should have a function that | 411 // fail on a boolean. OperationTyper should have a function that |
437 // computes a more precise type. | 412 // computes a more precise type. |
438 Type* lhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0))); | 413 Type* lhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0))); |
439 Type* rhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(1))); | 414 Type* rhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(1))); |
440 Type* static_type = op_typer_.NumberDivide(lhs, rhs); | 415 Type* computed_type = op_typer_.NumberDivide(lhs, rhs); |
441 if (info->type_check() == TypeCheckKind::kNone) { | 416 new_type = Type::Intersect(computed_type, info->restriction_type(), |
442 new_type = static_type; | 417 graph_zone()); |
443 } else { | |
444 Type* feedback_type = TypeOfSpeculativeOp(info->type_check()); | |
445 new_type = Type::Intersect(static_type, feedback_type, graph_zone()); | |
446 } | |
447 break; | 418 break; |
448 } | 419 } |
449 | 420 |
| 421 case IrOpcode::kNumberModulus: |
450 case IrOpcode::kSpeculativeNumberModulus: { | 422 case IrOpcode::kSpeculativeNumberModulus: { |
451 // TODO(jarin) The ToNumber conversion is too conservative here, | 423 // TODO(jarin) The ToNumber conversion is too conservative here, |
452 // e.g. it will treat true as 1 even though the number check will | 424 // e.g. it will treat true as 1 even though the number check will |
453 // fail on a boolean. OperationTyper should have a function that | 425 // fail on a boolean. OperationTyper should have a function that |
454 // computes a more precise type. | 426 // computes a more precise type. |
455 Type* lhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0))); | 427 Type* lhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(0))); |
456 Type* rhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(1))); | 428 Type* rhs = op_typer_.ToNumber(FeedbackTypeOf(node->InputAt(1))); |
457 Type* static_type = op_typer_.NumberModulus(lhs, rhs); | 429 Type* computed_type = op_typer_.NumberModulus(lhs, rhs); |
458 if (info->type_check() == TypeCheckKind::kNone) { | 430 new_type = Type::Intersect(computed_type, info->restriction_type(), |
459 new_type = static_type; | 431 graph_zone()); |
460 } else { | |
461 Type* feedback_type = TypeOfSpeculativeOp(info->type_check()); | |
462 new_type = Type::Intersect(static_type, feedback_type, graph_zone()); | |
463 } | |
464 break; | 432 break; |
465 } | 433 } |
466 | 434 |
467 case IrOpcode::kNumberAbs: { | 435 case IrOpcode::kNumberAbs: { |
468 new_type = op_typer_.NumberAbs(FeedbackTypeOf(node->InputAt(0))); | 436 new_type = op_typer_.NumberAbs(FeedbackTypeOf(node->InputAt(0))); |
469 break; | 437 break; |
470 } | 438 } |
471 | 439 |
472 case IrOpcode::kPhi: { | 440 case IrOpcode::kPhi: { |
473 new_type = TypePhi(node); | 441 new_type = TypePhi(node); |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
650 } | 618 } |
651 PrintTruncation(info->truncation()); | 619 PrintTruncation(info->truncation()); |
652 } | 620 } |
653 } | 621 } |
654 | 622 |
655 bool lower() const { return phase_ == LOWER; } | 623 bool lower() const { return phase_ == LOWER; } |
656 bool retype() const { return phase_ == RETYPE; } | 624 bool retype() const { return phase_ == RETYPE; } |
657 bool propagate() const { return phase_ == PROPAGATE; } | 625 bool propagate() const { return phase_ == PROPAGATE; } |
658 | 626 |
659 void SetOutput(Node* node, MachineRepresentation representation, | 627 void SetOutput(Node* node, MachineRepresentation representation, |
660 TypeCheckKind type_check = TypeCheckKind::kNone) { | 628 Type* restriction_type = Type::Any()) { |
661 NodeInfo* const info = GetInfo(node); | 629 NodeInfo* const info = GetInfo(node); |
662 switch (phase_) { | 630 switch (phase_) { |
663 case PROPAGATE: | 631 case PROPAGATE: |
664 info->set_type_check(type_check); | 632 info->set_restriction_type(restriction_type); |
665 break; | 633 break; |
666 case RETYPE: | 634 case RETYPE: |
667 DCHECK_EQ(info->type_check(), type_check); | 635 DCHECK(info->restriction_type()->Is(restriction_type)); |
| 636 DCHECK(restriction_type->Is(info->restriction_type())); |
668 info->set_output(representation); | 637 info->set_output(representation); |
669 break; | 638 break; |
670 case LOWER: | 639 case LOWER: |
671 DCHECK_EQ(info->type_check(), type_check); | |
672 DCHECK_EQ(info->representation(), representation); | 640 DCHECK_EQ(info->representation(), representation); |
| 641 DCHECK(info->restriction_type()->Is(restriction_type)); |
| 642 DCHECK(restriction_type->Is(info->restriction_type())); |
673 break; | 643 break; |
674 } | 644 } |
675 } | 645 } |
676 | 646 |
677 void ResetOutput(Node* node, MachineRepresentation representation, | |
678 TypeCheckKind type_check = TypeCheckKind::kNone) { | |
679 NodeInfo* info = GetInfo(node); | |
680 info->set_output(representation); | |
681 info->set_type_check(type_check); | |
682 } | |
683 | |
684 Type* GetUpperBound(Node* node) { return NodeProperties::GetType(node); } | 647 Type* GetUpperBound(Node* node) { return NodeProperties::GetType(node); } |
685 | 648 |
686 bool InputCannotBe(Node* node, Type* type) { | 649 bool InputCannotBe(Node* node, Type* type) { |
687 DCHECK_EQ(1, node->op()->ValueInputCount()); | 650 DCHECK_EQ(1, node->op()->ValueInputCount()); |
688 return !GetUpperBound(node->InputAt(0))->Maybe(type); | 651 return !GetUpperBound(node->InputAt(0))->Maybe(type); |
689 } | 652 } |
690 | 653 |
691 bool InputIs(Node* node, Type* type) { | 654 bool InputIs(Node* node, Type* type) { |
692 DCHECK_EQ(1, node->op()->ValueInputCount()); | 655 DCHECK_EQ(1, node->op()->ValueInputCount()); |
693 return GetUpperBound(node->InputAt(0))->Is(type); | 656 return GetUpperBound(node->InputAt(0))->Is(type); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
770 } | 733 } |
771 // Only enqueue other inputs (framestates, effects, control). | 734 // Only enqueue other inputs (framestates, effects, control). |
772 for (int i = tagged_count; i < node->InputCount(); i++) { | 735 for (int i = tagged_count; i < node->InputCount(); i++) { |
773 EnqueueInput(node, i); | 736 EnqueueInput(node, i); |
774 } | 737 } |
775 } | 738 } |
776 | 739 |
777 // Helper for binops of the R x L -> O variety. | 740 // Helper for binops of the R x L -> O variety. |
778 void VisitBinop(Node* node, UseInfo left_use, UseInfo right_use, | 741 void VisitBinop(Node* node, UseInfo left_use, UseInfo right_use, |
779 MachineRepresentation output, | 742 MachineRepresentation output, |
780 TypeCheckKind type_check = TypeCheckKind::kNone) { | 743 Type* restriction_type = Type::Any()) { |
781 DCHECK_EQ(2, node->op()->ValueInputCount()); | 744 DCHECK_EQ(2, node->op()->ValueInputCount()); |
782 ProcessInput(node, 0, left_use); | 745 ProcessInput(node, 0, left_use); |
783 ProcessInput(node, 1, right_use); | 746 ProcessInput(node, 1, right_use); |
784 for (int i = 2; i < node->InputCount(); i++) { | 747 for (int i = 2; i < node->InputCount(); i++) { |
785 EnqueueInput(node, i); | 748 EnqueueInput(node, i); |
786 } | 749 } |
787 SetOutput(node, output, type_check); | 750 SetOutput(node, output, restriction_type); |
788 } | 751 } |
789 | 752 |
790 // Helper for binops of the I x I -> O variety. | 753 // Helper for binops of the I x I -> O variety. |
791 void VisitBinop(Node* node, UseInfo input_use, MachineRepresentation output, | 754 void VisitBinop(Node* node, UseInfo input_use, MachineRepresentation output, |
792 TypeCheckKind type_check = TypeCheckKind::kNone) { | 755 Type* restriction_type = Type::Any()) { |
793 VisitBinop(node, input_use, input_use, output, type_check); | 756 VisitBinop(node, input_use, input_use, output, restriction_type); |
794 } | 757 } |
795 | 758 |
796 // Helper for unops of the I -> O variety. | 759 // Helper for unops of the I -> O variety. |
797 void VisitUnop(Node* node, UseInfo input_use, MachineRepresentation output) { | 760 void VisitUnop(Node* node, UseInfo input_use, MachineRepresentation output) { |
798 DCHECK_EQ(1, node->op()->ValueInputCount()); | 761 DCHECK_EQ(1, node->op()->ValueInputCount()); |
799 ProcessInput(node, 0, input_use); | 762 ProcessInput(node, 0, input_use); |
800 ProcessRemainingInputs(node, 1); | 763 ProcessRemainingInputs(node, 1); |
801 SetOutput(node, output); | 764 SetOutput(node, output); |
802 } | 765 } |
803 | 766 |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
999 } | 962 } |
1000 | 963 |
1001 const Operator* Int32OverflowOp(Node* node) { | 964 const Operator* Int32OverflowOp(Node* node) { |
1002 return changer_->Int32OverflowOperatorFor(node->opcode()); | 965 return changer_->Int32OverflowOperatorFor(node->opcode()); |
1003 } | 966 } |
1004 | 967 |
1005 const Operator* Uint32Op(Node* node) { | 968 const Operator* Uint32Op(Node* node) { |
1006 return changer_->Uint32OperatorFor(node->opcode()); | 969 return changer_->Uint32OperatorFor(node->opcode()); |
1007 } | 970 } |
1008 | 971 |
| 972 const Operator* Uint32OverflowOp(Node* node) { |
| 973 return changer_->Uint32OverflowOperatorFor(node->opcode()); |
| 974 } |
| 975 |
1009 const Operator* Float64Op(Node* node) { | 976 const Operator* Float64Op(Node* node) { |
1010 return changer_->Float64OperatorFor(node->opcode()); | 977 return changer_->Float64OperatorFor(node->opcode()); |
1011 } | 978 } |
1012 | 979 |
1013 WriteBarrierKind WriteBarrierKindFor( | 980 WriteBarrierKind WriteBarrierKindFor( |
1014 BaseTaggedness base_taggedness, | 981 BaseTaggedness base_taggedness, |
1015 MachineRepresentation field_representation, Type* field_type, | 982 MachineRepresentation field_representation, Type* field_type, |
1016 Node* value) { | 983 Node* value) { |
1017 if (base_taggedness == kTaggedBase && | 984 if (base_taggedness == kTaggedBase && |
1018 field_representation == MachineRepresentation::kTagged) { | 985 field_representation == MachineRepresentation::kTagged) { |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1101 Node* effect = NodeProperties::GetEffectInput(node); | 1068 Node* effect = NodeProperties::GetEffectInput(node); |
1102 ReplaceEffectControlUses(node, effect, control); | 1069 ReplaceEffectControlUses(node, effect, control); |
1103 node->TrimInputCount(new_op->ValueInputCount()); | 1070 node->TrimInputCount(new_op->ValueInputCount()); |
1104 } else { | 1071 } else { |
1105 DCHECK_EQ(0, node->op()->ControlInputCount()); | 1072 DCHECK_EQ(0, node->op()->ControlInputCount()); |
1106 } | 1073 } |
1107 | 1074 |
1108 NodeProperties::ChangeOp(node, new_op); | 1075 NodeProperties::ChangeOp(node, new_op); |
1109 } | 1076 } |
1110 | 1077 |
1111 void ChangeToInt32OverflowOp(Node* node, const Operator* new_op) { | 1078 void ChangeToInt32OverflowOp(Node* node) { |
1112 NodeProperties::ChangeOp(node, new_op); | 1079 NodeProperties::ChangeOp(node, Int32OverflowOp(node)); |
| 1080 } |
| 1081 |
| 1082 void ChangeToUint32OverflowOp(Node* node) { |
| 1083 NodeProperties::ChangeOp(node, Uint32OverflowOp(node)); |
1113 } | 1084 } |
1114 | 1085 |
1115 void VisitSpeculativeAdditiveOp(Node* node, Truncation truncation, | 1086 void VisitSpeculativeAdditiveOp(Node* node, Truncation truncation, |
1116 SimplifiedLowering* lowering) { | 1087 SimplifiedLowering* lowering) { |
1117 if (BothInputsAre(node, type_cache_.kSigned32OrMinusZero) && | 1088 if (BothInputsAre(node, type_cache_.kSigned32OrMinusZero) && |
1118 NodeProperties::GetType(node)->Is(Type::Signed32())) { | 1089 NodeProperties::GetType(node)->Is(Type::Signed32())) { |
1119 // int32 + int32 = int32 ==> signed Int32Add/Sub | 1090 // int32 + int32 = int32 ==> signed Int32Add/Sub |
1120 VisitInt32Binop(node); | 1091 VisitInt32Binop(node); |
1121 if (lower()) ChangeToPureOp(node, Int32Op(node)); | 1092 if (lower()) ChangeToPureOp(node, Int32Op(node)); |
1122 return; | 1093 return; |
(...skipping 14 matching lines...) Expand all Loading... |
1137 | 1108 |
1138 // Handle the case when no int32 checks on inputs are necessary | 1109 // Handle the case when no int32 checks on inputs are necessary |
1139 // (but an overflow check is needed on the output). | 1110 // (but an overflow check is needed on the output). |
1140 if (BothInputsAre(node, Type::Signed32()) || | 1111 if (BothInputsAre(node, Type::Signed32()) || |
1141 (BothInputsAre(node, type_cache_.kSigned32OrMinusZero) && | 1112 (BothInputsAre(node, type_cache_.kSigned32OrMinusZero) && |
1142 NodeProperties::GetType(node)->Is(type_cache_.kSafeInteger))) { | 1113 NodeProperties::GetType(node)->Is(type_cache_.kSafeInteger))) { |
1143 // If both the inputs the feedback are int32, use the overflow op. | 1114 // If both the inputs the feedback are int32, use the overflow op. |
1144 if (hint == BinaryOperationHints::kSignedSmall || | 1115 if (hint == BinaryOperationHints::kSignedSmall || |
1145 hint == BinaryOperationHints::kSigned32) { | 1116 hint == BinaryOperationHints::kSigned32) { |
1146 VisitBinop(node, UseInfo::TruncatingWord32(), | 1117 VisitBinop(node, UseInfo::TruncatingWord32(), |
1147 MachineRepresentation::kWord32, TypeCheckKind::kSigned32); | 1118 MachineRepresentation::kWord32, Type::Signed32()); |
1148 if (lower()) { | 1119 if (lower()) ChangeToInt32OverflowOp(node); |
1149 ChangeToInt32OverflowOp(node, Int32OverflowOp(node)); | |
1150 } | |
1151 return; | 1120 return; |
1152 } | 1121 } |
1153 } | 1122 } |
1154 | 1123 |
1155 if (hint == BinaryOperationHints::kSignedSmall || | 1124 if (hint == BinaryOperationHints::kSignedSmall || |
1156 hint == BinaryOperationHints::kSigned32) { | 1125 hint == BinaryOperationHints::kSigned32) { |
1157 VisitBinop(node, UseInfo::CheckedSigned32AsWord32(), | 1126 VisitBinop(node, UseInfo::CheckedSigned32AsWord32(), |
1158 MachineRepresentation::kWord32, TypeCheckKind::kSigned32); | 1127 MachineRepresentation::kWord32, Type::Signed32()); |
1159 if (lower()) { | 1128 if (lower()) ChangeToInt32OverflowOp(node); |
1160 ChangeToInt32OverflowOp(node, Int32OverflowOp(node)); | |
1161 } | |
1162 return; | 1129 return; |
1163 } | 1130 } |
1164 | 1131 |
1165 // default case => Float64Add/Sub | 1132 // default case => Float64Add/Sub |
1166 VisitBinop(node, UseInfo::CheckedNumberOrUndefinedAsFloat64(), | 1133 VisitBinop(node, UseInfo::CheckedNumberOrUndefinedAsFloat64(), |
1167 MachineRepresentation::kFloat64, TypeCheckKind::kNumber); | 1134 MachineRepresentation::kFloat64, Type::Number()); |
1168 if (lower()) { | 1135 if (lower()) { |
1169 ChangeToPureOp(node, Float64Op(node)); | 1136 ChangeToPureOp(node, Float64Op(node)); |
1170 } | 1137 } |
1171 return; | 1138 return; |
1172 } | 1139 } |
1173 | 1140 |
1174 // Dispatching routine for visiting the node {node} with the usage {use}. | 1141 // Dispatching routine for visiting the node {node} with the usage {use}. |
1175 // Depending on the operator, propagate new usage info to the inputs. | 1142 // Depending on the operator, propagate new usage info to the inputs. |
1176 void VisitNode(Node* node, Truncation truncation, | 1143 void VisitNode(Node* node, Truncation truncation, |
1177 SimplifiedLowering* lowering) { | 1144 SimplifiedLowering* lowering) { |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1341 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); | 1308 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); |
1342 } else { | 1309 } else { |
1343 // => Float64Add/Sub | 1310 // => Float64Add/Sub |
1344 VisitFloat64Binop(node); | 1311 VisitFloat64Binop(node); |
1345 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); | 1312 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); |
1346 } | 1313 } |
1347 return; | 1314 return; |
1348 } | 1315 } |
1349 case IrOpcode::kSpeculativeNumberMultiply: | 1316 case IrOpcode::kSpeculativeNumberMultiply: |
1350 case IrOpcode::kNumberMultiply: { | 1317 case IrOpcode::kNumberMultiply: { |
1351 if (BothInputsAreSigned32(node)) { | 1318 if (BothInputsAre(node, Type::Integral32()) && |
1352 if (NodeProperties::GetType(node)->Is(Type::Signed32())) { | 1319 (NodeProperties::GetType(node)->Is(Type::Signed32()) || |
1353 // Multiply reduces to Int32Mul if the inputs and the output | 1320 NodeProperties::GetType(node)->Is(Type::Unsigned32()) || |
1354 // are integers. | 1321 (truncation.TruncatesToWord32() && |
1355 VisitInt32Binop(node); | |
1356 if (lower()) ChangeToPureOp(node, Int32Op(node)); | |
1357 return; | |
1358 } | |
1359 if (truncation.TruncatesToWord32() && | |
1360 NodeProperties::GetType(node)->Is( | 1322 NodeProperties::GetType(node)->Is( |
1361 type_cache_.kSafeIntegerOrMinusZero)) { | 1323 type_cache_.kSafeIntegerOrMinusZero)))) { |
1362 // Multiply reduces to Int32Mul if the inputs are integers, | 1324 // Multiply reduces to Int32Mul if the inputs are integers, and |
1363 // the uses are truncating and the result is in the safe | 1325 // (a) the output is either known to be Signed32, or |
1364 // integer range. | 1326 // (b) the output is known to be Unsigned32, or |
1365 VisitWord32TruncatingBinop(node); | 1327 // (c) the uses are truncating and the result is in the safe |
1366 if (lower()) ChangeToPureOp(node, Int32Op(node)); | 1328 // integer range. |
1367 return; | 1329 VisitWord32TruncatingBinop(node); |
1368 } | 1330 if (lower()) ChangeToPureOp(node, Int32Op(node)); |
| 1331 return; |
1369 } | 1332 } |
1370 // Number x Number => Float64Mul | 1333 // Number x Number => Float64Mul |
1371 if (BothInputsAre(node, Type::NumberOrUndefined())) { | 1334 if (BothInputsAre(node, Type::NumberOrUndefined())) { |
1372 VisitFloat64Binop(node); | 1335 VisitFloat64Binop(node); |
1373 if (lower()) ChangeToPureOp(node, Float64Op(node)); | 1336 if (lower()) ChangeToPureOp(node, Float64Op(node)); |
1374 return; | 1337 return; |
1375 } | 1338 } |
1376 // Checked float64 x float64 => float64 | 1339 // Checked float64 x float64 => float64 |
1377 DCHECK_EQ(IrOpcode::kSpeculativeNumberMultiply, node->opcode()); | 1340 DCHECK_EQ(IrOpcode::kSpeculativeNumberMultiply, node->opcode()); |
1378 VisitBinop(node, UseInfo::CheckedNumberOrUndefinedAsFloat64(), | 1341 VisitBinop(node, UseInfo::CheckedNumberOrUndefinedAsFloat64(), |
1379 MachineRepresentation::kFloat64, TypeCheckKind::kNumber); | 1342 MachineRepresentation::kFloat64, Type::Number()); |
1380 if (lower()) ChangeToPureOp(node, Float64Op(node)); | 1343 if (lower()) ChangeToPureOp(node, Float64Op(node)); |
1381 return; | 1344 return; |
1382 } | 1345 } |
1383 case IrOpcode::kSpeculativeNumberDivide: { | 1346 case IrOpcode::kSpeculativeNumberDivide: { |
1384 if (BothInputsAreUnsigned32(node) && truncation.TruncatesToWord32()) { | 1347 if (BothInputsAreUnsigned32(node) && truncation.TruncatesToWord32()) { |
1385 // => unsigned Uint32Div | 1348 // => unsigned Uint32Div |
1386 VisitWord32TruncatingBinop(node); | 1349 VisitWord32TruncatingBinop(node); |
1387 if (lower()) DeferReplacement(node, lowering->Uint32Div(node)); | 1350 if (lower()) DeferReplacement(node, lowering->Uint32Div(node)); |
1388 return; | 1351 return; |
1389 } | 1352 } |
1390 if (BothInputsAreSigned32(node)) { | 1353 if (BothInputsAreSigned32(node)) { |
1391 if (NodeProperties::GetType(node)->Is(Type::Signed32())) { | 1354 if (NodeProperties::GetType(node)->Is(Type::Signed32())) { |
1392 // => signed Int32Div | 1355 // => signed Int32Div |
1393 VisitInt32Binop(node); | 1356 VisitInt32Binop(node); |
1394 if (lower()) DeferReplacement(node, lowering->Int32Div(node)); | 1357 if (lower()) DeferReplacement(node, lowering->Int32Div(node)); |
1395 return; | 1358 return; |
1396 } | 1359 } |
1397 if (truncation.TruncatesToWord32()) { | 1360 if (truncation.TruncatesToWord32()) { |
1398 // => signed Int32Div | 1361 // => signed Int32Div |
1399 VisitWord32TruncatingBinop(node); | 1362 VisitWord32TruncatingBinop(node); |
1400 if (lower()) DeferReplacement(node, lowering->Int32Div(node)); | 1363 if (lower()) DeferReplacement(node, lowering->Int32Div(node)); |
1401 return; | 1364 return; |
1402 } | 1365 } |
1403 } | 1366 } |
1404 | 1367 |
1405 // Try to use type feedback. | 1368 // Try to use type feedback. |
1406 BinaryOperationHints::Hint hint = BinaryOperationHintOf(node->op()); | 1369 BinaryOperationHints::Hint hint = BinaryOperationHintOf(node->op()); |
1407 | 1370 |
| 1371 // Handle the case when no uint32 checks on inputs are necessary |
| 1372 // (but an overflow check is needed on the output). |
| 1373 if (BothInputsAreUnsigned32(node)) { |
| 1374 if (hint == BinaryOperationHints::kSignedSmall || |
| 1375 hint == BinaryOperationHints::kSigned32) { |
| 1376 VisitBinop(node, UseInfo::TruncatingWord32(), |
| 1377 MachineRepresentation::kWord32, Type::Unsigned32()); |
| 1378 if (lower()) ChangeToUint32OverflowOp(node); |
| 1379 return; |
| 1380 } |
| 1381 } |
| 1382 |
1408 // Handle the case when no int32 checks on inputs are necessary | 1383 // Handle the case when no int32 checks on inputs are necessary |
1409 // (but an overflow check is needed on the output). | 1384 // (but an overflow check is needed on the output). |
1410 if (BothInputsAre(node, Type::Signed32())) { | 1385 if (BothInputsAreSigned32(node)) { |
1411 // If both the inputs the feedback are int32, use the overflow op. | 1386 // If both the inputs the feedback are int32, use the overflow op. |
1412 if (hint == BinaryOperationHints::kSignedSmall || | 1387 if (hint == BinaryOperationHints::kSignedSmall || |
1413 hint == BinaryOperationHints::kSigned32) { | 1388 hint == BinaryOperationHints::kSigned32) { |
1414 VisitBinop(node, UseInfo::TruncatingWord32(), | 1389 VisitBinop(node, UseInfo::TruncatingWord32(), |
1415 MachineRepresentation::kWord32, | 1390 MachineRepresentation::kWord32, Type::Signed32()); |
1416 TypeCheckKind::kSigned32); | 1391 if (lower()) ChangeToInt32OverflowOp(node); |
1417 if (lower()) ChangeToInt32OverflowOp(node, Int32OverflowOp(node)); | |
1418 return; | 1392 return; |
1419 } | 1393 } |
1420 } | 1394 } |
1421 | 1395 |
1422 if (hint == BinaryOperationHints::kSignedSmall || | 1396 if (hint == BinaryOperationHints::kSignedSmall || |
1423 hint == BinaryOperationHints::kSigned32) { | 1397 hint == BinaryOperationHints::kSigned32) { |
1424 // If the result is truncated, we only need to check the inputs. | 1398 // If the result is truncated, we only need to check the inputs. |
1425 if (truncation.TruncatesToWord32()) { | 1399 if (truncation.TruncatesToWord32()) { |
1426 VisitBinop(node, UseInfo::CheckedSigned32AsWord32(), | 1400 VisitBinop(node, UseInfo::CheckedSigned32AsWord32(), |
1427 MachineRepresentation::kWord32); | 1401 MachineRepresentation::kWord32); |
1428 if (lower()) DeferReplacement(node, lowering->Int32Div(node)); | 1402 if (lower()) DeferReplacement(node, lowering->Int32Div(node)); |
1429 } else { | 1403 } else { |
1430 VisitBinop(node, UseInfo::CheckedSigned32AsWord32(), | 1404 VisitBinop(node, UseInfo::CheckedSigned32AsWord32(), |
1431 MachineRepresentation::kWord32, | 1405 MachineRepresentation::kWord32, Type::Signed32()); |
1432 TypeCheckKind::kSigned32); | 1406 if (lower()) ChangeToInt32OverflowOp(node); |
1433 if (lower()) ChangeToInt32OverflowOp(node, Int32OverflowOp(node)); | |
1434 } | 1407 } |
1435 return; | 1408 return; |
1436 } | 1409 } |
1437 | 1410 |
1438 // default case => Float64Div | 1411 // default case => Float64Div |
1439 VisitBinop(node, UseInfo::CheckedNumberOrUndefinedAsFloat64(), | 1412 VisitBinop(node, UseInfo::CheckedNumberOrUndefinedAsFloat64(), |
1440 MachineRepresentation::kFloat64, TypeCheckKind::kNumber); | 1413 MachineRepresentation::kFloat64, Type::Number()); |
1441 if (lower()) ChangeToPureOp(node, Float64Op(node)); | 1414 if (lower()) ChangeToPureOp(node, Float64Op(node)); |
1442 return; | 1415 return; |
1443 } | 1416 } |
1444 case IrOpcode::kNumberDivide: { | 1417 case IrOpcode::kNumberDivide: { |
1445 if (BothInputsAreUnsigned32(node) && truncation.TruncatesToWord32()) { | 1418 if (BothInputsAreUnsigned32(node) && truncation.TruncatesToWord32()) { |
1446 // => unsigned Uint32Div | 1419 // => unsigned Uint32Div |
1447 VisitWord32TruncatingBinop(node); | 1420 VisitWord32TruncatingBinop(node); |
1448 if (lower()) DeferReplacement(node, lowering->Uint32Div(node)); | 1421 if (lower()) DeferReplacement(node, lowering->Uint32Div(node)); |
1449 return; | 1422 return; |
1450 } | 1423 } |
(...skipping 13 matching lines...) Expand all Loading... |
1464 } | 1437 } |
1465 // Number x Number => Float64Div | 1438 // Number x Number => Float64Div |
1466 if (BothInputsAre(node, Type::NumberOrUndefined())) { | 1439 if (BothInputsAre(node, Type::NumberOrUndefined())) { |
1467 VisitFloat64Binop(node); | 1440 VisitFloat64Binop(node); |
1468 if (lower()) ChangeToPureOp(node, Float64Op(node)); | 1441 if (lower()) ChangeToPureOp(node, Float64Op(node)); |
1469 return; | 1442 return; |
1470 } | 1443 } |
1471 // Checked float64 x float64 => float64 | 1444 // Checked float64 x float64 => float64 |
1472 DCHECK_EQ(IrOpcode::kSpeculativeNumberDivide, node->opcode()); | 1445 DCHECK_EQ(IrOpcode::kSpeculativeNumberDivide, node->opcode()); |
1473 VisitBinop(node, UseInfo::CheckedNumberOrUndefinedAsFloat64(), | 1446 VisitBinop(node, UseInfo::CheckedNumberOrUndefinedAsFloat64(), |
1474 MachineRepresentation::kFloat64, TypeCheckKind::kNumber); | 1447 MachineRepresentation::kFloat64, Type::Number()); |
1475 if (lower()) ChangeToPureOp(node, Float64Op(node)); | 1448 if (lower()) ChangeToPureOp(node, Float64Op(node)); |
1476 return; | 1449 return; |
1477 } | 1450 } |
1478 case IrOpcode::kSpeculativeNumberModulus: { | 1451 case IrOpcode::kSpeculativeNumberModulus: { |
1479 if (BothInputsAreUnsigned32(node) && truncation.TruncatesToWord32()) { | 1452 if (BothInputsAreUnsigned32(node) && truncation.TruncatesToWord32()) { |
1480 // => unsigned Uint32Mod | 1453 // => unsigned Uint32Mod |
1481 VisitWord32TruncatingBinop(node); | 1454 VisitWord32TruncatingBinop(node); |
1482 if (lower()) DeferReplacement(node, lowering->Uint32Mod(node)); | 1455 if (lower()) DeferReplacement(node, lowering->Uint32Mod(node)); |
1483 return; | 1456 return; |
1484 } | 1457 } |
1485 if (BothInputsAreSigned32(node)) { | 1458 if (BothInputsAreSigned32(node)) { |
1486 if (NodeProperties::GetType(node)->Is(Type::Signed32())) { | 1459 if (NodeProperties::GetType(node)->Is(Type::Signed32())) { |
1487 // => signed Int32Mod | 1460 // => signed Int32Mod |
1488 VisitInt32Binop(node); | 1461 VisitInt32Binop(node); |
1489 if (lower()) DeferReplacement(node, lowering->Int32Mod(node)); | 1462 if (lower()) DeferReplacement(node, lowering->Int32Mod(node)); |
1490 return; | 1463 return; |
1491 } | 1464 } |
1492 if (truncation.TruncatesToWord32()) { | 1465 if (truncation.TruncatesToWord32()) { |
1493 // => signed Int32Mod | 1466 // => signed Int32Mod |
1494 VisitWord32TruncatingBinop(node); | 1467 VisitWord32TruncatingBinop(node); |
1495 if (lower()) DeferReplacement(node, lowering->Int32Mod(node)); | 1468 if (lower()) DeferReplacement(node, lowering->Int32Mod(node)); |
1496 return; | 1469 return; |
1497 } | 1470 } |
1498 } | 1471 } |
1499 | 1472 |
1500 // Try to use type feedback. | 1473 // Try to use type feedback. |
1501 BinaryOperationHints::Hint hint = BinaryOperationHintOf(node->op()); | 1474 BinaryOperationHints::Hint hint = BinaryOperationHintOf(node->op()); |
1502 | 1475 |
| 1476 // Handle the case when no uint32 checks on inputs are necessary |
| 1477 // (but an overflow check is needed on the output). |
| 1478 if (BothInputsAreUnsigned32(node)) { |
| 1479 if (hint == BinaryOperationHints::kSignedSmall || |
| 1480 hint == BinaryOperationHints::kSigned32) { |
| 1481 VisitBinop(node, UseInfo::TruncatingWord32(), |
| 1482 MachineRepresentation::kWord32, Type::Unsigned32()); |
| 1483 if (lower()) ChangeToUint32OverflowOp(node); |
| 1484 return; |
| 1485 } |
| 1486 } |
| 1487 |
1503 // Handle the case when no int32 checks on inputs are necessary | 1488 // Handle the case when no int32 checks on inputs are necessary |
1504 // (but an overflow check is needed on the output). | 1489 // (but an overflow check is needed on the output). |
1505 if (BothInputsAre(node, Type::Signed32())) { | 1490 if (BothInputsAre(node, Type::Signed32())) { |
1506 // If both the inputs the feedback are int32, use the overflow op. | 1491 // If both the inputs the feedback are int32, use the overflow op. |
1507 if (hint == BinaryOperationHints::kSignedSmall || | 1492 if (hint == BinaryOperationHints::kSignedSmall || |
1508 hint == BinaryOperationHints::kSigned32) { | 1493 hint == BinaryOperationHints::kSigned32) { |
1509 VisitBinop(node, UseInfo::TruncatingWord32(), | 1494 VisitBinop(node, UseInfo::TruncatingWord32(), |
1510 MachineRepresentation::kWord32, | 1495 MachineRepresentation::kWord32, Type::Signed32()); |
1511 TypeCheckKind::kSigned32); | 1496 if (lower()) ChangeToInt32OverflowOp(node); |
1512 if (lower()) ChangeToInt32OverflowOp(node, Int32OverflowOp(node)); | |
1513 return; | 1497 return; |
1514 } | 1498 } |
1515 } | 1499 } |
1516 | 1500 |
1517 if (hint == BinaryOperationHints::kSignedSmall || | 1501 if (hint == BinaryOperationHints::kSignedSmall || |
1518 hint == BinaryOperationHints::kSigned32) { | 1502 hint == BinaryOperationHints::kSigned32) { |
1519 // If the result is truncated, we only need to check the inputs. | 1503 // If the result is truncated, we only need to check the inputs. |
1520 if (truncation.TruncatesToWord32()) { | 1504 if (truncation.TruncatesToWord32()) { |
1521 VisitBinop(node, UseInfo::CheckedSigned32AsWord32(), | 1505 VisitBinop(node, UseInfo::CheckedSigned32AsWord32(), |
1522 MachineRepresentation::kWord32); | 1506 MachineRepresentation::kWord32); |
1523 if (lower()) DeferReplacement(node, lowering->Int32Mod(node)); | 1507 if (lower()) DeferReplacement(node, lowering->Int32Mod(node)); |
1524 } else { | 1508 } else { |
1525 VisitBinop(node, UseInfo::CheckedSigned32AsWord32(), | 1509 VisitBinop(node, UseInfo::CheckedSigned32AsWord32(), |
1526 MachineRepresentation::kWord32, | 1510 MachineRepresentation::kWord32, Type::Signed32()); |
1527 TypeCheckKind::kSigned32); | 1511 if (lower()) ChangeToInt32OverflowOp(node); |
1528 if (lower()) ChangeToInt32OverflowOp(node, Int32OverflowOp(node)); | |
1529 } | 1512 } |
1530 return; | 1513 return; |
1531 } | 1514 } |
1532 | 1515 |
1533 // default case => Float64Mod | 1516 // default case => Float64Mod |
1534 VisitBinop(node, UseInfo::CheckedNumberOrUndefinedAsFloat64(), | 1517 VisitBinop(node, UseInfo::CheckedNumberOrUndefinedAsFloat64(), |
1535 MachineRepresentation::kFloat64, TypeCheckKind::kNumber); | 1518 MachineRepresentation::kFloat64, Type::Number()); |
1536 if (lower()) ChangeToPureOp(node, Float64Op(node)); | 1519 if (lower()) ChangeToPureOp(node, Float64Op(node)); |
1537 return; | 1520 return; |
1538 } | 1521 } |
1539 case IrOpcode::kNumberModulus: { | 1522 case IrOpcode::kNumberModulus: { |
1540 if (BothInputsAreUnsigned32(node) && truncation.TruncatesToWord32()) { | 1523 if (BothInputsAreUnsigned32(node) && truncation.TruncatesToWord32()) { |
1541 // => unsigned Uint32Mod | 1524 // => unsigned Uint32Mod |
1542 VisitWord32TruncatingBinop(node); | 1525 VisitWord32TruncatingBinop(node); |
1543 if (lower()) DeferReplacement(node, lowering->Uint32Mod(node)); | 1526 if (lower()) DeferReplacement(node, lowering->Uint32Mod(node)); |
1544 return; | 1527 return; |
1545 } | 1528 } |
(...skipping 1742 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3288 isolate(), graph()->zone(), callable.descriptor(), 0, flags, | 3271 isolate(), graph()->zone(), callable.descriptor(), 0, flags, |
3289 Operator::kNoProperties); | 3272 Operator::kNoProperties); |
3290 to_number_operator_.set(common()->Call(desc)); | 3273 to_number_operator_.set(common()->Call(desc)); |
3291 } | 3274 } |
3292 return to_number_operator_.get(); | 3275 return to_number_operator_.get(); |
3293 } | 3276 } |
3294 | 3277 |
3295 } // namespace compiler | 3278 } // namespace compiler |
3296 } // namespace internal | 3279 } // namespace internal |
3297 } // namespace v8 | 3280 } // namespace v8 |
OLD | NEW |