OLD | NEW |
(Empty) | |
| 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 |
| 23 class InstructionSelector V8_FINAL { |
| 24 public: |
| 25 explicit InstructionSelector(InstructionSequence* sequence, |
| 26 SourcePositionTable* source_positions); |
| 27 |
| 28 // Visit code for the entire graph with the included schedule. |
| 29 void SelectInstructions(); |
| 30 |
| 31 // =========================================================================== |
| 32 // ============= Architecture-independent code emission methods. ============= |
| 33 // =========================================================================== |
| 34 |
| 35 Instruction* Emit(InstructionCode opcode, InstructionOperand* output, |
| 36 size_t temp_count = 0, InstructionOperand* *temps = NULL); |
| 37 Instruction* Emit(InstructionCode opcode, InstructionOperand* output, |
| 38 InstructionOperand* a, size_t temp_count = 0, |
| 39 InstructionOperand* *temps = NULL); |
| 40 Instruction* Emit(InstructionCode opcode, InstructionOperand* output, |
| 41 InstructionOperand* a, InstructionOperand* b, |
| 42 size_t temp_count = 0, InstructionOperand* *temps = NULL); |
| 43 Instruction* Emit(InstructionCode opcode, InstructionOperand* output, |
| 44 InstructionOperand* a, InstructionOperand* b, |
| 45 InstructionOperand* c, size_t temp_count = 0, |
| 46 InstructionOperand* *temps = NULL); |
| 47 Instruction* Emit(InstructionCode opcode, InstructionOperand* output, |
| 48 InstructionOperand* a, InstructionOperand* b, |
| 49 InstructionOperand* c, InstructionOperand* d, |
| 50 size_t temp_count = 0, InstructionOperand* *temps = NULL); |
| 51 Instruction* Emit(InstructionCode opcode, size_t output_count, |
| 52 InstructionOperand** outputs, size_t input_count, |
| 53 InstructionOperand** inputs, size_t temp_count = 0, |
| 54 InstructionOperand* *temps = NULL); |
| 55 Instruction* Emit(Instruction* instr); |
| 56 |
| 57 private: |
| 58 friend class OperandGenerator; |
| 59 |
| 60 // =========================================================================== |
| 61 // ============ Architecture-independent graph covering methods. ============= |
| 62 // =========================================================================== |
| 63 |
| 64 // Checks if {block} will appear directly after {current_block_} when |
| 65 // assembling code, in which case, a fall-through can be used. |
| 66 bool IsNextInAssemblyOrder(const BasicBlock* block) const; |
| 67 |
| 68 // Used in pattern matching during code generation. |
| 69 // Check if {node} can be covered while generating code for the current |
| 70 // instruction. A node can be covered if the {user} of the node has the only |
| 71 // edge and the two are in the same basic block. |
| 72 bool CanCover(Node* user, Node* node) const; |
| 73 |
| 74 // Checks if {node} has any uses, and therefore code has to be generated for |
| 75 // it. |
| 76 bool IsUsed(Node* node) const; |
| 77 |
| 78 // Inform the instruction selection that {node} has at least one use and we |
| 79 // will need to generate code for it. |
| 80 void MarkAsUsed(Node* node); |
| 81 |
| 82 // Checks if {node} is marked as double. |
| 83 bool IsDouble(const Node* node) const; |
| 84 |
| 85 // Inform the register allocator of a double result. |
| 86 void MarkAsDouble(Node* node); |
| 87 |
| 88 // Checks if {node} is marked as reference. |
| 89 bool IsReference(const Node* node) const; |
| 90 |
| 91 // Inform the register allocator of a reference result. |
| 92 void MarkAsReference(Node* node); |
| 93 |
| 94 // Inform the register allocation of the representation of the value produced |
| 95 // by {node}. |
| 96 void MarkAsRepresentation(MachineRepresentation rep, Node* node); |
| 97 |
| 98 // Initialize the call buffer with the InstructionOperands, nodes, etc, |
| 99 // corresponding |
| 100 // to the inputs and outputs of the call. |
| 101 // {call_code_immediate} to generate immediate operands to calls of code. |
| 102 // {call_address_immediate} to generate immediate operands to address calls. |
| 103 void InitializeCallBuffer(Node* call, CallBuffer* buffer, |
| 104 bool call_code_immediate, |
| 105 bool call_address_immediate, BasicBlock* cont_node, |
| 106 BasicBlock* deopt_node); |
| 107 |
| 108 // =========================================================================== |
| 109 // ============= Architecture-specific graph covering methods. =============== |
| 110 // =========================================================================== |
| 111 |
| 112 // Visit nodes in the given block and generate code. |
| 113 void VisitBlock(BasicBlock* block); |
| 114 |
| 115 // Visit the node for the control flow at the end of the block, generating |
| 116 // code if necessary. |
| 117 void VisitControl(BasicBlock* block); |
| 118 |
| 119 // Visit the node and generate code, if any. |
| 120 void VisitNode(Node* node); |
| 121 |
| 122 #define DECLARE_GENERATOR(x) void Visit##x(Node* node); |
| 123 MACHINE_OP_LIST(DECLARE_GENERATOR) |
| 124 #undef DECLARE_GENERATOR |
| 125 |
| 126 void VisitWord32Test(Node* node, FlagsContinuation* cont); |
| 127 void VisitWord64Test(Node* node, FlagsContinuation* cont); |
| 128 void VisitWord32Compare(Node* node, FlagsContinuation* cont); |
| 129 void VisitWord64Compare(Node* node, FlagsContinuation* cont); |
| 130 void VisitFloat64Compare(Node* node, FlagsContinuation* cont); |
| 131 |
| 132 void VisitPhi(Node* node); |
| 133 void VisitParameter(Node* node); |
| 134 void VisitConstant(Node* node); |
| 135 void VisitCall(Node* call, BasicBlock* continuation, |
| 136 BasicBlock* deoptimization); |
| 137 void VisitGoto(BasicBlock* target); |
| 138 void VisitBranch(Node* input, BasicBlock* tbranch, BasicBlock* fbranch); |
| 139 void VisitReturn(Node* value); |
| 140 void VisitThrow(Node* value); |
| 141 void VisitDeoptimization(Node* deopt); |
| 142 |
| 143 // =========================================================================== |
| 144 |
| 145 Graph* graph() const { return sequence()->graph(); } |
| 146 Linkage* linkage() const { return sequence()->linkage(); } |
| 147 Schedule* schedule() const { return sequence()->schedule(); } |
| 148 InstructionSequence* sequence() const { return sequence_; } |
| 149 Zone* instruction_zone() const { return sequence()->zone(); } |
| 150 Zone* zone() { return &zone_; } |
| 151 |
| 152 // =========================================================================== |
| 153 |
| 154 typedef zone_allocator<Instruction*> InstructionPtrZoneAllocator; |
| 155 typedef std::deque<Instruction*, InstructionPtrZoneAllocator> Instructions; |
| 156 |
| 157 Zone zone_; |
| 158 InstructionSequence* sequence_; |
| 159 SourcePositionTable* source_positions_; |
| 160 BasicBlock* current_block_; |
| 161 Instructions instructions_; |
| 162 BoolVector used_; |
| 163 }; |
| 164 |
| 165 } // namespace compiler |
| 166 } // namespace internal |
| 167 } // namespace v8 |
| 168 |
| 169 #endif // V8_COMPILER_INSTRUCTION_SELECTOR_H_ |
OLD | NEW |