From 008966e04672b2d0aa9cbb6d2d0a31d56ca3d6b9 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Wed, 21 Jan 2026 14:40:22 +0000 Subject: [PATCH] mie: ir: add ir builder interface --- mie/include/mie/ir/builder.h | 38 ++++++++ mie/ir/builder.c | 171 +++++++++++++++++++++++++++++++++++ 2 files changed, 209 insertions(+) create mode 100644 mie/include/mie/ir/builder.h create mode 100644 mie/ir/builder.c diff --git a/mie/include/mie/ir/builder.h b/mie/include/mie/ir/builder.h new file mode 100644 index 0000000..a7df61c --- /dev/null +++ b/mie/include/mie/ir/builder.h @@ -0,0 +1,38 @@ +#ifndef MIE_IR_BUILDER_H_ +#define MIE_IR_BUILDER_H_ + +#include +#include + +struct mie_op; +struct mie_ctx; +struct mie_type; +struct mie_name; +struct mie_block; +struct mie_region; +struct mie_register; + +struct mie_builder; + +MIE_API struct mie_builder *mie_builder_create( + struct mie_ctx *ctx, struct mie_op *root); +MIE_API void mie_builder_destroy(struct mie_builder *builder); + +MIE_API struct mie_ctx *mie_builder_get_ctx(struct mie_builder *builder); +MIE_API struct mie_block *mie_builder_get_current_block(struct mie_builder *builder); + +MIE_API void mie_builder_step_into_op( + struct mie_builder *builder, struct mie_op *op); +MIE_API void mie_builder_step_into_region( + struct mie_builder *builder, struct mie_region *region); +MIE_API void mie_builder_step_into_block( + struct mie_builder *builder, struct mie_block *block); +MIE_API void mie_builder_step_out(struct mie_builder *builder); + +MIE_API struct mie_op *mie_builder_put_op( + struct mie_builder *, const char *dialect, const char *op, + struct mie_register **args, size_t nr_args); +MIE_API enum mie_status mie_builder_put_name( + struct mie_builder *, struct mie_name *name, const char *hint); + +#endif diff --git a/mie/ir/builder.c b/mie/ir/builder.c new file mode 100644 index 0000000..9d911bb --- /dev/null +++ b/mie/ir/builder.c @@ -0,0 +1,171 @@ +#include +#include +#include +#include +#include +#include + +struct builder_scope { + b_queue_entry s_entry; + struct mie_op *s_op; + struct mie_region *s_region; + struct mie_block *s_block; +}; + +struct mie_builder { + struct mie_ctx *b_ctx; + b_queue b_scope_stack; + struct mie_op *b_root; + struct mie_op *b_prev_op; +}; + +struct mie_builder *mie_builder_create(struct mie_ctx *ctx, struct mie_op *root) +{ + struct mie_builder *out = malloc(sizeof *out); + if (!out) { + return NULL; + } + + memset(out, 0x0, sizeof *out); + + out->b_ctx = ctx; + out->b_root = root; + + mie_builder_step_into_op(out, root); + + return out; +} + +struct mie_ctx *mie_builder_get_ctx(struct mie_builder *builder) +{ + return builder->b_ctx; +} + +struct mie_block *mie_builder_get_current_block(struct mie_builder *builder) +{ + b_queue_entry *entry = b_queue_last(&builder->b_scope_stack); + if (!entry) { + return NULL; + } + + struct builder_scope *scope + = b_unbox(struct builder_scope, entry, s_entry); + + return scope->s_block; +} + +void mie_builder_step_into_op(struct mie_builder *builder, struct mie_op *op) +{ + struct mie_region *region = NULL; + + if (MIE_VECTOR_COUNT(op->op_regions) == 0) { + region = mie_op_add_region(op); + } else { + region = &op->op_regions.items[MIE_VECTOR_COUNT(op->op_regions) - 1]; + } + + mie_builder_step_into_region(builder, region); +} + +void mie_builder_step_into_region( + struct mie_builder *builder, struct mie_region *region) +{ + struct mie_block *block = NULL; + + if (MIE_VECTOR_COUNT(region->r_blocks) == 0) { + block = mie_region_add_block(region); + } else { + block = ®ion->r_blocks.items[MIE_VECTOR_COUNT(region->r_blocks) - 1]; + } + + mie_builder_step_into_block(builder, block); +} + +void mie_builder_step_into_block(struct mie_builder *builder, struct mie_block *block) +{ + struct builder_scope *scope = malloc(sizeof *scope); + if (!scope) { + return; + } + + memset(scope, 0x0, sizeof *scope); + + scope->s_block = block; + scope->s_region = block->b_parent; + scope->s_op = scope->s_region->r_parent; + + b_queue_push_back(&builder->b_scope_stack, &scope->s_entry); +} + +void mie_builder_step_out(struct mie_builder *builder) +{ + b_queue_entry *entry = b_queue_last(&builder->b_scope_stack); + if (!entry) { + return; + } + + struct builder_scope *scope + = b_unbox(struct builder_scope, entry, s_entry); + b_queue_delete(&builder->b_scope_stack, entry); + free(scope); +} + +static struct mie_block *create_current_block(struct mie_builder *builder) +{ + struct mie_region *region = NULL; + + if (MIE_VECTOR_COUNT(builder->b_root->op_regions) == 0) { + region = mie_op_add_region(builder->b_root); + } else { + region = &builder->b_root->op_regions + .items[MIE_VECTOR_COUNT(builder->b_root->op_result) - 1]; + } + + struct mie_block *block = NULL; + + if (MIE_VECTOR_COUNT(region->r_blocks) == 0) { + block = mie_region_add_block(region); + } else { + block = ®ion->r_blocks.items[MIE_VECTOR_COUNT(region->r_blocks)]; + } + + return block; +} + +struct mie_op *mie_builder_put_op( + struct mie_builder *builder, const char *dialect, const char *op_name, + struct mie_register **args, size_t nr_args) +{ + struct mie_block *block = mie_builder_get_current_block(builder); + + const struct mie_op_definition *op_def + = mie_ctx_get_op_definition(builder->b_ctx, dialect, op_name); + if (!op_def) { + return NULL; + } + + struct mie_op *op = mie_block_add_op(block); + op->op_flags = MIE_OP_F_OP_RESOLVED; + op->op_info = op_def; + op->op_dialect = op_def->op_parent; + + for (size_t i = 0; i < nr_args; i++) { + struct mie_op_arg *arg = mie_op_add_arg(op); + arg->arg_flags = MIE_OP_F_ARG_RESOLVED; + arg->arg_value.u_reg = args[i]; + arg->arg_value.u_user = op; + b_queue_push_back(&args[i]->reg_use, &arg->arg_value.u_entry); + } + + return op; +} + +enum mie_status mie_builder_put_name( + struct mie_builder *builder, struct mie_name *name, const char *hint) +{ + struct mie_block *block = mie_builder_get_current_block(builder); + struct mie_region *scope = block->b_parent; + return mie_name_map_put(scope->r_names, name, hint, 0) + ? MIE_SUCCESS + : MIE_ERR_NAME_EXISTS; +}