OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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_SCHEDULER_H_ | 5 #ifndef V8_COMPILER_INSTRUCTION_SCHEDULER_H_ |
6 #define V8_COMPILER_INSTRUCTION_SCHEDULER_H_ | 6 #define V8_COMPILER_INSTRUCTION_SCHEDULER_H_ |
7 | 7 |
8 #include "src/compiler/instruction.h" | 8 #include "src/compiler/instruction.h" |
9 #include "src/zone-containers.h" | 9 #include "src/zone-containers.h" |
10 | 10 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 // the graph (i.e. a node with no successor). | 83 // the graph (i.e. a node with no successor). |
84 int total_latency_; | 84 int total_latency_; |
85 | 85 |
86 // The scheduler keeps a nominal cycle count to keep track of when the | 86 // The scheduler keeps a nominal cycle count to keep track of when the |
87 // result of an instruction is available. This field is updated by the | 87 // result of an instruction is available. This field is updated by the |
88 // scheduler to indicate when the value of all the operands of this | 88 // scheduler to indicate when the value of all the operands of this |
89 // instruction will be available. | 89 // instruction will be available. |
90 int start_cycle_; | 90 int start_cycle_; |
91 }; | 91 }; |
92 | 92 |
93 // Compare the two nodes and return true if node1 is a better candidate than | 93 // Keep track of all nodes ready to be scheduled (i.e. all their dependencies |
94 // node2 (i.e. node1 should be scheduled before node2). | 94 // have been scheduled. Note that this class is inteded to be extended by |
95 bool CompareNodes(ScheduleGraphNode *node1, ScheduleGraphNode *node2) const; | 95 // concrete implementation of the scheduling queue which define the policy |
| 96 // to pop node from the queue. |
| 97 class SchedulingQueueBase { |
| 98 public: |
| 99 explicit SchedulingQueueBase(InstructionScheduler* scheduler) |
| 100 : scheduler_(scheduler), |
| 101 nodes_(scheduler->zone()) { |
| 102 } |
96 | 103 |
97 // Perform scheduling for the current block. | 104 void AddNode(ScheduleGraphNode* node) { |
| 105 nodes_.push_back(node); |
| 106 } |
| 107 |
| 108 bool IsEmpty() const { |
| 109 return nodes_.empty(); |
| 110 } |
| 111 |
| 112 protected: |
| 113 InstructionScheduler* scheduler_; |
| 114 ZoneLinkedList<ScheduleGraphNode*> nodes_; |
| 115 }; |
| 116 |
| 117 // A scheduling queue which prioritize nodes on the critical path (we look |
| 118 // for the instruction with the highest latency on the path to reach the end |
| 119 // of the graph). |
| 120 class CriticalPathFirstQueue : public SchedulingQueueBase { |
| 121 public: |
| 122 explicit CriticalPathFirstQueue(InstructionScheduler* scheduler) |
| 123 : SchedulingQueueBase(scheduler) { } |
| 124 |
| 125 // Look for the best candidate to schedule, remove it from the queue and |
| 126 // return it. |
| 127 ScheduleGraphNode* PopBestCandidate(int cycle); |
| 128 |
| 129 private: |
| 130 // Compare the two nodes and return true if node1 is a better candidate than |
| 131 // node2 (i.e. node1 should be scheduled before node2). |
| 132 bool CompareNodes(ScheduleGraphNode *node1, ScheduleGraphNode *node2) const; |
| 133 }; |
| 134 |
| 135 // A queue which pop a random node from the queue to perform stress tests on |
| 136 // the scheduler. |
| 137 class StressSchedulerQueue : public SchedulingQueueBase { |
| 138 public: |
| 139 explicit StressSchedulerQueue(InstructionScheduler* scheduler) |
| 140 : SchedulingQueueBase(scheduler) { } |
| 141 |
| 142 ScheduleGraphNode* PopBestCandidate(int cycle); |
| 143 |
| 144 private: |
| 145 Isolate *isolate() { |
| 146 return scheduler_->isolate(); |
| 147 } |
| 148 }; |
| 149 |
| 150 // Perform scheduling for the current block specifying the queue type to |
| 151 // use to determine the next best candidate. |
| 152 template <typename QueueType> |
98 void ScheduleBlock(); | 153 void ScheduleBlock(); |
99 | 154 |
100 // Return the scheduling properties of the given instruction. | 155 // Return the scheduling properties of the given instruction. |
101 int GetInstructionFlags(const Instruction* instr) const; | 156 int GetInstructionFlags(const Instruction* instr) const; |
102 int GetTargetInstructionFlags(const Instruction* instr) const; | 157 int GetTargetInstructionFlags(const Instruction* instr) const; |
103 | 158 |
104 // Return true if instr2 uses any value defined by instr1. | 159 // Return true if instr2 uses any value defined by instr1. |
105 bool HasOperandDependency(const Instruction* instr1, | 160 bool HasOperandDependency(const Instruction* instr1, |
106 const Instruction* instr2) const; | 161 const Instruction* instr2) const; |
107 | 162 |
(...skipping 19 matching lines...) Expand all Loading... |
127 (instr->OutputAt(0)->IsUnallocated()) && | 182 (instr->OutputAt(0)->IsUnallocated()) && |
128 UnallocatedOperand::cast(instr->OutputAt(0))->HasFixedRegisterPolicy(); | 183 UnallocatedOperand::cast(instr->OutputAt(0))->HasFixedRegisterPolicy(); |
129 } | 184 } |
130 | 185 |
131 void ComputeTotalLatencies(); | 186 void ComputeTotalLatencies(); |
132 | 187 |
133 static int GetInstructionLatency(const Instruction* instr); | 188 static int GetInstructionLatency(const Instruction* instr); |
134 | 189 |
135 Zone* zone() { return zone_; } | 190 Zone* zone() { return zone_; } |
136 InstructionSequence* sequence() { return sequence_; } | 191 InstructionSequence* sequence() { return sequence_; } |
| 192 Isolate* isolate() { return sequence()->isolate(); } |
137 | 193 |
138 Zone* zone_; | 194 Zone* zone_; |
139 InstructionSequence* sequence_; | 195 InstructionSequence* sequence_; |
140 ZoneVector<ScheduleGraphNode*> graph_; | 196 ZoneVector<ScheduleGraphNode*> graph_; |
141 | 197 |
142 // Last side effect instruction encountered while building the graph. | 198 // Last side effect instruction encountered while building the graph. |
143 ScheduleGraphNode* last_side_effect_instr_; | 199 ScheduleGraphNode* last_side_effect_instr_; |
144 | 200 |
145 // Set of load instructions encountered since the last side effect instruction | 201 // Set of load instructions encountered since the last side effect instruction |
146 // which will be added as predecessors of the next instruction with side | 202 // which will be added as predecessors of the next instruction with side |
147 // effects. | 203 // effects. |
148 ZoneVector<ScheduleGraphNode*> pending_loads_; | 204 ZoneVector<ScheduleGraphNode*> pending_loads_; |
149 | 205 |
150 // Live-in register markers are nop instructions which are emitted at the | 206 // Live-in register markers are nop instructions which are emitted at the |
151 // beginning of a basic block so that the register allocator will find a | 207 // beginning of a basic block so that the register allocator will find a |
152 // defining instruction for live-in values. They must not be moved. | 208 // defining instruction for live-in values. They must not be moved. |
153 // All these nops are chained together and added as a predecessor of every | 209 // All these nops are chained together and added as a predecessor of every |
154 // other instructions in the basic block. | 210 // other instructions in the basic block. |
155 ScheduleGraphNode* last_live_in_reg_marker_; | 211 ScheduleGraphNode* last_live_in_reg_marker_; |
156 }; | 212 }; |
157 | 213 |
158 } // namespace compiler | 214 } // namespace compiler |
159 } // namespace internal | 215 } // namespace internal |
160 } // namespace v8 | 216 } // namespace v8 |
161 | 217 |
162 #endif // V8_COMPILER_INSTRUCTION_SCHEDULER_H_ | 218 #endif // V8_COMPILER_INSTRUCTION_SCHEDULER_H_ |
OLD | NEW |