LibJS: Add a basic pass manager and add some basic passes

This commit adds a bunch of passes, the most interesting of which is a
pass that merges blocks together, and a pass that places blocks that
flow into each other next to each other, and a very simply pass that
removes duplicate basic blocks.
Note that this does not remove the jump at the end of each block in that
pass to avoid scope creep in the passes.
This commit is contained in:
Ali Mohammad Pur 2021-06-13 20:40:20 +04:30 committed by Ali Mohammad Pur
commit 1414c7b049
Notes: sideshowbarker 2024-07-18 12:13:09 +09:00
17 changed files with 751 additions and 30 deletions

View file

@ -165,6 +165,14 @@ void Jump::execute_impl(Bytecode::Interpreter& interpreter) const
interpreter.jump(*m_true_target);
}
void Jump::replace_references_impl(BasicBlock const& from, BasicBlock const& to)
{
if (m_true_target.has_value() && &m_true_target->block() == &from)
m_true_target = Label { to };
if (m_false_target.has_value() && &m_false_target->block() == &from)
m_false_target = Label { to };
}
void JumpConditional::execute_impl(Bytecode::Interpreter& interpreter) const
{
VERIFY(m_true_target.has_value());
@ -261,6 +269,16 @@ void EnterUnwindContext::execute_impl(Bytecode::Interpreter& interpreter) const
interpreter.jump(m_entry_point);
}
void EnterUnwindContext::replace_references_impl(BasicBlock const& from, BasicBlock const& to)
{
if (&m_entry_point.block() == &from)
m_entry_point = Label { to };
if (m_handler_target.has_value() && &m_handler_target->block() == &from)
m_handler_target = Label { to };
if (m_finalizer_target.has_value() && &m_finalizer_target->block() == &from)
m_finalizer_target = Label { to };
}
void LeaveUnwindContext::execute_impl(Bytecode::Interpreter& interpreter) const
{
interpreter.leave_unwind_context();
@ -271,6 +289,12 @@ void ContinuePendingUnwind::execute_impl(Bytecode::Interpreter& interpreter) con
interpreter.continue_pending_unwind(m_resume_target);
}
void ContinuePendingUnwind::replace_references_impl(BasicBlock const& from, BasicBlock const& to)
{
if (&m_resume_target.block() == &from)
m_resume_target = Label { to };
}
void PushLexicalEnvironment::execute_impl(Bytecode::Interpreter& interpreter) const
{
HashMap<FlyString, Variable> resolved_variables;
@ -292,6 +316,12 @@ void Yield::execute_impl(Bytecode::Interpreter& interpreter) const
interpreter.do_return(object);
}
void Yield::replace_references_impl(BasicBlock const& from, BasicBlock const& to)
{
if (m_continuation_label.has_value() && &m_continuation_label->block() == &from)
m_continuation_label = Label { to };
}
void GetByValue::execute_impl(Bytecode::Interpreter& interpreter) const
{
if (auto* object = interpreter.reg(m_base).to_object(interpreter.global_object())) {