frontend: compile: create and (optionally) show isel graph for each block
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
#include "../debug.h"
|
||||
#include "cmd.h"
|
||||
#include "mie/select/builder.h"
|
||||
|
||||
#include <blue/cmd.h>
|
||||
#include <blue/term.h>
|
||||
@@ -11,8 +12,12 @@
|
||||
#include <ivy/lang/diag.h>
|
||||
#include <ivy/lang/lex.h>
|
||||
#include <mie/ctx.h>
|
||||
#include <mie/ir/block.h>
|
||||
#include <mie/ir/convert.h>
|
||||
#include <mie/ir/func.h>
|
||||
#include <mie/ir/module.h>
|
||||
#include <mie/select/builder.h>
|
||||
#include <mie/select/graph.h>
|
||||
#include <stdio.h>
|
||||
|
||||
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");
|
||||
|
||||
Reference in New Issue
Block a user