5c31db74e9a158dd495283fbfe3f119768850530
[platform/upstream/nodejs.git] / deps / v8 / src / compiler / instruction-selector.h
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.
4
5 #ifndef V8_COMPILER_INSTRUCTION_SELECTOR_H_
6 #define V8_COMPILER_INSTRUCTION_SELECTOR_H_
7
8 #include <map>
9
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"
15
16 namespace v8 {
17 namespace internal {
18 namespace compiler {
19
20 // Forward declarations.
21 struct CallBuffer;  // TODO(bmeurer): Remove this.
22 class FlagsContinuation;
23 class Linkage;
24
25
26 typedef ZoneVector<InstructionOperand> InstructionOperandVector;
27
28
29 // Instruction selection generates an InstructionSequence for a given Schedule.
30 class InstructionSelector FINAL {
31  public:
32   // Forward declarations.
33   class Features;
34
35   InstructionSelector(Zone* zone, size_t node_count, Linkage* linkage,
36                       InstructionSequence* sequence, Schedule* schedule,
37                       SourcePositionTable* source_positions,
38                       Features features = SupportedFeatures());
39
40   // Visit code for the entire graph with the included schedule.
41   void SelectInstructions();
42
43   // ===========================================================================
44   // ============= Architecture-independent code emission methods. =============
45   // ===========================================================================
46
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);
78
79   // ===========================================================================
80   // ============== Architecture-independent CPU feature methods. ==============
81   // ===========================================================================
82
83   class Features FINAL {
84    public:
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)) {}
89
90     bool Contains(CpuFeature f) const { return (bits_ & (1u << f)); }
91
92    private:
93     unsigned bits_;
94   };
95
96   bool IsSupported(CpuFeature feature) const {
97     return features_.Contains(feature);
98   }
99
100   // Returns the features supported on the target platform.
101   static Features SupportedFeatures() {
102     return Features(CpuFeatures::SupportedFeatures());
103   }
104
105   // TODO(sigurds) This should take a CpuFeatures argument.
106   static MachineOperatorBuilder::Flags SupportedMachineOperatorFlags();
107
108   // ===========================================================================
109   // ============ Architecture-independent graph covering methods. =============
110   // ===========================================================================
111
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;
117
118   // Checks if {node} was already defined, and therefore code was already
119   // generated for it.
120   bool IsDefined(Node* node) const;
121
122   // Checks if {node} has any uses, and therefore code has to be generated for
123   // it.
124   bool IsUsed(Node* node) const;
125
126   // Checks if {node} is currently live.
127   bool IsLive(Node* node) const { return !IsDefined(node) && IsUsed(node); }
128
129   int GetVirtualRegister(const Node* node);
130   const std::map<NodeId, int> GetVirtualRegistersForTesting() const;
131
132  private:
133   friend class OperandGenerator;
134
135   // Inform the instruction selection that {node} was just defined.
136   void MarkAsDefined(Node* node);
137
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);
141
142   // Checks if {node} is marked as double.
143   bool IsDouble(const Node* node) const;
144
145   // Inform the register allocator of a double result.
146   void MarkAsDouble(Node* node);
147
148   // Checks if {node} is marked as reference.
149   bool IsReference(const Node* node) const;
150
151   // Inform the register allocator of a reference result.
152   void MarkAsReference(Node* node);
153
154   // Inform the register allocation of the representation of the value produced
155   // by {node}.
156   void MarkAsRepresentation(MachineType rep, Node* node);
157
158   // Inform the register allocation of the representation of the unallocated
159   // operand {op}.
160   void MarkAsRepresentation(MachineType rep, const InstructionOperand& op);
161
162   // Initialize the call buffer with the InstructionOperands, nodes, etc,
163   // corresponding
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);
170
171   FrameStateDescriptor* GetFrameStateDescriptor(Node* node);
172   void FillTypeVectorFromStateValues(ZoneVector<MachineType>* parameters,
173                                      Node* state_values);
174   void AddFrameStateInputs(Node* state, InstructionOperandVector* inputs,
175                            FrameStateDescriptor* descriptor);
176   MachineType GetMachineType(Node* node);
177
178   // ===========================================================================
179   // ============= Architecture-specific graph covering methods. ===============
180   // ===========================================================================
181
182   // Visit nodes in the given block and generate code.
183   void VisitBlock(BasicBlock* block);
184
185   // Visit the node for the control flow at the end of the block, generating
186   // code if necessary.
187   void VisitControl(BasicBlock* block);
188
189   // Visit the node and generate code, if any.
190   void VisitNode(Node* node);
191
192 #define DECLARE_GENERATOR(x) void Visit##x(Node* node);
193   MACHINE_OP_LIST(DECLARE_GENERATOR)
194 #undef DECLARE_GENERATOR
195
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);
211
212   // ===========================================================================
213
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_; }
219
220   // ===========================================================================
221
222   Zone* const zone_;
223   Linkage* const linkage_;
224   InstructionSequence* const sequence_;
225   SourcePositionTable* const source_positions_;
226   Features features_;
227   Schedule* const schedule_;
228   BasicBlock* current_block_;
229   ZoneVector<Instruction*> instructions_;
230   BoolVector defined_;
231   BoolVector used_;
232   IntVector virtual_registers_;
233 };
234
235 }  // namespace compiler
236 }  // namespace internal
237 }  // namespace v8
238
239 #endif  // V8_COMPILER_INSTRUCTION_SELECTOR_H_