frontend: compile: create and (optionally) show isel graph for each block
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
#include "../debug.h"
|
#include "../debug.h"
|
||||||
#include "cmd.h"
|
#include "cmd.h"
|
||||||
|
#include "mie/select/builder.h"
|
||||||
|
|
||||||
#include <blue/cmd.h>
|
#include <blue/cmd.h>
|
||||||
#include <blue/term.h>
|
#include <blue/term.h>
|
||||||
@@ -11,8 +12,12 @@
|
|||||||
#include <ivy/lang/diag.h>
|
#include <ivy/lang/diag.h>
|
||||||
#include <ivy/lang/lex.h>
|
#include <ivy/lang/lex.h>
|
||||||
#include <mie/ctx.h>
|
#include <mie/ctx.h>
|
||||||
|
#include <mie/ir/block.h>
|
||||||
#include <mie/ir/convert.h>
|
#include <mie/ir/convert.h>
|
||||||
|
#include <mie/ir/func.h>
|
||||||
#include <mie/ir/module.h>
|
#include <mie/ir/module.h>
|
||||||
|
#include <mie/select/builder.h>
|
||||||
|
#include <mie/select/graph.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@@ -20,6 +25,8 @@ enum {
|
|||||||
OPT_SHOW_LEX_TOKENS,
|
OPT_SHOW_LEX_TOKENS,
|
||||||
OPT_SHOW_AST_NODES,
|
OPT_SHOW_AST_NODES,
|
||||||
OPT_SHOW_IR,
|
OPT_SHOW_IR,
|
||||||
|
OPT_SHOW_ISEL_PRE,
|
||||||
|
OPT_SHOW_ISEL_POST,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct codegen_args {
|
struct codegen_args {
|
||||||
@@ -54,6 +61,9 @@ static int compile_file(const char *path, const b_arglist *args)
|
|||||||
> 0;
|
> 0;
|
||||||
bool show_ir
|
bool show_ir
|
||||||
= b_arglist_get_count(args, OPT_SHOW_IR, B_COMMAND_INVALID_ID) > 0;
|
= 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;
|
enum ivy_status status = IVY_OK;
|
||||||
|
|
||||||
struct ivy_file *src = NULL;
|
struct ivy_file *src = NULL;
|
||||||
@@ -123,11 +133,6 @@ static int compile_file(const char *path, const b_arglist *args)
|
|||||||
if (status != IVY_OK) {
|
if (status != IVY_OK) {
|
||||||
ivy_diag_ctx_write(
|
ivy_diag_ctx_write(
|
||||||
diag, IVY_DIAG_FORMAT_PRETTY, &diag_stream);
|
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;
|
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);
|
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);
|
ivy_codegen_start_module(codegen);
|
||||||
|
|
||||||
struct ivy_ast_node *node = ivy_parser_root_node(parser);
|
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;
|
struct mie_module *mod = NULL;
|
||||||
ivy_codegen_end_module(codegen, &mod);
|
ivy_codegen_end_module(codegen, &mod);
|
||||||
|
|
||||||
struct mie_ir_converter *convert
|
if (show_ir) {
|
||||||
= mie_ir_converter_create(ctx, MIE_IR_MEM, MIE_IR_TEXT);
|
struct mie_ir_converter *convert
|
||||||
mie_ir_converter_set_src_value(convert, MIE_VALUE(mod));
|
= mie_ir_converter_create(ctx, MIE_IR_MEM, MIE_IR_TEXT);
|
||||||
mie_ir_converter_set_dest_file(convert, stdout);
|
mie_ir_converter_set_src_value(convert, MIE_VALUE(mod));
|
||||||
mie_ir_converter_process(convert);
|
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_value_destroy(MIE_VALUE(mod));
|
||||||
mie_ir_converter_destroy(convert);
|
|
||||||
ivy_codegen_destroy(codegen);
|
ivy_codegen_destroy(codegen);
|
||||||
|
|
||||||
ivy_parser_destroy(parser, NULL);
|
ivy_parser_destroy(parser, NULL);
|
||||||
@@ -267,6 +317,24 @@ B_COMMAND(CMD_COMPILE, CMD_ROOT)
|
|||||||
"input files.");
|
"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_COMMAND_ARG(ARG_SOURCE_FILE)
|
||||||
{
|
{
|
||||||
B_ARG_NAME("source file");
|
B_ARG_NAME("source file");
|
||||||
|
|||||||
Reference in New Issue
Block a user