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.
21 struct CallBuffer; // TODO(bmeurer): Remove this.
22 class FlagsContinuation;
26 typedef ZoneVector<InstructionOperand> InstructionOperandVector;
29 // Instruction selection generates an InstructionSequence for a given Schedule.
30 class InstructionSelector FINAL {
32 // Forward declarations.
35 InstructionSelector(Zone* zone, size_t node_count, Linkage* linkage,
36 InstructionSequence* sequence, Schedule* schedule,
37 SourcePositionTable* source_positions,
38 Features features = SupportedFeatures());
40 // Visit code for the entire graph with the included schedule.
41 void SelectInstructions();
43 // ===========================================================================
44 // ============= Architecture-independent code emission methods. =============
45 // ===========================================================================
47 Instruction* Emit(InstructionCode opcode, InstructionOperand output,
48 size_t temp_count = 0, InstructionOperand* temps = NULL);
49 Instruction* Emit(InstructionCode opcode, InstructionOperand output,
50 InstructionOperand a, size_t temp_count = 0,
51 InstructionOperand* temps = NULL);
52 Instruction* Emit(InstructionCode opcode, InstructionOperand output,
53 InstructionOperand a, InstructionOperand b,
54 size_t temp_count = 0, InstructionOperand* temps = NULL);
55 Instruction* Emit(InstructionCode opcode, InstructionOperand output,
56 InstructionOperand a, InstructionOperand b,
57 InstructionOperand c, size_t temp_count = 0,
58 InstructionOperand* temps = NULL);
59 Instruction* Emit(InstructionCode opcode, InstructionOperand output,
60 InstructionOperand a, InstructionOperand b,
61 InstructionOperand c, InstructionOperand d,
62 size_t temp_count = 0, InstructionOperand* temps = NULL);
63 Instruction* Emit(InstructionCode opcode, InstructionOperand output,
64 InstructionOperand a, InstructionOperand b,
65 InstructionOperand c, InstructionOperand d,
66 InstructionOperand e, size_t temp_count = 0,
67 InstructionOperand* temps = NULL);
68 Instruction* Emit(InstructionCode opcode, InstructionOperand output,
69 InstructionOperand a, InstructionOperand b,
70 InstructionOperand c, InstructionOperand d,
71 InstructionOperand e, InstructionOperand f,
72 size_t temp_count = 0, InstructionOperand* temps = NULL);
73 Instruction* Emit(InstructionCode opcode, size_t output_count,
74 InstructionOperand* outputs, size_t input_count,
75 InstructionOperand* inputs, size_t temp_count = 0,
76 InstructionOperand* temps = NULL);
77 Instruction* Emit(Instruction* instr);
79 // ===========================================================================
80 // ============== Architecture-independent CPU feature methods. ==============
81 // ===========================================================================
83 class Features FINAL {
85 Features() : bits_(0) {}
86 explicit Features(unsigned bits) : bits_(bits) {}
87 explicit Features(CpuFeature f) : bits_(1u << f) {}
88 Features(CpuFeature f1, CpuFeature f2) : bits_((1u << f1) | (1u << f2)) {}
90 bool Contains(CpuFeature f) const { return (bits_ & (1u << f)); }
96 bool IsSupported(CpuFeature feature) const {
97 return features_.Contains(feature);
100 // Returns the features supported on the target platform.
101 static Features SupportedFeatures() {
102 return Features(CpuFeatures::SupportedFeatures());
105 // TODO(sigurds) This should take a CpuFeatures argument.
106 static MachineOperatorBuilder::Flags SupportedMachineOperatorFlags();
108 // ===========================================================================
109 // ============ Architecture-independent graph covering methods. =============
110 // ===========================================================================
112 // Used in pattern matching during code generation.
113 // Check if {node} can be covered while generating code for the current
114 // instruction. A node can be covered if the {user} of the node has the only
115 // edge and the two are in the same basic block.
116 bool CanCover(Node* user, Node* node) const;
118 // Checks if {node} was already defined, and therefore code was already
120 bool IsDefined(Node* node) const;
122 // Checks if {node} has any uses, and therefore code has to be generated for
124 bool IsUsed(Node* node) const;
126 // Checks if {node} is currently live.
127 bool IsLive(Node* node) const { return !IsDefined(node) && IsUsed(node); }
129 int GetVirtualRegister(const Node* node);
130 const std::map<NodeId, int> GetVirtualRegistersForTesting() const;
133 friend class OperandGenerator;
135 // Inform the instruction selection that {node} was just defined.
136 void MarkAsDefined(Node* node);
138 // Inform the instruction selection that {node} has at least one use and we
139 // will need to generate code for it.
140 void MarkAsUsed(Node* node);
142 // Checks if {node} is marked as double.
143 bool IsDouble(const Node* node) const;
145 // Inform the register allocator of a double result.
146 void MarkAsDouble(Node* node);
148 // Checks if {node} is marked as reference.
149 bool IsReference(const Node* node) const;
151 // Inform the register allocator of a reference result.
152 void MarkAsReference(Node* node);
154 // Inform the register allocation of the representation of the value produced
156 void MarkAsRepresentation(MachineType rep, Node* node);
158 // Inform the register allocation of the representation of the unallocated
160 void MarkAsRepresentation(MachineType rep, const InstructionOperand& op);
162 // Initialize the call buffer with the InstructionOperands, nodes, etc,
164 // to the inputs and outputs of the call.
165 // {call_code_immediate} to generate immediate operands to calls of code.
166 // {call_address_immediate} to generate immediate operands to address calls.
167 void InitializeCallBuffer(Node* call, CallBuffer* buffer,
168 bool call_code_immediate,
169 bool call_address_immediate);
171 FrameStateDescriptor* GetFrameStateDescriptor(Node* node);
172 void FillTypeVectorFromStateValues(ZoneVector<MachineType>* parameters,
174 void AddFrameStateInputs(Node* state, InstructionOperandVector* inputs,
175 FrameStateDescriptor* descriptor);
176 MachineType GetMachineType(Node* node);
178 // ===========================================================================
179 // ============= Architecture-specific graph covering methods. ===============
180 // ===========================================================================
182 // Visit nodes in the given block and generate code.
183 void VisitBlock(BasicBlock* block);
185 // Visit the node for the control flow at the end of the block, generating
186 // code if necessary.
187 void VisitControl(BasicBlock* block);
189 // Visit the node and generate code, if any.
190 void VisitNode(Node* node);
192 #define DECLARE_GENERATOR(x) void Visit##x(Node* node);
193 MACHINE_OP_LIST(DECLARE_GENERATOR)
194 #undef DECLARE_GENERATOR
196 void VisitFinish(Node* node);
197 void VisitParameter(Node* node);
198 void VisitOsrValue(Node* node);
199 void VisitPhi(Node* node);
200 void VisitProjection(Node* node);
201 void VisitConstant(Node* node);
202 void VisitCall(Node* call);
203 void VisitGoto(BasicBlock* target);
204 void VisitBranch(Node* input, BasicBlock* tbranch, BasicBlock* fbranch);
205 void VisitSwitch(Node* node, BasicBlock* default_branch,
206 BasicBlock** case_branches, int32_t* case_values,
207 size_t case_count, int32_t min_value, int32_t max_value);
208 void VisitReturn(Node* value);
209 void VisitThrow(Node* value);
210 void VisitDeoptimize(Node* deopt);
212 // ===========================================================================
214 Schedule* schedule() const { return schedule_; }
215 Linkage* linkage() const { return linkage_; }
216 InstructionSequence* sequence() const { return sequence_; }
217 Zone* instruction_zone() const { return sequence()->zone(); }
218 Zone* zone() const { return zone_; }
220 // ===========================================================================
223 Linkage* const linkage_;
224 InstructionSequence* const sequence_;
225 SourcePositionTable* const source_positions_;
227 Schedule* const schedule_;
228 BasicBlock* current_block_;
229 ZoneVector<Instruction*> instructions_;
232 IntVector virtual_registers_;
235 } // namespace compiler
236 } // namespace internal
239 #endif // V8_COMPILER_INSTRUCTION_SELECTOR_H_