1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 11:48:10 +00:00

LibJS/Bytecode: Bring back the bytecode optimization pipeline

...minus the EliminateLoads pass, since it was not compatible with the
new bytecode format.
This commit is contained in:
Andreas Kling 2024-02-25 17:59:20 +01:00
parent 836d93f7e3
commit 5b29974bfa
15 changed files with 962 additions and 65 deletions

View file

@ -0,0 +1,58 @@
/*
* Copyright (c) 2021, Ali Mohammad Pur <mpfard@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibJS/Bytecode/PassManager.h>
namespace JS::Bytecode::Passes {
void PlaceBlocks::perform(PassPipelineExecutable& executable)
{
started();
VERIFY(executable.cfg.has_value());
auto cfg = executable.cfg.release_value();
Vector<BasicBlock&> replaced_blocks;
HashTable<BasicBlock const*> reachable_blocks;
// Visit the blocks in CFG order
Function<void(BasicBlock const*)> visit = [&](auto* block) {
if (reachable_blocks.contains(block))
return;
reachable_blocks.set(block);
replaced_blocks.append(*const_cast<BasicBlock*>(block));
auto children = cfg.find(block);
if (children == cfg.end())
return;
for (auto& entry : children->value)
visit(entry);
};
// Make sure to visit the entry block first
visit(executable.executable.basic_blocks.first());
for (auto& entry : cfg)
visit(entry.key);
// Put the unreferenced blocks back in at the end
for (auto& entry : static_cast<Vector<NonnullOwnPtr<BasicBlock>>&>(executable.executable.basic_blocks)) {
if (reachable_blocks.contains(entry.ptr()))
(void)entry.leak_ptr();
else
replaced_blocks.append(*entry.leak_ptr()); // Don't try to do DCE here.
}
executable.executable.basic_blocks.clear();
for (auto& block : replaced_blocks)
executable.executable.basic_blocks.append(adopt_own(block));
finished();
}
}