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