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 #ifndef V8_COMPILER_INSTRUCTION_H_ | 5 #ifndef V8_COMPILER_INSTRUCTION_H_ |
6 #define V8_COMPILER_INSTRUCTION_H_ | 6 #define V8_COMPILER_INSTRUCTION_H_ |
7 | 7 |
8 #include <deque> | 8 #include <deque> |
9 #include <iosfwd> | 9 #include <iosfwd> |
10 #include <map> | 10 #include <map> |
(...skipping 15 matching lines...) Expand all Loading... |
26 // Forward declarations. | 26 // Forward declarations. |
27 class Schedule; | 27 class Schedule; |
28 | 28 |
29 | 29 |
30 class InstructionOperand { | 30 class InstructionOperand { |
31 public: | 31 public: |
32 static const int kInvalidVirtualRegister = -1; | 32 static const int kInvalidVirtualRegister = -1; |
33 | 33 |
34 // TODO(dcarney): recover bit. INVALID can be represented as UNALLOCATED with | 34 // TODO(dcarney): recover bit. INVALID can be represented as UNALLOCATED with |
35 // kInvalidVirtualRegister and some DCHECKS. | 35 // kInvalidVirtualRegister and some DCHECKS. |
36 enum Kind { INVALID, UNALLOCATED, CONSTANT, IMMEDIATE, EXPLICIT, ALLOCATED }; | 36 enum Kind { |
| 37 INVALID, |
| 38 UNALLOCATED, |
| 39 CONSTANT, |
| 40 IMMEDIATE, |
| 41 // Location operand kinds. |
| 42 EXPLICIT, |
| 43 ALLOCATED, |
| 44 FIRST_LOCATION_OPERAND_KIND = EXPLICIT |
| 45 // Location operand kinds must be last. |
| 46 }; |
37 | 47 |
38 InstructionOperand() : InstructionOperand(INVALID) {} | 48 InstructionOperand() : InstructionOperand(INVALID) {} |
39 | 49 |
40 Kind kind() const { return KindField::decode(value_); } | 50 Kind kind() const { return KindField::decode(value_); } |
41 | 51 |
42 #define INSTRUCTION_OPERAND_PREDICATE(name, type) \ | 52 #define INSTRUCTION_OPERAND_PREDICATE(name, type) \ |
43 bool Is##name() const { return kind() == type; } | 53 bool Is##name() const { return kind() == type; } |
44 INSTRUCTION_OPERAND_PREDICATE(Invalid, INVALID) | 54 INSTRUCTION_OPERAND_PREDICATE(Invalid, INVALID) |
45 // UnallocatedOperands are place-holder operands created before register | 55 // UnallocatedOperands are place-holder operands created before register |
46 // allocation. They later are assigned registers and become AllocatedOperands. | 56 // allocation. They later are assigned registers and become AllocatedOperands. |
(...skipping 10 matching lines...) Expand all Loading... |
57 // ExplicitOperands do not participate in register allocation. They are | 67 // ExplicitOperands do not participate in register allocation. They are |
58 // created by the instruction selector for direct access to registers and | 68 // created by the instruction selector for direct access to registers and |
59 // stack slots, completely bypassing the register allocator. They are never | 69 // stack slots, completely bypassing the register allocator. They are never |
60 // associated with a virtual register | 70 // associated with a virtual register |
61 INSTRUCTION_OPERAND_PREDICATE(Explicit, EXPLICIT) | 71 INSTRUCTION_OPERAND_PREDICATE(Explicit, EXPLICIT) |
62 // AllocatedOperands are registers or stack slots that are assigned by the | 72 // AllocatedOperands are registers or stack slots that are assigned by the |
63 // register allocator and are always associated with a virtual register. | 73 // register allocator and are always associated with a virtual register. |
64 INSTRUCTION_OPERAND_PREDICATE(Allocated, ALLOCATED) | 74 INSTRUCTION_OPERAND_PREDICATE(Allocated, ALLOCATED) |
65 #undef INSTRUCTION_OPERAND_PREDICATE | 75 #undef INSTRUCTION_OPERAND_PREDICATE |
66 | 76 |
| 77 inline bool IsAnyLocationOperand() const; |
| 78 inline bool IsLocationOperand() const; |
| 79 inline bool IsFPLocationOperand() const; |
67 inline bool IsAnyRegister() const; | 80 inline bool IsAnyRegister() const; |
68 inline bool IsRegister() const; | 81 inline bool IsRegister() const; |
69 inline bool IsFPRegister() const; | 82 inline bool IsFPRegister() const; |
70 inline bool IsFloatRegister() const; | 83 inline bool IsFloatRegister() const; |
71 inline bool IsDoubleRegister() const; | 84 inline bool IsDoubleRegister() const; |
72 inline bool IsSimd128Register() const; | 85 inline bool IsSimd128Register() const; |
| 86 inline bool IsAnyStackSlot() const; |
73 inline bool IsStackSlot() const; | 87 inline bool IsStackSlot() const; |
74 inline bool IsFPStackSlot() const; | 88 inline bool IsFPStackSlot() const; |
75 inline bool IsFloatStackSlot() const; | 89 inline bool IsFloatStackSlot() const; |
76 inline bool IsDoubleStackSlot() const; | 90 inline bool IsDoubleStackSlot() const; |
77 inline bool IsSimd128StackSlot() const; | 91 inline bool IsSimd128StackSlot() const; |
78 | 92 |
79 template <typename SubKindOperand> | 93 template <typename SubKindOperand> |
80 static SubKindOperand* New(Zone* zone, const SubKindOperand& op) { | 94 static SubKindOperand* New(Zone* zone, const SubKindOperand& op) { |
81 void* buffer = zone->New(sizeof(op)); | 95 void* buffer = zone->New(sizeof(op)); |
82 return new (buffer) SubKindOperand(op); | 96 return new (buffer) SubKindOperand(op); |
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
475 case MachineRepresentation::kWord8: | 489 case MachineRepresentation::kWord8: |
476 case MachineRepresentation::kWord16: | 490 case MachineRepresentation::kWord16: |
477 case MachineRepresentation::kNone: | 491 case MachineRepresentation::kNone: |
478 return false; | 492 return false; |
479 } | 493 } |
480 UNREACHABLE(); | 494 UNREACHABLE(); |
481 return false; | 495 return false; |
482 } | 496 } |
483 | 497 |
484 static LocationOperand* cast(InstructionOperand* op) { | 498 static LocationOperand* cast(InstructionOperand* op) { |
485 DCHECK(ALLOCATED == op->kind() || EXPLICIT == op->kind()); | 499 DCHECK(op->IsAnyLocationOperand()); |
486 return static_cast<LocationOperand*>(op); | 500 return static_cast<LocationOperand*>(op); |
487 } | 501 } |
488 | 502 |
489 static const LocationOperand* cast(const InstructionOperand* op) { | 503 static const LocationOperand* cast(const InstructionOperand* op) { |
490 DCHECK(ALLOCATED == op->kind() || EXPLICIT == op->kind()); | 504 DCHECK(op->IsAnyLocationOperand()); |
491 return static_cast<const LocationOperand*>(op); | 505 return static_cast<const LocationOperand*>(op); |
492 } | 506 } |
493 | 507 |
494 static LocationOperand cast(const InstructionOperand& op) { | 508 static LocationOperand cast(const InstructionOperand& op) { |
495 DCHECK(ALLOCATED == op.kind() || EXPLICIT == op.kind()); | 509 DCHECK(op.IsAnyLocationOperand()); |
496 return *static_cast<const LocationOperand*>(&op); | 510 return *static_cast<const LocationOperand*>(&op); |
497 } | 511 } |
498 | 512 |
499 STATIC_ASSERT(KindField::kSize == 3); | 513 STATIC_ASSERT(KindField::kSize == 3); |
500 class LocationKindField : public BitField64<LocationKind, 3, 2> {}; | 514 class LocationKindField : public BitField64<LocationKind, 3, 2> {}; |
501 class RepresentationField : public BitField64<MachineRepresentation, 5, 8> {}; | 515 class RepresentationField : public BitField64<MachineRepresentation, 5, 8> {}; |
502 class IndexField : public BitField64<int32_t, 35, 29> {}; | 516 class IndexField : public BitField64<int32_t, 35, 29> {}; |
503 }; | 517 }; |
504 | 518 |
505 | 519 |
(...skipping 19 matching lines...) Expand all Loading... |
525 MachineRepresentation rep, int index) { | 539 MachineRepresentation rep, int index) { |
526 return InstructionOperand::New(zone, AllocatedOperand(kind, rep, index)); | 540 return InstructionOperand::New(zone, AllocatedOperand(kind, rep, index)); |
527 } | 541 } |
528 | 542 |
529 INSTRUCTION_OPERAND_CASTS(AllocatedOperand, ALLOCATED); | 543 INSTRUCTION_OPERAND_CASTS(AllocatedOperand, ALLOCATED); |
530 }; | 544 }; |
531 | 545 |
532 | 546 |
533 #undef INSTRUCTION_OPERAND_CASTS | 547 #undef INSTRUCTION_OPERAND_CASTS |
534 | 548 |
| 549 bool InstructionOperand::IsAnyLocationOperand() const { |
| 550 return this->kind() >= FIRST_LOCATION_OPERAND_KIND; |
| 551 } |
| 552 |
| 553 bool InstructionOperand::IsLocationOperand() const { |
| 554 return IsAnyLocationOperand() && |
| 555 !IsFloatingPoint(LocationOperand::cast(this)->representation()); |
| 556 } |
| 557 |
| 558 bool InstructionOperand::IsFPLocationOperand() const { |
| 559 return IsAnyLocationOperand() && |
| 560 IsFloatingPoint(LocationOperand::cast(this)->representation()); |
| 561 } |
535 | 562 |
536 bool InstructionOperand::IsAnyRegister() const { | 563 bool InstructionOperand::IsAnyRegister() const { |
537 return (IsAllocated() || IsExplicit()) && | 564 return IsAnyLocationOperand() && |
538 LocationOperand::cast(this)->location_kind() == | 565 LocationOperand::cast(this)->location_kind() == |
539 LocationOperand::REGISTER; | 566 LocationOperand::REGISTER; |
540 } | 567 } |
541 | 568 |
542 | 569 |
543 bool InstructionOperand::IsRegister() const { | 570 bool InstructionOperand::IsRegister() const { |
544 return IsAnyRegister() && | 571 return IsAnyRegister() && |
545 !IsFloatingPoint(LocationOperand::cast(this)->representation()); | 572 !IsFloatingPoint(LocationOperand::cast(this)->representation()); |
546 } | 573 } |
547 | 574 |
(...skipping 13 matching lines...) Expand all Loading... |
561 LocationOperand::cast(this)->representation() == | 588 LocationOperand::cast(this)->representation() == |
562 MachineRepresentation::kFloat64; | 589 MachineRepresentation::kFloat64; |
563 } | 590 } |
564 | 591 |
565 bool InstructionOperand::IsSimd128Register() const { | 592 bool InstructionOperand::IsSimd128Register() const { |
566 return IsAnyRegister() && | 593 return IsAnyRegister() && |
567 LocationOperand::cast(this)->representation() == | 594 LocationOperand::cast(this)->representation() == |
568 MachineRepresentation::kSimd128; | 595 MachineRepresentation::kSimd128; |
569 } | 596 } |
570 | 597 |
| 598 bool InstructionOperand::IsAnyStackSlot() const { |
| 599 return IsAnyLocationOperand() && |
| 600 LocationOperand::cast(this)->location_kind() == |
| 601 LocationOperand::STACK_SLOT; |
| 602 } |
| 603 |
571 bool InstructionOperand::IsStackSlot() const { | 604 bool InstructionOperand::IsStackSlot() const { |
572 return (IsAllocated() || IsExplicit()) && | 605 return IsAnyStackSlot() && |
573 LocationOperand::cast(this)->location_kind() == | |
574 LocationOperand::STACK_SLOT && | |
575 !IsFloatingPoint(LocationOperand::cast(this)->representation()); | 606 !IsFloatingPoint(LocationOperand::cast(this)->representation()); |
576 } | 607 } |
577 | 608 |
578 bool InstructionOperand::IsFPStackSlot() const { | 609 bool InstructionOperand::IsFPStackSlot() const { |
579 return (IsAllocated() || IsExplicit()) && | 610 return IsAnyStackSlot() && |
580 LocationOperand::cast(this)->location_kind() == | |
581 LocationOperand::STACK_SLOT && | |
582 IsFloatingPoint(LocationOperand::cast(this)->representation()); | 611 IsFloatingPoint(LocationOperand::cast(this)->representation()); |
583 } | 612 } |
584 | 613 |
585 bool InstructionOperand::IsFloatStackSlot() const { | 614 bool InstructionOperand::IsFloatStackSlot() const { |
586 return (IsAllocated() || IsExplicit()) && | 615 return IsAnyLocationOperand() && |
587 LocationOperand::cast(this)->location_kind() == | 616 LocationOperand::cast(this)->location_kind() == |
588 LocationOperand::STACK_SLOT && | 617 LocationOperand::STACK_SLOT && |
589 LocationOperand::cast(this)->representation() == | 618 LocationOperand::cast(this)->representation() == |
590 MachineRepresentation::kFloat32; | 619 MachineRepresentation::kFloat32; |
591 } | 620 } |
592 | 621 |
593 bool InstructionOperand::IsDoubleStackSlot() const { | 622 bool InstructionOperand::IsDoubleStackSlot() const { |
594 return (IsAllocated() || IsExplicit()) && | 623 return IsAnyLocationOperand() && |
595 LocationOperand::cast(this)->location_kind() == | 624 LocationOperand::cast(this)->location_kind() == |
596 LocationOperand::STACK_SLOT && | 625 LocationOperand::STACK_SLOT && |
597 LocationOperand::cast(this)->representation() == | 626 LocationOperand::cast(this)->representation() == |
598 MachineRepresentation::kFloat64; | 627 MachineRepresentation::kFloat64; |
599 } | 628 } |
600 | 629 |
601 bool InstructionOperand::IsSimd128StackSlot() const { | 630 bool InstructionOperand::IsSimd128StackSlot() const { |
602 return (IsAllocated() || IsExplicit()) && | 631 return IsAnyLocationOperand() && |
603 LocationOperand::cast(this)->location_kind() == | 632 LocationOperand::cast(this)->location_kind() == |
604 LocationOperand::STACK_SLOT && | 633 LocationOperand::STACK_SLOT && |
605 LocationOperand::cast(this)->representation() == | 634 LocationOperand::cast(this)->representation() == |
606 MachineRepresentation::kSimd128; | 635 MachineRepresentation::kSimd128; |
607 } | 636 } |
608 | 637 |
609 uint64_t InstructionOperand::GetCanonicalizedValue() const { | 638 uint64_t InstructionOperand::GetCanonicalizedValue() const { |
610 if (IsAllocated() || IsExplicit()) { | 639 if (IsAnyLocationOperand()) { |
611 MachineRepresentation canonical = MachineRepresentation::kNone; | 640 MachineRepresentation canonical = MachineRepresentation::kNone; |
612 if (IsFPRegister()) { | 641 if (IsFPRegister()) { |
613 // We treat all FP register operands the same for simple aliasing. | 642 // We treat all FP register operands the same for simple aliasing. |
614 canonical = MachineRepresentation::kFloat64; | 643 canonical = MachineRepresentation::kFloat64; |
615 } | 644 } |
616 return InstructionOperand::KindField::update( | 645 return InstructionOperand::KindField::update( |
617 LocationOperand::RepresentationField::update(this->value_, canonical), | 646 LocationOperand::RepresentationField::update(this->value_, canonical), |
618 LocationOperand::EXPLICIT); | 647 LocationOperand::EXPLICIT); |
619 } | 648 } |
620 return this->value_; | 649 return this->value_; |
(...skipping 881 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1502 | 1531 |
1503 | 1532 |
1504 std::ostream& operator<<(std::ostream& os, | 1533 std::ostream& operator<<(std::ostream& os, |
1505 const PrintableInstructionSequence& code); | 1534 const PrintableInstructionSequence& code); |
1506 | 1535 |
1507 } // namespace compiler | 1536 } // namespace compiler |
1508 } // namespace internal | 1537 } // namespace internal |
1509 } // namespace v8 | 1538 } // namespace v8 |
1510 | 1539 |
1511 #endif // V8_COMPILER_INSTRUCTION_H_ | 1540 #endif // V8_COMPILER_INSTRUCTION_H_ |
OLD | NEW |