58 lines
1.6 KiB
C++
58 lines
1.6 KiB
C++
/*
|
|
* 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();
|
|
}
|
|
|
|
}
|