Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(610)

Side by Side Diff: src/compiler/instruction.h

Issue 1081373002: [turbofan] cleanup ParallelMove (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/gap-resolver.cc ('k') | src/compiler/instruction.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 INSTRUCTION_OPERAND_PREDICATE(Constant, CONSTANT) 43 INSTRUCTION_OPERAND_PREDICATE(Constant, CONSTANT)
44 INSTRUCTION_OPERAND_PREDICATE(Immediate, IMMEDIATE) 44 INSTRUCTION_OPERAND_PREDICATE(Immediate, IMMEDIATE)
45 INSTRUCTION_OPERAND_PREDICATE(Allocated, ALLOCATED) 45 INSTRUCTION_OPERAND_PREDICATE(Allocated, ALLOCATED)
46 #undef INSTRUCTION_OPERAND_PREDICATE 46 #undef INSTRUCTION_OPERAND_PREDICATE
47 47
48 inline bool IsRegister() const; 48 inline bool IsRegister() const;
49 inline bool IsDoubleRegister() const; 49 inline bool IsDoubleRegister() const;
50 inline bool IsStackSlot() const; 50 inline bool IsStackSlot() const;
51 inline bool IsDoubleStackSlot() const; 51 inline bool IsDoubleStackSlot() const;
52 52
53 bool Equals(const InstructionOperand* other) const {
54 return value_ == other->value_;
55 }
56
57 // Useful for map/set keys. 53 // Useful for map/set keys.
58 bool operator<(const InstructionOperand& op) const { 54 bool operator<(const InstructionOperand& op) const {
59 return value_ < op.value_; 55 return value_ < op.value_;
60 } 56 }
61 57
62 bool operator==(const InstructionOperand& op) const { 58 bool operator==(const InstructionOperand& op) const {
63 return value_ == op.value_; 59 return value_ == op.value_;
64 } 60 }
65 61
62 bool operator!=(const InstructionOperand& op) const {
63 return value_ != op.value_;
64 }
65
66 template <typename SubKindOperand> 66 template <typename SubKindOperand>
67 static SubKindOperand* New(Zone* zone, const SubKindOperand& op) { 67 static SubKindOperand* New(Zone* zone, const SubKindOperand& op) {
68 void* buffer = zone->New(sizeof(op)); 68 void* buffer = zone->New(sizeof(op));
69 return new (buffer) SubKindOperand(op); 69 return new (buffer) SubKindOperand(op);
70 } 70 }
71 71
72 static void ReplaceWith(InstructionOperand* dest, 72 static void ReplaceWith(InstructionOperand* dest,
73 const InstructionOperand* src) { 73 const InstructionOperand* src) {
74 *dest = *src; 74 *dest = *src;
75 } 75 }
76 76
77 protected: 77 protected:
78 explicit InstructionOperand(Kind kind) : value_(KindField::encode(kind)) {} 78 explicit InstructionOperand(Kind kind) : value_(KindField::encode(kind)) {}
79 79
80 class KindField : public BitField64<Kind, 0, 3> {}; 80 class KindField : public BitField64<Kind, 0, 3> {};
81 81
82 uint64_t value_; 82 uint64_t value_;
83 }; 83 };
84 84
85 struct PrintableInstructionOperand { 85 struct PrintableInstructionOperand {
86 const RegisterConfiguration* register_configuration_; 86 const RegisterConfiguration* register_configuration_;
87 const InstructionOperand* op_; 87 InstructionOperand op_;
88 }; 88 };
89 89
90 std::ostream& operator<<(std::ostream& os, 90 std::ostream& operator<<(std::ostream& os,
91 const PrintableInstructionOperand& op); 91 const PrintableInstructionOperand& op);
92 92
93 #define INSTRUCTION_OPERAND_CASTS(OperandType, OperandKind) \ 93 #define INSTRUCTION_OPERAND_CASTS(OperandType, OperandKind) \
94 \ 94 \
95 static OperandType* cast(InstructionOperand* op) { \ 95 static OperandType* cast(InstructionOperand* op) { \
96 DCHECK_EQ(OperandKind, op->kind()); \ 96 DCHECK_EQ(OperandKind, op->kind()); \
97 return static_cast<OperandType*>(op); \ 97 return static_cast<OperandType*>(op); \
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 } 160 }
161 161
162 UnallocatedOperand(ExtendedPolicy policy, Lifetime lifetime, 162 UnallocatedOperand(ExtendedPolicy policy, Lifetime lifetime,
163 int virtual_register) 163 int virtual_register)
164 : UnallocatedOperand(virtual_register) { 164 : UnallocatedOperand(virtual_register) {
165 value_ |= BasicPolicyField::encode(EXTENDED_POLICY); 165 value_ |= BasicPolicyField::encode(EXTENDED_POLICY);
166 value_ |= ExtendedPolicyField::encode(policy); 166 value_ |= ExtendedPolicyField::encode(policy);
167 value_ |= LifetimeField::encode(lifetime); 167 value_ |= LifetimeField::encode(lifetime);
168 } 168 }
169 169
170 UnallocatedOperand* Copy(Zone* zone) { return New(zone, *this); }
171
172 UnallocatedOperand* CopyUnconstrained(Zone* zone) {
173 return New(zone, UnallocatedOperand(ANY, virtual_register()));
174 }
175
176 // Predicates for the operand policy. 170 // Predicates for the operand policy.
177 bool HasAnyPolicy() const { 171 bool HasAnyPolicy() const {
178 return basic_policy() == EXTENDED_POLICY && extended_policy() == ANY; 172 return basic_policy() == EXTENDED_POLICY && extended_policy() == ANY;
179 } 173 }
180 bool HasFixedPolicy() const { 174 bool HasFixedPolicy() const {
181 return basic_policy() == FIXED_SLOT || 175 return basic_policy() == FIXED_SLOT ||
182 extended_policy() == FIXED_REGISTER || 176 extended_policy() == FIXED_REGISTER ||
183 extended_policy() == FIXED_DOUBLE_REGISTER; 177 extended_policy() == FIXED_DOUBLE_REGISTER;
184 } 178 }
185 bool HasRegisterPolicy() const { 179 bool HasRegisterPolicy() const {
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
428 \ 422 \
429 static SubKind##Operand cast(const InstructionOperand& op) { \ 423 static SubKind##Operand cast(const InstructionOperand& op) { \
430 DCHECK_EQ(kOperandKind, AllocatedOperand::cast(op).allocated_kind()); \ 424 DCHECK_EQ(kOperandKind, AllocatedOperand::cast(op).allocated_kind()); \
431 return *static_cast<const SubKind##Operand*>(&op); \ 425 return *static_cast<const SubKind##Operand*>(&op); \
432 } \ 426 } \
433 }; 427 };
434 ALLOCATED_OPERAND_LIST(ALLOCATED_OPERAND_CLASS) 428 ALLOCATED_OPERAND_LIST(ALLOCATED_OPERAND_CLASS)
435 #undef ALLOCATED_OPERAND_CLASS 429 #undef ALLOCATED_OPERAND_CLASS
436 430
437 431
438 class MoveOperands FINAL { 432 class MoveOperands FINAL : public ZoneObject {
439 public: 433 public:
440 MoveOperands(InstructionOperand* source, InstructionOperand* destination) 434 MoveOperands(const InstructionOperand& source,
441 : source_(source), destination_(destination) {} 435 const InstructionOperand& destination)
436 : source_(source), destination_(destination) {
437 DCHECK(!source.IsInvalid() && !destination.IsInvalid());
438 }
442 439
443 InstructionOperand* source() const { return source_; } 440 const InstructionOperand& source() const { return source_; }
444 void set_source(InstructionOperand* operand) { source_ = operand; } 441 InstructionOperand& source() { return source_; }
442 void set_source(const InstructionOperand& operand) { source_ = operand; }
445 443
446 InstructionOperand* destination() const { return destination_; } 444 const InstructionOperand& destination() const { return destination_; }
447 void set_destination(InstructionOperand* operand) { destination_ = operand; } 445 InstructionOperand& destination() { return destination_; }
446 void set_destination(const InstructionOperand& operand) {
447 destination_ = operand;
448 }
448 449
449 // The gap resolver marks moves as "in-progress" by clearing the 450 // The gap resolver marks moves as "in-progress" by clearing the
450 // destination (but not the source). 451 // destination (but not the source).
451 bool IsPending() const { return destination_ == NULL && source_ != NULL; } 452 bool IsPending() const {
453 return destination_.IsInvalid() && !source_.IsInvalid();
454 }
455 void SetPending() { destination_ = InstructionOperand(); }
452 456
453 // True if this move a move into the given destination operand. 457 // True if this move a move into the given destination operand.
454 bool Blocks(InstructionOperand* operand) const { 458 bool Blocks(const InstructionOperand& operand) const {
455 return !IsEliminated() && source()->Equals(operand); 459 return !IsEliminated() && source() == operand;
456 } 460 }
457 461
458 // A move is redundant if it's been eliminated or if its source and 462 // A move is redundant if it's been eliminated or if its source and
459 // destination are the same. 463 // destination are the same.
460 bool IsRedundant() const { 464 bool IsRedundant() const {
461 DCHECK_IMPLIES(destination_ != nullptr, !destination_->IsConstant()); 465 DCHECK_IMPLIES(!destination_.IsInvalid(), !destination_.IsConstant());
462 return IsEliminated() || source_->Equals(destination_); 466 return IsEliminated() || source_ == destination_;
463 } 467 }
464 468
465 // We clear both operands to indicate move that's been eliminated. 469 // We clear both operands to indicate move that's been eliminated.
466 void Eliminate() { source_ = destination_ = NULL; } 470 void Eliminate() { source_ = destination_ = InstructionOperand(); }
467 bool IsEliminated() const { 471 bool IsEliminated() const {
468 DCHECK(source_ != NULL || destination_ == NULL); 472 DCHECK_IMPLIES(source_.IsInvalid(), destination_.IsInvalid());
469 return source_ == NULL; 473 return source_.IsInvalid();
470 } 474 }
471 475
472 private: 476 private:
473 InstructionOperand* source_; 477 InstructionOperand source_;
474 InstructionOperand* destination_; 478 InstructionOperand destination_;
479
480 DISALLOW_COPY_AND_ASSIGN(MoveOperands);
475 }; 481 };
476 482
477 483
478 struct PrintableMoveOperands { 484 struct PrintableMoveOperands {
479 const RegisterConfiguration* register_configuration_; 485 const RegisterConfiguration* register_configuration_;
480 const MoveOperands* move_operands_; 486 const MoveOperands* move_operands_;
481 }; 487 };
482 488
483 489
484 std::ostream& operator<<(std::ostream& os, const PrintableMoveOperands& mo); 490 std::ostream& operator<<(std::ostream& os, const PrintableMoveOperands& mo);
485 491
486 492
487 class ParallelMove FINAL : public ZoneObject { 493 class ParallelMove FINAL : public ZoneVector<MoveOperands*>, public ZoneObject {
488 public: 494 public:
489 explicit ParallelMove(Zone* zone) : move_operands_(4, zone) {} 495 explicit ParallelMove(Zone* zone) : ZoneVector<MoveOperands*>(zone) {
496 reserve(4);
497 }
490 498
491 void AddMove(InstructionOperand* from, InstructionOperand* to, Zone* zone) { 499 MoveOperands* AddMove(const InstructionOperand& from,
492 move_operands_.Add(MoveOperands(from, to), zone); 500 const InstructionOperand& to) {
501 auto zone = get_allocator().zone();
502 auto move = new (zone) MoveOperands(from, to);
503 push_back(move);
504 return move;
493 } 505 }
494 506
495 bool IsRedundant() const; 507 bool IsRedundant() const;
496 508
497 ZoneList<MoveOperands>* move_operands() { return &move_operands_; }
498 const ZoneList<MoveOperands>* move_operands() const {
499 return &move_operands_;
500 }
501
502 // Prepare this ParallelMove to insert move as if it happened in a subsequent 509 // Prepare this ParallelMove to insert move as if it happened in a subsequent
503 // ParallelMove. move->source() may be changed. The MoveOperand returned 510 // ParallelMove. move->source() may be changed. The MoveOperand returned
504 // must be Eliminated and, as it points directly into move_operands_, it must 511 // must be Eliminated.
505 // be Eliminated before any further mutation.
506 MoveOperands* PrepareInsertAfter(MoveOperands* move) const; 512 MoveOperands* PrepareInsertAfter(MoveOperands* move) const;
507 513
508 private: 514 private:
509 ZoneList<MoveOperands> move_operands_; 515 DISALLOW_COPY_AND_ASSIGN(ParallelMove);
510 }; 516 };
511 517
512 518
513 struct PrintableParallelMove { 519 struct PrintableParallelMove {
514 const RegisterConfiguration* register_configuration_; 520 const RegisterConfiguration* register_configuration_;
515 const ParallelMove* parallel_move_; 521 const ParallelMove* parallel_move_;
516 }; 522 };
517 523
518 524
519 std::ostream& operator<<(std::ostream& os, const PrintableParallelMove& pm); 525 std::ostream& operator<<(std::ostream& os, const PrintableParallelMove& pm);
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after
849 public: 855 public:
850 typedef ZoneVector<InstructionOperand> Inputs; 856 typedef ZoneVector<InstructionOperand> Inputs;
851 857
852 PhiInstruction(Zone* zone, int virtual_register, size_t input_count); 858 PhiInstruction(Zone* zone, int virtual_register, size_t input_count);
853 859
854 void SetInput(size_t offset, int virtual_register); 860 void SetInput(size_t offset, int virtual_register);
855 861
856 int virtual_register() const { return virtual_register_; } 862 int virtual_register() const { return virtual_register_; }
857 const IntVector& operands() const { return operands_; } 863 const IntVector& operands() const { return operands_; }
858 864
865 // TODO(dcarney): this has no real business being here, since it's internal to
866 // the register allocator, but putting it here was convenient.
859 const InstructionOperand& output() const { return output_; } 867 const InstructionOperand& output() const { return output_; }
860 InstructionOperand& output() { return output_; } 868 InstructionOperand& output() { return output_; }
861 const Inputs& inputs() const { return inputs_; }
862 Inputs& inputs() { return inputs_; }
863 869
864 private: 870 private:
865 // TODO(dcarney): some of these fields are only for verification, move them to
866 // verifier.
867 const int virtual_register_; 871 const int virtual_register_;
868 InstructionOperand output_; 872 InstructionOperand output_;
869 IntVector operands_; 873 IntVector operands_;
870 Inputs inputs_;
871 }; 874 };
872 875
873 876
874 // Analogue of BasicBlock for Instructions instead of Nodes. 877 // Analogue of BasicBlock for Instructions instead of Nodes.
875 class InstructionBlock FINAL : public ZoneObject { 878 class InstructionBlock FINAL : public ZoneObject {
876 public: 879 public:
877 InstructionBlock(Zone* zone, RpoNumber rpo_number, RpoNumber loop_header, 880 InstructionBlock(Zone* zone, RpoNumber rpo_number, RpoNumber loop_header,
878 RpoNumber loop_end, bool deferred); 881 RpoNumber loop_end, bool deferred);
879 882
880 // Instruction indexes (used by the register allocator). 883 // Instruction indexes (used by the register allocator).
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
1111 1114
1112 1115
1113 std::ostream& operator<<(std::ostream& os, 1116 std::ostream& operator<<(std::ostream& os,
1114 const PrintableInstructionSequence& code); 1117 const PrintableInstructionSequence& code);
1115 1118
1116 } // namespace compiler 1119 } // namespace compiler
1117 } // namespace internal 1120 } // namespace internal
1118 } // namespace v8 1121 } // namespace v8
1119 1122
1120 #endif // V8_COMPILER_INSTRUCTION_H_ 1123 #endif // V8_COMPILER_INSTRUCTION_H_
OLDNEW
« no previous file with comments | « src/compiler/gap-resolver.cc ('k') | src/compiler/instruction.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698