PlaceBlocks.cpp 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. /*
  2. * Copyright (c) 2021, Ali Mohammad Pur <mpfard@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <LibJS/Bytecode/PassManager.h>
  7. namespace JS::Bytecode::Passes {
  8. void PlaceBlocks::perform(PassPipelineExecutable& executable)
  9. {
  10. started();
  11. VERIFY(executable.cfg.has_value());
  12. auto cfg = executable.cfg.release_value();
  13. Vector<BasicBlock&> replaced_blocks;
  14. HashTable<BasicBlock const*> reachable_blocks;
  15. // Visit the blocks in CFG order
  16. Function<void(BasicBlock const*)> visit = [&](auto* block) {
  17. if (reachable_blocks.contains(block))
  18. return;
  19. reachable_blocks.set(block);
  20. replaced_blocks.append(*const_cast<BasicBlock*>(block));
  21. for (auto& entry : cfg.get(block).value_or({}))
  22. visit(entry);
  23. };
  24. // Make sure to visit the entry block first
  25. visit(&executable.executable.basic_blocks.first());
  26. for (auto& entry : cfg)
  27. visit(entry.key);
  28. // Put the unreferenced blocks back in at the end
  29. for (auto& entry : static_cast<Vector<NonnullOwnPtr<BasicBlock>>&>(executable.executable.basic_blocks)) {
  30. if (reachable_blocks.contains(entry.ptr()))
  31. (void)entry.leak_ptr();
  32. else
  33. replaced_blocks.append(*entry.leak_ptr()); // Don't try to do DCE here.
  34. }
  35. executable.executable.basic_blocks.clear();
  36. for (auto& block : replaced_blocks)
  37. executable.executable.basic_blocks.append(adopt_own(block));
  38. finished();
  39. }
  40. }