5#ifndef V8_INTERPRETER_BYTECODE_REGISTER_OPTIMIZER_H_
6#define V8_INTERPRETER_BYTECODE_REGISTER_OPTIMIZER_H_
18namespace interpreter {
57 RegisterTransfer(input_info, accumulator_info_);
61 RegisterTransfer(accumulator_info_, output_info);
66 RegisterTransfer(input_info, output_info);
71 bool EnsureAllRegistersAreFlushed()
const;
74 template <Bytecode
bytecode, ImplicitRegisterUse implicit_register_use>
76 if (Bytecodes::IsJump(bytecode) || Bytecodes::IsSwitch(bytecode) ||
77 bytecode == Bytecode::kDebugger ||
78 bytecode == Bytecode::kSuspendGenerator ||
79 bytecode == Bytecode::kResumeGenerator) {
94 if (BytecodeOperands::ReadsAccumulator(implicit_register_use)) {
95 Materialize(accumulator_info_);
100 if (BytecodeOperands::WritesOrClobbersAccumulator(implicit_register_use)) {
101 PrepareOutputRegister(accumulator_);
102 DCHECK_EQ(GetTypeHint(accumulator_), TypeHint::kAny);
129 return GetPotentialVariableInRegister(accumulator_);
136 void SetTypeHintForAccumulator(
TypeHint hint);
137 void ResetTypeHintForAccumulator();
138 bool IsAccumulatorReset();
149 void RegisterListAllocateEvent(
RegisterList reg_list)
override;
168 size_t index = GetRegisterInfoTableIndex(
reg);
169 DCHECK_LT(index, register_info_table_.size());
170 return register_info_table_[
index];
173 size_t index = GetRegisterInfoTableIndex(
reg);
174 return index < register_info_table_.size() ? register_info_table_[
index]
175 : NewRegisterInfo(
reg);
178 size_t index = GetRegisterInfoTableIndex(
reg);
179 DCHECK_GE(index, register_info_table_.size());
180 GrowRegisterMap(
reg);
181 return register_info_table_[
index];
187 return reg >= temporary_base_;
191 return reg != accumulator_ && !RegisterIsTemporary(
reg);
195 return Register::FromOperand(
static_cast<int32_t
>(operand));
199 return static_cast<size_t>(
reg.index() + register_info_table_offset_);
203 return Register(
static_cast<int>(index) - register_info_table_offset_);
208 CHECK_NE(equivalence_id_, kInvalidEquivalenceId);
209 return equivalence_id_;
212 void AllocateRegister(RegisterInfo* info);
BytecodeWriter(const BytecodeWriter &)=delete
virtual void EmitStar(Register output)=0
virtual void EmitMov(Register input, Register output)=0
virtual ~BytecodeWriter()=default
BytecodeWriter & operator=(const BytecodeWriter &)=delete
virtual void EmitLdar(Register input)=0
BytecodeRegisterOptimizer(const BytecodeRegisterOptimizer &)=delete
ZoneDeque< RegisterInfo * > registers_needing_flushed_
RegisterInfo * accumulator_info_
RegisterInfo * GetOrCreateRegisterInfo(Register reg)
size_t GetRegisterInfoTableIndex(Register reg) const
const Register temporary_base_
bool RegisterIsObservable(Register reg) const
static const uint32_t kInvalidEquivalenceId
V8_INLINE void PrepareForBytecode()
Register RegisterFromRegisterInfoTableIndex(size_t index) const
BytecodeGenerator::TypeHint TypeHint
int maxiumum_register_index() const
~BytecodeRegisterOptimizer() override=default
RegisterInfo * NewRegisterInfo(Register reg)
void DoLdar(Register input)
ZoneVector< RegisterInfo * > register_info_table_
void DoStar(Register output)
void DoMov(Register input, Register output)
static Register OperandToRegister(uint32_t operand)
int register_info_table_offset_
RegisterInfo * GetRegisterInfo(Register reg)
BytecodeRegisterOptimizer & operator=(const BytecodeRegisterOptimizer &)=delete
uint32_t NextEquivalenceId()
BytecodeWriter * bytecode_writer_
bool RegisterIsTemporary(Register reg) const
const Register accumulator_
Variable * GetPotentialVariableInAccumulator()
#define NON_EXPORTED_BASE(code)
#define CHECK_NE(lhs, rhs)
#define DCHECK_GE(v1, v2)
#define DCHECK_LT(v1, v2)
#define DCHECK_EQ(v1, v2)
#define V8_EXPORT_PRIVATE