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
3 // found in the LICENSE file.
5 #ifndef V8_COMPILER_INSTRUCTION_SELECTOR_H_
6 #define V8_COMPILER_INSTRUCTION_SELECTOR_H_
10 #include "src/compiler/common-operator.h"
11 #include "src/compiler/instruction.h"
12 #include "src/compiler/machine-operator.h"
13 #include "src/compiler/node.h"
14 #include "src/zone-containers.h"
20 // Forward declarations.
22 struct CallBuffer; // TODO(bmeurer): Remove this.
23 class FlagsContinuation;
27 typedef ZoneVector<InstructionOperand> InstructionOperandVector;
30 // Instruction selection generates an InstructionSequence for a given Schedule.
31 class InstructionSelector FINAL {
33 // Forward declarations.
36 InstructionSelector(Zone* zone, size_t node_count, Linkage* linkage,
37 InstructionSequence* sequence, Schedule* schedule,
38 SourcePositionTable* source_positions,
39 Features features = SupportedFeatures());
41 // Visit code for the entire graph with the included schedule.
42 void SelectInstructions();
44 // ===========================================================================
45 // ============= Architecture-independent code emission methods. =============
46 // ===========================================================================
48 Instruction* Emit(InstructionCode opcode, InstructionOperand output,
49 size_t temp_count = 0, InstructionOperand* temps = NULL);
50 Instruction* Emit(InstructionCode opcode, InstructionOperand output,
51 InstructionOperand a, size_t temp_count = 0,
52 InstructionOperand* temps = NULL);
53 Instruction* Emit(InstructionCode opcode, InstructionOperand output,
54 InstructionOperand a, InstructionOperand b,
55 size_t temp_count = 0, InstructionOperand* temps = NULL);
56 Instruction* Emit(InstructionCode opcode, InstructionOperand output,
57 InstructionOperand a, InstructionOperand b,
58 InstructionOperand c, size_t temp_count = 0,
59 InstructionOperand* temps = NULL);
60 Instruction* Emit(InstructionCode opcode, InstructionOperand output,
61 InstructionOperand a, InstructionOperand b,
62 InstructionOperand c, InstructionOperand d,
63 size_t temp_count = 0, InstructionOperand* temps = NULL);
64 Instruction* Emit(InstructionCode opcode, InstructionOperand output,
65 InstructionOperand a, InstructionOperand b,
66 InstructionOperand c, InstructionOperand d,
67 InstructionOperand e, size_t temp_count = 0,
68 InstructionOperand* temps = NULL);
69 Instruction* Emit(InstructionCode opcode, InstructionOperand output,
70 InstructionOperand a, InstructionOperand b,
71 InstructionOperand c, InstructionOperand d,
72 InstructionOperand e, InstructionOperand f,
73 size_t temp_count = 0, InstructionOperand* temps = NULL);
74 Instruction* Emit(InstructionCode opcode, size_t output_count,
75 InstructionOperand* outputs, size_t input_count,
76 InstructionOperand* inputs, size_t temp_count = 0,
77 InstructionOperand* temps = NULL);
78 Instruction* Emit(Instruction* instr);
80 // ===========================================================================
81 // ============== Architecture-independent CPU feature methods. ==============
82 // ===========================================================================
84 class Features FINAL {
86 Features() : bits_(0) {}
87 explicit Features(unsigned bits) : bits_(bits) {}
88 explicit Features(CpuFeature f) : bits_(1u << f) {}
89 Features(CpuFeature f1, CpuFeature f2) : bits_((1u << f1) | (1u << f2)) {}
91 bool Contains(CpuFeature f) const { return (bits_ & (1u << f)); }
97 bool IsSupported(CpuFeature feature) const {
98 return features_.Contains(feature);
101 // Returns the features supported on the target platform.
102 static Features SupportedFeatures() {
103 return Features(CpuFeatures::SupportedFeatures());
106 // TODO(sigurds) This should take a CpuFeatures argument.
107 static MachineOperatorBuilder::Flags SupportedMachineOperatorFlags();
109 // ===========================================================================
110 // ============ Architecture-independent graph covering methods. =============
111 // ===========================================================================
113 // Used in pattern matching during code generation.
114 // Check if {node} can be covered while generating code for the current
115 // instruction. A node can be covered if the {user} of the node has the only
116 // edge and the two are in the same basic block.
117 bool CanCover(Node* user, Node* node) const;
119 // Checks if {node} was already defined, and therefore code was already
121 bool IsDefined(Node* node) const;
123 // Checks if {node} has any uses, and therefore code has to be generated for
125 bool IsUsed(Node* node) const;
127 // Checks if {node} is currently live.
128 bool IsLive(Node* node) const { return !IsDefined(node) && IsUsed(node); }
130 int GetVirtualRegister(const Node* node);
131 const std::map<NodeId, int> GetVirtualRegistersForTesting() const;
133 Isolate* isolate() const { return sequence()->isolate(); }
136 friend class OperandGenerator;
138 void EmitTableSwitch(const SwitchInfo& sw, InstructionOperand& index_operand);
139 void EmitLookupSwitch(const SwitchInfo& sw,
140 InstructionOperand& value_operand);
142 // Inform the instruction selection that {node} was just defined.
143 void MarkAsDefined(Node* node);
145 // Inform the instruction selection that {node} has at least one use and we
146 // will need to generate code for it.
147 void MarkAsUsed(Node* node);
149 // Checks if {node} is marked as double.
150 bool IsDouble(const Node* node) const;
152 // Inform the register allocator of a double result.
153 void MarkAsDouble(Node* node);
155 // Checks if {node} is marked as reference.
156 bool IsReference(const Node* node) const;
158 // Inform the register allocator of a reference result.
159 void MarkAsReference(Node* node);
161 // Inform the register allocation of the representation of the value produced
163 void MarkAsRepresentation(MachineType rep, Node* node);
165 // Inform the register allocation of the representation of the unallocated
167 void MarkAsRepresentation(MachineType rep, const InstructionOperand& op);
169 // Initialize the call buffer with the InstructionOperands, nodes, etc,
171 // to the inputs and outputs of the call.
172 // {call_code_immediate} to generate immediate operands to calls of code.
173 // {call_address_immediate} to generate immediate operands to address calls.
174 void InitializeCallBuffer(Node* call, CallBuffer* buffer,
175 bool call_code_immediate,
176 bool call_address_immediate);
178 FrameStateDescriptor* GetFrameStateDescriptor(Node* node);
179 void AddFrameStateInputs(Node* state, InstructionOperandVector* inputs,
180 FrameStateDescriptor* descriptor);
182 // ===========================================================================
183 // ============= Architecture-specific graph covering methods. ===============
184 // ===========================================================================
186 // Visit nodes in the given block and generate code.
187 void VisitBlock(BasicBlock* block);
189 // Visit the node for the control flow at the end of the block, generating
190 // code if necessary.
191 void VisitControl(BasicBlock* block);
193 // Visit the node and generate code, if any.
194 void VisitNode(Node* node);
196 #define DECLARE_GENERATOR(x) void Visit##x(Node* node);
197 MACHINE_OP_LIST(DECLARE_GENERATOR)
198 #undef DECLARE_GENERATOR
200 void VisitFinish(Node* node);
201 void VisitParameter(Node* node);
202 void VisitOsrValue(Node* node);
203 void VisitPhi(Node* node);
204 void VisitProjection(Node* node);
205 void VisitConstant(Node* node);
206 void VisitCall(Node* call, BasicBlock* handler);
207 void VisitGoto(BasicBlock* target);
208 void VisitBranch(Node* input, BasicBlock* tbranch, BasicBlock* fbranch);
209 void VisitSwitch(Node* node, const SwitchInfo& sw);
210 void VisitDeoptimize(Node* value);
211 void VisitReturn(Node* value);
212 void VisitThrow(Node* value);
214 // ===========================================================================
216 Schedule* schedule() const { return schedule_; }
217 Linkage* linkage() const { return linkage_; }
218 InstructionSequence* sequence() const { return sequence_; }
219 Zone* instruction_zone() const { return sequence()->zone(); }
220 Zone* zone() const { return zone_; }
222 // ===========================================================================
225 Linkage* const linkage_;
226 InstructionSequence* const sequence_;
227 SourcePositionTable* const source_positions_;
229 Schedule* const schedule_;
230 BasicBlock* current_block_;
231 ZoneVector<Instruction*> instructions_;
234 IntVector virtual_registers_;
237 } // namespace compiler
238 } // namespace internal
241 #endif // V8_COMPILER_INSTRUCTION_SELECTOR_H_