Chromium Code Reviews| 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 IsLocation() const; | |
|
Mircea Trofin
2016/09/30 21:52:10
As discussed offline, how about these names:
IsLo
bbudge
2016/10/03 21:37:18
Done.
| |
| 67 inline bool IsAnyRegister() const; | 78 inline bool IsAnyRegister() const; |
| 68 inline bool IsRegister() const; | 79 inline bool IsRegister() const; |
| 69 inline bool IsFPRegister() const; | 80 inline bool IsFPRegister() const; |
| 70 inline bool IsFloatRegister() const; | 81 inline bool IsFloatRegister() const; |
| 71 inline bool IsDoubleRegister() const; | 82 inline bool IsDoubleRegister() const; |
| 72 inline bool IsSimd128Register() const; | 83 inline bool IsSimd128Register() const; |
| 73 inline bool IsStackSlot() const; | 84 inline bool IsStackSlot() const; |
| 74 inline bool IsFPStackSlot() const; | 85 inline bool IsFPStackSlot() const; |
| 75 inline bool IsFloatStackSlot() const; | 86 inline bool IsFloatStackSlot() const; |
| 76 inline bool IsDoubleStackSlot() const; | 87 inline bool IsDoubleStackSlot() const; |
| 77 inline bool IsSimd128StackSlot() const; | 88 inline bool IsSimd128StackSlot() const; |
| 89 inline bool IsFPLocation() const; | |
| 78 | 90 |
| 79 template <typename SubKindOperand> | 91 template <typename SubKindOperand> |
| 80 static SubKindOperand* New(Zone* zone, const SubKindOperand& op) { | 92 static SubKindOperand* New(Zone* zone, const SubKindOperand& op) { |
| 81 void* buffer = zone->New(sizeof(op)); | 93 void* buffer = zone->New(sizeof(op)); |
| 82 return new (buffer) SubKindOperand(op); | 94 return new (buffer) SubKindOperand(op); |
| 83 } | 95 } |
| 84 | 96 |
| 85 static void ReplaceWith(InstructionOperand* dest, | 97 static void ReplaceWith(InstructionOperand* dest, |
| 86 const InstructionOperand* src) { | 98 const InstructionOperand* src) { |
| 87 *dest = *src; | 99 *dest = *src; |
| (...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 475 case MachineRepresentation::kWord8: | 487 case MachineRepresentation::kWord8: |
| 476 case MachineRepresentation::kWord16: | 488 case MachineRepresentation::kWord16: |
| 477 case MachineRepresentation::kNone: | 489 case MachineRepresentation::kNone: |
| 478 return false; | 490 return false; |
| 479 } | 491 } |
| 480 UNREACHABLE(); | 492 UNREACHABLE(); |
| 481 return false; | 493 return false; |
| 482 } | 494 } |
| 483 | 495 |
| 484 static LocationOperand* cast(InstructionOperand* op) { | 496 static LocationOperand* cast(InstructionOperand* op) { |
| 485 DCHECK(ALLOCATED == op->kind() || EXPLICIT == op->kind()); | 497 DCHECK(op->IsLocation()); |
| 486 return static_cast<LocationOperand*>(op); | 498 return static_cast<LocationOperand*>(op); |
| 487 } | 499 } |
| 488 | 500 |
| 489 static const LocationOperand* cast(const InstructionOperand* op) { | 501 static const LocationOperand* cast(const InstructionOperand* op) { |
| 490 DCHECK(ALLOCATED == op->kind() || EXPLICIT == op->kind()); | 502 DCHECK(op->IsLocation()); |
| 491 return static_cast<const LocationOperand*>(op); | 503 return static_cast<const LocationOperand*>(op); |
| 492 } | 504 } |
| 493 | 505 |
| 494 static LocationOperand cast(const InstructionOperand& op) { | 506 static LocationOperand cast(const InstructionOperand& op) { |
| 495 DCHECK(ALLOCATED == op.kind() || EXPLICIT == op.kind()); | 507 DCHECK(op.IsLocation()); |
| 496 return *static_cast<const LocationOperand*>(&op); | 508 return *static_cast<const LocationOperand*>(&op); |
| 497 } | 509 } |
| 498 | 510 |
| 499 STATIC_ASSERT(KindField::kSize == 3); | 511 STATIC_ASSERT(KindField::kSize == 3); |
| 500 class LocationKindField : public BitField64<LocationKind, 3, 2> {}; | 512 class LocationKindField : public BitField64<LocationKind, 3, 2> {}; |
| 501 class RepresentationField : public BitField64<MachineRepresentation, 5, 8> {}; | 513 class RepresentationField : public BitField64<MachineRepresentation, 5, 8> {}; |
| 502 class IndexField : public BitField64<int32_t, 35, 29> {}; | 514 class IndexField : public BitField64<int32_t, 35, 29> {}; |
| 503 }; | 515 }; |
| 504 | 516 |
| 505 | 517 |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 525 MachineRepresentation rep, int index) { | 537 MachineRepresentation rep, int index) { |
| 526 return InstructionOperand::New(zone, AllocatedOperand(kind, rep, index)); | 538 return InstructionOperand::New(zone, AllocatedOperand(kind, rep, index)); |
| 527 } | 539 } |
| 528 | 540 |
| 529 INSTRUCTION_OPERAND_CASTS(AllocatedOperand, ALLOCATED); | 541 INSTRUCTION_OPERAND_CASTS(AllocatedOperand, ALLOCATED); |
| 530 }; | 542 }; |
| 531 | 543 |
| 532 | 544 |
| 533 #undef INSTRUCTION_OPERAND_CASTS | 545 #undef INSTRUCTION_OPERAND_CASTS |
| 534 | 546 |
| 547 bool InstructionOperand::IsLocation() const { | |
| 548 return this->kind() >= FIRST_LOCATION_OPERAND_KIND; | |
| 549 } | |
| 535 | 550 |
| 536 bool InstructionOperand::IsAnyRegister() const { | 551 bool InstructionOperand::IsAnyRegister() const { |
| 537 return (IsAllocated() || IsExplicit()) && | 552 return IsLocation() && |
| 538 LocationOperand::cast(this)->location_kind() == | 553 LocationOperand::cast(this)->location_kind() == |
| 539 LocationOperand::REGISTER; | 554 LocationOperand::REGISTER; |
| 540 } | 555 } |
| 541 | 556 |
| 542 | 557 |
| 543 bool InstructionOperand::IsRegister() const { | 558 bool InstructionOperand::IsRegister() const { |
| 544 return IsAnyRegister() && | 559 return IsAnyRegister() && |
| 545 !IsFloatingPoint(LocationOperand::cast(this)->representation()); | 560 !IsFloatingPoint(LocationOperand::cast(this)->representation()); |
| 546 } | 561 } |
| 547 | 562 |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 562 MachineRepresentation::kFloat64; | 577 MachineRepresentation::kFloat64; |
| 563 } | 578 } |
| 564 | 579 |
| 565 bool InstructionOperand::IsSimd128Register() const { | 580 bool InstructionOperand::IsSimd128Register() const { |
| 566 return IsAnyRegister() && | 581 return IsAnyRegister() && |
| 567 LocationOperand::cast(this)->representation() == | 582 LocationOperand::cast(this)->representation() == |
| 568 MachineRepresentation::kSimd128; | 583 MachineRepresentation::kSimd128; |
| 569 } | 584 } |
| 570 | 585 |
| 571 bool InstructionOperand::IsStackSlot() const { | 586 bool InstructionOperand::IsStackSlot() const { |
| 572 return (IsAllocated() || IsExplicit()) && | 587 return IsLocation() && |
| 573 LocationOperand::cast(this)->location_kind() == | 588 LocationOperand::cast(this)->location_kind() == |
| 574 LocationOperand::STACK_SLOT && | 589 LocationOperand::STACK_SLOT && |
| 575 !IsFloatingPoint(LocationOperand::cast(this)->representation()); | 590 !IsFloatingPoint(LocationOperand::cast(this)->representation()); |
| 576 } | 591 } |
| 577 | 592 |
| 578 bool InstructionOperand::IsFPStackSlot() const { | 593 bool InstructionOperand::IsFPStackSlot() const { |
| 579 return (IsAllocated() || IsExplicit()) && | 594 return IsLocation() && |
| 580 LocationOperand::cast(this)->location_kind() == | 595 LocationOperand::cast(this)->location_kind() == |
| 581 LocationOperand::STACK_SLOT && | 596 LocationOperand::STACK_SLOT && |
| 582 IsFloatingPoint(LocationOperand::cast(this)->representation()); | 597 IsFloatingPoint(LocationOperand::cast(this)->representation()); |
| 583 } | 598 } |
| 584 | 599 |
| 585 bool InstructionOperand::IsFloatStackSlot() const { | 600 bool InstructionOperand::IsFloatStackSlot() const { |
| 586 return (IsAllocated() || IsExplicit()) && | 601 return IsLocation() && |
| 587 LocationOperand::cast(this)->location_kind() == | 602 LocationOperand::cast(this)->location_kind() == |
| 588 LocationOperand::STACK_SLOT && | 603 LocationOperand::STACK_SLOT && |
| 589 LocationOperand::cast(this)->representation() == | 604 LocationOperand::cast(this)->representation() == |
| 590 MachineRepresentation::kFloat32; | 605 MachineRepresentation::kFloat32; |
| 591 } | 606 } |
| 592 | 607 |
| 593 bool InstructionOperand::IsDoubleStackSlot() const { | 608 bool InstructionOperand::IsDoubleStackSlot() const { |
| 594 return (IsAllocated() || IsExplicit()) && | 609 return IsLocation() && |
| 595 LocationOperand::cast(this)->location_kind() == | 610 LocationOperand::cast(this)->location_kind() == |
| 596 LocationOperand::STACK_SLOT && | 611 LocationOperand::STACK_SLOT && |
| 597 LocationOperand::cast(this)->representation() == | 612 LocationOperand::cast(this)->representation() == |
| 598 MachineRepresentation::kFloat64; | 613 MachineRepresentation::kFloat64; |
| 599 } | 614 } |
| 600 | 615 |
| 601 bool InstructionOperand::IsSimd128StackSlot() const { | 616 bool InstructionOperand::IsSimd128StackSlot() const { |
| 602 return (IsAllocated() || IsExplicit()) && | 617 return IsLocation() && |
| 603 LocationOperand::cast(this)->location_kind() == | 618 LocationOperand::cast(this)->location_kind() == |
| 604 LocationOperand::STACK_SLOT && | 619 LocationOperand::STACK_SLOT && |
| 605 LocationOperand::cast(this)->representation() == | 620 LocationOperand::cast(this)->representation() == |
| 606 MachineRepresentation::kSimd128; | 621 MachineRepresentation::kSimd128; |
| 607 } | 622 } |
| 608 | 623 |
| 624 bool InstructionOperand::IsFPLocation() const { | |
| 625 return IsLocation() && | |
| 626 IsFloatingPoint(LocationOperand::cast(this)->representation()); | |
| 627 } | |
| 628 | |
| 609 uint64_t InstructionOperand::GetCanonicalizedValue() const { | 629 uint64_t InstructionOperand::GetCanonicalizedValue() const { |
| 610 if (IsAllocated() || IsExplicit()) { | 630 if (IsLocation()) { |
| 611 MachineRepresentation canonical = MachineRepresentation::kNone; | 631 MachineRepresentation canonical = MachineRepresentation::kNone; |
| 612 if (IsFPRegister()) { | 632 if (IsFPRegister()) { |
| 613 // We treat all FP register operands the same for simple aliasing. | 633 // We treat all FP register operands the same for simple aliasing. |
| 614 canonical = MachineRepresentation::kFloat64; | 634 canonical = MachineRepresentation::kFloat64; |
| 615 } | 635 } |
| 616 return InstructionOperand::KindField::update( | 636 return InstructionOperand::KindField::update( |
| 617 LocationOperand::RepresentationField::update(this->value_, canonical), | 637 LocationOperand::RepresentationField::update(this->value_, canonical), |
| 618 LocationOperand::EXPLICIT); | 638 LocationOperand::EXPLICIT); |
| 619 } | 639 } |
| 620 return this->value_; | 640 return this->value_; |
| (...skipping 881 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1502 | 1522 |
| 1503 | 1523 |
| 1504 std::ostream& operator<<(std::ostream& os, | 1524 std::ostream& operator<<(std::ostream& os, |
| 1505 const PrintableInstructionSequence& code); | 1525 const PrintableInstructionSequence& code); |
| 1506 | 1526 |
| 1507 } // namespace compiler | 1527 } // namespace compiler |
| 1508 } // namespace internal | 1528 } // namespace internal |
| 1509 } // namespace v8 | 1529 } // namespace v8 |
| 1510 | 1530 |
| 1511 #endif // V8_COMPILER_INSTRUCTION_H_ | 1531 #endif // V8_COMPILER_INSTRUCTION_H_ |
| OLD | NEW |