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 FINAL { 24 public: 25 // Forward declarations. 26 class Features; 27 28 InstructionSelector(InstructionSequence* sequence, 29 SourcePositionTable* source_positions, 30 Features features = SupportedFeatures()); 31 32 // Visit code for the entire graph with the included schedule. 33 void SelectInstructions(); 34 35 // =========================================================================== 36 // ============= Architecture-independent code emission methods. ============= 37 // =========================================================================== 38 39 Instruction* Emit(InstructionCode opcode, InstructionOperand* output, 40 size_t temp_count = 0, InstructionOperand* *temps = NULL); 41 Instruction* Emit(InstructionCode opcode, InstructionOperand* output, 42 InstructionOperand* a, size_t temp_count = 0, 43 InstructionOperand* *temps = NULL); 44 Instruction* Emit(InstructionCode opcode, InstructionOperand* output, 45 InstructionOperand* a, InstructionOperand* b, 46 size_t temp_count = 0, InstructionOperand* *temps = NULL); 47 Instruction* Emit(InstructionCode opcode, InstructionOperand* output, 48 InstructionOperand* a, InstructionOperand* b, 49 InstructionOperand* c, size_t temp_count = 0, 50 InstructionOperand* *temps = NULL); 51 Instruction* Emit(InstructionCode opcode, InstructionOperand* output, 52 InstructionOperand* a, InstructionOperand* b, 53 InstructionOperand* c, InstructionOperand* d, 54 size_t temp_count = 0, InstructionOperand* *temps = NULL); 55 Instruction* Emit(InstructionCode opcode, size_t output_count, 56 InstructionOperand** outputs, size_t input_count, 57 InstructionOperand** inputs, size_t temp_count = 0, 58 InstructionOperand* *temps = NULL); 59 Instruction* Emit(Instruction* instr); 60 61 // =========================================================================== 62 // ============== Architecture-independent CPU feature methods. ============== 63 // =========================================================================== 64 65 class Features FINAL { 66 public: Features()67 Features() : bits_(0) {} Features(unsigned bits)68 explicit Features(unsigned bits) : bits_(bits) {} Features(CpuFeature f)69 explicit Features(CpuFeature f) : bits_(1u << f) {} Features(CpuFeature f1,CpuFeature f2)70 Features(CpuFeature f1, CpuFeature f2) : bits_((1u << f1) | (1u << f2)) {} 71 Contains(CpuFeature f)72 bool Contains(CpuFeature f) const { return (bits_ & (1u << f)); } 73 74 private: 75 unsigned bits_; 76 }; 77 IsSupported(CpuFeature feature)78 bool IsSupported(CpuFeature feature) const { 79 return features_.Contains(feature); 80 } 81 82 // Returns the features supported on the target platform. SupportedFeatures()83 static Features SupportedFeatures() { 84 return Features(CpuFeatures::SupportedFeatures()); 85 } 86 87 private: 88 friend class OperandGenerator; 89 90 // =========================================================================== 91 // ============ Architecture-independent graph covering methods. ============= 92 // =========================================================================== 93 94 // Checks if {block} will appear directly after {current_block_} when 95 // assembling code, in which case, a fall-through can be used. 96 bool IsNextInAssemblyOrder(const BasicBlock* block) const; 97 98 // Used in pattern matching during code generation. 99 // Check if {node} can be covered while generating code for the current 100 // instruction. A node can be covered if the {user} of the node has the only 101 // edge and the two are in the same basic block. 102 bool CanCover(Node* user, Node* node) const; 103 104 // Checks if {node} was already defined, and therefore code was already 105 // generated for it. 106 bool IsDefined(Node* node) const; 107 108 // Inform the instruction selection that {node} was just defined. 109 void MarkAsDefined(Node* node); 110 111 // Checks if {node} has any uses, and therefore code has to be generated for 112 // it. 113 bool IsUsed(Node* node) const; 114 115 // Inform the instruction selection that {node} has at least one use and we 116 // will need to generate code for it. 117 void MarkAsUsed(Node* node); 118 119 // Checks if {node} is marked as double. 120 bool IsDouble(const Node* node) const; 121 122 // Inform the register allocator of a double result. 123 void MarkAsDouble(Node* node); 124 125 // Checks if {node} is marked as reference. 126 bool IsReference(const Node* node) const; 127 128 // Inform the register allocator of a reference result. 129 void MarkAsReference(Node* node); 130 131 // Inform the register allocation of the representation of the value produced 132 // by {node}. 133 void MarkAsRepresentation(MachineType rep, Node* node); 134 135 // Initialize the call buffer with the InstructionOperands, nodes, etc, 136 // corresponding 137 // to the inputs and outputs of the call. 138 // {call_code_immediate} to generate immediate operands to calls of code. 139 // {call_address_immediate} to generate immediate operands to address calls. 140 void InitializeCallBuffer(Node* call, CallBuffer* buffer, 141 bool call_code_immediate, 142 bool call_address_immediate); 143 144 FrameStateDescriptor* GetFrameStateDescriptor(Node* node); 145 void AddFrameStateInputs(Node* state, InstructionOperandVector* inputs, 146 FrameStateDescriptor* descriptor); 147 148 // =========================================================================== 149 // ============= Architecture-specific graph covering methods. =============== 150 // =========================================================================== 151 152 // Visit nodes in the given block and generate code. 153 void VisitBlock(BasicBlock* block); 154 155 // Visit the node for the control flow at the end of the block, generating 156 // code if necessary. 157 void VisitControl(BasicBlock* block); 158 159 // Visit the node and generate code, if any. 160 void VisitNode(Node* node); 161 162 #define DECLARE_GENERATOR(x) void Visit##x(Node* node); 163 MACHINE_OP_LIST(DECLARE_GENERATOR) 164 #undef DECLARE_GENERATOR 165 166 void VisitInt32AddWithOverflow(Node* node, FlagsContinuation* cont); 167 void VisitInt32SubWithOverflow(Node* node, FlagsContinuation* cont); 168 169 void VisitWord32Test(Node* node, FlagsContinuation* cont); 170 void VisitWord64Test(Node* node, FlagsContinuation* cont); 171 void VisitWord32Compare(Node* node, FlagsContinuation* cont); 172 void VisitWord64Compare(Node* node, FlagsContinuation* cont); 173 void VisitFloat64Compare(Node* node, FlagsContinuation* cont); 174 175 void VisitFinish(Node* node); 176 void VisitParameter(Node* node); 177 void VisitPhi(Node* node); 178 void VisitProjection(Node* node); 179 void VisitConstant(Node* node); 180 void VisitCall(Node* call, BasicBlock* continuation, 181 BasicBlock* deoptimization); 182 void VisitGoto(BasicBlock* target); 183 void VisitBranch(Node* input, BasicBlock* tbranch, BasicBlock* fbranch); 184 void VisitReturn(Node* value); 185 void VisitThrow(Node* value); 186 void VisitDeoptimize(Node* deopt); 187 188 // =========================================================================== 189 graph()190 Graph* graph() const { return sequence()->graph(); } linkage()191 Linkage* linkage() const { return sequence()->linkage(); } schedule()192 Schedule* schedule() const { return sequence()->schedule(); } sequence()193 InstructionSequence* sequence() const { return sequence_; } instruction_zone()194 Zone* instruction_zone() const { return sequence()->zone(); } zone()195 Zone* zone() { return &zone_; } 196 197 // =========================================================================== 198 199 Zone zone_; 200 InstructionSequence* sequence_; 201 SourcePositionTable* source_positions_; 202 Features features_; 203 BasicBlock* current_block_; 204 ZoneDeque<Instruction*> instructions_; 205 BoolVector defined_; 206 BoolVector used_; 207 }; 208 209 } // namespace compiler 210 } // namespace internal 211 } // namespace v8 212 213 #endif // V8_COMPILER_INSTRUCTION_SELECTOR_H_ 214