소스 검색

JSSpecCompiler: Add `--dump-cfg` option

Dan Klishch 1 년 전
부모
커밋
ce6b987330

+ 1 - 0
Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/CMakeLists.txt

@@ -2,6 +2,7 @@ set(SOURCES
     AST/AST.cpp
     AST/ASTPrinting.cpp
     Compiler/CompilerPass.cpp
+    Compiler/ControlFlowGraph.cpp
     Compiler/GenericASTPass.cpp
     Compiler/Passes/CFGBuildingPass.cpp
     Compiler/Passes/FunctionCallCanonicalizationPass.cpp

+ 29 - 0
Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Compiler/ControlFlowGraph.cpp

@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2023, Dan Klishch <danilklishch@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <AK/StringBuilder.h>
+
+#include "AST/AST.h"
+#include "Compiler/ControlFlowGraph.h"
+
+using namespace JSSpecCompiler;
+
+ErrorOr<void> AK::Formatter<ControlFlowGraph>::format(FormatBuilder& format_builder, ControlFlowGraph const& control_flow_graph)
+{
+    auto& builder = format_builder.builder();
+
+    for (auto const& block : control_flow_graph.blocks) {
+        builder.appendff("{}:\n", block->m_index);
+        for (auto const& expression : block->m_expressions)
+            builder.appendff("{}", expression);
+        builder.appendff("{}\n", Tree(block->m_continuation));
+    }
+
+    // Remove trailing \n
+    builder.trim(1);
+
+    return {};
+}

+ 9 - 0
Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/Compiler/ControlFlowGraph.h

@@ -39,3 +39,12 @@ public:
 };
 
 }
+
+namespace AK {
+
+template<>
+struct Formatter<JSSpecCompiler::ControlFlowGraph> : Formatter<StringView> {
+    ErrorOr<void> format(FormatBuilder& builder, JSSpecCompiler::ControlFlowGraph const& control_flow_graph);
+};
+
+}

+ 14 - 0
Meta/Lagom/Tools/CodeGenerators/JSSpecCompiler/main.cpp

@@ -21,6 +21,7 @@ using namespace JSSpecCompiler;
 struct CompilationStepWithDumpOptions {
     OwnPtr<CompilationStep> step;
     bool dump_ast = false;
+    bool dump_cfg = false;
 };
 
 class CompilationPipeline {
@@ -91,6 +92,9 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
     StringView passes_to_dump_ast;
     args_parser.add_option(passes_to_dump_ast, "Dump AST after specified passes.", "dump-ast", 0, "{all|last|<pass-name>|-<pass-name>[,...]}");
 
+    StringView passes_to_dump_cfg;
+    args_parser.add_option(passes_to_dump_cfg, "Dump CFG after specified passes.", "dump-cfg", 0, "{all|last|<pass-name>|-<pass-name>[,...]}");
+
     args_parser.parse(arguments);
 
     CompilationPipeline pipeline;
@@ -106,6 +110,9 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
     pipeline.for_each_step_in(passes_to_dump_ast, [](CompilationStepWithDumpOptions& step) {
         step.dump_ast = true;
     });
+    pipeline.for_each_step_in(passes_to_dump_cfg, [](CompilationStepWithDumpOptions& step) {
+        step.dump_cfg = true;
+    });
 
     TranslationUnit translation_unit;
     translation_unit.filename = filename;
@@ -132,6 +139,13 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
                 outln(stderr, "{}", function->m_ast);
             }
         }
+        if (step.dump_cfg && translation_unit.function_definitions[0]->m_cfg != nullptr) {
+            outln(stderr, "===== CFG after {} =====", step.step->name());
+            for (auto const& function : translation_unit.function_definitions) {
+                outln(stderr, "{}():", function->m_name);
+                outln(stderr, "{}", *function->m_cfg);
+            }
+        }
     }
 
     return 0;