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

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

Issue 1375253002: [WIP][turbofan] Instruction scheduler for Turbofan. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years 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
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #ifndef V8_COMPILER_INSTRUCTION_SCHEDULER_H_
6 #define V8_COMPILER_INSTRUCTION_SCHEDULER_H_
7
8 #include "src/compiler/instruction.h"
9 #include "src/zone-containers.h"
10
11 namespace v8 {
12 namespace internal {
13 namespace compiler {
14
15 // A set of flags describing properties of the instructions so that the
16 // scheduler is aware of dependencies between instructions.
17 enum ArchOpcodeFlags {
18 kNoOpcodeFlags = 0,
19 kIsBlockTerminator = 1, // The instruction marks the end of a basic block
20 // e.g.: jump and return instructions.
21 kHasSideEffect = 2, // The instruction has some side effects (memory
22 // store, function call...)
23 kIsLoadOperation = 4, // The instruction is a memory load.
24 };
25
26
27 class InstructionScheduler final : public ZoneObject {
28 public:
29 InstructionScheduler(Zone* zone, InstructionSequence* sequence);
30
31 void StartBlock(RpoNumber rpo);
32 void EndBlock(RpoNumber rpo);
33
34 void AddInstruction(Instruction* instr);
35
36 private:
37 // A scheduling graph node.
38 // Represent an instruction and their dependencies.
39 class ScheduleGraphNode: public ZoneObject {
40 public:
41 ScheduleGraphNode(Zone* zone, Instruction* instr);
42
43 // Mark the instruction represented by 'node' as a dependecy of this one.
44 // The current instruction will be registered as an unscheduled predecessor
45 // of 'node' (i.e. it must be scheduled before 'node').
46 void AddSuccessor(ScheduleGraphNode* node);
47
48 // Check if all the predecessors of this instruction have been scheduled.
49 bool HasUnscheduledPredecessor() {
50 return unscheduled_predecessors_count_ != 0;
51 }
52
53 // Record that we have scheduled one of the predecessors of this node.
54 void DropUnscheduledPredecessor() {
55 DCHECK(unscheduled_predecessors_count_ > 0);
56 unscheduled_predecessors_count_--;
57 }
58
59 Instruction* instruction() { return instr_; }
60 ZoneDeque<ScheduleGraphNode*>& successors() { return successors_; }
61 int latency() const { return latency_; }
62
63 int total_latency() const { return total_latency_; }
64 void set_total_latency(int latency) { total_latency_ = latency; }
65
66 int start_cycle() const { return start_cycle_; }
67 void set_start_cycle(int start_cycle) { start_cycle_ = start_cycle; }
68
69 private:
70 Instruction* instr_;
71 ZoneDeque<ScheduleGraphNode*> successors_;
72
73 // Number of unscheduled predecessors for this node.
74 int unscheduled_predecessors_count_;
75
76 // Estimate of the instruction latency (the number of cycles it takes for
77 // instruction to complete).
78 int latency_;
79
80 // The sum of all the latencies on the path from this node to the end of
81 // the graph (i.e. a node with no successor).
82 int total_latency_;
83
84 // The scheduler keeps a nominal cycle count to keep track of when the
85 // result of an instruction is available. This field is updated by the
86 // scheduler to indicate when the value of all the operands of this
87 // instruction will be available.
88 int start_cycle_;
89 };
90
91 // Compare the two nodes and return true if node1 is a better candidate than
92 // node2 (i.e. node1 should be scheduled before node2).
93 bool CompareNodes(ScheduleGraphNode *node1, ScheduleGraphNode *node2) const;
94
95 // Perform scheduling for the current block.
96 void ScheduleBlock();
97
98 // Return the scheduling properties of the given instruction.
99 int GetInstructionFlags(const Instruction* instr) const;
100 int GetTargetInstructionFlags(const Instruction* instr) const;
101
102 // Return true if instr2 uses any value defined by instr1.
103 bool HasOperandDependency(const Instruction* instr1,
104 const Instruction* instr2) const;
105
106 // Return true if the instruction is a basic block terminator.
107 bool IsBlockTerminator(const Instruction* instr) const;
108
109 // Check whether the given instruction has side effects (e.g. function call,
110 // memory store).
111 bool HasSideEffect(const Instruction* instr) const {
112 return GetInstructionFlags(instr) & kHasSideEffect;
113 }
114
115 // Return true if the instruction is a memory load.
116 bool IsLoadOperation(const Instruction* instr) const {
117 return GetInstructionFlags(instr) & kIsLoadOperation;
118 }
119
120 // Identify nops used as a definition point for live-in registers at
121 // function entry.
122 bool IsFixedRegisterParameter(const Instruction* instr) const {
123 return (instr->arch_opcode() == kArchNop) &&
124 (instr->OutputCount() == 1) &&
125 (instr->OutputAt(0)->IsUnallocated()) &&
126 UnallocatedOperand::cast(instr->OutputAt(0))->HasFixedRegisterPolicy();
127 }
128
129 void ComputeTotalLatencies();
130
131 static int GetInstructionLatency(const Instruction* instr);
132
133 Zone* zone() { return zone_; }
134 InstructionSequence* sequence() { return sequence_; }
135
136 Zone* zone_;
137 InstructionSequence* sequence_;
138 ZoneVector<ScheduleGraphNode*> graph_;
139
140 // Last side effect instruction encountered while building the graph.
141 ScheduleGraphNode* last_side_effect_instr_;
142
143 // Set of load instructions encountered since the last side effect instruction
144 // which will be added as predecessors of the next instruction with side
145 // effects.
146 ZoneVector<ScheduleGraphNode*> pending_loads_;
147
148 // Live-in register markers are nop instructions which are emitted at the
149 // beginning of a basic block so that the register allocator will find a
150 // defining instruction for live-in values. They must not be moved.
151 // All these nops are chained together and added as a predecessor of every
152 // other instructions in the basic block.
153 ScheduleGraphNode* last_live_in_reg_marker_;
154 };
155
156 } // namespace compiler
157 } // namespace internal
158 } // namespace v8
159
160 #endif // V8_COMPILER_INSTRUCTION_SCHEDULER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698