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 |