From ebfbbd0a1a0f10b6a06b79bb81db235cc65b292e Mon Sep 17 00:00:00 2001 From: Max Wash Date: Fri, 29 Aug 2025 15:47:42 +0100 Subject: [PATCH] frontend: compile: create and (optionally) show isel graph for each block --- frontend/cmd/compile.c | 100 ++++++++++++++++++++++++++++++++++------- 1 file changed, 84 insertions(+), 16 deletions(-) diff --git a/frontend/cmd/compile.c b/frontend/cmd/compile.c index 397a665..7849582 100644 --- a/frontend/cmd/compile.c +++ b/frontend/cmd/compile.c @@ -1,5 +1,6 @@ #include "../debug.h" #include "cmd.h" +#include "mie/select/builder.h" #include #include @@ -11,8 +12,12 @@ #include #include #include +#include #include +#include #include +#include +#include #include enum { @@ -20,6 +25,8 @@ enum { OPT_SHOW_LEX_TOKENS, OPT_SHOW_AST_NODES, OPT_SHOW_IR, + OPT_SHOW_ISEL_PRE, + OPT_SHOW_ISEL_POST, }; struct codegen_args { @@ -54,6 +61,9 @@ static int compile_file(const char *path, const b_arglist *args) > 0; bool show_ir = b_arglist_get_count(args, OPT_SHOW_IR, B_COMMAND_INVALID_ID) > 0; + bool show_isel_pre + = b_arglist_get_count(args, OPT_SHOW_ISEL_PRE, B_COMMAND_INVALID_ID) + > 0; enum ivy_status status = IVY_OK; struct ivy_file *src = NULL; @@ -123,11 +133,6 @@ static int compile_file(const char *path, const b_arglist *args) if (status != IVY_OK) { ivy_diag_ctx_write( diag, IVY_DIAG_FORMAT_PRETTY, &diag_stream); -#if 0 - b_err("failed to parse '%s'", path); - b_i("reason: lex error (%s)", - ivy_status_to_string(ivy_lexer_get_status(lex))); -#endif break; } @@ -172,11 +177,6 @@ static int compile_file(const char *path, const b_arglist *args) ivy_ast_node_iterate(root, &it, print_ast_node, NULL); } - if (!show_ir) { - ivy_parser_destroy(parser, NULL); - return 0; - } - ivy_codegen_start_module(codegen); struct ivy_ast_node *node = ivy_parser_root_node(parser); @@ -197,14 +197,64 @@ static int compile_file(const char *path, const b_arglist *args) struct mie_module *mod = NULL; ivy_codegen_end_module(codegen, &mod); - struct mie_ir_converter *convert - = mie_ir_converter_create(ctx, MIE_IR_MEM, MIE_IR_TEXT); - mie_ir_converter_set_src_value(convert, MIE_VALUE(mod)); - mie_ir_converter_set_dest_file(convert, stdout); - mie_ir_converter_process(convert); + if (show_ir) { + struct mie_ir_converter *convert + = mie_ir_converter_create(ctx, MIE_IR_MEM, MIE_IR_TEXT); + mie_ir_converter_set_src_value(convert, MIE_VALUE(mod)); + mie_ir_converter_set_dest_file(convert, stdout); + mie_ir_converter_process(convert); + + mie_ir_converter_destroy(convert); + } + + struct mie_select_builder *builder = mie_select_builder_create(ctx); + + b_queue_iterator func_it; + b_queue_foreach (&func_it, &mod->m_func) { + struct mie_value *func_v + = b_unbox(struct mie_value, func_it.entry, v_entry); + struct mie_func *func = (struct mie_func *)func_v; + + b_queue_iterator block_it; + b_queue_foreach (&block_it, &func->f_blocks) { + struct mie_value *block_v = b_unbox( + struct mie_value, block_it.entry, v_entry); + struct mie_block *block = (struct mie_block *)block_v; + + b_queue_iterator instr_it; + b_queue_foreach (&instr_it, &block->b_phi) { + struct mie_value *instr_v = b_unbox( + struct mie_value, instr_it.entry, v_entry); + mie_select_builder_push_instr( + builder, (struct mie_instr *)instr_v); + } + + b_queue_foreach (&instr_it, &block->b_instr) { + struct mie_value *instr_v = b_unbox( + struct mie_value, instr_it.entry, v_entry); + mie_select_builder_push_instr( + builder, (struct mie_instr *)instr_v); + } + + if (block->b_terminator) { + mie_select_builder_push_instr( + builder, block->b_terminator); + } + + struct mie_select_graph *graph + = mie_select_builder_finish(builder); + + if (show_isel_pre) { + printf("%s.%s instruction graph:\n", + func->f_base.v_name.n_str, + block->b_base.v_name.n_str); + mie_select_graph_dump_dot(graph); + mie_select_graph_destroy(graph); + } + } + } mie_value_destroy(MIE_VALUE(mod)); - mie_ir_converter_destroy(convert); ivy_codegen_destroy(codegen); ivy_parser_destroy(parser, NULL); @@ -267,6 +317,24 @@ B_COMMAND(CMD_COMPILE, CMD_ROOT) "input files."); } + B_COMMAND_OPTION(OPT_SHOW_ISEL_PRE) + { + B_OPTION_LONG_NAME("show-isel-pre"); + B_OPTION_SHORT_NAME('s'); + B_OPTION_DESC( + "print the instruction selection graph before " + "selection has taken place."); + } + + B_COMMAND_OPTION(OPT_SHOW_ISEL_POST) + { + B_OPTION_LONG_NAME("show-isel-post"); + B_OPTION_SHORT_NAME('m'); + B_OPTION_DESC( + "print the instruction selection graph after " + "selection has taken place."); + } + B_COMMAND_ARG(ARG_SOURCE_FILE) { B_ARG_NAME("source file");