From e8534f8d70fec3006f60c4124a70c031a9f22fec Mon Sep 17 00:00:00 2001 From: Max Wash Date: Sun, 25 Jan 2026 14:56:47 +0000 Subject: [PATCH] mie: ir: Op->Region, Region->Block, and Block->Op lists are now b_queues rather than mie_vectors this change has two key benefits: 1. we no longer need to allocate large contigious buffers for Regions with lots of Blocks, or Blocks with lots of Ops. 2. this simplifies re-arranging, inserting, and moving parts of the IR structure. --- mie/include/mie/ir/block.h | 14 +++++- mie/include/mie/ir/op.h | 18 ++++++- mie/include/mie/ir/region.h | 16 +++++- mie/ir/block.c | 77 ++++++++++++++++++++++++++++- mie/ir/builder.c | 34 ++----------- mie/ir/op.c | 97 +++++++++++++++++++++++++++++++++++++ mie/ir/region.c | 77 ++++++++++++++++++++++++++++- mie/print/block.c | 8 +-- mie/print/op.c | 12 +++-- mie/print/region.c | 9 +++- 10 files changed, 318 insertions(+), 44 deletions(-) diff --git a/mie/include/mie/ir/block.h b/mie/include/mie/ir/block.h index ec8630f..18f1943 100644 --- a/mie/include/mie/ir/block.h +++ b/mie/include/mie/ir/block.h @@ -12,14 +12,26 @@ struct mie_register; struct mie_block { struct mie_name b_name; struct mie_region *b_parent; + /* used by struct mie_region */ + b_queue_entry b_entry; MIE_VECTOR_DECLARE(struct mie_register, b_params); - MIE_VECTOR_DECLARE(struct mie_op, b_ops); + /* queue of struct mie_op */ + b_queue b_ops; }; extern struct mie_vector_ops mie_block_vector_ops; +MIE_API struct mie_op *mie_block_get_first_op(const struct mie_block *block); +MIE_API struct mie_op *mie_block_get_prev_op( + const struct mie_block *block, const struct mie_op *before); +MIE_API struct mie_op *mie_block_get_next_op( + const struct mie_block *block, const struct mie_op *after); +MIE_API struct mie_op *mie_block_get_last_op(const struct mie_block *block); + MIE_API struct mie_op *mie_block_add_op(struct mie_block *block); +MIE_API struct mie_op *mie_block_add_op_after( + struct mie_block *block, struct mie_op *after); MIE_API struct mie_register *mie_block_add_param(struct mie_block *block); #endif diff --git a/mie/include/mie/ir/op.h b/mie/include/mie/ir/op.h index acc7dd1..127fa6f 100644 --- a/mie/include/mie/ir/op.h +++ b/mie/include/mie/ir/op.h @@ -50,6 +50,8 @@ struct mie_op_successor { struct mie_op { enum mie_op_flags op_flags; + /* used by struct mie_block */ + b_queue_entry op_entry; /* these pointers are only valid if the F_OP_RESOLVED flag is set */ const struct mie_dialect *op_dialect; @@ -60,7 +62,8 @@ struct mie_op { /* only valid if the F_RESOLVED flag is NOT set */ char *op_name; - MIE_VECTOR_DECLARE(struct mie_region, op_regions); + b_queue op_regions; + MIE_VECTOR_DECLARE(struct mie_op_successor, op_successors); struct mie_attribute_map op_attrib; MIE_VECTOR_DECLARE(struct mie_op_arg, op_args); @@ -83,6 +86,19 @@ MIE_API bool mie_op_has_trait( MIE_API bool mie_op_has_interface( const struct mie_op *op, const char *dialect_name, const char *iface_name); +MIE_API struct mie_op *mie_op_get_parent(const struct mie_op *op); +MIE_API struct mie_region *mie_op_get_first_region(const struct mie_op *op); +MIE_API struct mie_region *mie_op_get_prev_region( + const struct mie_op *op, const struct mie_region *before); +MIE_API struct mie_region *mie_op_get_next_region( + const struct mie_op *op, const struct mie_region *after); +MIE_API struct mie_region *mie_op_get_last_region(const struct mie_op *op); + +MIE_API struct mie_register *mie_op_get_arg(const struct mie_op *op, size_t index); + +MIE_API struct mie_op *mie_op_get_first_child_op(const struct mie_op *op); +MIE_API struct mie_op *mie_op_get_last_child_op(const struct mie_op *op); + MIE_API const struct mie_type *mie_op_arg_get_type(const struct mie_op_arg *arg); #endif diff --git a/mie/include/mie/ir/region.h b/mie/include/mie/ir/region.h index a295010..dabc140 100644 --- a/mie/include/mie/ir/region.h +++ b/mie/include/mie/ir/region.h @@ -1,6 +1,7 @@ #ifndef MIE_IR_REGION_H_ #define MIE_IR_REGION_H_ +#include #include #include #include @@ -11,9 +12,22 @@ struct mie_block; struct mie_region { struct mie_name_map *r_names; struct mie_op *r_parent; - MIE_VECTOR_DECLARE(struct mie_block, r_blocks); + /* used by struct mie_op */ + b_queue_entry r_entry; + /* queue of struct mie_block */ + b_queue r_blocks; }; +MIE_API struct mie_block *mie_region_get_first_block( + const struct mie_region *region); +MIE_API struct mie_block *mie_region_get_prev_block( + const struct mie_region *region, const struct mie_block *before); +MIE_API struct mie_block *mie_region_get_next_block( + const struct mie_region *region, const struct mie_block *after); +MIE_API struct mie_block *mie_region_get_last_block(const struct mie_region *region); + MIE_API struct mie_block *mie_region_add_block(struct mie_region *region); +MIE_API struct mie_block *mie_region_add_block_after( + struct mie_region *region, struct mie_block *after); #endif diff --git a/mie/ir/block.c b/mie/ir/block.c index 9416da4..e8d8ee5 100644 --- a/mie/ir/block.c +++ b/mie/ir/block.c @@ -2,9 +2,59 @@ #include #include +struct mie_op *mie_block_get_first_op(const struct mie_block *block) +{ + b_queue_entry *entry = b_queue_first(&block->b_ops); + if (!entry) { + return NULL; + } + + return b_unbox(struct mie_op, entry, op_entry); +} + +struct mie_op *mie_block_get_prev_op( + const struct mie_block *block, const struct mie_op *before) +{ + if (!before || before->op_container != block) { + return NULL; + } + + b_queue_entry *entry = b_queue_prev(&before->op_entry); + if (!entry) { + return NULL; + } + + return b_unbox(struct mie_op, entry, op_entry); +} + +struct mie_op *mie_block_get_next_op( + const struct mie_block *block, const struct mie_op *after) +{ + if (!after || after->op_container != block) { + return NULL; + } + + b_queue_entry *entry = b_queue_next(&after->op_entry); + if (!entry) { + return NULL; + } + + return b_unbox(struct mie_op, entry, op_entry); +} + +struct mie_op *mie_block_get_last_op(const struct mie_block *block) +{ + b_queue_entry *entry = b_queue_last(&block->b_ops); + if (!entry) { + return NULL; + } + + return b_unbox(struct mie_op, entry, op_entry); +} + struct mie_op *mie_block_add_op(struct mie_block *block) { - struct mie_op *op = mie_vector_emplace_back(block->b_ops, NULL); + struct mie_op *op = malloc(sizeof *op); if (!op) { return NULL; } @@ -12,6 +62,31 @@ struct mie_op *mie_block_add_op(struct mie_block *block) mie_op_init(op); op->op_container = block; + b_queue_push_back(&block->b_ops, &op->op_entry); + + return op; +} + +struct mie_op *mie_block_add_op_after(struct mie_block *block, struct mie_op *after) +{ + if (after && after->op_container != block) { + return NULL; + } + + struct mie_op *op = malloc(sizeof *op); + if (!op) { + return NULL; + } + + mie_op_init(op); + op->op_container = block; + + if (after) { + b_queue_insert_after(&block->b_ops, &op->op_entry, &after->op_entry); + } else { + b_queue_push_back(&block->b_ops, &op->op_entry); + } + return op; } diff --git a/mie/ir/builder.c b/mie/ir/builder.c index 84183d4..9dde8a7 100644 --- a/mie/ir/builder.c +++ b/mie/ir/builder.c @@ -80,12 +80,10 @@ struct mie_block *mie_builder_get_current_block(struct mie_builder *builder) void mie_builder_step_into_op(struct mie_builder *builder, struct mie_op *op) { - struct mie_region *region = NULL; + struct mie_region *region = mie_op_get_last_region(op); - if (MIE_VECTOR_COUNT(op->op_regions) == 0) { + if (!region) { 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); @@ -94,12 +92,10 @@ void mie_builder_step_into_op(struct mie_builder *builder, struct mie_op *op) void mie_builder_step_into_region( struct mie_builder *builder, struct mie_region *region) { - struct mie_block *block = NULL; + struct mie_block *block = mie_region_get_last_block(region); - if (MIE_VECTOR_COUNT(region->r_blocks) == 0) { + if (!block) { 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); @@ -134,28 +130,6 @@ void mie_builder_step_out(struct mie_builder *builder) 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) diff --git a/mie/ir/op.c b/mie/ir/op.c index 9b13117..ca1a90c 100644 --- a/mie/ir/op.c +++ b/mie/ir/op.c @@ -1,4 +1,6 @@ #include +#include +#include #include #include #include @@ -76,6 +78,7 @@ struct mie_register *mie_op_add_result(struct mie_op *op, const struct mie_type result->reg_flags = MIE_REGISTER_F_VIRTUAL | MIE_REGISTER_F_OP_RESULT; result->reg_type = ty; result->reg_op = op; + result->reg_block = op->op_container; return result; } @@ -131,3 +134,97 @@ bool mie_op_has_interface( &op->op_info->op_iface, dialect_name, iface_name); return p != NULL; } + +struct mie_region *mie_op_get_first_region(const struct mie_op *op) +{ + b_queue_entry *entry = b_queue_first(&op->op_regions); + if (!entry) { + return NULL; + } + + return b_unbox(struct mie_region, entry, r_entry); +} + +struct mie_region *mie_op_get_prev_region( + const struct mie_op *op, const struct mie_region *before) +{ + if (!before || before->r_parent != op) { + return NULL; + } + + b_queue_entry *entry = b_queue_prev(&before->r_entry); + if (!entry) { + return NULL; + } + + return b_unbox(struct mie_region, entry, r_entry); +} + +struct mie_region *mie_op_get_next_region( + const struct mie_op *op, const struct mie_region *after) +{ + if (!after || after->r_parent != op) { + return NULL; + } + + b_queue_entry *entry = b_queue_next(&after->r_entry); + if (!entry) { + return NULL; + } + + return b_unbox(struct mie_region, entry, r_entry); +} + +struct mie_region *mie_op_get_last_region(const struct mie_op *op) +{ + b_queue_entry *entry = b_queue_last(&op->op_regions); + if (!entry) { + return NULL; + } + + return b_unbox(struct mie_region, entry, r_entry); +} + +struct mie_register *mie_op_get_arg(const struct mie_op *op, size_t index) +{ + if (MIE_VECTOR_COUNT(op->op_args) <= index) { + return NULL; + } + + const struct mie_op_arg *arg = &op->op_args.items[index]; + if (!(arg->arg_flags & MIE_OP_F_ARG_RESOLVED)) { + return NULL; + } + + return arg->arg_value.u_reg; +} + +struct mie_op *mie_op_get_first_child_op(const struct mie_op *op) +{ + struct mie_region *first_region = mie_op_get_first_region(op); + if (!first_region) { + return NULL; + } + + struct mie_block *first_block = mie_region_get_first_block(first_region); + if (!first_block) { + return NULL; + } + + return mie_block_get_first_op(first_block); +} + +struct mie_op *mie_op_get_last_child_op(const struct mie_op *op) +{ + struct mie_region *last_region = mie_op_get_last_region(op); + if (!last_region) { + return NULL; + } + + struct mie_block *last_block = mie_region_get_last_block(last_region); + if (!last_block) { + return NULL; + } + + return mie_block_get_last_op(last_block); +} diff --git a/mie/ir/region.c b/mie/ir/region.c index 7627376..b34e214 100644 --- a/mie/ir/region.c +++ b/mie/ir/region.c @@ -3,16 +3,89 @@ #include #include +struct mie_block *mie_region_get_first_block(const struct mie_region *region) +{ + b_queue_entry *entry = b_queue_first(®ion->r_blocks); + if (!entry) { + return NULL; + } + + return b_unbox(struct mie_block, entry, b_entry); +} + +struct mie_block *mie_region_get_prev_block( + const struct mie_region *region, const struct mie_block *before) +{ + if (!before || before->b_parent != region) { + return NULL; + } + + b_queue_entry *entry = b_queue_prev(&before->b_entry); + if (!entry) { + return NULL; + } + + return b_unbox(struct mie_block, entry, b_entry); +} + +struct mie_block *mie_region_get_next_block( + const struct mie_region *region, const struct mie_block *after) +{ + if (!after || after->b_parent != region) { + return NULL; + } + + b_queue_entry *entry = b_queue_next(&after->b_entry); + if (!entry) { + return NULL; + } + + return b_unbox(struct mie_block, entry, b_entry); +} + +struct mie_block *mie_region_get_last_block(const struct mie_region *region) +{ + b_queue_entry *entry = b_queue_last(®ion->r_blocks); + if (!entry) { + return NULL; + } + + return b_unbox(struct mie_block, entry, b_entry); +} + struct mie_block *mie_region_add_block(struct mie_region *region) { - struct mie_block *block = mie_vector_emplace_back( - region->r_blocks, &mie_block_vector_ops); + struct mie_block *block = malloc(sizeof *block); if (!block) { return NULL; } + memset(block, 0x0, sizeof *block); block->b_parent = region; + b_queue_push_back(®ion->r_blocks, &block->b_entry); + + return block; +} + +struct mie_block *mie_region_add_block_after( + struct mie_region *region, struct mie_block *after) +{ + if (after->b_parent != region) { + return NULL; + } + + struct mie_block *block = malloc(sizeof *block); + + if (!block) { + return NULL; + } + + memset(block, 0x0, sizeof *block); + block->b_parent = region; + + b_queue_insert_after(®ion->r_blocks, &block->b_entry, &after->b_entry); + return block; } diff --git a/mie/print/block.c b/mie/print/block.c index f875748..152ded9 100644 --- a/mie/print/block.c +++ b/mie/print/block.c @@ -51,7 +51,8 @@ static void print_block_header_params( static void print_block_header( struct mie_printer *printer, const struct mie_block *block) { - if (!block->b_name.n_str && !MIE_VECTOR_COUNT(block->b_params)) { + bool first_block = b_queue_prev(&block->b_entry) == NULL; + if (first_block && !block->b_name.n_str) { return; } @@ -76,10 +77,11 @@ void mie_printer_print_block( b_stream_push_indent(printer->p_stream, 4); - for (size_t i = 0; i < MIE_VECTOR_COUNT(block->b_ops); i++) { - const struct mie_op *op = &block->b_ops.items[i]; + struct mie_op *op = mie_block_get_first_op(block); + while (op) { mie_printer_print_op(printer, op); b_stream_write_char(printer->p_stream, '\n'); + op = mie_block_get_next_op(block, op); } b_stream_pop_indent(printer->p_stream); diff --git a/mie/print/op.c b/mie/print/op.c index 19fd66e..1162590 100644 --- a/mie/print/op.c +++ b/mie/print/op.c @@ -96,18 +96,24 @@ static void print_successor_list( static void print_region_list(struct mie_printer *printer, const struct mie_op *op) { - if (!MIE_VECTOR_COUNT(op->op_regions)) { + if (b_queue_empty(&op->op_regions)) { return; } b_stream_write_string(printer->p_stream, " (", NULL); - for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_regions); i++) { + struct mie_region *region = mie_op_get_first_region(op); + size_t i = 0; + + while (region) { if (i > 0) { b_stream_write_string(printer->p_stream, ", ", NULL); } - mie_printer_print_region(printer, &op->op_regions.items[i], 0); + mie_printer_print_region(printer, region, 0); + + region = mie_op_get_next_region(op, region); + i++; } b_stream_write_string(printer->p_stream, ")", NULL); diff --git a/mie/print/region.c b/mie/print/region.c index 08e5916..5d73e41 100644 --- a/mie/print/region.c +++ b/mie/print/region.c @@ -8,15 +8,20 @@ void mie_printer_print_region( { b_stream_write_string(printer->p_stream, "{\n", NULL); - for (size_t i = 0; i < MIE_VECTOR_COUNT(region->r_blocks); i++) { + struct mie_block *block = mie_region_get_first_block(region); + size_t i = 0; + + while (block) { enum mie_print_flags block_flags = 0; if ((flags & MIE_PRINT_F_EXCLUDE_FIRST_BLOCK_HEADER) && (i == 0)) { block_flags = MIE_PRINT_F_EXCLUDE_BLOCK_HEADER; } - const struct mie_block *block = ®ion->r_blocks.items[i]; mie_printer_print_block(printer, block, block_flags); + + block = mie_region_get_next_block(region, block); + i++; } b_stream_write_string(printer->p_stream, "}", NULL);