blob: a86e1560c6994c201094ecae149cd4ec1fca5c08 [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;
22
23class InstructionSelector FINAL {
24 public:
25 // Forward declarations.
26 class Features;
27
28 InstructionSelector(InstructionSequence* sequence,
29 SourcePositionTable* source_positions,
30 Features features = SupportedFeatures());
31
32 // Visit code for the entire graph with the included schedule.
33 void SelectInstructions();
34
35 // ===========================================================================
36 // ============= Architecture-independent code emission methods. =============
37 // ===========================================================================
38
39 Instruction* Emit(InstructionCode opcode, InstructionOperand* output,
40 size_t temp_count = 0, InstructionOperand* *temps = NULL);
41 Instruction* Emit(InstructionCode opcode, InstructionOperand* output,
42 InstructionOperand* a, size_t temp_count = 0,
43 InstructionOperand* *temps = NULL);
44 Instruction* Emit(InstructionCode opcode, InstructionOperand* output,
45 InstructionOperand* a, InstructionOperand* b,
46 size_t temp_count = 0, InstructionOperand* *temps = NULL);
47 Instruction* Emit(InstructionCode opcode, InstructionOperand* output,
48 InstructionOperand* a, InstructionOperand* b,
49 InstructionOperand* c, size_t temp_count = 0,
50 InstructionOperand* *temps = NULL);
51 Instruction* Emit(InstructionCode opcode, InstructionOperand* output,
52 InstructionOperand* a, InstructionOperand* b,
53 InstructionOperand* c, InstructionOperand* d,
54 size_t temp_count = 0, InstructionOperand* *temps = NULL);
55 Instruction* Emit(InstructionCode opcode, size_t output_count,
56 InstructionOperand** outputs, size_t input_count,
57 InstructionOperand** inputs, size_t temp_count = 0,
58 InstructionOperand* *temps = NULL);
59 Instruction* Emit(Instruction* instr);
60
61 // ===========================================================================
62 // ============== Architecture-independent CPU feature methods. ==============
63 // ===========================================================================
64
65 class Features FINAL {
66 public:
67 Features() : bits_(0) {}
68 explicit Features(unsigned bits) : bits_(bits) {}
69 explicit Features(CpuFeature f) : bits_(1u << f) {}
70 Features(CpuFeature f1, CpuFeature f2) : bits_((1u << f1) | (1u << f2)) {}
71
72 bool Contains(CpuFeature f) const { return (bits_ & (1u << f)); }
73
74 private:
75 unsigned bits_;
76 };
77
78 bool IsSupported(CpuFeature feature) const {
79 return features_.Contains(feature);
80 }
81
82 // Returns the features supported on the target platform.
83 static Features SupportedFeatures() {
84 return Features(CpuFeatures::SupportedFeatures());
85 }
86
87 private:
88 friend class OperandGenerator;
89
90 // ===========================================================================
91 // ============ Architecture-independent graph covering methods. =============
92 // ===========================================================================
93
94 // Checks if {block} will appear directly after {current_block_} when
95 // assembling code, in which case, a fall-through can be used.
96 bool IsNextInAssemblyOrder(const BasicBlock* block) const;
97
98 // Used in pattern matching during code generation.
99 // Check if {node} can be covered while generating code for the current
100 // instruction. A node can be covered if the {user} of the node has the only
101 // edge and the two are in the same basic block.
102 bool CanCover(Node* user, Node* node) const;
103
104 // Checks if {node} was already defined, and therefore code was already
105 // generated for it.
106 bool IsDefined(Node* node) const;
107
108 // Inform the instruction selection that {node} was just defined.
109 void MarkAsDefined(Node* node);
110
111 // Checks if {node} has any uses, and therefore code has to be generated for
112 // it.
113 bool IsUsed(Node* node) const;
114
115 // Inform the instruction selection that {node} has at least one use and we
116 // will need to generate code for it.
117 void MarkAsUsed(Node* node);
118
119 // Checks if {node} is marked as double.
120 bool IsDouble(const Node* node) const;
121
122 // Inform the register allocator of a double result.
123 void MarkAsDouble(Node* node);
124
125 // Checks if {node} is marked as reference.
126 bool IsReference(const Node* node) const;
127
128 // Inform the register allocator of a reference result.
129 void MarkAsReference(Node* node);
130
131 // Inform the register allocation of the representation of the value produced
132 // by {node}.
133 void MarkAsRepresentation(MachineType rep, Node* node);
134
135 // Initialize the call buffer with the InstructionOperands, nodes, etc,
136 // corresponding
137 // to the inputs and outputs of the call.
138 // {call_code_immediate} to generate immediate operands to calls of code.
139 // {call_address_immediate} to generate immediate operands to address calls.
140 void InitializeCallBuffer(Node* call, CallBuffer* buffer,
141 bool call_code_immediate,
142 bool call_address_immediate);
143
144 FrameStateDescriptor* GetFrameStateDescriptor(Node* node);
145 void AddFrameStateInputs(Node* state, InstructionOperandVector* inputs,
146 FrameStateDescriptor* descriptor);
147
148 // ===========================================================================
149 // ============= Architecture-specific graph covering methods. ===============
150 // ===========================================================================
151
152 // Visit nodes in the given block and generate code.
153 void VisitBlock(BasicBlock* block);
154
155 // Visit the node for the control flow at the end of the block, generating
156 // code if necessary.
157 void VisitControl(BasicBlock* block);
158
159 // Visit the node and generate code, if any.
160 void VisitNode(Node* node);
161
162#define DECLARE_GENERATOR(x) void Visit##x(Node* node);
163 MACHINE_OP_LIST(DECLARE_GENERATOR)
164#undef DECLARE_GENERATOR
165
166 void VisitInt32AddWithOverflow(Node* node, FlagsContinuation* cont);
167 void VisitInt32SubWithOverflow(Node* node, FlagsContinuation* cont);
168
169 void VisitWord32Test(Node* node, FlagsContinuation* cont);
170 void VisitWord64Test(Node* node, FlagsContinuation* cont);
171 void VisitWord32Compare(Node* node, FlagsContinuation* cont);
172 void VisitWord64Compare(Node* node, FlagsContinuation* cont);
173 void VisitFloat64Compare(Node* node, FlagsContinuation* cont);
174
175 void VisitFinish(Node* node);
176 void VisitParameter(Node* node);
177 void VisitPhi(Node* node);
178 void VisitProjection(Node* node);
179 void VisitConstant(Node* node);
180 void VisitCall(Node* call, BasicBlock* continuation,
181 BasicBlock* deoptimization);
182 void VisitGoto(BasicBlock* target);
183 void VisitBranch(Node* input, BasicBlock* tbranch, BasicBlock* fbranch);
184 void VisitReturn(Node* value);
185 void VisitThrow(Node* value);
186 void VisitDeoptimize(Node* deopt);
187
188 // ===========================================================================
189
190 Graph* graph() const { return sequence()->graph(); }
191 Linkage* linkage() const { return sequence()->linkage(); }
192 Schedule* schedule() const { return sequence()->schedule(); }
193 InstructionSequence* sequence() const { return sequence_; }
194 Zone* instruction_zone() const { return sequence()->zone(); }
195 Zone* zone() { return &zone_; }
196
197 // ===========================================================================
198
199 Zone zone_;
200 InstructionSequence* sequence_;
201 SourcePositionTable* source_positions_;
202 Features features_;
203 BasicBlock* current_block_;
204 ZoneDeque<Instruction*> instructions_;
205 BoolVector defined_;
206 BoolVector used_;
207};
208
209} // namespace compiler
210} // namespace internal
211} // namespace v8
212
213#endif // V8_COMPILER_INSTRUCTION_SELECTOR_H_