Compare commits
3 Commits
00152cac56
...
b5fa40d4d8
| Author | SHA1 | Date | |
|---|---|---|---|
| b5fa40d4d8 | |||
| a67e4b6688 | |||
| 5873326138 |
@@ -1,6 +1,7 @@
|
||||
file(GLOB tool_sources
|
||||
*.c *.h
|
||||
cmd/*.c cmd/*.h)
|
||||
cmd/*.c cmd/*.h
|
||||
cmd/internal/*.c)
|
||||
|
||||
if (WIN32)
|
||||
set(rc_file ${CMAKE_CURRENT_SOURCE_DIR}/../res/win32/frontend.rc)
|
||||
|
||||
@@ -4,7 +4,11 @@
|
||||
enum command_id {
|
||||
CMD_ROOT,
|
||||
CMD_VALIDATE,
|
||||
CMD_OPTIMISE,
|
||||
|
||||
CMD_INTERNAL,
|
||||
CMD_INTERNAL_BUILDER_TEST,
|
||||
CMD_INTERNAL_CTX_DUMP,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
#include "cmd.h"
|
||||
#include <blue/cmd.h>
|
||||
#include <blue/term.h>
|
||||
|
||||
enum {
|
||||
OPT_PRINT_SYMBOLS = 0x1000,
|
||||
OPT_PRINT_KEYWORDS,
|
||||
};
|
||||
|
||||
static int internal(const b_command* cmd, const b_arglist* args, const b_array* _)
|
||||
{
|
||||
#if 0
|
||||
if (b_arglist_get_count(args, OPT_PRINT_SYMBOLS, B_COMMAND_INVALID_ID)) {
|
||||
internal_lexer_print_symbol_tree(lex);
|
||||
}
|
||||
|
||||
if (b_arglist_get_count(args, OPT_PRINT_KEYWORDS, B_COMMAND_INVALID_ID)) {
|
||||
internal_lexer_print_keyword_dict(lex);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
B_COMMAND(CMD_INTERNAL, CMD_ROOT)
|
||||
{
|
||||
B_COMMAND_NAME("internal");
|
||||
B_COMMAND_SHORT_NAME('X');
|
||||
B_COMMAND_DESC("internal frontend debugging tools.");
|
||||
B_COMMAND_FUNCTION(internal);
|
||||
|
||||
B_COMMAND_OPTION(OPT_PRINT_SYMBOLS)
|
||||
{
|
||||
B_OPTION_LONG_NAME("print-symbols");
|
||||
B_OPTION_SHORT_NAME('s');
|
||||
B_OPTION_DESC(
|
||||
"print the symbol tree used by the language lexer.");
|
||||
}
|
||||
|
||||
B_COMMAND_OPTION(OPT_PRINT_KEYWORDS)
|
||||
{
|
||||
B_OPTION_LONG_NAME("print-keywords");
|
||||
B_OPTION_SHORT_NAME('k');
|
||||
B_OPTION_DESC(
|
||||
"print the keyword dictionary used by the language lexer.");
|
||||
}
|
||||
|
||||
B_COMMAND_HELP_OPTION();
|
||||
}
|
||||
182
tool/cmd/internal/builder-test.c
Normal file
182
tool/cmd/internal/builder-test.c
Normal file
@@ -0,0 +1,182 @@
|
||||
#include "../cmd.h"
|
||||
|
||||
#include <blue/cmd.h>
|
||||
#include <blue/term.h>
|
||||
#include <mie/attribute/attribute-definition.h>
|
||||
#include <mie/ctx.h>
|
||||
#include <mie/dialect/arith.h>
|
||||
#include <mie/dialect/builtin.h>
|
||||
#include <mie/dialect/cf.h>
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/dialect/func.h>
|
||||
#include <mie/dialect/index.h>
|
||||
#include <mie/dialect/meta.h>
|
||||
#include <mie/dialect/ptr.h>
|
||||
#include <mie/dialect/scf.h>
|
||||
#include <mie/dialect/select.h>
|
||||
#include <mie/ir/builder.h>
|
||||
#include <mie/ir/op.h>
|
||||
#include <mie/pass/builtin.h>
|
||||
#include <mie/pass/pass-manager.h>
|
||||
#include <mie/print/printer.h>
|
||||
|
||||
enum {
|
||||
OPT_GENERIC,
|
||||
OPT_NO_ABBREV,
|
||||
OPT_PASS_OFFSET = 100,
|
||||
};
|
||||
|
||||
static int builder_test(
|
||||
const b_command *cmd, const b_arglist *args, const b_array *_)
|
||||
{
|
||||
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_op *module = mie_ctx_create_op(ctx, "builtin", "module");
|
||||
struct mie_builder *builder = mie_builder_create(ctx, module);
|
||||
|
||||
const struct mie_type *i32 = mie_ctx_get_int_type(ctx, 32);
|
||||
const struct mie_type *i64 = mie_ctx_get_int_type(ctx, 64);
|
||||
|
||||
struct mie_func_parameter params[] = {
|
||||
{.param_name = "p1", .param_type = i32},
|
||||
{.param_name = "p2", .param_type = i64},
|
||||
};
|
||||
size_t nr_params = sizeof params / sizeof params[0];
|
||||
const struct mie_type *ret_type = mie_ctx_get_int_type(ctx, 64);
|
||||
|
||||
struct mie_op *func = mie_func_func_put(
|
||||
MIE_EMITTER(builder), "test_func", params, nr_params, &ret_type, 1);
|
||||
mie_builder_step_into_op(builder, func);
|
||||
|
||||
struct mie_region *r_true, *r_false;
|
||||
struct mie_op *if_op = mie_scf_if_put(
|
||||
MIE_EMITTER(builder), params[0].param_reg, i32, &r_true,
|
||||
&r_false, NULL);
|
||||
|
||||
struct mie_register *tmp = NULL;
|
||||
|
||||
mie_builder_step_into_region(builder, r_true);
|
||||
tmp = mie_arith_constant_i_put(MIE_EMITTER(builder), 10, NULL);
|
||||
mie_scf_yield_put(MIE_EMITTER(builder), tmp);
|
||||
mie_builder_step_out(builder);
|
||||
|
||||
mie_builder_step_into_region(builder, r_false);
|
||||
tmp = mie_arith_constant_i_put(MIE_EMITTER(builder), 20, NULL);
|
||||
mie_scf_yield_put(MIE_EMITTER(builder), tmp);
|
||||
mie_builder_step_out(builder);
|
||||
|
||||
struct mie_register *v1
|
||||
= mie_arith_constant_i_put(MIE_EMITTER(builder), 1024, NULL);
|
||||
struct mie_register *v2
|
||||
= mie_arith_constant_i_put(MIE_EMITTER(builder), 2048, NULL);
|
||||
struct mie_register *add
|
||||
= mie_arith_addi_put(MIE_EMITTER(builder), v1, v2, NULL);
|
||||
struct mie_register *add2 = mie_arith_addi_put(
|
||||
MIE_EMITTER(builder), add, &if_op->op_result.items[0], NULL);
|
||||
|
||||
mie_builder_step_out(builder);
|
||||
|
||||
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");
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
const char *pass_name = b_command_option_get_long_name(opt);
|
||||
struct mie_pass *pass = NULL;
|
||||
enum mie_status status
|
||||
= mie_ctx_get_pass(ctx, pass_name, NULL, &pass);
|
||||
if (status != MIE_SUCCESS) {
|
||||
printf("cannot load pass %s\n", pass_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
mie_pass_manager_add_pass(func_pm, pass);
|
||||
}
|
||||
|
||||
mie_pass_manager_run(pm, module);
|
||||
|
||||
enum mie_print_flags flags = 0;
|
||||
if (b_arglist_get_count(args, OPT_GENERIC, B_COMMAND_INVALID_ID) > 0) {
|
||||
flags |= MIE_PRINT_F_GENERIC;
|
||||
}
|
||||
|
||||
if (b_arglist_get_count(args, OPT_NO_ABBREV, B_COMMAND_INVALID_ID) == 0) {
|
||||
flags |= MIE_PRINT_F_ABBREVIATED;
|
||||
}
|
||||
|
||||
struct mie_printer printer;
|
||||
mie_printer_init(&printer, ctx, b_stdout, flags);
|
||||
mie_printer_print_op(&printer, module);
|
||||
printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
B_COMMAND(CMD_INTERNAL_BUILDER_TEST, CMD_INTERNAL)
|
||||
{
|
||||
B_COMMAND_NAME("builder-test");
|
||||
B_COMMAND_DESC("mie_builder test");
|
||||
B_COMMAND_FUNCTION(builder_test);
|
||||
|
||||
B_COMMAND_OPTION(OPT_GENERIC)
|
||||
{
|
||||
B_OPTION_LONG_NAME("generic");
|
||||
B_OPTION_SHORT_NAME('g');
|
||||
B_OPTION_DESC("print operations in generic format.");
|
||||
}
|
||||
|
||||
B_COMMAND_OPTION(OPT_NO_ABBREV)
|
||||
{
|
||||
B_OPTION_LONG_NAME("no-abbrev");
|
||||
B_OPTION_SHORT_NAME('n');
|
||||
B_OPTION_DESC(
|
||||
"don't use abbreviations for builtin types and ops.");
|
||||
}
|
||||
|
||||
B_COMMAND_HELP_OPTION();
|
||||
|
||||
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 + i)
|
||||
{
|
||||
B_OPTION_LONG_NAME(pass->p_name);
|
||||
B_OPTION_DESC(pass->p_description);
|
||||
}
|
||||
|
||||
node = b_btree_next(node);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
366
tool/cmd/internal/ctx-dump.c
Normal file
366
tool/cmd/internal/ctx-dump.c
Normal file
@@ -0,0 +1,366 @@
|
||||
#include "../cmd.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <blue/cmd.h>
|
||||
#include <blue/term.h>
|
||||
#include <mie/attribute/attribute-definition.h>
|
||||
#include <mie/ctx.h>
|
||||
#include <mie/dialect/arith.h>
|
||||
#include <mie/dialect/builtin.h>
|
||||
#include <mie/dialect/cf.h>
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/dialect/func.h>
|
||||
#include <mie/dialect/index.h>
|
||||
#include <mie/dialect/meta.h>
|
||||
#include <mie/dialect/ptr.h>
|
||||
#include <mie/dialect/scf.h>
|
||||
#include <mie/dialect/select.h>
|
||||
#include <mie/interface/interface-definition.h>
|
||||
#include <mie/ir/block.h>
|
||||
#include <mie/ir/op-definition.h>
|
||||
#include <mie/ir/op.h>
|
||||
#include <mie/ir/region.h>
|
||||
#include <mie/ir/register.h>
|
||||
#include <mie/pass/builtin.h>
|
||||
#include <mie/pass/pass-manager.h>
|
||||
#include <mie/print/printer.h>
|
||||
#include <mie/trait/trait-definition.h>
|
||||
#include <mie/trait/trait.h>
|
||||
#include <mie/type/type-definition.h>
|
||||
#include <mie/type/type.h>
|
||||
|
||||
static int trait_ref_print(const struct mie_trait *trait, void *arg)
|
||||
{
|
||||
fputc(' ', stdout);
|
||||
mie_trait_print(trait, b_stdout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void op_arg_dump(struct mie_printer *printer, const struct mie_op_arg *arg)
|
||||
{
|
||||
enum mie_register_flags arg_flags = 0;
|
||||
const char *arg_name = NULL;
|
||||
const struct mie_type *arg_type = NULL;
|
||||
|
||||
if (MIE_TEST_FLAGS(arg->arg_flags, MIE_OP_F_ARG_RESOLVED)) {
|
||||
arg_flags = arg->arg_value.u_reg->reg_flags;
|
||||
arg_name = arg->arg_value.u_reg->reg_name.n_str;
|
||||
arg_type = arg->arg_value.u_reg->reg_type;
|
||||
} else {
|
||||
arg_flags = arg->arg_unresolved.reg_flags;
|
||||
arg_name = arg->arg_unresolved.reg_name;
|
||||
arg_type = arg->arg_unresolved.reg_type;
|
||||
}
|
||||
|
||||
if (arg_flags & MIE_REGISTER_F_MACHINE) {
|
||||
b_printf(" [bold,red]MR");
|
||||
} else {
|
||||
b_printf(" [bold,magenta]VR");
|
||||
}
|
||||
|
||||
printf(":(");
|
||||
mie_printer_print_type(printer, arg_type);
|
||||
b_printf(")%s[reset]", arg_name);
|
||||
}
|
||||
|
||||
static void op_dump(const struct mie_op *op)
|
||||
{
|
||||
b_stringstream *tmp = b_stringstream_create();
|
||||
struct mie_printer printer;
|
||||
mie_printer_init(&printer, NULL, b_stdout, MIE_PRINT_F_GENERIC);
|
||||
|
||||
printf("FLAGS:");
|
||||
(op->op_flags & MIE_OP_F_OP_RESOLVED) && printf(" OP_RESOLVED");
|
||||
(op->op_flags & MIE_OP_F_ARG_RESOLVED) && printf(" ARG_RESOLVED");
|
||||
printf("\n");
|
||||
printf("DIALECT: %s\n",
|
||||
op->op_dialect ? op->op_dialect->d_name : "<unknown>");
|
||||
printf("OP: %s\n", op->op_info ? op->op_info->op_name : "<unknown>");
|
||||
printf("NAME: %s\n", op->op_name ? op->op_name : "<unknown>");
|
||||
printf("TRAITS:");
|
||||
mie_trait_table_iterate(&op->op_info->op_traits, trait_ref_print, NULL);
|
||||
printf("\n");
|
||||
printf("ATTRIBUTES:");
|
||||
#if 0
|
||||
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_attrib); i++) {
|
||||
printf(" (%s = ", op->op_attrib.items[i].attrib_name);
|
||||
mie_printer_print_value(
|
||||
&printer, op->op_attrib.items[i].attrib_value);
|
||||
printf(")");
|
||||
}
|
||||
#endif
|
||||
printf("\n");
|
||||
|
||||
printf("REGIONS: %zu\n", b_queue_length(&op->op_regions));
|
||||
printf("SUCCESSORS:");
|
||||
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_successors); i++) {
|
||||
const struct mie_op_successor *s = &op->op_successors.items[i];
|
||||
if (MIE_TEST_FLAGS(s->s_flags, MIE_OP_F_SUCCESSOR_RESOLVED)) {
|
||||
printf(" ^%s", s->s_block->b_name.n_str);
|
||||
} else {
|
||||
printf(" ^%s?", s->s_block_name);
|
||||
}
|
||||
|
||||
printf(":(");
|
||||
|
||||
for (size_t i = 0; i < MIE_VECTOR_COUNT(s->s_args); i++) {
|
||||
const struct mie_op_arg *arg = &s->s_args.items[i];
|
||||
op_arg_dump(&printer, arg);
|
||||
}
|
||||
|
||||
printf(" )");
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
printf("ARGS:");
|
||||
for (size_t i = 0; i < op->op_args.count; i++) {
|
||||
const struct mie_op_arg *arg = &op->op_args.items[i];
|
||||
op_arg_dump(&printer, arg);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
printf("RESULT:");
|
||||
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_result); i++) {
|
||||
const struct mie_register *reg = &op->op_result.items[i];
|
||||
printf(" %s:(",
|
||||
(reg->reg_flags & MIE_REGISTER_F_MACHINE) ? "MR" : "VR");
|
||||
mie_printer_print_type(&printer, reg->reg_type);
|
||||
printf(")%s", reg->reg_name.n_str);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void mie_op_definition_print(const struct mie_op_definition *op)
|
||||
{
|
||||
char id_str[MIE_ID_STRING_MAX];
|
||||
mie_id_to_string(&op->op_id, id_str, sizeof id_str);
|
||||
b_printf(
|
||||
" [bold,red]Op:[reset]%-20s [dark_grey]{%s}[reset]\n",
|
||||
op->op_name, id_str);
|
||||
}
|
||||
|
||||
static void mie_type_definition_print(const struct mie_type_definition *type)
|
||||
{
|
||||
char id_str[MIE_ID_STRING_MAX];
|
||||
mie_id_to_string(&type->ty_id, id_str, sizeof id_str);
|
||||
b_printf(
|
||||
" [bold,blue]Ty:[reset]%-20s [dark_grey]{%s}[reset]\n",
|
||||
type->ty_name, id_str);
|
||||
}
|
||||
|
||||
static void mie_trait_definition_print(const struct mie_trait_definition *trait)
|
||||
{
|
||||
char id_str[MIE_ID_STRING_MAX];
|
||||
mie_id_to_string(&trait->tr_id, id_str, sizeof id_str);
|
||||
b_printf(
|
||||
" [bold,yellow]Tr:[reset]%-20s [dark_grey]{%s}[reset]\n",
|
||||
trait->tr_name, id_str);
|
||||
}
|
||||
|
||||
static void mie_attribute_definition_print(
|
||||
const struct mie_attribute_definition *attribute)
|
||||
{
|
||||
char id_str[MIE_ID_STRING_MAX];
|
||||
mie_id_to_string(&attribute->a_id, id_str, sizeof id_str);
|
||||
b_printf(
|
||||
" [bold,magenta]At:[reset]%-20s [dark_grey]{%s}[reset]\n",
|
||||
attribute->a_name, id_str);
|
||||
}
|
||||
|
||||
static void mie_interface_definition_print(
|
||||
const struct mie_interface_definition *interface)
|
||||
{
|
||||
char id_str[MIE_ID_STRING_MAX];
|
||||
mie_id_to_string(&interface->if_id, id_str, sizeof id_str);
|
||||
b_printf(
|
||||
" [bold,cyan]If:[reset]%-20s [dark_grey]{%s}[reset]\n",
|
||||
interface->if_name, id_str);
|
||||
}
|
||||
|
||||
static void mie_pass_definition_print(const struct mie_pass_definition *interface)
|
||||
{
|
||||
char id_str[MIE_ID_STRING_MAX];
|
||||
mie_id_to_string(&interface->p_id, id_str, sizeof id_str);
|
||||
b_printf(
|
||||
" [bold,cyan]Ps:[reset]%-20s [dark_grey]{%s}[reset]\n",
|
||||
interface->p_name, id_str);
|
||||
}
|
||||
|
||||
static void mie_dialect_print(const struct mie_dialect *dialect)
|
||||
{
|
||||
char id_str[MIE_ID_STRING_MAX];
|
||||
mie_id_to_string(&dialect->d_id, id_str, sizeof id_str);
|
||||
b_printf(
|
||||
"[bold,green]D:[reset]%-20s [dark_grey]{%s}[reset]\n",
|
||||
dialect->d_name, id_str);
|
||||
|
||||
b_btree_node *node = b_btree_first(&dialect->d_ops.map_entries);
|
||||
while (node) {
|
||||
mie_id *id = b_unbox(mie_id, node, e_node);
|
||||
struct mie_op_definition *op
|
||||
= b_unbox(struct mie_op_definition, id, op_id);
|
||||
|
||||
mie_op_definition_print(op);
|
||||
node = b_btree_next(node);
|
||||
}
|
||||
|
||||
node = b_btree_first(&dialect->d_types.map_entries);
|
||||
while (node) {
|
||||
mie_id *id = b_unbox(mie_id, node, e_node);
|
||||
struct mie_type_definition *type
|
||||
= b_unbox(struct mie_type_definition, id, ty_id);
|
||||
|
||||
mie_type_definition_print(type);
|
||||
node = b_btree_next(node);
|
||||
}
|
||||
|
||||
node = b_btree_first(&dialect->d_traits.map_entries);
|
||||
while (node) {
|
||||
mie_id *id = b_unbox(mie_id, node, e_node);
|
||||
struct mie_trait_definition *trait
|
||||
= b_unbox(struct mie_trait_definition, id, tr_id);
|
||||
|
||||
mie_trait_definition_print(trait);
|
||||
node = b_btree_next(node);
|
||||
}
|
||||
|
||||
node = b_btree_first(&dialect->d_attributes.map_entries);
|
||||
while (node) {
|
||||
mie_id *id = b_unbox(mie_id, node, e_node);
|
||||
struct mie_attribute_definition *attribute
|
||||
= b_unbox(struct mie_attribute_definition, id, a_id);
|
||||
|
||||
mie_attribute_definition_print(attribute);
|
||||
node = b_btree_next(node);
|
||||
}
|
||||
|
||||
node = b_btree_first(&dialect->d_interfaces.map_entries);
|
||||
while (node) {
|
||||
mie_id *id = b_unbox(mie_id, node, e_node);
|
||||
struct mie_interface_definition *interface = b_unbox(
|
||||
struct mie_interface_definition, id, if_id);
|
||||
|
||||
mie_interface_definition_print(interface);
|
||||
node = b_btree_next(node);
|
||||
}
|
||||
}
|
||||
|
||||
static void mie_ctx_print(const struct mie_ctx *ctx)
|
||||
{
|
||||
printf("Dialects:\n");
|
||||
b_btree_node *node = b_btree_first(&ctx->ctx_dialects.map_entries);
|
||||
while (node) {
|
||||
mie_id *id = b_unbox(mie_id, node, e_node);
|
||||
struct mie_dialect *dialect
|
||||
= b_unbox(struct mie_dialect, id, d_id);
|
||||
|
||||
mie_dialect_print(dialect);
|
||||
node = b_btree_next(node);
|
||||
}
|
||||
|
||||
printf("\nPasses:\n");
|
||||
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);
|
||||
|
||||
mie_pass_definition_print(pass);
|
||||
node = b_btree_next(node);
|
||||
}
|
||||
}
|
||||
|
||||
static int ctx_dump(const b_command *cmd, const b_arglist *args, const b_array *_)
|
||||
{
|
||||
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);
|
||||
|
||||
mie_ctx_print(ctx);
|
||||
|
||||
struct mie_type *i32 = mie_ctx_get_int_type(ctx, 32);
|
||||
struct mie_type *str = mie_ctx_get_type(ctx, "builtin", "string");
|
||||
struct mie_type *index = mie_ctx_get_type(ctx, "builtin", "index");
|
||||
struct mie_attribute *i32_value = mie_ctx_get_int(ctx, 1024, 32);
|
||||
struct mie_attribute *index_value = mie_ctx_get_index(ctx, 25000);
|
||||
struct mie_attribute *str_value
|
||||
= mie_ctx_get_string(ctx, "Hello, world!");
|
||||
|
||||
const struct mie_type *storage_type_parts[] = {i32, str, index};
|
||||
struct mie_type *storage_type = mie_ctx_get_storage_type(
|
||||
ctx, storage_type_parts,
|
||||
sizeof storage_type_parts / sizeof *storage_type_parts);
|
||||
|
||||
const struct mie_type *func_in_parts[] = {i32, str};
|
||||
const struct mie_type *func_out_parts[] = {index};
|
||||
struct mie_type *func_type = mie_ctx_get_function_type(
|
||||
ctx, func_in_parts, sizeof func_in_parts / sizeof *func_in_parts,
|
||||
func_out_parts, sizeof func_out_parts / sizeof *func_out_parts);
|
||||
|
||||
/* make sure storage/function type caching is working */
|
||||
assert(storage_type
|
||||
== mie_ctx_get_storage_type(
|
||||
ctx, storage_type_parts,
|
||||
sizeof storage_type_parts / sizeof *storage_type_parts));
|
||||
assert(func_type
|
||||
== mie_ctx_get_function_type(
|
||||
ctx, func_in_parts,
|
||||
sizeof func_in_parts / sizeof *func_in_parts, func_out_parts,
|
||||
sizeof func_out_parts / sizeof *func_out_parts));
|
||||
|
||||
struct mie_printer printer;
|
||||
mie_printer_init(&printer, ctx, b_stdout, MIE_PRINT_F_ABBREVIATED);
|
||||
|
||||
char id_str[MIE_ID_STRING_MAX];
|
||||
mie_id_to_string(&i32->ty_id, id_str, sizeof id_str);
|
||||
printf("i32 type: {%s} %s (instance of %s.%s)\n", id_str, i32->ty_name,
|
||||
i32->ty_def->ty_parent->d_name, i32->ty_def->ty_name);
|
||||
mie_id_to_string(&str->ty_id, id_str, sizeof id_str);
|
||||
printf("str type: {%s} %s (instance of %s.%s)\n", id_str, str->ty_name,
|
||||
str->ty_def->ty_parent->d_name, str->ty_def->ty_name);
|
||||
mie_id_to_string(&index->ty_id, id_str, sizeof id_str);
|
||||
printf("index type: {%s} %s (instance of %s.%s)\n", id_str, index->ty_name,
|
||||
index->ty_def->ty_parent->d_name, index->ty_def->ty_name);
|
||||
mie_id_to_string(&storage_type->ty_id, id_str, sizeof id_str);
|
||||
printf("storage type: {%s} ", id_str);
|
||||
mie_printer_print_type(&printer, storage_type);
|
||||
printf("\n");
|
||||
|
||||
mie_id_to_string(&func_type->ty_id, id_str, sizeof id_str);
|
||||
printf("function type: {%s} ", id_str);
|
||||
mie_printer_print_type(&printer, func_type);
|
||||
printf("\n");
|
||||
|
||||
printf("i32 value: ");
|
||||
mie_printer_print_attribute(&printer, i32_value);
|
||||
printf("\n");
|
||||
|
||||
printf("index value: ");
|
||||
mie_printer_print_attribute(&printer, index_value);
|
||||
printf("\n");
|
||||
|
||||
printf("str value: ");
|
||||
mie_printer_print_attribute(&printer, str_value);
|
||||
printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
B_COMMAND(CMD_INTERNAL_CTX_DUMP, CMD_INTERNAL)
|
||||
{
|
||||
B_COMMAND_NAME("ctx-dump");
|
||||
B_COMMAND_DESC("mie_ctx dump");
|
||||
B_COMMAND_FUNCTION(ctx_dump);
|
||||
|
||||
B_COMMAND_HELP_OPTION();
|
||||
}
|
||||
20
tool/cmd/internal/internal.c
Normal file
20
tool/cmd/internal/internal.c
Normal file
@@ -0,0 +1,20 @@
|
||||
#include "../cmd.h"
|
||||
|
||||
#include <blue/cmd.h>
|
||||
#include <blue/term.h>
|
||||
|
||||
static int internal(const b_command *cmd, const b_arglist *args, const b_array *_)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
B_COMMAND(CMD_INTERNAL, CMD_ROOT)
|
||||
{
|
||||
B_COMMAND_SHORT_NAME('X');
|
||||
B_COMMAND_DESC("internal frontend debugging tools.");
|
||||
B_COMMAND_FUNCTION(internal);
|
||||
B_COMMAND_FLAGS(B_COMMAND_SHOW_HELP_BY_DEFAULT);
|
||||
|
||||
B_COMMAND_HELP_OPTION();
|
||||
}
|
||||
244
tool/cmd/optimise.c
Normal file
244
tool/cmd/optimise.c
Normal file
@@ -0,0 +1,244 @@
|
||||
#include "cmd.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <blue/cmd.h>
|
||||
#include <blue/io/file.h>
|
||||
#include <blue/io/path.h>
|
||||
#include <blue/term.h>
|
||||
#include <mie/attribute/attribute-definition.h>
|
||||
#include <mie/ctx.h>
|
||||
#include <mie/dialect/arith.h>
|
||||
#include <mie/dialect/builtin.h>
|
||||
#include <mie/dialect/cf.h>
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/dialect/func.h>
|
||||
#include <mie/dialect/index.h>
|
||||
#include <mie/dialect/meta.h>
|
||||
#include <mie/dialect/ptr.h>
|
||||
#include <mie/dialect/scf.h>
|
||||
#include <mie/dialect/select.h>
|
||||
#include <mie/interface/interface-definition.h>
|
||||
#include <mie/ir/block.h>
|
||||
#include <mie/ir/op-definition.h>
|
||||
#include <mie/ir/op.h>
|
||||
#include <mie/ir/region.h>
|
||||
#include <mie/ir/register.h>
|
||||
#include <mie/ir/walk.h>
|
||||
#include <mie/name.h>
|
||||
#include <mie/parse/lex.h>
|
||||
#include <mie/parse/parser.h>
|
||||
#include <mie/parse/token.h>
|
||||
#include <mie/pass/builtin.h>
|
||||
#include <mie/pass/pass-manager.h>
|
||||
#include <mie/print/printer.h>
|
||||
#include <mie/trait/trait-definition.h>
|
||||
#include <mie/trait/trait.h>
|
||||
#include <mie/type/type-definition.h>
|
||||
#include <mie/type/type.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -43,248 +43,6 @@ enum {
|
||||
ARG_FILEPATH,
|
||||
};
|
||||
|
||||
static int trait_ref_print(const struct mie_trait *trait, void *arg)
|
||||
{
|
||||
fputc(' ', stdout);
|
||||
mie_trait_print(trait, b_stdout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void op_arg_dump(struct mie_printer *printer, const struct mie_op_arg *arg)
|
||||
{
|
||||
enum mie_register_flags arg_flags = 0;
|
||||
const char *arg_name = NULL;
|
||||
const struct mie_type *arg_type = NULL;
|
||||
|
||||
if (MIE_TEST_FLAGS(arg->arg_flags, MIE_OP_F_ARG_RESOLVED)) {
|
||||
arg_flags = arg->arg_value.u_reg->reg_flags;
|
||||
arg_name = arg->arg_value.u_reg->reg_name.n_str;
|
||||
arg_type = arg->arg_value.u_reg->reg_type;
|
||||
} else {
|
||||
arg_flags = arg->arg_unresolved.reg_flags;
|
||||
arg_name = arg->arg_unresolved.reg_name;
|
||||
arg_type = arg->arg_unresolved.reg_type;
|
||||
}
|
||||
|
||||
if (arg_flags & MIE_REGISTER_F_MACHINE) {
|
||||
b_printf(" [bold,red]MR");
|
||||
} else {
|
||||
b_printf(" [bold,magenta]VR");
|
||||
}
|
||||
|
||||
printf(":(");
|
||||
mie_printer_print_type(printer, arg_type);
|
||||
b_printf(")%s[reset]", arg_name);
|
||||
}
|
||||
|
||||
static void op_dump(const struct mie_op *op)
|
||||
{
|
||||
b_stringstream *tmp = b_stringstream_create();
|
||||
struct mie_printer printer;
|
||||
mie_printer_init(&printer, NULL, b_stdout, MIE_PRINT_F_GENERIC);
|
||||
|
||||
printf("FLAGS:");
|
||||
(op->op_flags & MIE_OP_F_OP_RESOLVED) && printf(" OP_RESOLVED");
|
||||
(op->op_flags & MIE_OP_F_ARG_RESOLVED) && printf(" ARG_RESOLVED");
|
||||
printf("\n");
|
||||
printf("DIALECT: %s\n",
|
||||
op->op_dialect ? op->op_dialect->d_name : "<unknown>");
|
||||
printf("OP: %s\n", op->op_info ? op->op_info->op_name : "<unknown>");
|
||||
printf("NAME: %s\n", op->op_name ? op->op_name : "<unknown>");
|
||||
printf("TRAITS:");
|
||||
mie_trait_table_iterate(&op->op_info->op_traits, trait_ref_print, NULL);
|
||||
printf("\n");
|
||||
printf("ATTRIBUTES:");
|
||||
#if 0
|
||||
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_attrib); i++) {
|
||||
printf(" (%s = ", op->op_attrib.items[i].attrib_name);
|
||||
mie_printer_print_value(
|
||||
&printer, op->op_attrib.items[i].attrib_value);
|
||||
printf(")");
|
||||
}
|
||||
#endif
|
||||
printf("\n");
|
||||
|
||||
printf("REGIONS: %zu\n", MIE_VECTOR_COUNT(op->op_regions));
|
||||
printf("SUCCESSORS:");
|
||||
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_successors); i++) {
|
||||
const struct mie_op_successor *s = &op->op_successors.items[i];
|
||||
if (MIE_TEST_FLAGS(s->s_flags, MIE_OP_F_SUCCESSOR_RESOLVED)) {
|
||||
printf(" ^%s", s->s_block->b_name.n_str);
|
||||
} else {
|
||||
printf(" ^%s?", s->s_block_name);
|
||||
}
|
||||
|
||||
printf(":(");
|
||||
|
||||
for (size_t i = 0; i < MIE_VECTOR_COUNT(s->s_args); i++) {
|
||||
const struct mie_op_arg *arg = &s->s_args.items[i];
|
||||
op_arg_dump(&printer, arg);
|
||||
}
|
||||
|
||||
printf(" )");
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
printf("ARGS:");
|
||||
for (size_t i = 0; i < op->op_args.count; i++) {
|
||||
const struct mie_op_arg *arg = &op->op_args.items[i];
|
||||
op_arg_dump(&printer, arg);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
printf("RESULT:");
|
||||
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_result); i++) {
|
||||
const struct mie_register *reg = &op->op_result.items[i];
|
||||
printf(" %s:(",
|
||||
(reg->reg_flags & MIE_REGISTER_F_MACHINE) ? "MR" : "VR");
|
||||
mie_printer_print_type(&printer, reg->reg_type);
|
||||
printf(")%s", reg->reg_name.n_str);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void mie_op_definition_print(const struct mie_op_definition *op)
|
||||
{
|
||||
char id_str[MIE_ID_STRING_MAX];
|
||||
mie_id_to_string(&op->op_id, id_str, sizeof id_str);
|
||||
b_printf(
|
||||
" [bold,red]Op:[reset]%-20s [dark_grey]{%s}[reset]\n",
|
||||
op->op_name, id_str);
|
||||
}
|
||||
|
||||
static void mie_type_definition_print(const struct mie_type_definition *type)
|
||||
{
|
||||
char id_str[MIE_ID_STRING_MAX];
|
||||
mie_id_to_string(&type->ty_id, id_str, sizeof id_str);
|
||||
b_printf(
|
||||
" [bold,blue]Ty:[reset]%-20s [dark_grey]{%s}[reset]\n",
|
||||
type->ty_name, id_str);
|
||||
}
|
||||
|
||||
static void mie_trait_definition_print(const struct mie_trait_definition *trait)
|
||||
{
|
||||
char id_str[MIE_ID_STRING_MAX];
|
||||
mie_id_to_string(&trait->tr_id, id_str, sizeof id_str);
|
||||
b_printf(
|
||||
" [bold,yellow]Tr:[reset]%-20s [dark_grey]{%s}[reset]\n",
|
||||
trait->tr_name, id_str);
|
||||
}
|
||||
|
||||
static void mie_attribute_definition_print(
|
||||
const struct mie_attribute_definition *attribute)
|
||||
{
|
||||
char id_str[MIE_ID_STRING_MAX];
|
||||
mie_id_to_string(&attribute->a_id, id_str, sizeof id_str);
|
||||
b_printf(
|
||||
" [bold,magenta]At:[reset]%-20s [dark_grey]{%s}[reset]\n",
|
||||
attribute->a_name, id_str);
|
||||
}
|
||||
|
||||
static void mie_interface_definition_print(
|
||||
const struct mie_interface_definition *interface)
|
||||
{
|
||||
char id_str[MIE_ID_STRING_MAX];
|
||||
mie_id_to_string(&interface->if_id, id_str, sizeof id_str);
|
||||
b_printf(
|
||||
" [bold,cyan]If:[reset]%-20s [dark_grey]{%s}[reset]\n",
|
||||
interface->if_name, id_str);
|
||||
}
|
||||
|
||||
static void mie_pass_definition_print(const struct mie_pass_definition *interface)
|
||||
{
|
||||
char id_str[MIE_ID_STRING_MAX];
|
||||
mie_id_to_string(&interface->p_id, id_str, sizeof id_str);
|
||||
b_printf(
|
||||
" [bold,cyan]Ps:[reset]%-20s [dark_grey]{%s}[reset]\n",
|
||||
interface->p_name, id_str);
|
||||
}
|
||||
|
||||
static void mie_dialect_print(const struct mie_dialect *dialect)
|
||||
{
|
||||
char id_str[MIE_ID_STRING_MAX];
|
||||
mie_id_to_string(&dialect->d_id, id_str, sizeof id_str);
|
||||
b_printf(
|
||||
"[bold,green]D:[reset]%-20s [dark_grey]{%s}[reset]\n",
|
||||
dialect->d_name, id_str);
|
||||
|
||||
b_btree_node *node = b_btree_first(&dialect->d_ops.map_entries);
|
||||
while (node) {
|
||||
mie_id *id = b_unbox(mie_id, node, e_node);
|
||||
struct mie_op_definition *op
|
||||
= b_unbox(struct mie_op_definition, id, op_id);
|
||||
|
||||
mie_op_definition_print(op);
|
||||
node = b_btree_next(node);
|
||||
}
|
||||
|
||||
node = b_btree_first(&dialect->d_types.map_entries);
|
||||
while (node) {
|
||||
mie_id *id = b_unbox(mie_id, node, e_node);
|
||||
struct mie_type_definition *type
|
||||
= b_unbox(struct mie_type_definition, id, ty_id);
|
||||
|
||||
mie_type_definition_print(type);
|
||||
node = b_btree_next(node);
|
||||
}
|
||||
|
||||
node = b_btree_first(&dialect->d_traits.map_entries);
|
||||
while (node) {
|
||||
mie_id *id = b_unbox(mie_id, node, e_node);
|
||||
struct mie_trait_definition *trait
|
||||
= b_unbox(struct mie_trait_definition, id, tr_id);
|
||||
|
||||
mie_trait_definition_print(trait);
|
||||
node = b_btree_next(node);
|
||||
}
|
||||
|
||||
node = b_btree_first(&dialect->d_attributes.map_entries);
|
||||
while (node) {
|
||||
mie_id *id = b_unbox(mie_id, node, e_node);
|
||||
struct mie_attribute_definition *attribute
|
||||
= b_unbox(struct mie_attribute_definition, id, a_id);
|
||||
|
||||
mie_attribute_definition_print(attribute);
|
||||
node = b_btree_next(node);
|
||||
}
|
||||
|
||||
node = b_btree_first(&dialect->d_interfaces.map_entries);
|
||||
while (node) {
|
||||
mie_id *id = b_unbox(mie_id, node, e_node);
|
||||
struct mie_interface_definition *interface = b_unbox(
|
||||
struct mie_interface_definition, id, if_id);
|
||||
|
||||
mie_interface_definition_print(interface);
|
||||
node = b_btree_next(node);
|
||||
}
|
||||
}
|
||||
|
||||
static void mie_ctx_print(const struct mie_ctx *ctx)
|
||||
{
|
||||
printf("Dialects:\n");
|
||||
b_btree_node *node = b_btree_first(&ctx->ctx_dialects.map_entries);
|
||||
while (node) {
|
||||
mie_id *id = b_unbox(mie_id, node, e_node);
|
||||
struct mie_dialect *dialect
|
||||
= b_unbox(struct mie_dialect, id, d_id);
|
||||
|
||||
mie_dialect_print(dialect);
|
||||
node = b_btree_next(node);
|
||||
}
|
||||
|
||||
printf("\nPasses:\n");
|
||||
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);
|
||||
|
||||
mie_pass_definition_print(pass);
|
||||
node = b_btree_next(node);
|
||||
}
|
||||
}
|
||||
|
||||
static int validate_file(const char *path, const b_arglist *args)
|
||||
{
|
||||
b_file *file = NULL;
|
||||
@@ -310,75 +68,6 @@ static int validate_file(const char *path, const b_arglist *args)
|
||||
|
||||
mie_builtin_passes_register(ctx);
|
||||
|
||||
mie_ctx_print(ctx);
|
||||
|
||||
struct mie_type *i32 = mie_ctx_get_int_type(ctx, 32);
|
||||
struct mie_type *str = mie_ctx_get_type(ctx, "builtin", "string");
|
||||
struct mie_type *index = mie_ctx_get_type(ctx, "builtin", "index");
|
||||
struct mie_attribute *i32_value = mie_ctx_get_int(ctx, 1024, 32);
|
||||
struct mie_attribute *index_value = mie_ctx_get_index(ctx, 25000);
|
||||
struct mie_attribute *str_value
|
||||
= mie_ctx_get_string(ctx, "Hello, world!");
|
||||
|
||||
printf("%zu\n", sizeof(struct mie_op));
|
||||
|
||||
const struct mie_type *storage_type_parts[] = {i32, str, index};
|
||||
struct mie_type *storage_type = mie_ctx_get_storage_type(
|
||||
ctx, storage_type_parts,
|
||||
sizeof storage_type_parts / sizeof *storage_type_parts);
|
||||
|
||||
const struct mie_type *func_in_parts[] = {i32, str};
|
||||
const struct mie_type *func_out_parts[] = {index};
|
||||
struct mie_type *func_type = mie_ctx_get_function_type(
|
||||
ctx, func_in_parts, sizeof func_in_parts / sizeof *func_in_parts,
|
||||
func_out_parts, sizeof func_out_parts / sizeof *func_out_parts);
|
||||
|
||||
/* make sure storage/function type caching is working */
|
||||
assert(storage_type
|
||||
== mie_ctx_get_storage_type(
|
||||
ctx, storage_type_parts,
|
||||
sizeof storage_type_parts / sizeof *storage_type_parts));
|
||||
assert(func_type
|
||||
== mie_ctx_get_function_type(
|
||||
ctx, func_in_parts,
|
||||
sizeof func_in_parts / sizeof *func_in_parts, func_out_parts,
|
||||
sizeof func_out_parts / sizeof *func_out_parts));
|
||||
|
||||
struct mie_printer printer;
|
||||
mie_printer_init(&printer, ctx, b_stdout, MIE_PRINT_F_ABBREVIATED);
|
||||
|
||||
char id_str[MIE_ID_STRING_MAX];
|
||||
mie_id_to_string(&i32->ty_id, id_str, sizeof id_str);
|
||||
printf("i32 type: {%s} %s (instance of %s.%s)\n", id_str, i32->ty_name,
|
||||
i32->ty_def->ty_parent->d_name, i32->ty_def->ty_name);
|
||||
mie_id_to_string(&str->ty_id, id_str, sizeof id_str);
|
||||
printf("str type: {%s} %s (instance of %s.%s)\n", id_str, str->ty_name,
|
||||
str->ty_def->ty_parent->d_name, str->ty_def->ty_name);
|
||||
mie_id_to_string(&index->ty_id, id_str, sizeof id_str);
|
||||
printf("index type: {%s} %s (instance of %s.%s)\n", id_str, index->ty_name,
|
||||
index->ty_def->ty_parent->d_name, index->ty_def->ty_name);
|
||||
mie_id_to_string(&storage_type->ty_id, id_str, sizeof id_str);
|
||||
printf("storage type: {%s} ", id_str);
|
||||
mie_printer_print_type(&printer, storage_type);
|
||||
printf("\n");
|
||||
|
||||
mie_id_to_string(&func_type->ty_id, id_str, sizeof id_str);
|
||||
printf("function type: {%s} ", id_str);
|
||||
mie_printer_print_type(&printer, func_type);
|
||||
printf("\n");
|
||||
|
||||
printf("i32 value: ");
|
||||
mie_printer_print_attribute(&printer, i32_value);
|
||||
printf("\n");
|
||||
|
||||
printf("index value: ");
|
||||
mie_printer_print_attribute(&printer, index_value);
|
||||
printf("\n");
|
||||
|
||||
printf("str value: ");
|
||||
mie_printer_print_attribute(&printer, str_value);
|
||||
printf("\n");
|
||||
|
||||
struct mie_lex *lex = mie_lex_create(file);
|
||||
struct mie_parser *parse = mie_parser_create(ctx, lex);
|
||||
|
||||
@@ -391,26 +80,44 @@ static int validate_file(const char *path, const b_arglist *args)
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct mie_walker *walker = mie_walker_begin(
|
||||
root, MIE_WALKER_F_INCLUDE_OPS | MIE_WALKER_F_PREORDER
|
||||
| MIE_WALKER_F_FORWARD | MIE_WALKER_F_RECURSIVE);
|
||||
enum mie_walker_flags walk_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, walk_flags);
|
||||
|
||||
do {
|
||||
const struct mie_walker_item *item = mie_walker_get(walker);
|
||||
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);
|
||||
switch (item->i_type) {
|
||||
case MIE_WALK_ITEM_REGION:
|
||||
printf("looking at region %p...\n", item->i_region);
|
||||
continue;
|
||||
case MIE_WALK_ITEM_BLOCK:
|
||||
printf("looking at block %p %s...\n", item->i_block,
|
||||
item->i_block->b_name.n_str);
|
||||
continue;
|
||||
case MIE_WALK_ITEM_OP:
|
||||
|
||||
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);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} while (mie_walker_step(&walker) == MIE_SUCCESS);
|
||||
mie_walker_end(&walker);
|
||||
|
||||
struct mie_pass *prefix_func_with_underscore = NULL;
|
||||
if (mie_ctx_get_pass(
|
||||
enum mie_status status = mie_ctx_get_pass(
|
||||
ctx, "prefix-func-with-underscore", NULL,
|
||||
&prefix_func_with_underscore)
|
||||
!= MIE_SUCCESS) {
|
||||
&prefix_func_with_underscore);
|
||||
if (status != MIE_SUCCESS) {
|
||||
printf("cannot load pass prefix-func-with-underscore\n");
|
||||
return -1;
|
||||
}
|
||||
@@ -424,13 +131,52 @@ static int validate_file(const char *path, const b_arglist *args)
|
||||
|
||||
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");
|
||||
|
||||
struct mie_op *func = mie_op_get_first_child_op(root);
|
||||
walk_flags = MIE_WALKER_F_INCLUDE_OPS | MIE_WALKER_F_PREORDER
|
||||
| MIE_WALKER_F_FORWARD;
|
||||
mie_walker_begin(&walker, func, walk_flags);
|
||||
|
||||
do {
|
||||
const struct mie_walk_item *item = mie_walker_get(&walker);
|
||||
for (size_t i = 0; i < item->i_depth; i++) {
|
||||
fputs(" ", stdout);
|
||||
}
|
||||
|
||||
switch (item->i_type) {
|
||||
case MIE_WALK_ITEM_REGION:
|
||||
printf("looking at region %p...\n", item->i_region);
|
||||
break;
|
||||
case MIE_WALK_ITEM_BLOCK:
|
||||
printf("looking at block %p %s...\n", item->i_block,
|
||||
item->i_block->b_name.n_str);
|
||||
break;
|
||||
case MIE_WALK_ITEM_OP:
|
||||
if (item->i_op->op_flags & MIE_OP_F_OP_RESOLVED) {
|
||||
printf("looking at %p %s.%s...\n", item->i_op,
|
||||
item->i_op->op_dialect->d_name,
|
||||
item->i_op->op_info->op_name);
|
||||
} else {
|
||||
printf("looking at %p %s...\n", item->i_op,
|
||||
item->i_op->op_name);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} while (mie_walker_step(&walker) == MIE_SUCCESS);
|
||||
mie_walker_end(&walker);
|
||||
|
||||
#if 0
|
||||
|
||||
while (1) {
|
||||
|
||||
Reference in New Issue
Block a user