From b5fa40d4d8949de46e2f0671e061430a62ac8e07 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Sun, 25 Jan 2026 15:12:07 +0000 Subject: [PATCH] mie: tool: add command to run optimisations on an input IR file --- tool/cmd/cmd.h | 2 + tool/cmd/optimise.c | 244 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 246 insertions(+) create mode 100644 tool/cmd/optimise.c diff --git a/tool/cmd/cmd.h b/tool/cmd/cmd.h index 14cde7c..2f99c97 100644 --- a/tool/cmd/cmd.h +++ b/tool/cmd/cmd.h @@ -4,6 +4,8 @@ enum command_id { CMD_ROOT, CMD_VALIDATE, + CMD_OPTIMISE, + CMD_INTERNAL, CMD_INTERNAL_BUILDER_TEST, CMD_INTERNAL_CTX_DUMP, diff --git a/tool/cmd/optimise.c b/tool/cmd/optimise.c new file mode 100644 index 0000000..e2fe697 --- /dev/null +++ b/tool/cmd/optimise.c @@ -0,0 +1,244 @@ +#include "cmd.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +enum { + ARG_FILEPATH, + + OPT_PASS_OFFSET = 200, +}; + +static int optimise_file( + const b_command *cmd, const char *path, const b_arglist *args) +{ + b_file *file = NULL; + b_result result + = b_file_open(NULL, B_RV_PATH(path), B_FILE_READ_ONLY, &file); + if (b_result_is_error(result)) { + b_throw(result); + return -1; + } + + printf("File OK\n"); + + b_arglist_iterator it; + b_arglist_foreach(&it, args) + { + if (it.opt_id < OPT_PASS_OFFSET) { + continue; + } + + const b_command_option *opt = b_command_get_option(cmd, it.opt_id); + if (!opt) { + continue; + } + + printf("running pass %s\n", b_command_option_get_long_name(opt)); + } + + struct mie_ctx *ctx = mie_ctx_create(); + mie_builtin_dialect_create(ctx); + mie_meta_dialect_create(ctx); + mie_select_dialect_create(ctx); + mie_ptr_dialect_create(ctx); + mie_arith_dialect_create(ctx); + mie_func_dialect_create(ctx); + mie_cf_dialect_create(ctx); + mie_scf_dialect_create(ctx); + mie_index_dialect_create(ctx); + + mie_builtin_passes_register(ctx); + + struct mie_lex *lex = mie_lex_create(file); + struct mie_parser *parse = mie_parser_create(ctx, lex); + + struct mie_name_map *names = mie_name_map_create(NULL); + + struct mie_op *root = mie_op_create(); + + if (!mie_parser_parse_op(parse, NULL, root)) { + printf("parse failed\n"); + return -1; + } + + enum mie_walker_flags flags = MIE_WALKER_F_INCLUDE_OPS + | MIE_WALKER_F_PREORDER | MIE_WALKER_F_FORWARD + | MIE_WALKER_F_RECURSIVE; + struct mie_walker walker; + mie_walker_begin(&walker, root, flags); + + do { + const struct mie_walk_item *item = mie_walker_get(&walker); + for (size_t i = 0; i < item->i_depth; i++) { + fputs(" ", stdout); + } + + printf("resolving %p %s... ", item->i_op, item->i_op->op_name); + bool ok = mie_ctx_resolve_op(ctx, item->i_op); + printf("%s\n", ok ? "OK" : "FAIL"); + } while (mie_walker_step(&walker) == MIE_SUCCESS); + + struct mie_pass *prefix_func_with_underscore = NULL; + if (mie_ctx_get_pass( + ctx, "prefix-func-with-underscore", NULL, + &prefix_func_with_underscore) + != MIE_SUCCESS) { + printf("cannot load pass prefix-func-with-underscore\n"); + return -1; + } + + struct mie_pass_manager *pm = mie_pass_manager_create(ctx); + struct mie_pass_manager *module_pm = mie_pass_manager_nest(pm); + mie_pass_manager_filter_op(module_pm, "builtin", "module"); + + struct mie_pass_manager *func_pm = mie_pass_manager_nest(pm); + mie_pass_manager_filter_op(module_pm, "func", "func"); + + mie_pass_manager_add_pass(func_pm, prefix_func_with_underscore); + +#if 0 + mie_pass_manager_parse( + pm, "builtin.module(func.func(prefix-func-with-underscore))"); +#endif + mie_pass_manager_run(pm, root); + + struct mie_printer printer; + mie_printer_init(&printer, ctx, b_stdout, MIE_PRINT_F_ABBREVIATED); + mie_printer_print_op(&printer, root); + printf("\n"); + +#if 0 + + while (1) { + struct mie_token *tok = mie_lex_peek(lex); + if (!tok) { + break; + } + + printf("%s[%d:%d -> %d:%d]", + mie_token_type_to_string(tok->tok_type), + tok->tok_start.c_row, tok->tok_start.c_col, + tok->tok_end.c_row, tok->tok_end.c_col); + + switch (tok->tok_value_type) { + case MIE_TOK_V_STRING: + printf(" S:%s", tok->tok_str); + break; + case MIE_TOK_V_INT: + printf(" I:%lld", tok->tok_int); + break; + case MIE_TOK_V_DOUBLE: + printf(" D:%lf", tok->tok_double); + break; + case MIE_TOK_V_SYMBOL: + printf(" SYM:%s", mie_token_symbol_to_string(tok->tok_sym)); + break; + default: + break; + } + + printf("\n"); + + mie_lex_advance(lex); + } +#endif + + mie_lex_destroy(lex); + + b_file_unref(file); + + return 0; +} + +int optimise(const b_command *cmd, const b_arglist *args, const b_array *_) +{ + b_arglist_iterator it; + b_arglist_foreach_filtered(&it, args, B_COMMAND_INVALID_ID, ARG_FILEPATH) + { + b_arglist_value *path = it.value; + if (path->val_type != B_COMMAND_ARG_STRING) { + continue; + } + + int r = optimise_file(cmd, path->val_str, args); + if (r != 0) { + return r; + } + } + + return 0; +} + +B_COMMAND(CMD_OPTIMISE, CMD_ROOT) +{ + B_COMMAND_NAME("optimise"); + B_COMMAND_SHORT_NAME('O'); + B_COMMAND_DESC("optimise a mie ir file."); + B_COMMAND_FLAGS(B_COMMAND_SHOW_HELP_BY_DEFAULT); + B_COMMAND_FUNCTION(optimise); + + B_COMMAND_HELP_OPTION(); + + B_COMMAND_ARG(ARG_FILEPATH) + { + B_ARG_NAME("filepath"); + B_ARG_DESC("the mie file to optimise"); + B_ARG_NR_VALUES(1); + } + + struct mie_ctx *ctx = mie_ctx_create(); + mie_builtin_passes_register(ctx); + + size_t i = 0; + b_btree_node *node = b_btree_first(&ctx->ctx_passes.map_entries); + while (node) { + mie_id *id = b_unbox(mie_id, node, e_node); + struct mie_pass_definition *pass + = b_unbox(struct mie_pass_definition, id, p_id); + + B_COMMAND_OPTION_GEN(OPT_PASS_OFFSET + 1) + { + B_OPTION_LONG_NAME(pass->p_name); + B_OPTION_DESC(pass->p_description); + } + + node = b_btree_next(node); + } +}