OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2015 the V8 project authors. All rights reserved. | |
rmcilroy
2016/05/26 10:24:53
2016
oth
2016/05/26 21:26:51
Done.
| |
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_INTERPRETER_BYTECODE_REGISTER_OPTIMIZER_H_ | |
6 #define V8_INTERPRETER_BYTECODE_REGISTER_OPTIMIZER_H_ | |
7 | |
8 #include "src/interpreter/bytecode-pipeline.h" | |
9 | |
10 namespace v8 { | |
11 namespace internal { | |
12 namespace interpreter { | |
13 | |
14 // An optimization stage for eliminating unnecessary transfers between | |
15 // registers. The bytecode generator uses temporary registers | |
16 // liberally for correctness and convenience and this stage removes | |
17 // transfers that are not required and preserves correctness. | |
18 class BytecodeRegisterOptimizer final : public BytecodePipelineStage, | |
19 public TemporaryRegisterObserver, | |
20 public ZoneObject { | |
21 public: | |
22 BytecodeRegisterOptimizer(Zone* zone, | |
23 TemporaryRegisterAllocator* register_allocator, | |
24 int parameter_count, int fixed_register_count, | |
25 BytecodePipelineStage* next_stage); | |
26 virtual ~BytecodeRegisterOptimizer() {} | |
27 | |
28 // BytecodePipelineStage interface. | |
29 size_t FlushForOffset() override; | |
30 void FlushBasicBlock() override; | |
31 void Write(BytecodeNode* node) override; | |
32 | |
33 private: | |
34 class RegisterInfo; | |
35 | |
36 // TemporaryRegisterObserver interface. | |
37 void TemporaryRegisterFreeEvent(Register reg) override; | |
38 | |
39 // Helpers for BytecodePipelineStage interface. | |
40 void FlushState(); | |
41 void WriteToNextStage(BytecodeNode* node); | |
42 void WriteToNextStage(BytecodeNode* node, RegisterInfo* output_info); | |
43 | |
44 // Update internal state for register transfer from |input| to |output|. | |
45 void RegisterTransfer(RegisterInfo* input, RegisterInfo* output); | |
46 | |
47 // Emit a register transfer bytecode from |input| to |output|. | |
48 void OutputRegisterTransfer(RegisterInfo* input, RegisterInfo* output); | |
49 | |
50 // Emits a Nop in place of |node| taking the source position | |
51 // associated with |Nop|. | |
rmcilroy
2016/05/26 10:24:54
/s/|Nop|/|node| ?
oth
2016/05/26 21:26:51
Done.
| |
52 void EmitNopTakingSourcePosition(BytecodeNode* node); | |
53 | |
54 // Handlers for bytecode nodes for register to register transfers. | |
55 void DoLdar(const BytecodeNode* const node); | |
56 void DoMov(const BytecodeNode* const node); | |
57 void DoStar(const BytecodeNode* const node); | |
58 | |
59 // Operand processing methods for bytecodes other than those | |
60 // performing register to register transfers. | |
61 void PrepareOperands(BytecodeNode* const node); | |
62 void PrepareAccumulator(BytecodeNode* const node); | |
63 void PrepareRegisterOperands(BytecodeNode* const node); | |
64 | |
65 void PrepareRegisterOutputOperand(RegisterInfo* reg_info); | |
66 void PrepareRegisterRangeOutputOperand(Register start, int count); | |
67 Register PrepareRegisterInputOperand(Register reg); | |
68 void PrepareRegisterRangeInputOperand(Register start, int count); | |
69 | |
70 static Register GetRegisterInputOperand(int index, Bytecode bytecode, | |
71 const uint32_t* operands, | |
72 int operand_count); | |
73 static Register GetRegisterOutputOperand(int index, Bytecode bytecode, | |
74 const uint32_t* operands, | |
75 int operand_count); | |
76 | |
77 void CreateMaterializedEquivalentIfRequired(RegisterInfo* info); | |
78 RegisterInfo* GetMaterializedEquivalent(RegisterInfo* info); | |
79 RegisterInfo* GetMaterializedEquivalentNotAccumulator(RegisterInfo* info); | |
80 void Materialize(RegisterInfo* info); | |
81 | |
82 // Methods for finding and creating metadata for each register. | |
83 RegisterInfo* GetOrCreateRegisterInfo(Register reg); | |
84 RegisterInfo* GetRegisterInfo(Register reg); | |
85 RegisterInfo* NewRegisterInfo(Register reg); | |
86 void GrowRegisterMap(Register reg); | |
87 | |
88 bool RegisterIsTemporary(Register reg) const { | |
89 return reg >= temporary_base_; | |
90 } | |
91 | |
92 bool RegisterIsObservable(Register reg) const { | |
93 return reg != accumulator_ && !RegisterIsTemporary(reg); | |
94 } | |
95 | |
96 static Register OperandToRegister(uint32_t operand) { | |
97 return Register::FromOperand(static_cast<int32_t>(operand)); | |
98 } | |
99 | |
100 size_t GetMapIndex(Register reg) const { | |
101 return static_cast<size_t>(reg.index() + map_index_offset_); | |
102 } | |
103 | |
104 Register RegisterFromMapIndex(size_t index) const { | |
105 return Register(static_cast<int>(index) - map_index_offset_); | |
106 } | |
107 | |
108 Zone* zone() { return zone_; } | |
109 | |
110 const Register accumulator_; | |
111 RegisterInfo* accumulator_info_; | |
112 const Register temporary_base_; | |
113 | |
114 // Direct mapping to register info. | |
115 ZoneVector<RegisterInfo*> register_map_; | |
rmcilroy
2016/05/26 10:24:53
This is not a map, how about register_infos_ (if s
oth
2016/05/26 21:26:51
Done.
| |
116 int map_index_offset_; | |
117 | |
118 // Counter for equivalence sets identifiers. | |
119 int equivalence_id_; | |
120 | |
121 BytecodePipelineStage* next_stage_; | |
122 bool flushed_; | |
123 Zone* zone_; | |
124 | |
125 DISALLOW_COPY_AND_ASSIGN(BytecodeRegisterOptimizer); | |
126 }; | |
127 | |
128 } // namespace interpreter | |
129 } // namespace internal | |
130 } // namespace v8 | |
131 | |
132 #endif // V8_INTERPRETER_BYTECODE_REGISTER_OPTIMIZER_H_ | |
OLD | NEW |