OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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-operator.h" | 5 #include "src/compiler/simplified-operator.h" |
6 | 6 |
7 #include "src/base/lazy-instance.h" | 7 #include "src/base/lazy-instance.h" |
8 #include "src/compiler/opcodes.h" | 8 #include "src/compiler/opcodes.h" |
9 #include "src/compiler/operator.h" | 9 #include "src/compiler/operator.h" |
10 #include "src/types.h" | 10 #include "src/types.h" |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
262 } | 262 } |
263 UNREACHABLE(); | 263 UNREACHABLE(); |
264 return os; | 264 return os; |
265 } | 265 } |
266 | 266 |
267 ElementsTransition ElementsTransitionOf(const Operator* op) { | 267 ElementsTransition ElementsTransitionOf(const Operator* op) { |
268 DCHECK_EQ(IrOpcode::kTransitionElementsKind, op->opcode()); | 268 DCHECK_EQ(IrOpcode::kTransitionElementsKind, op->opcode()); |
269 return OpParameter<ElementsTransition>(op); | 269 return OpParameter<ElementsTransition>(op); |
270 } | 270 } |
271 | 271 |
272 BinaryOperationHints::Hint BinaryOperationHintOf(const Operator* op) { | 272 std::ostream& operator<<(std::ostream& os, NumberOperationHint hint) { |
| 273 switch (hint) { |
| 274 case NumberOperationHint::kSignedSmall: |
| 275 return os << "SignedSmall"; |
| 276 case NumberOperationHint::kSigned32: |
| 277 return os << "Signed32"; |
| 278 case NumberOperationHint::kNumberOrOddball: |
| 279 return os << "NumberOrOddball"; |
| 280 } |
| 281 UNREACHABLE(); |
| 282 return os; |
| 283 } |
| 284 |
| 285 size_t hash_value(NumberOperationHint hint) { |
| 286 return static_cast<uint8_t>(hint); |
| 287 } |
| 288 |
| 289 NumberOperationHint NumberOperationHintOf(const Operator* op) { |
273 DCHECK(op->opcode() == IrOpcode::kSpeculativeNumberAdd || | 290 DCHECK(op->opcode() == IrOpcode::kSpeculativeNumberAdd || |
274 op->opcode() == IrOpcode::kSpeculativeNumberSubtract || | 291 op->opcode() == IrOpcode::kSpeculativeNumberSubtract || |
275 op->opcode() == IrOpcode::kSpeculativeNumberMultiply || | 292 op->opcode() == IrOpcode::kSpeculativeNumberMultiply || |
276 op->opcode() == IrOpcode::kSpeculativeNumberDivide || | 293 op->opcode() == IrOpcode::kSpeculativeNumberDivide || |
277 op->opcode() == IrOpcode::kSpeculativeNumberModulus || | 294 op->opcode() == IrOpcode::kSpeculativeNumberModulus || |
278 op->opcode() == IrOpcode::kSpeculativeNumberShiftLeft || | 295 op->opcode() == IrOpcode::kSpeculativeNumberShiftLeft || |
279 op->opcode() == IrOpcode::kSpeculativeNumberShiftRight || | 296 op->opcode() == IrOpcode::kSpeculativeNumberShiftRight || |
280 op->opcode() == IrOpcode::kSpeculativeNumberShiftRightLogical || | 297 op->opcode() == IrOpcode::kSpeculativeNumberShiftRightLogical || |
281 op->opcode() == IrOpcode::kSpeculativeNumberBitwiseAnd || | 298 op->opcode() == IrOpcode::kSpeculativeNumberBitwiseAnd || |
282 op->opcode() == IrOpcode::kSpeculativeNumberBitwiseOr || | 299 op->opcode() == IrOpcode::kSpeculativeNumberBitwiseOr || |
283 op->opcode() == IrOpcode::kSpeculativeNumberBitwiseXor); | 300 op->opcode() == IrOpcode::kSpeculativeNumberBitwiseXor || |
284 return OpParameter<BinaryOperationHints::Hint>(op); | 301 op->opcode() == IrOpcode::kSpeculativeNumberEqual || |
285 } | |
286 | |
287 CompareOperationHints::Hint CompareOperationHintOf(const Operator* op) { | |
288 DCHECK(op->opcode() == IrOpcode::kSpeculativeNumberEqual || | |
289 op->opcode() == IrOpcode::kSpeculativeNumberLessThan || | 302 op->opcode() == IrOpcode::kSpeculativeNumberLessThan || |
290 op->opcode() == IrOpcode::kSpeculativeNumberLessThanOrEqual); | 303 op->opcode() == IrOpcode::kSpeculativeNumberLessThanOrEqual); |
291 return OpParameter<CompareOperationHints::Hint>(op); | 304 return OpParameter<NumberOperationHint>(op); |
292 } | 305 } |
293 | 306 |
294 #define PURE_OP_LIST(V) \ | 307 #define PURE_OP_LIST(V) \ |
295 V(BooleanNot, Operator::kNoProperties, 1, 0) \ | 308 V(BooleanNot, Operator::kNoProperties, 1, 0) \ |
296 V(NumberEqual, Operator::kCommutative, 2, 0) \ | 309 V(NumberEqual, Operator::kCommutative, 2, 0) \ |
297 V(NumberLessThan, Operator::kNoProperties, 2, 0) \ | 310 V(NumberLessThan, Operator::kNoProperties, 2, 0) \ |
298 V(NumberLessThanOrEqual, Operator::kNoProperties, 2, 0) \ | 311 V(NumberLessThanOrEqual, Operator::kNoProperties, 2, 0) \ |
299 V(NumberAdd, Operator::kCommutative, 2, 0) \ | 312 V(NumberAdd, Operator::kCommutative, 2, 0) \ |
300 V(NumberSubtract, Operator::kNoProperties, 2, 0) \ | 313 V(NumberSubtract, Operator::kNoProperties, 2, 0) \ |
301 V(NumberMultiply, Operator::kCommutative, 2, 0) \ | 314 V(NumberMultiply, Operator::kCommutative, 2, 0) \ |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
363 V(ObjectIsCallable, Operator::kNoProperties, 1, 0) \ | 376 V(ObjectIsCallable, Operator::kNoProperties, 1, 0) \ |
364 V(ObjectIsNumber, Operator::kNoProperties, 1, 0) \ | 377 V(ObjectIsNumber, Operator::kNoProperties, 1, 0) \ |
365 V(ObjectIsReceiver, Operator::kNoProperties, 1, 0) \ | 378 V(ObjectIsReceiver, Operator::kNoProperties, 1, 0) \ |
366 V(ObjectIsSmi, Operator::kNoProperties, 1, 0) \ | 379 V(ObjectIsSmi, Operator::kNoProperties, 1, 0) \ |
367 V(ObjectIsString, Operator::kNoProperties, 1, 0) \ | 380 V(ObjectIsString, Operator::kNoProperties, 1, 0) \ |
368 V(ObjectIsUndetectable, Operator::kNoProperties, 1, 0) \ | 381 V(ObjectIsUndetectable, Operator::kNoProperties, 1, 0) \ |
369 V(StringEqual, Operator::kCommutative, 2, 0) \ | 382 V(StringEqual, Operator::kCommutative, 2, 0) \ |
370 V(StringLessThan, Operator::kNoProperties, 2, 0) \ | 383 V(StringLessThan, Operator::kNoProperties, 2, 0) \ |
371 V(StringLessThanOrEqual, Operator::kNoProperties, 2, 0) | 384 V(StringLessThanOrEqual, Operator::kNoProperties, 2, 0) |
372 | 385 |
373 #define SPECULATIVE_BINOP_LIST(V) \ | 386 #define SPECULATIVE_NUMBER_BINOP_LIST(V) \ |
374 V(SpeculativeNumberAdd) \ | 387 SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(V) \ |
375 V(SpeculativeNumberSubtract) \ | 388 V(SpeculativeNumberEqual) \ |
376 V(SpeculativeNumberDivide) \ | 389 V(SpeculativeNumberLessThan) \ |
377 V(SpeculativeNumberMultiply) \ | 390 V(SpeculativeNumberLessThanOrEqual) |
378 V(SpeculativeNumberModulus) \ | |
379 V(SpeculativeNumberShiftLeft) \ | |
380 V(SpeculativeNumberShiftRight) \ | |
381 V(SpeculativeNumberShiftRightLogical) \ | |
382 V(SpeculativeNumberBitwiseAnd) \ | |
383 V(SpeculativeNumberBitwiseOr) \ | |
384 V(SpeculativeNumberBitwiseXor) | |
385 | 391 |
386 #define CHECKED_OP_LIST(V) \ | 392 #define CHECKED_OP_LIST(V) \ |
387 V(CheckBounds, 2, 1) \ | 393 V(CheckBounds, 2, 1) \ |
388 V(CheckIf, 1, 0) \ | 394 V(CheckIf, 1, 0) \ |
389 V(CheckNumber, 1, 1) \ | 395 V(CheckNumber, 1, 1) \ |
390 V(CheckString, 1, 1) \ | 396 V(CheckString, 1, 1) \ |
391 V(CheckTaggedPointer, 1, 1) \ | 397 V(CheckTaggedPointer, 1, 1) \ |
392 V(CheckTaggedSigned, 1, 1) \ | 398 V(CheckTaggedSigned, 1, 1) \ |
393 V(CheckedInt32Add, 2, 1) \ | 399 V(CheckedInt32Add, 2, 1) \ |
394 V(CheckedInt32Sub, 2, 1) \ | 400 V(CheckedInt32Sub, 2, 1) \ |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
506 struct EnsureWritableFastElementsOperator final : public Operator { | 512 struct EnsureWritableFastElementsOperator final : public Operator { |
507 EnsureWritableFastElementsOperator() | 513 EnsureWritableFastElementsOperator() |
508 : Operator( // -- | 514 : Operator( // -- |
509 IrOpcode::kEnsureWritableFastElements, // opcode | 515 IrOpcode::kEnsureWritableFastElements, // opcode |
510 Operator::kNoDeopt | Operator::kNoThrow, // flags | 516 Operator::kNoDeopt | Operator::kNoThrow, // flags |
511 "EnsureWritableFastElements", // name | 517 "EnsureWritableFastElements", // name |
512 2, 1, 1, 1, 1, 0) {} // counts | 518 2, 1, 1, 1, 1, 0) {} // counts |
513 }; | 519 }; |
514 EnsureWritableFastElementsOperator kEnsureWritableFastElements; | 520 EnsureWritableFastElementsOperator kEnsureWritableFastElements; |
515 | 521 |
| 522 #define SPECULATIVE_NUMBER_BINOP(Name) \ |
| 523 template <NumberOperationHint kHint> \ |
| 524 struct Name##Operator final : public Operator1<NumberOperationHint> { \ |
| 525 Name##Operator() \ |
| 526 : Operator1<NumberOperationHint>( \ |
| 527 IrOpcode::k##Name, Operator::kFoldable | Operator::kNoThrow, \ |
| 528 #Name, 2, 1, 1, 1, 1, 0, kHint) {} \ |
| 529 }; \ |
| 530 Name##Operator<NumberOperationHint::kSignedSmall> \ |
| 531 k##Name##SignedSmallOperator; \ |
| 532 Name##Operator<NumberOperationHint::kSigned32> k##Name##Signed32Operator; \ |
| 533 Name##Operator<NumberOperationHint::kNumberOrOddball> \ |
| 534 k##Name##NumberOrOddballOperator; |
| 535 SPECULATIVE_NUMBER_BINOP_LIST(SPECULATIVE_NUMBER_BINOP) |
| 536 #undef SPECULATIVE_NUMBER_BINOP |
| 537 |
516 #define BUFFER_ACCESS(Type, type, TYPE, ctype, size) \ | 538 #define BUFFER_ACCESS(Type, type, TYPE, ctype, size) \ |
517 struct LoadBuffer##Type##Operator final : public Operator1<BufferAccess> { \ | 539 struct LoadBuffer##Type##Operator final : public Operator1<BufferAccess> { \ |
518 LoadBuffer##Type##Operator() \ | 540 LoadBuffer##Type##Operator() \ |
519 : Operator1<BufferAccess>( \ | 541 : Operator1<BufferAccess>( \ |
520 IrOpcode::kLoadBuffer, \ | 542 IrOpcode::kLoadBuffer, \ |
521 Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoWrite, \ | 543 Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoWrite, \ |
522 "LoadBuffer", 3, 1, 1, 1, 1, 0, \ | 544 "LoadBuffer", 3, 1, 1, 1, 1, 0, \ |
523 BufferAccess(kExternal##Type##Array)) {} \ | 545 BufferAccess(kExternal##Type##Array)) {} \ |
524 }; \ | 546 }; \ |
525 struct StoreBuffer##Type##Operator final : public Operator1<BufferAccess> { \ | 547 struct StoreBuffer##Type##Operator final : public Operator1<BufferAccess> { \ |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
672 #define STORE_BUFFER(Type, type, TYPE, ctype, size) \ | 694 #define STORE_BUFFER(Type, type, TYPE, ctype, size) \ |
673 case kExternal##Type##Array: \ | 695 case kExternal##Type##Array: \ |
674 return &cache_.kStoreBuffer##Type; | 696 return &cache_.kStoreBuffer##Type; |
675 TYPED_ARRAYS(STORE_BUFFER) | 697 TYPED_ARRAYS(STORE_BUFFER) |
676 #undef STORE_BUFFER | 698 #undef STORE_BUFFER |
677 } | 699 } |
678 UNREACHABLE(); | 700 UNREACHABLE(); |
679 return nullptr; | 701 return nullptr; |
680 } | 702 } |
681 | 703 |
682 #define SPECULATIVE_BINOP_DEF(Name) \ | 704 #define SPECULATIVE_NUMBER_BINOP(Name) \ |
683 const Operator* SimplifiedOperatorBuilder::Name( \ | 705 const Operator* SimplifiedOperatorBuilder::Name(NumberOperationHint hint) { \ |
684 BinaryOperationHints::Hint hint) { \ | 706 switch (hint) { \ |
685 return new (zone()) Operator1<BinaryOperationHints::Hint>( \ | 707 case NumberOperationHint::kSignedSmall: \ |
686 IrOpcode::k##Name, Operator::kFoldable | Operator::kNoThrow, #Name, 2, \ | 708 return &cache_.k##Name##SignedSmallOperator; \ |
687 1, 1, 1, 1, 0, hint); \ | 709 case NumberOperationHint::kSigned32: \ |
| 710 return &cache_.k##Name##Signed32Operator; \ |
| 711 case NumberOperationHint::kNumberOrOddball: \ |
| 712 return &cache_.k##Name##NumberOrOddballOperator; \ |
| 713 } \ |
| 714 UNREACHABLE(); \ |
| 715 return nullptr; \ |
688 } | 716 } |
689 SPECULATIVE_BINOP_LIST(SPECULATIVE_BINOP_DEF) | 717 SPECULATIVE_NUMBER_BINOP_LIST(SPECULATIVE_NUMBER_BINOP) |
690 #undef SPECULATIVE_BINOP_DEF | 718 #undef SPECULATIVE_NUMBER_BINOP |
691 | |
692 const Operator* SimplifiedOperatorBuilder::SpeculativeNumberEqual( | |
693 CompareOperationHints::Hint hint) { | |
694 return new (zone()) Operator1<CompareOperationHints::Hint>( | |
695 IrOpcode::kSpeculativeNumberEqual, | |
696 Operator::kFoldable | Operator::kNoThrow, "SpeculativeNumberEqual", 2, 1, | |
697 1, 1, 1, 0, hint); | |
698 } | |
699 | |
700 const Operator* SimplifiedOperatorBuilder::SpeculativeNumberLessThan( | |
701 CompareOperationHints::Hint hint) { | |
702 return new (zone()) Operator1<CompareOperationHints::Hint>( | |
703 IrOpcode::kSpeculativeNumberLessThan, | |
704 Operator::kFoldable | Operator::kNoThrow, "SpeculativeNumberLessThan", 2, | |
705 1, 1, 1, 1, 0, hint); | |
706 } | |
707 | |
708 const Operator* SimplifiedOperatorBuilder::SpeculativeNumberLessThanOrEqual( | |
709 CompareOperationHints::Hint hint) { | |
710 return new (zone()) Operator1<CompareOperationHints::Hint>( | |
711 IrOpcode::kSpeculativeNumberLessThanOrEqual, | |
712 Operator::kFoldable | Operator::kNoThrow, | |
713 "SpeculativeNumberLessThanOrEqual", 2, 1, 1, 1, 1, 0, hint); | |
714 } | |
715 | 719 |
716 #define ACCESS_OP_LIST(V) \ | 720 #define ACCESS_OP_LIST(V) \ |
717 V(LoadField, FieldAccess, Operator::kNoWrite, 1, 1, 1) \ | 721 V(LoadField, FieldAccess, Operator::kNoWrite, 1, 1, 1) \ |
718 V(StoreField, FieldAccess, Operator::kNoRead, 2, 1, 0) \ | 722 V(StoreField, FieldAccess, Operator::kNoRead, 2, 1, 0) \ |
719 V(LoadElement, ElementAccess, Operator::kNoWrite, 2, 1, 1) \ | 723 V(LoadElement, ElementAccess, Operator::kNoWrite, 2, 1, 1) \ |
720 V(StoreElement, ElementAccess, Operator::kNoRead, 3, 1, 0) \ | 724 V(StoreElement, ElementAccess, Operator::kNoRead, 3, 1, 0) \ |
721 V(LoadTypedElement, ExternalArrayType, Operator::kNoWrite, 4, 1, 1) \ | 725 V(LoadTypedElement, ExternalArrayType, Operator::kNoWrite, 4, 1, 1) \ |
722 V(StoreTypedElement, ExternalArrayType, Operator::kNoRead, 5, 1, 0) | 726 V(StoreTypedElement, ExternalArrayType, Operator::kNoRead, 5, 1, 0) |
723 | 727 |
724 #define ACCESS(Name, Type, properties, value_input_count, control_input_count, \ | 728 #define ACCESS(Name, Type, properties, value_input_count, control_input_count, \ |
725 output_count) \ | 729 output_count) \ |
726 const Operator* SimplifiedOperatorBuilder::Name(const Type& access) { \ | 730 const Operator* SimplifiedOperatorBuilder::Name(const Type& access) { \ |
727 return new (zone()) \ | 731 return new (zone()) \ |
728 Operator1<Type>(IrOpcode::k##Name, \ | 732 Operator1<Type>(IrOpcode::k##Name, \ |
729 Operator::kNoDeopt | Operator::kNoThrow | properties, \ | 733 Operator::kNoDeopt | Operator::kNoThrow | properties, \ |
730 #Name, value_input_count, 1, control_input_count, \ | 734 #Name, value_input_count, 1, control_input_count, \ |
731 output_count, 1, 0, access); \ | 735 output_count, 1, 0, access); \ |
732 } | 736 } |
733 ACCESS_OP_LIST(ACCESS) | 737 ACCESS_OP_LIST(ACCESS) |
734 #undef ACCESS | 738 #undef ACCESS |
735 | 739 |
736 } // namespace compiler | 740 } // namespace compiler |
737 } // namespace internal | 741 } // namespace internal |
738 } // namespace v8 | 742 } // namespace v8 |
OLD | NEW |