blob: 5e3c52f959bf11da7bf6e1e78cf07f90ec5b77bf [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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
3// found in the LICENSE file.
4
5#ifndef V8_COMPILER_INSTRUCTION_SELECTOR_H_
6#define V8_COMPILER_INSTRUCTION_SELECTOR_H_
7
8#include <deque>
9
10#include "src/compiler/common-operator.h"
11#include "src/compiler/instruction.h"
12#include "src/compiler/machine-operator.h"
13#include "src/zone-containers.h"
14
15namespace v8 {
16namespace internal {
17namespace compiler {
18
19// Forward declarations.
20struct CallBuffer; // TODO(bmeurer): Remove this.
21class FlagsContinuation;
Emily Bernierd0a1eb72015-03-24 16:35:39 -040022class Linkage;
23
24typedef IntVector NodeToVregMap;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000025
26class InstructionSelector FINAL {
27 public:
Emily Bernierd0a1eb72015-03-24 16:35:39 -040028 static const int kNodeUnmapped = -1;
29
Ben Murdochb8a8cc12014-11-26 15:28:44 +000030 // Forward declarations.
31 class Features;
32
Emily Bernierd0a1eb72015-03-24 16:35:39 -040033 // TODO(dcarney): pass in vreg mapping instead of graph.
34 InstructionSelector(Zone* local_zone, Graph* graph, Linkage* linkage,
35 InstructionSequence* sequence, Schedule* schedule,
Ben Murdochb8a8cc12014-11-26 15:28:44 +000036 SourcePositionTable* source_positions,
37 Features features = SupportedFeatures());
38
39 // Visit code for the entire graph with the included schedule.
40 void SelectInstructions();
41
42 // ===========================================================================
43 // ============= Architecture-independent code emission methods. =============
44 // ===========================================================================
45
46 Instruction* Emit(InstructionCode opcode, InstructionOperand* output,
47 size_t temp_count = 0, InstructionOperand* *temps = NULL);
48 Instruction* Emit(InstructionCode opcode, InstructionOperand* output,
49 InstructionOperand* a, size_t temp_count = 0,
50 InstructionOperand* *temps = NULL);
51 Instruction* Emit(InstructionCode opcode, InstructionOperand* output,
52 InstructionOperand* a, InstructionOperand* b,
53 size_t temp_count = 0, InstructionOperand* *temps = NULL);
54 Instruction* Emit(InstructionCode opcode, InstructionOperand* output,
55 InstructionOperand* a, InstructionOperand* b,
56 InstructionOperand* c, size_t temp_count = 0,
57 InstructionOperand* *temps = NULL);
58 Instruction* Emit(InstructionCode opcode, InstructionOperand* output,
59 InstructionOperand* a, InstructionOperand* b,
60 InstructionOperand* c, InstructionOperand* d,
61 size_t temp_count = 0, InstructionOperand* *temps = NULL);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040062 Instruction* Emit(InstructionCode opcode, InstructionOperand* output,
63 InstructionOperand* a, InstructionOperand* b,
64 InstructionOperand* c, InstructionOperand* d,
65 InstructionOperand* e, size_t temp_count = 0,
66 InstructionOperand* *temps = NULL);
67 Instruction* Emit(InstructionCode opcode, InstructionOperand* output,
68 InstructionOperand* a, InstructionOperand* b,
69 InstructionOperand* c, InstructionOperand* d,
70 InstructionOperand* e, InstructionOperand* f,
71 size_t temp_count = 0, InstructionOperand* *temps = NULL);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000072 Instruction* Emit(InstructionCode opcode, size_t output_count,
73 InstructionOperand** outputs, size_t input_count,
74 InstructionOperand** inputs, size_t temp_count = 0,
75 InstructionOperand* *temps = NULL);
76 Instruction* Emit(Instruction* instr);
77
78 // ===========================================================================
79 // ============== Architecture-independent CPU feature methods. ==============
80 // ===========================================================================
81
82 class Features FINAL {
83 public:
84 Features() : bits_(0) {}
85 explicit Features(unsigned bits) : bits_(bits) {}
86 explicit Features(CpuFeature f) : bits_(1u << f) {}
87 Features(CpuFeature f1, CpuFeature f2) : bits_((1u << f1) | (1u << f2)) {}
88
89 bool Contains(CpuFeature f) const { return (bits_ & (1u << f)); }
90
91 private:
92 unsigned bits_;
93 };
94
95 bool IsSupported(CpuFeature feature) const {
96 return features_.Contains(feature);
97 }
98
99 // Returns the features supported on the target platform.
100 static Features SupportedFeatures() {
101 return Features(CpuFeatures::SupportedFeatures());
102 }
103
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400104 // TODO(sigurds) This should take a CpuFeatures argument.
105 static MachineOperatorBuilder::Flags SupportedMachineOperatorFlags();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000106
107 // ===========================================================================
108 // ============ Architecture-independent graph covering methods. =============
109 // ===========================================================================
110
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000111 // Used in pattern matching during code generation.
112 // Check if {node} can be covered while generating code for the current
113 // instruction. A node can be covered if the {user} of the node has the only
114 // edge and the two are in the same basic block.
115 bool CanCover(Node* user, Node* node) const;
116
117 // Checks if {node} was already defined, and therefore code was already
118 // generated for it.
119 bool IsDefined(Node* node) const;
120
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000121 // Checks if {node} has any uses, and therefore code has to be generated for
122 // it.
123 bool IsUsed(Node* node) const;
124
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400125 // Checks if {node} is currently live.
126 bool IsLive(Node* node) const { return !IsDefined(node) && IsUsed(node); }
127
128 int GetVirtualRegister(const Node* node);
129 // Gets the current mapping if it exists, kNodeUnmapped otherwise.
130 int GetMappedVirtualRegister(const Node* node) const;
131 const NodeToVregMap& GetNodeMapForTesting() const { return node_map_; }
132
133 private:
134 friend class OperandGenerator;
135
136 // Inform the instruction selection that {node} was just defined.
137 void MarkAsDefined(Node* node);
138
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000139 // Inform the instruction selection that {node} has at least one use and we
140 // will need to generate code for it.
141 void MarkAsUsed(Node* node);
142
143 // Checks if {node} is marked as double.
144 bool IsDouble(const Node* node) const;
145
146 // Inform the register allocator of a double result.
147 void MarkAsDouble(Node* node);
148
149 // Checks if {node} is marked as reference.
150 bool IsReference(const Node* node) const;
151
152 // Inform the register allocator of a reference result.
153 void MarkAsReference(Node* node);
154
155 // Inform the register allocation of the representation of the value produced
156 // by {node}.
157 void MarkAsRepresentation(MachineType rep, Node* node);
158
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400159 // Inform the register allocation of the representation of the unallocated
160 // operand {op}.
161 void MarkAsRepresentation(MachineType rep, InstructionOperand* op);
162
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000163 // Initialize the call buffer with the InstructionOperands, nodes, etc,
164 // corresponding
165 // to the inputs and outputs of the call.
166 // {call_code_immediate} to generate immediate operands to calls of code.
167 // {call_address_immediate} to generate immediate operands to address calls.
168 void InitializeCallBuffer(Node* call, CallBuffer* buffer,
169 bool call_code_immediate,
170 bool call_address_immediate);
171
172 FrameStateDescriptor* GetFrameStateDescriptor(Node* node);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400173 void FillTypeVectorFromStateValues(ZoneVector<MachineType>* parameters,
174 Node* state_values);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000175 void AddFrameStateInputs(Node* state, InstructionOperandVector* inputs,
176 FrameStateDescriptor* descriptor);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400177 MachineType GetMachineType(Node* node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000178
179 // ===========================================================================
180 // ============= Architecture-specific graph covering methods. ===============
181 // ===========================================================================
182
183 // Visit nodes in the given block and generate code.
184 void VisitBlock(BasicBlock* block);
185
186 // Visit the node for the control flow at the end of the block, generating
187 // code if necessary.
188 void VisitControl(BasicBlock* block);
189
190 // Visit the node and generate code, if any.
191 void VisitNode(Node* node);
192
193#define DECLARE_GENERATOR(x) void Visit##x(Node* node);
194 MACHINE_OP_LIST(DECLARE_GENERATOR)
195#undef DECLARE_GENERATOR
196
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000197 void VisitFinish(Node* node);
198 void VisitParameter(Node* node);
199 void VisitPhi(Node* node);
200 void VisitProjection(Node* node);
201 void VisitConstant(Node* node);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400202 void VisitCall(Node* call);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000203 void VisitGoto(BasicBlock* target);
204 void VisitBranch(Node* input, BasicBlock* tbranch, BasicBlock* fbranch);
205 void VisitReturn(Node* value);
206 void VisitThrow(Node* value);
207 void VisitDeoptimize(Node* deopt);
208
209 // ===========================================================================
210
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400211 Schedule* schedule() const { return schedule_; }
212 Linkage* linkage() const { return linkage_; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000213 InstructionSequence* sequence() const { return sequence_; }
214 Zone* instruction_zone() const { return sequence()->zone(); }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400215 Zone* zone() const { return zone_; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000216
217 // ===========================================================================
218
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400219 Zone* const zone_;
220 Linkage* const linkage_;
221 InstructionSequence* const sequence_;
222 SourcePositionTable* const source_positions_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000223 Features features_;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400224 Schedule* const schedule_;
225 NodeToVregMap node_map_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000226 BasicBlock* current_block_;
227 ZoneDeque<Instruction*> instructions_;
228 BoolVector defined_;
229 BoolVector used_;
230};
231
232} // namespace compiler
233} // namespace internal
234} // namespace v8
235
236#endif // V8_COMPILER_INSTRUCTION_SELECTOR_H_