PassManager.h 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. /*
  2. * Copyright (c) 2021, Ali Mohammad Pur <mpfard@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <LibCore/ElapsedTimer.h>
  8. #include <LibJS/Bytecode/BasicBlock.h>
  9. #include <LibJS/Bytecode/Generator.h>
  10. namespace JS::Bytecode {
  11. struct PassPipelineExecutable {
  12. Executable& executable;
  13. Optional<HashMap<BasicBlock const*, HashTable<BasicBlock const*>>> cfg {};
  14. Optional<HashMap<BasicBlock const*, HashTable<BasicBlock const*>>> inverted_cfg {};
  15. Optional<HashTable<BasicBlock const*>> exported_blocks {};
  16. };
  17. class Pass {
  18. public:
  19. Pass() = default;
  20. virtual ~Pass() = default;
  21. virtual void perform(PassPipelineExecutable&) = 0;
  22. void started()
  23. {
  24. m_timer.start();
  25. }
  26. void finished()
  27. {
  28. m_time_difference = m_timer.elapsed_time();
  29. }
  30. u64 elapsed() const { return m_time_difference.to_microseconds(); }
  31. protected:
  32. Core::ElapsedTimer m_timer;
  33. Duration m_time_difference {};
  34. };
  35. class PassManager : public Pass {
  36. public:
  37. PassManager() = default;
  38. ~PassManager() override = default;
  39. void add(NonnullOwnPtr<Pass> pass) { m_passes.append(move(pass)); }
  40. template<typename PassT, typename... Args>
  41. void add(Args&&... args) { m_passes.append(make<PassT>(forward<Args>(args)...)); }
  42. void perform(Executable& executable)
  43. {
  44. PassPipelineExecutable pipeline_executable { executable };
  45. perform(pipeline_executable);
  46. }
  47. virtual void perform(PassPipelineExecutable& executable) override
  48. {
  49. started();
  50. for (auto& pass : m_passes)
  51. pass->perform(executable);
  52. finished();
  53. }
  54. private:
  55. Vector<NonnullOwnPtr<Pass>> m_passes;
  56. };
  57. namespace Passes {
  58. class GenerateCFG : public Pass {
  59. public:
  60. GenerateCFG() = default;
  61. ~GenerateCFG() override = default;
  62. private:
  63. virtual void perform(PassPipelineExecutable&) override;
  64. };
  65. class MergeBlocks : public Pass {
  66. public:
  67. MergeBlocks() = default;
  68. ~MergeBlocks() override = default;
  69. private:
  70. virtual void perform(PassPipelineExecutable&) override;
  71. };
  72. class PlaceBlocks : public Pass {
  73. public:
  74. PlaceBlocks() = default;
  75. ~PlaceBlocks() override = default;
  76. private:
  77. virtual void perform(PassPipelineExecutable&) override;
  78. };
  79. class UnifySameBlocks : public Pass {
  80. public:
  81. UnifySameBlocks() = default;
  82. ~UnifySameBlocks() override = default;
  83. private:
  84. virtual void perform(PassPipelineExecutable&) override;
  85. };
  86. class DumpCFG : public Pass {
  87. public:
  88. DumpCFG(FILE* file)
  89. : m_file(file)
  90. {
  91. }
  92. ~DumpCFG() override = default;
  93. private:
  94. virtual void perform(PassPipelineExecutable&) override;
  95. FILE* m_file { nullptr };
  96. };
  97. class EliminateLoads : public Pass {
  98. public:
  99. EliminateLoads() = default;
  100. virtual ~EliminateLoads() override = default;
  101. private:
  102. virtual void perform(PassPipelineExecutable&) override;
  103. };
  104. }
  105. }