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 |