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