Home | History | Annotate | Download | only in compiler
      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:
     67     Features() : bits_(0) {}
     68     explicit Features(unsigned bits) : bits_(bits) {}
     69     explicit Features(CpuFeature f) : bits_(1u << f) {}
     70     Features(CpuFeature f1, CpuFeature f2) : bits_((1u << f1) | (1u << f2)) {}
     71 
     72     bool Contains(CpuFeature f) const { return (bits_ & (1u << f)); }
     73 
     74    private:
     75     unsigned bits_;
     76   };
     77 
     78   bool IsSupported(CpuFeature feature) const {
     79     return features_.Contains(feature);
     80   }
     81 
     82   // Returns the features supported on the target platform.
     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 
    190   Graph* graph() const { return sequence()->graph(); }
    191   Linkage* linkage() const { return sequence()->linkage(); }
    192   Schedule* schedule() const { return sequence()->schedule(); }
    193   InstructionSequence* sequence() const { return sequence_; }
    194   Zone* instruction_zone() const { return sequence()->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