1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2014 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifndef V8_COMPILER_INSTRUCTION_SELECTOR_H_
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define V8_COMPILER_INSTRUCTION_SELECTOR_H_
7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
8014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include <map>
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/common-operator.h"
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/instruction.h"
12014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler/instruction-scheduler.h"
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/machine-operator.h"
14014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler/node.h"
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/zone-containers.h"
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 {
18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal {
19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace compiler {
20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Forward declarations.
22014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass BasicBlock;
23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstruct CallBuffer;  // TODO(bmeurer): Remove this.
24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass FlagsContinuation;
25958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierclass Linkage;
26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass OperandGenerator;
27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstruct SwitchInfo;
28958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// This struct connects nodes of parameters which are going to be pushed on the
30014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// call stack with their parameter index in the call descriptor of the callee.
31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass PushParameter {
32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  PushParameter() : node_(nullptr), type_(MachineType::None()) {}
34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  PushParameter(Node* node, MachineType type) : node_(node), type_(type) {}
35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* node() const { return node_; }
37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MachineType type() const { return type_; }
38014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
39014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private:
40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* node_;
41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MachineType type_;
42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
43958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
44014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Instruction selection generates an InstructionSequence for a given Schedule.
45014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass InstructionSelector final {
46014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Forward declarations.
48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  class Features;
49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  enum SourcePositionMode { kCallSourcePositions, kAllSourcePositions };
51014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
52014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionSelector(
53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Zone* zone, size_t node_count, Linkage* linkage,
54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      InstructionSequence* sequence, Schedule* schedule,
55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SourcePositionTable* source_positions,
56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SourcePositionMode source_position_mode = kCallSourcePositions,
57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Features features = SupportedFeatures());
58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Visit code for the entire graph with the included schedule.
60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void SelectInstructions();
61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void StartBlock(RpoNumber rpo);
63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void EndBlock(RpoNumber rpo);
64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void AddInstruction(Instruction* instr);
65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // ===========================================================================
67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // ============= Architecture-independent code emission methods. =============
68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // ===========================================================================
69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Instruction* Emit(InstructionCode opcode, InstructionOperand output,
71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    size_t temp_count = 0, InstructionOperand* temps = nullptr);
72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Instruction* Emit(InstructionCode opcode, InstructionOperand output,
73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    InstructionOperand a, size_t temp_count = 0,
74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    InstructionOperand* temps = nullptr);
75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Instruction* Emit(InstructionCode opcode, InstructionOperand output,
76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    InstructionOperand a, InstructionOperand b,
77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    size_t temp_count = 0, InstructionOperand* temps = nullptr);
78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Instruction* Emit(InstructionCode opcode, InstructionOperand output,
79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    InstructionOperand a, InstructionOperand b,
80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    InstructionOperand c, size_t temp_count = 0,
81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    InstructionOperand* temps = nullptr);
82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Instruction* Emit(InstructionCode opcode, InstructionOperand output,
83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    InstructionOperand a, InstructionOperand b,
84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    InstructionOperand c, InstructionOperand d,
85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    size_t temp_count = 0, InstructionOperand* temps = nullptr);
86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Instruction* Emit(InstructionCode opcode, InstructionOperand output,
87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    InstructionOperand a, InstructionOperand b,
88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    InstructionOperand c, InstructionOperand d,
89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    InstructionOperand e, size_t temp_count = 0,
90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    InstructionOperand* temps = nullptr);
91014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Instruction* Emit(InstructionCode opcode, InstructionOperand output,
92014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    InstructionOperand a, InstructionOperand b,
93014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    InstructionOperand c, InstructionOperand d,
94014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    InstructionOperand e, InstructionOperand f,
95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    size_t temp_count = 0, InstructionOperand* temps = nullptr);
96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instruction* Emit(InstructionCode opcode, size_t output_count,
97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    InstructionOperand* outputs, size_t input_count,
98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    InstructionOperand* inputs, size_t temp_count = 0,
99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    InstructionOperand* temps = nullptr);
100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instruction* Emit(Instruction* instr);
101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // ===========================================================================
103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // ============== Architecture-independent CPU feature methods. ==============
104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // ===========================================================================
105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  class Features final {
107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch   public:
108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Features() : bits_(0) {}
109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    explicit Features(unsigned bits) : bits_(bits) {}
110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    explicit Features(CpuFeature f) : bits_(1u << f) {}
111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Features(CpuFeature f1, CpuFeature f2) : bits_((1u << f1) | (1u << f2)) {}
112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool Contains(CpuFeature f) const { return (bits_ & (1u << f)); }
114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch   private:
116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    unsigned bits_;
117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsSupported(CpuFeature feature) const {
120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return features_.Contains(feature);
121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Returns the features supported on the target platform.
124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Features SupportedFeatures() {
125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Features(CpuFeatures::SupportedFeatures());
126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
128958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // TODO(sigurds) This should take a CpuFeatures argument.
129958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static MachineOperatorBuilder::Flags SupportedMachineOperatorFlags();
130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // ===========================================================================
132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // ============ Architecture-independent graph covering methods. =============
133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // ===========================================================================
134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Used in pattern matching during code generation.
136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Check if {node} can be covered while generating code for the current
137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // instruction. A node can be covered if the {user} of the node has the only
138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // edge and the two are in the same basic block.
139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool CanCover(Node* user, Node* node) const;
140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Checks if {node} was already defined, and therefore code was already
142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // generated for it.
143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsDefined(Node* node) const;
144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Checks if {node} has any uses, and therefore code has to be generated for
146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // it.
147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsUsed(Node* node) const;
148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
149958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Checks if {node} is currently live.
150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool IsLive(Node* node) const { return !IsDefined(node) && IsUsed(node); }
151958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
152958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int GetVirtualRegister(const Node* node);
153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const std::map<NodeId, int> GetVirtualRegistersForTesting() const;
154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Isolate* isolate() const { return sequence()->isolate(); }
156958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
157958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private:
158958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  friend class OperandGenerator;
159958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void EmitTableSwitch(const SwitchInfo& sw, InstructionOperand& index_operand);
161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void EmitLookupSwitch(const SwitchInfo& sw,
162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                        InstructionOperand& value_operand);
163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
164958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Inform the instruction selection that {node} was just defined.
165958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void MarkAsDefined(Node* node);
166958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Inform the instruction selection that {node} has at least one use and we
168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // will need to generate code for it.
169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void MarkAsUsed(Node* node);
170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Inform the register allocation of the representation of the value produced
172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // by {node}.
173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void MarkAsRepresentation(MachineRepresentation rep, Node* node);
174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void MarkAsWord32(Node* node) {
175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MarkAsRepresentation(MachineRepresentation::kWord32, node);
176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void MarkAsWord64(Node* node) {
178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MarkAsRepresentation(MachineRepresentation::kWord64, node);
179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void MarkAsFloat32(Node* node) {
181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MarkAsRepresentation(MachineRepresentation::kFloat32, node);
182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void MarkAsFloat64(Node* node) {
184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MarkAsRepresentation(MachineRepresentation::kFloat64, node);
185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void MarkAsReference(Node* node) {
187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MarkAsRepresentation(MachineRepresentation::kTagged, node);
188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
190958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Inform the register allocation of the representation of the unallocated
191958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // operand {op}.
192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void MarkAsRepresentation(MachineRepresentation rep,
193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            const InstructionOperand& op);
194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  enum CallBufferFlag {
196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kCallCodeImmediate = 1u << 0,
197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kCallAddressImmediate = 1u << 1,
198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kCallTail = 1u << 2
199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  };
200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  typedef base::Flags<CallBufferFlag> CallBufferFlags;
201958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Initialize the call buffer with the InstructionOperands, nodes, etc,
203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // corresponding
204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // to the inputs and outputs of the call.
205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // {call_code_immediate} to generate immediate operands to calls of code.
206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // {call_address_immediate} to generate immediate operands to address calls.
207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void InitializeCallBuffer(Node* call, CallBuffer* buffer,
208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            CallBufferFlags flags, int stack_param_delta = 0);
209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsTailCallAddressImmediate();
210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FrameStateDescriptor* GetFrameStateDescriptor(Node* node);
212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // ===========================================================================
214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // ============= Architecture-specific graph covering methods. ===============
215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // ===========================================================================
216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Visit nodes in the given block and generate code.
218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void VisitBlock(BasicBlock* block);
219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Visit the node for the control flow at the end of the block, generating
221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // code if necessary.
222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void VisitControl(BasicBlock* block);
223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Visit the node and generate code, if any.
225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void VisitNode(Node* node);
226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define DECLARE_GENERATOR(x) void Visit##x(Node* node);
228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MACHINE_OP_LIST(DECLARE_GENERATOR)
229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef DECLARE_GENERATOR
230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void VisitFinishRegion(Node* node);
232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void VisitGuard(Node* node);
233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void VisitParameter(Node* node);
234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void VisitIfException(Node* node);
235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void VisitOsrValue(Node* node);
236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void VisitPhi(Node* node);
237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void VisitProjection(Node* node);
238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void VisitConstant(Node* node);
239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void VisitCall(Node* call, BasicBlock* handler = nullptr);
240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void VisitTailCall(Node* call);
241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void VisitGoto(BasicBlock* target);
242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void VisitBranch(Node* input, BasicBlock* tbranch, BasicBlock* fbranch);
243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void VisitSwitch(Node* node, const SwitchInfo& sw);
244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void VisitDeoptimize(DeoptimizeKind kind, Node* value);
245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void VisitReturn(Node* ret);
246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void VisitThrow(Node* value);
247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void EmitPrepareArguments(ZoneVector<compiler::PushParameter>* arguments,
249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            const CallDescriptor* descriptor, Node* node);
250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // ===========================================================================
252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
253958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Schedule* schedule() const { return schedule_; }
254958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Linkage* linkage() const { return linkage_; }
255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  InstructionSequence* sequence() const { return sequence_; }
256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Zone* instruction_zone() const { return sequence()->zone(); }
257958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Zone* zone() const { return zone_; }
258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // ===========================================================================
260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
261958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Zone* const zone_;
262958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Linkage* const linkage_;
263958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  InstructionSequence* const sequence_;
264958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  SourcePositionTable* const source_positions_;
265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SourcePositionMode const source_position_mode_;
266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Features features_;
267958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Schedule* const schedule_;
268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BasicBlock* current_block_;
269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ZoneVector<Instruction*> instructions_;
270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BoolVector defined_;
271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BoolVector used_;
272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  IntVector virtual_registers_;
273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionScheduler* scheduler_;
274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace compiler
277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace internal
278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace v8
279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // V8_COMPILER_INSTRUCTION_SELECTOR_H_
281