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 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
254 } | 254 } |
255 UNREACHABLE(); | 255 UNREACHABLE(); |
256 return os; | 256 return os; |
257 } | 257 } |
258 | 258 |
259 ElementsTransition ElementsTransitionOf(const Operator* op) { | 259 ElementsTransition ElementsTransitionOf(const Operator* op) { |
260 DCHECK_EQ(IrOpcode::kTransitionElementsKind, op->opcode()); | 260 DCHECK_EQ(IrOpcode::kTransitionElementsKind, op->opcode()); |
261 return OpParameter<ElementsTransition>(op); | 261 return OpParameter<ElementsTransition>(op); |
262 } | 262 } |
263 | 263 |
264 BinaryOperationHints::Hint BinaryOperationHintOf(const Operator* op) { | 264 size_t hash_value(NumberOperationHint hint) { |
| 265 return static_cast<uint8_t>(hint); |
| 266 } |
| 267 |
| 268 std::ostream& operator<<(std::ostream& os, NumberOperationHint hint) { |
| 269 switch (hint) { |
| 270 case NumberOperationHint::kNone: |
| 271 return os << "None"; |
| 272 case NumberOperationHint::kSigned32: |
| 273 return os << "Signed32"; |
| 274 case NumberOperationHint::kNumberOrOddball: |
| 275 return os << "NumberOrOddball"; |
| 276 } |
| 277 UNREACHABLE(); |
| 278 return os; |
| 279 } |
| 280 |
| 281 NumberOperationHint NumberOperationHintOf(const Operator* op) { |
265 DCHECK(op->opcode() == IrOpcode::kSpeculativeNumberAdd || | 282 DCHECK(op->opcode() == IrOpcode::kSpeculativeNumberAdd || |
266 op->opcode() == IrOpcode::kSpeculativeNumberSubtract || | 283 op->opcode() == IrOpcode::kSpeculativeNumberSubtract || |
267 op->opcode() == IrOpcode::kSpeculativeNumberMultiply || | 284 op->opcode() == IrOpcode::kSpeculativeNumberMultiply || |
268 op->opcode() == IrOpcode::kSpeculativeNumberDivide || | 285 op->opcode() == IrOpcode::kSpeculativeNumberDivide || |
269 op->opcode() == IrOpcode::kSpeculativeNumberModulus || | 286 op->opcode() == IrOpcode::kSpeculativeNumberModulus || |
270 op->opcode() == IrOpcode::kSpeculativeNumberShiftLeft); | 287 op->opcode() == IrOpcode::kSpeculativeNumberShiftLeft || |
271 return OpParameter<BinaryOperationHints::Hint>(op); | 288 op->opcode() == IrOpcode::kSpeculativeNumberEqual || |
272 } | |
273 | |
274 CompareOperationHints::Hint CompareOperationHintOf(const Operator* op) { | |
275 DCHECK(op->opcode() == IrOpcode::kSpeculativeNumberEqual || | |
276 op->opcode() == IrOpcode::kSpeculativeNumberLessThan || | 289 op->opcode() == IrOpcode::kSpeculativeNumberLessThan || |
277 op->opcode() == IrOpcode::kSpeculativeNumberLessThanOrEqual); | 290 op->opcode() == IrOpcode::kSpeculativeNumberLessThanOrEqual); |
278 return OpParameter<CompareOperationHints::Hint>(op); | 291 return OpParameter<NumberOperationHint>(op); |
279 } | 292 } |
280 | 293 |
281 #define PURE_OP_LIST(V) \ | 294 #define PURE_OP_LIST(V) \ |
282 V(BooleanNot, Operator::kNoProperties, 1) \ | 295 V(BooleanNot, Operator::kNoProperties, 1) \ |
283 V(NumberEqual, Operator::kCommutative, 2) \ | 296 V(NumberEqual, Operator::kCommutative, 2) \ |
284 V(NumberLessThan, Operator::kNoProperties, 2) \ | 297 V(NumberLessThan, Operator::kNoProperties, 2) \ |
285 V(NumberLessThanOrEqual, Operator::kNoProperties, 2) \ | 298 V(NumberLessThanOrEqual, Operator::kNoProperties, 2) \ |
286 V(NumberAdd, Operator::kCommutative, 2) \ | 299 V(NumberAdd, Operator::kCommutative, 2) \ |
287 V(NumberSubtract, Operator::kNoProperties, 2) \ | 300 V(NumberSubtract, Operator::kNoProperties, 2) \ |
288 V(NumberMultiply, Operator::kCommutative, 2) \ | 301 V(NumberMultiply, Operator::kCommutative, 2) \ |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
355 V(StringEqual, Operator::kCommutative, 2) \ | 368 V(StringEqual, Operator::kCommutative, 2) \ |
356 V(StringLessThan, Operator::kNoProperties, 2) \ | 369 V(StringLessThan, Operator::kNoProperties, 2) \ |
357 V(StringLessThanOrEqual, Operator::kNoProperties, 2) | 370 V(StringLessThanOrEqual, Operator::kNoProperties, 2) |
358 | 371 |
359 #define SPECULATIVE_BINOP_LIST(V) \ | 372 #define SPECULATIVE_BINOP_LIST(V) \ |
360 V(SpeculativeNumberAdd) \ | 373 V(SpeculativeNumberAdd) \ |
361 V(SpeculativeNumberSubtract) \ | 374 V(SpeculativeNumberSubtract) \ |
362 V(SpeculativeNumberDivide) \ | 375 V(SpeculativeNumberDivide) \ |
363 V(SpeculativeNumberMultiply) \ | 376 V(SpeculativeNumberMultiply) \ |
364 V(SpeculativeNumberModulus) \ | 377 V(SpeculativeNumberModulus) \ |
365 V(SpeculativeNumberShiftLeft) | 378 V(SpeculativeNumberShiftLeft) \ |
| 379 V(SpeculativeNumberEqual) \ |
| 380 V(SpeculativeNumberLessThan) \ |
| 381 V(SpeculativeNumberLessThanOrEqual) |
366 | 382 |
367 #define CHECKED_OP_LIST(V) \ | 383 #define CHECKED_OP_LIST(V) \ |
368 V(CheckBounds, 2, 1) \ | 384 V(CheckBounds, 2, 1) \ |
369 V(CheckIf, 1, 0) \ | 385 V(CheckIf, 1, 0) \ |
370 V(CheckNumber, 1, 1) \ | 386 V(CheckNumber, 1, 1) \ |
371 V(CheckTaggedPointer, 1, 1) \ | 387 V(CheckTaggedPointer, 1, 1) \ |
372 V(CheckTaggedSigned, 1, 1) \ | 388 V(CheckTaggedSigned, 1, 1) \ |
373 V(CheckedInt32Add, 2, 1) \ | 389 V(CheckedInt32Add, 2, 1) \ |
374 V(CheckedInt32Sub, 2, 1) \ | 390 V(CheckedInt32Sub, 2, 1) \ |
375 V(CheckedInt32Div, 2, 1) \ | 391 V(CheckedInt32Div, 2, 1) \ |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
448 struct AllocateOperator final : public Operator1<PretenureFlag> { | 464 struct AllocateOperator final : public Operator1<PretenureFlag> { |
449 AllocateOperator() | 465 AllocateOperator() |
450 : Operator1<PretenureFlag>( | 466 : Operator1<PretenureFlag>( |
451 IrOpcode::kAllocate, | 467 IrOpcode::kAllocate, |
452 Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoWrite, | 468 Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoWrite, |
453 "Allocate", 1, 1, 1, 1, 1, 0, kPretenure) {} | 469 "Allocate", 1, 1, 1, 1, 1, 0, kPretenure) {} |
454 }; | 470 }; |
455 AllocateOperator<NOT_TENURED> kAllocateNotTenuredOperator; | 471 AllocateOperator<NOT_TENURED> kAllocateNotTenuredOperator; |
456 AllocateOperator<TENURED> kAllocateTenuredOperator; | 472 AllocateOperator<TENURED> kAllocateTenuredOperator; |
457 | 473 |
| 474 #define SPECULATIVE_BINOP(Name) \ |
| 475 template <NumberOperationHint kHint> \ |
| 476 struct Name##Operator final : public Operator1<NumberOperationHint> { \ |
| 477 Name##Operator() \ |
| 478 : Operator1<NumberOperationHint>( \ |
| 479 IrOpcode::k##Name, Operator::kFoldable | Operator::kNoThrow, \ |
| 480 #Name, 2, 1, 1, 1, 1, 0, kHint) {} \ |
| 481 }; \ |
| 482 Name##Operator<NumberOperationHint::kNone> k##Name##NoneOperator; \ |
| 483 Name##Operator<NumberOperationHint::kSigned32> k##Name##Signed32Operator; \ |
| 484 Name##Operator<NumberOperationHint::kNumberOrOddball> \ |
| 485 k##Name##NumberOrOddballOperator; |
| 486 SPECULATIVE_BINOP_LIST(SPECULATIVE_BINOP) |
| 487 #undef SPECULATIVE_BINOP |
| 488 |
458 #define BUFFER_ACCESS(Type, type, TYPE, ctype, size) \ | 489 #define BUFFER_ACCESS(Type, type, TYPE, ctype, size) \ |
459 struct LoadBuffer##Type##Operator final : public Operator1<BufferAccess> { \ | 490 struct LoadBuffer##Type##Operator final : public Operator1<BufferAccess> { \ |
460 LoadBuffer##Type##Operator() \ | 491 LoadBuffer##Type##Operator() \ |
461 : Operator1<BufferAccess>( \ | 492 : Operator1<BufferAccess>( \ |
462 IrOpcode::kLoadBuffer, \ | 493 IrOpcode::kLoadBuffer, \ |
463 Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoWrite, \ | 494 Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoWrite, \ |
464 "LoadBuffer", 3, 1, 1, 1, 1, 0, \ | 495 "LoadBuffer", 3, 1, 1, 1, 1, 0, \ |
465 BufferAccess(kExternal##Type##Array)) {} \ | 496 BufferAccess(kExternal##Type##Array)) {} \ |
466 }; \ | 497 }; \ |
467 struct StoreBuffer##Type##Operator final : public Operator1<BufferAccess> { \ | 498 struct StoreBuffer##Type##Operator final : public Operator1<BufferAccess> { \ |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
578 #define STORE_BUFFER(Type, type, TYPE, ctype, size) \ | 609 #define STORE_BUFFER(Type, type, TYPE, ctype, size) \ |
579 case kExternal##Type##Array: \ | 610 case kExternal##Type##Array: \ |
580 return &cache_.kStoreBuffer##Type; | 611 return &cache_.kStoreBuffer##Type; |
581 TYPED_ARRAYS(STORE_BUFFER) | 612 TYPED_ARRAYS(STORE_BUFFER) |
582 #undef STORE_BUFFER | 613 #undef STORE_BUFFER |
583 } | 614 } |
584 UNREACHABLE(); | 615 UNREACHABLE(); |
585 return nullptr; | 616 return nullptr; |
586 } | 617 } |
587 | 618 |
588 #define SPECULATIVE_BINOP_DEF(Name) \ | 619 #define SPECULATIVE_BINOP(Name) \ |
589 const Operator* SimplifiedOperatorBuilder::Name( \ | 620 const Operator* SimplifiedOperatorBuilder::Name(NumberOperationHint hint) { \ |
590 BinaryOperationHints::Hint hint) { \ | 621 switch (hint) { \ |
591 return new (zone()) Operator1<BinaryOperationHints::Hint>( \ | 622 case NumberOperationHint::kNone: \ |
592 IrOpcode::k##Name, Operator::kFoldable | Operator::kNoThrow, #Name, 2, \ | 623 return &cache_.k##Name##NoneOperator; \ |
593 1, 1, 1, 1, 0, hint); \ | 624 case NumberOperationHint::kSigned32: \ |
| 625 return &cache_.k##Name##Signed32Operator; \ |
| 626 case NumberOperationHint::kNumberOrOddball: \ |
| 627 return &cache_.k##Name##NumberOrOddballOperator; \ |
| 628 } \ |
| 629 UNREACHABLE(); \ |
| 630 return nullptr; \ |
594 } | 631 } |
595 SPECULATIVE_BINOP_LIST(SPECULATIVE_BINOP_DEF) | 632 SPECULATIVE_BINOP_LIST(SPECULATIVE_BINOP) |
596 #undef SPECULATIVE_BINOP_DEF | 633 #undef SPECULATIVE_BINOP |
597 | |
598 const Operator* SimplifiedOperatorBuilder::SpeculativeNumberEqual( | |
599 CompareOperationHints::Hint hint) { | |
600 return new (zone()) Operator1<CompareOperationHints::Hint>( | |
601 IrOpcode::kSpeculativeNumberEqual, | |
602 Operator::kFoldable | Operator::kNoThrow, "SpeculativeNumberEqual", 2, 1, | |
603 1, 1, 1, 0, hint); | |
604 } | |
605 | |
606 const Operator* SimplifiedOperatorBuilder::SpeculativeNumberLessThan( | |
607 CompareOperationHints::Hint hint) { | |
608 return new (zone()) Operator1<CompareOperationHints::Hint>( | |
609 IrOpcode::kSpeculativeNumberLessThan, | |
610 Operator::kFoldable | Operator::kNoThrow, "SpeculativeNumberLessThan", 2, | |
611 1, 1, 1, 1, 0, hint); | |
612 } | |
613 | |
614 const Operator* SimplifiedOperatorBuilder::SpeculativeNumberLessThanOrEqual( | |
615 CompareOperationHints::Hint hint) { | |
616 return new (zone()) Operator1<CompareOperationHints::Hint>( | |
617 IrOpcode::kSpeculativeNumberLessThanOrEqual, | |
618 Operator::kFoldable | Operator::kNoThrow, | |
619 "SpeculativeNumberLessThanOrEqual", 2, 1, 1, 1, 1, 0, hint); | |
620 } | |
621 | 634 |
622 #define ACCESS_OP_LIST(V) \ | 635 #define ACCESS_OP_LIST(V) \ |
623 V(LoadField, FieldAccess, Operator::kNoWrite, 1, 1, 1) \ | 636 V(LoadField, FieldAccess, Operator::kNoWrite, 1, 1, 1) \ |
624 V(StoreField, FieldAccess, Operator::kNoRead, 2, 1, 0) \ | 637 V(StoreField, FieldAccess, Operator::kNoRead, 2, 1, 0) \ |
625 V(LoadElement, ElementAccess, Operator::kNoWrite, 2, 1, 1) \ | 638 V(LoadElement, ElementAccess, Operator::kNoWrite, 2, 1, 1) \ |
626 V(StoreElement, ElementAccess, Operator::kNoRead, 3, 1, 0) | 639 V(StoreElement, ElementAccess, Operator::kNoRead, 3, 1, 0) |
627 | 640 |
628 #define ACCESS(Name, Type, properties, value_input_count, control_input_count, \ | 641 #define ACCESS(Name, Type, properties, value_input_count, control_input_count, \ |
629 output_count) \ | 642 output_count) \ |
630 const Operator* SimplifiedOperatorBuilder::Name(const Type& access) { \ | 643 const Operator* SimplifiedOperatorBuilder::Name(const Type& access) { \ |
631 return new (zone()) \ | 644 return new (zone()) \ |
632 Operator1<Type>(IrOpcode::k##Name, \ | 645 Operator1<Type>(IrOpcode::k##Name, \ |
633 Operator::kNoDeopt | Operator::kNoThrow | properties, \ | 646 Operator::kNoDeopt | Operator::kNoThrow | properties, \ |
634 #Name, value_input_count, 1, control_input_count, \ | 647 #Name, value_input_count, 1, control_input_count, \ |
635 output_count, 1, 0, access); \ | 648 output_count, 1, 0, access); \ |
636 } | 649 } |
637 ACCESS_OP_LIST(ACCESS) | 650 ACCESS_OP_LIST(ACCESS) |
638 #undef ACCESS | 651 #undef ACCESS |
639 | 652 |
640 } // namespace compiler | 653 } // namespace compiler |
641 } // namespace internal | 654 } // namespace internal |
642 } // namespace v8 | 655 } // namespace v8 |
OLD | NEW |