LibJS: Remove redundant Store op

If the property for GetByValue in Generator::load_from_reference
is a calculated value this would be stored in an allocated
register and returned from the function. Not all callers want
this information however, so now only give it out when asked for.

Reduced the instruction count for Kraken/ai-astar.js function
"neighbours" from 214 to 192.
This commit is contained in:
Todderod 2023-11-08 20:21:48 +01:00 committed by Andreas Kling
parent 13726fd3b7
commit bb9230bbcd
Notes: sideshowbarker 2024-07-17 03:19:14 +09:00
3 changed files with 21 additions and 12 deletions

View file

@ -525,7 +525,7 @@ Bytecode::CodeGenerationErrorOr<void> AssignmentExpression::generate_bytecode(By
VERIFY(m_lhs.has<NonnullRefPtr<Expression const>>());
auto& lhs = m_lhs.get<NonnullRefPtr<Expression const>>();
auto reference_registers = TRY(generator.emit_load_from_reference(lhs));
auto reference_registers = TRY(generator.emit_load_from_reference(lhs, Bytecode::Generator::CollectRegisters::Yes));
Bytecode::BasicBlock* rhs_block_ptr { nullptr };
Bytecode::BasicBlock* end_block_ptr { nullptr };
@ -1057,7 +1057,7 @@ Bytecode::CodeGenerationErrorOr<void> ArrayExpression::generate_bytecode(Bytecod
Bytecode::CodeGenerationErrorOr<void> MemberExpression::generate_bytecode(Bytecode::Generator& generator) const
{
Bytecode::Generator::SourceLocationScope scope(generator, *this);
(void)TRY(generator.emit_load_from_reference(*this));
(void)TRY(generator.emit_load_from_reference(*this, Bytecode::Generator::CollectRegisters::No));
return {};
}
@ -2258,7 +2258,7 @@ Bytecode::CodeGenerationErrorOr<void> TaggedTemplateLiteral::generate_bytecode(B
Bytecode::CodeGenerationErrorOr<void> UpdateExpression::generate_bytecode(Bytecode::Generator& generator) const
{
Bytecode::Generator::SourceLocationScope scope(generator, *this);
auto reference_registers = TRY(generator.emit_load_from_reference(*m_argument));
auto reference_registers = TRY(generator.emit_load_from_reference(*m_argument, Bytecode::Generator::CollectRegisters::Yes));
Optional<Bytecode::Register> previous_value_for_postfix_reg;
if (!m_prefixed) {

View file

@ -205,7 +205,7 @@ CodeGenerationErrorOr<Generator::ReferenceRegisters> Generator::emit_super_refer
};
}
CodeGenerationErrorOr<Optional<Generator::ReferenceRegisters>> Generator::emit_load_from_reference(JS::ASTNode const& node)
CodeGenerationErrorOr<Optional<Generator::ReferenceRegisters>> Generator::emit_load_from_reference(JS::ASTNode const& node, CollectRegisters collect_registers)
{
if (is<Identifier>(node)) {
auto& identifier = static_cast<Identifier const&>(node);
@ -238,15 +238,20 @@ CodeGenerationErrorOr<Optional<Generator::ReferenceRegisters>> Generator::emit_l
emit<Bytecode::Op::Store>(object_reg);
TRY(expression.property().generate_bytecode(*this));
auto property_reg = allocate_register();
emit<Bytecode::Op::Store>(property_reg);
Optional<Register> property_reg {};
if (collect_registers == CollectRegisters::Yes) {
property_reg = allocate_register();
emit<Bytecode::Op::Store>(property_reg.value());
}
emit<Bytecode::Op::GetByValue>(object_reg);
return ReferenceRegisters {
.base = object_reg,
.referenced_name = property_reg,
.this_value = object_reg,
};
if (collect_registers == CollectRegisters::Yes)
return ReferenceRegisters {
.base = object_reg,
.referenced_name = property_reg.value(),
.this_value = object_reg,
};
return Optional<ReferenceRegisters> {};
} else if (expression.property().is_identifier()) {
auto identifier_table_ref = intern_identifier(verify_cast<Identifier>(expression.property()).string());
emit_get_by_id(identifier_table_ref);

View file

@ -98,7 +98,11 @@ public:
Register this_value; // [[ThisValue]]
};
CodeGenerationErrorOr<Optional<ReferenceRegisters>> emit_load_from_reference(JS::ASTNode const&);
enum class CollectRegisters {
Yes,
No
};
CodeGenerationErrorOr<Optional<ReferenceRegisters>> emit_load_from_reference(JS::ASTNode const&, CollectRegisters);
CodeGenerationErrorOr<void> emit_store_to_reference(JS::ASTNode const&);
CodeGenerationErrorOr<void> emit_store_to_reference(ReferenceRegisters const&);
CodeGenerationErrorOr<void> emit_delete_reference(JS::ASTNode const&);