| OLD | NEW |
| 1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef V8_INTERPRETER_BYTECODE_REGISTER_OPTIMIZER_H_ | 5 #ifndef V8_INTERPRETER_BYTECODE_REGISTER_OPTIMIZER_H_ |
| 6 #define V8_INTERPRETER_BYTECODE_REGISTER_OPTIMIZER_H_ | 6 #define V8_INTERPRETER_BYTECODE_REGISTER_OPTIMIZER_H_ |
| 7 | 7 |
| 8 #include "src/base/compiler-specific.h" | 8 #include "src/base/compiler-specific.h" |
| 9 #include "src/globals.h" | 9 #include "src/globals.h" |
| 10 #include "src/interpreter/bytecode-pipeline.h" | 10 #include "src/interpreter/bytecode-pipeline.h" |
| 11 | 11 |
| 12 namespace v8 { | 12 namespace v8 { |
| 13 namespace internal { | 13 namespace internal { |
| 14 namespace interpreter { | 14 namespace interpreter { |
| 15 | 15 |
| 16 // An optimization stage for eliminating unnecessary transfers between | 16 // An optimization stage for eliminating unnecessary transfers between |
| 17 // registers. The bytecode generator uses temporary registers | 17 // registers. The bytecode generator uses temporary registers |
| 18 // liberally for correctness and convenience and this stage removes | 18 // liberally for correctness and convenience and this stage removes |
| 19 // transfers that are not required and preserves correctness. | 19 // transfers that are not required and preserves correctness. |
| 20 class V8_EXPORT_PRIVATE BytecodeRegisterOptimizer final | 20 class V8_EXPORT_PRIVATE BytecodeRegisterOptimizer final |
| 21 : public NON_EXPORTED_BASE(BytecodePipelineStage), | 21 : public NON_EXPORTED_BASE(BytecodeRegisterAllocator::Observer), |
| 22 public NON_EXPORTED_BASE(BytecodeRegisterAllocator::Observer), | |
| 23 public NON_EXPORTED_BASE(ZoneObject) { | 22 public NON_EXPORTED_BASE(ZoneObject) { |
| 24 public: | 23 public: |
| 25 BytecodeRegisterOptimizer(Zone* zone, | 24 BytecodeRegisterOptimizer(Zone* zone, |
| 26 BytecodeRegisterAllocator* register_allocator, | 25 BytecodeRegisterAllocator* register_allocator, |
| 27 int fixed_registers_count, int parameter_count, | 26 int fixed_registers_count, int parameter_count, |
| 28 BytecodePipelineStage* next_stage); | 27 BytecodePipelineStage* next_stage); |
| 29 virtual ~BytecodeRegisterOptimizer() {} | 28 virtual ~BytecodeRegisterOptimizer() {} |
| 30 | 29 |
| 31 // BytecodePipelineStage interface. | 30 // Perform explicit register transfer operations. |
| 32 void Write(BytecodeNode* node) override; | 31 void DoLdar(Register input, BytecodeSourceInfo source_info) { |
| 33 void WriteJump(BytecodeNode* node, BytecodeLabel* label) override; | 32 RegisterInfo* input_info = GetRegisterInfo(input); |
| 34 void BindLabel(BytecodeLabel* label) override; | 33 RegisterTransfer(input_info, accumulator_info_, source_info); |
| 35 void BindLabel(const BytecodeLabel& target, BytecodeLabel* label) override; | 34 } |
| 36 Handle<BytecodeArray> ToBytecodeArray( | 35 void DoStar(Register output, BytecodeSourceInfo source_info) { |
| 37 Isolate* isolate, int register_count, int parameter_count, | 36 RegisterInfo* output_info = GetRegisterInfo(output); |
| 38 Handle<FixedArray> handler_table) override; | 37 RegisterTransfer(accumulator_info_, output_info, source_info); |
| 38 } |
| 39 void DoMov(Register input, Register output, BytecodeSourceInfo source_info) { |
| 40 RegisterInfo* input_info = GetRegisterInfo(input); |
| 41 RegisterInfo* output_info = GetRegisterInfo(output); |
| 42 RegisterTransfer(input_info, output_info, source_info); |
| 43 } |
| 44 |
| 45 // Materialize all live registers and flush equivalence sets. |
| 46 void Flush(); |
| 47 |
| 48 // Prepares for |bytecode|. |
| 49 void PrepareForBytecode(Bytecode bytecode); |
| 50 |
| 51 // Prepares |reg| for being used as an output operand. |
| 52 void PrepareOutputRegister(Register reg); |
| 53 |
| 54 // Prepares registers in |reg_list| for being used as an output operand. |
| 55 void PrepareOutputRegisterList(RegisterList reg_list); |
| 56 |
| 57 // Returns an equivalent register to |reg| to be used as an input operand. |
| 58 Register GetInputRegister(Register reg); |
| 59 |
| 60 // Returns an equivalent register list to |reg_list| to be used as an input |
| 61 // operand. |
| 62 RegisterList GetInputRegisterList(RegisterList reg_list); |
| 63 |
| 64 int maxiumum_register_index() const { return max_register_index_; } |
| 39 | 65 |
| 40 private: | 66 private: |
| 41 static const uint32_t kInvalidEquivalenceId; | 67 static const uint32_t kInvalidEquivalenceId; |
| 42 | 68 |
| 43 class RegisterInfo; | 69 class RegisterInfo; |
| 44 | 70 |
| 45 // BytecodeRegisterAllocator::Observer interface. | 71 // BytecodeRegisterAllocator::Observer interface. |
| 46 void RegisterAllocateEvent(Register reg) override; | 72 void RegisterAllocateEvent(Register reg) override; |
| 47 void RegisterListAllocateEvent(RegisterList reg_list) override; | 73 void RegisterListAllocateEvent(RegisterList reg_list) override; |
| 48 void RegisterListFreeEvent(RegisterList reg) override; | 74 void RegisterListFreeEvent(RegisterList reg) override; |
| 49 | 75 |
| 50 // Helpers for BytecodePipelineStage interface. | |
| 51 void FlushState(); | |
| 52 | |
| 53 // Update internal state for register transfer from |input| to | 76 // Update internal state for register transfer from |input| to |
| 54 // |output| using |source_info| as source position information if | 77 // |output| using |source_info| as source position information if |
| 55 // any bytecodes are emitted due to transfer. | 78 // any bytecodes are emitted due to transfer. |
| 56 void RegisterTransfer(RegisterInfo* input, RegisterInfo* output, | 79 void RegisterTransfer(RegisterInfo* input, RegisterInfo* output, |
| 57 BytecodeSourceInfo* source_info); | 80 BytecodeSourceInfo source_info); |
| 58 | 81 |
| 59 // Emit a register transfer bytecode from |input| to |output|. | 82 // Emit a register transfer bytecode from |input| to |output|. |
| 60 void OutputRegisterTransfer(RegisterInfo* input, RegisterInfo* output, | 83 void OutputRegisterTransfer( |
| 61 BytecodeSourceInfo* source_info = nullptr); | 84 RegisterInfo* input, RegisterInfo* output, |
| 85 BytecodeSourceInfo source_info = BytecodeSourceInfo()); |
| 62 | 86 |
| 63 // Emits a Nop to preserve source position information in the | 87 // Emits a Nop to preserve source position information in the |
| 64 // bytecode pipeline. | 88 // bytecode pipeline. |
| 65 void EmitNopForSourceInfo(BytecodeSourceInfo* source_info) const; | 89 void EmitNopForSourceInfo(BytecodeSourceInfo source_info) const; |
| 66 | |
| 67 // Handlers for bytecode nodes for register to register transfers. | |
| 68 void DoLdar(BytecodeNode* node); | |
| 69 void DoMov(BytecodeNode* node); | |
| 70 void DoStar(BytecodeNode* node); | |
| 71 | |
| 72 // Operand processing methods for bytecodes other than those | |
| 73 // performing register to register transfers. | |
| 74 void PrepareOperands(BytecodeNode* const node); | |
| 75 void PrepareAccumulator(BytecodeNode* const node); | |
| 76 void PrepareRegisterOperands(BytecodeNode* const node); | |
| 77 | |
| 78 void PrepareRegisterOutputOperand(RegisterInfo* reg_info); | |
| 79 void PrepareRegisterRangeOutputOperand(Register start, int count); | |
| 80 void PrepareRegisterInputOperand(BytecodeNode* const node, Register reg, | |
| 81 int operand_index); | |
| 82 void PrepareRegisterRangeInputOperand(Register start, int count); | |
| 83 | |
| 84 Register GetEquivalentRegisterForInputOperand(Register reg); | |
| 85 | |
| 86 static Register GetRegisterInputOperand(int index, Bytecode bytecode, | |
| 87 const uint32_t* operands, | |
| 88 int operand_count); | |
| 89 static Register GetRegisterOutputOperand(int index, Bytecode bytecode, | |
| 90 const uint32_t* operands, | |
| 91 int operand_count); | |
| 92 | 90 |
| 93 void CreateMaterializedEquivalent(RegisterInfo* info); | 91 void CreateMaterializedEquivalent(RegisterInfo* info); |
| 94 RegisterInfo* GetMaterializedEquivalent(RegisterInfo* info); | 92 RegisterInfo* GetMaterializedEquivalent(RegisterInfo* info); |
| 95 RegisterInfo* GetMaterializedEquivalentNotAccumulator(RegisterInfo* info); | 93 RegisterInfo* GetMaterializedEquivalentNotAccumulator(RegisterInfo* info); |
| 96 void Materialize(RegisterInfo* info); | 94 void Materialize(RegisterInfo* info); |
| 97 void AddToEquivalenceSet(RegisterInfo* set_member, | 95 void AddToEquivalenceSet(RegisterInfo* set_member, |
| 98 RegisterInfo* non_set_member); | 96 RegisterInfo* non_set_member); |
| 99 | 97 |
| 100 // Methods for finding and creating metadata for each register. | 98 // Methods for finding and creating metadata for each register. |
| 101 RegisterInfo* GetOrCreateRegisterInfo(Register reg); | 99 RegisterInfo* GetRegisterInfo(Register reg) { |
| 102 RegisterInfo* GetRegisterInfo(Register reg); | 100 size_t index = GetRegisterInfoTableIndex(reg); |
| 103 RegisterInfo* NewRegisterInfo(Register reg); | 101 DCHECK_LT(index, register_info_table_.size()); |
| 102 return register_info_table_[index]; |
| 103 } |
| 104 RegisterInfo* GetOrCreateRegisterInfo(Register reg) { |
| 105 size_t index = GetRegisterInfoTableIndex(reg); |
| 106 return index < register_info_table_.size() ? register_info_table_[index] |
| 107 : NewRegisterInfo(reg); |
| 108 } |
| 109 RegisterInfo* NewRegisterInfo(Register reg) { |
| 110 size_t index = GetRegisterInfoTableIndex(reg); |
| 111 DCHECK_GE(index, register_info_table_.size()); |
| 112 GrowRegisterMap(reg); |
| 113 return register_info_table_[index]; |
| 114 } |
| 115 |
| 104 void GrowRegisterMap(Register reg); | 116 void GrowRegisterMap(Register reg); |
| 105 | 117 |
| 106 bool RegisterIsTemporary(Register reg) const { | 118 bool RegisterIsTemporary(Register reg) const { |
| 107 return reg >= temporary_base_; | 119 return reg >= temporary_base_; |
| 108 } | 120 } |
| 109 | 121 |
| 110 bool RegisterIsObservable(Register reg) const { | 122 bool RegisterIsObservable(Register reg) const { |
| 111 return reg != accumulator_ && !RegisterIsTemporary(reg); | 123 return reg != accumulator_ && !RegisterIsTemporary(reg); |
| 112 } | 124 } |
| 113 | 125 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 148 Zone* zone_; | 160 Zone* zone_; |
| 149 | 161 |
| 150 DISALLOW_COPY_AND_ASSIGN(BytecodeRegisterOptimizer); | 162 DISALLOW_COPY_AND_ASSIGN(BytecodeRegisterOptimizer); |
| 151 }; | 163 }; |
| 152 | 164 |
| 153 } // namespace interpreter | 165 } // namespace interpreter |
| 154 } // namespace internal | 166 } // namespace internal |
| 155 } // namespace v8 | 167 } // namespace v8 |
| 156 | 168 |
| 157 #endif // V8_INTERPRETER_BYTECODE_REGISTER_OPTIMIZER_H_ | 169 #endif // V8_INTERPRETER_BYTECODE_REGISTER_OPTIMIZER_H_ |
| OLD | NEW |