deps: upgrade v8 to 3.31.74.1
[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 <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
15 namespace v8 {
16 namespace internal {
17 namespace compiler {
18
19 // Forward declarations.
20 struct CallBuffer;  // TODO(bmeurer): Remove this.
21 class FlagsContinuation;
22 class Linkage;
23
24 typedef IntVector NodeToVregMap;
25
26 class InstructionSelector FINAL {
27  public:
28   static const int kNodeUnmapped = -1;
29
30   // Forward declarations.
31   class Features;
32
33   // TODO(dcarney): pass in vreg mapping instead of graph.
34   InstructionSelector(Zone* local_zone, Graph* graph, Linkage* linkage,
35                       InstructionSequence* sequence, Schedule* schedule,
36                       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);
62   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);
72   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
104   // TODO(sigurds) This should take a CpuFeatures argument.
105   static MachineOperatorBuilder::Flags SupportedMachineOperatorFlags();
106
107   // ===========================================================================
108   // ============ Architecture-independent graph covering methods. =============
109   // ===========================================================================
110
111   // 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
121   // Checks if {node} has any uses, and therefore code has to be generated for
122   // it.
123   bool IsUsed(Node* node) const;
124
125   // 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
139   // 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
159   // Inform the register allocation of the representation of the unallocated
160   // operand {op}.
161   void MarkAsRepresentation(MachineType rep, InstructionOperand* op);
162
163   // 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);
173   void FillTypeVectorFromStateValues(ZoneVector<MachineType>* parameters,
174                                      Node* state_values);
175   void AddFrameStateInputs(Node* state, InstructionOperandVector* inputs,
176                            FrameStateDescriptor* descriptor);
177   MachineType GetMachineType(Node* node);
178
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
197   void VisitFinish(Node* node);
198   void VisitParameter(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 VisitReturn(Node* value);
206   void VisitThrow(Node* value);
207   void VisitDeoptimize(Node* deopt);
208
209   // ===========================================================================
210
211   Schedule* schedule() const { return schedule_; }
212   Linkage* linkage() const { return linkage_; }
213   InstructionSequence* sequence() const { return sequence_; }
214   Zone* instruction_zone() const { return sequence()->zone(); }
215   Zone* zone() const { return zone_; }
216
217   // ===========================================================================
218
219   Zone* const zone_;
220   Linkage* const linkage_;
221   InstructionSequence* const sequence_;
222   SourcePositionTable* const source_positions_;
223   Features features_;
224   Schedule* const schedule_;
225   NodeToVregMap node_map_;
226   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_