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.
This commit is contained in:
2026-01-25 14:56:47 +00:00
parent bf8c966c03
commit e8534f8d70
10 changed files with 318 additions and 44 deletions

View File

@@ -12,14 +12,26 @@ struct mie_register;
struct mie_block { struct mie_block {
struct mie_name b_name; struct mie_name b_name;
struct mie_region *b_parent; 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_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; 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(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); MIE_API struct mie_register *mie_block_add_param(struct mie_block *block);
#endif #endif

View File

@@ -50,6 +50,8 @@ struct mie_op_successor {
struct mie_op { struct mie_op {
enum mie_op_flags op_flags; 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 */ /* these pointers are only valid if the F_OP_RESOLVED flag is set */
const struct mie_dialect *op_dialect; const struct mie_dialect *op_dialect;
@@ -60,7 +62,8 @@ struct mie_op {
/* only valid if the F_RESOLVED flag is NOT set */ /* only valid if the F_RESOLVED flag is NOT set */
char *op_name; char *op_name;
MIE_VECTOR_DECLARE(struct mie_region, op_regions); b_queue op_regions;
MIE_VECTOR_DECLARE(struct mie_op_successor, op_successors); MIE_VECTOR_DECLARE(struct mie_op_successor, op_successors);
struct mie_attribute_map op_attrib; struct mie_attribute_map op_attrib;
MIE_VECTOR_DECLARE(struct mie_op_arg, op_args); 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( MIE_API bool mie_op_has_interface(
const struct mie_op *op, const char *dialect_name, const char *iface_name); 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); MIE_API const struct mie_type *mie_op_arg_get_type(const struct mie_op_arg *arg);
#endif #endif

View File

@@ -1,6 +1,7 @@
#ifndef MIE_IR_REGION_H_ #ifndef MIE_IR_REGION_H_
#define MIE_IR_REGION_H_ #define MIE_IR_REGION_H_
#include <blue/core/queue.h>
#include <mie/misc.h> #include <mie/misc.h>
#include <mie/vector.h> #include <mie/vector.h>
#include <stddef.h> #include <stddef.h>
@@ -11,9 +12,22 @@ struct mie_block;
struct mie_region { struct mie_region {
struct mie_name_map *r_names; struct mie_name_map *r_names;
struct mie_op *r_parent; 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(struct mie_region *region);
MIE_API struct mie_block *mie_region_add_block_after(
struct mie_region *region, struct mie_block *after);
#endif #endif

View File

@@ -2,9 +2,59 @@
#include <mie/ir/op.h> #include <mie/ir/op.h>
#include <mie/ir/register.h> #include <mie/ir/register.h>
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 *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) { if (!op) {
return NULL; return NULL;
} }
@@ -12,6 +62,31 @@ struct mie_op *mie_block_add_op(struct mie_block *block)
mie_op_init(op); mie_op_init(op);
op->op_container = block; 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; return op;
} }

View File

@@ -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) 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); 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); 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( void mie_builder_step_into_region(
struct mie_builder *builder, struct mie_region *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); block = mie_region_add_block(region);
} else {
block = &region->r_blocks.items[MIE_VECTOR_COUNT(region->r_blocks) - 1];
} }
mie_builder_step_into_block(builder, block); mie_builder_step_into_block(builder, block);
@@ -134,28 +130,6 @@ void mie_builder_step_out(struct mie_builder *builder)
free(scope); 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 = &region->r_blocks.items[MIE_VECTOR_COUNT(region->r_blocks)];
}
return block;
}
struct mie_op *mie_builder_put_op( struct mie_op *mie_builder_put_op(
struct mie_builder *builder, const char *dialect, const char *op_name, struct mie_builder *builder, const char *dialect, const char *op_name,
struct mie_register **args, size_t nr_args) struct mie_register **args, size_t nr_args)

View File

@@ -1,4 +1,6 @@
#include <assert.h> #include <assert.h>
#include <mie/dialect/dialect.h>
#include <mie/ir/block.h>
#include <mie/ir/op-definition.h> #include <mie/ir/op-definition.h>
#include <mie/ir/op.h> #include <mie/ir/op.h>
#include <mie/ir/region.h> #include <mie/ir/region.h>
@@ -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_flags = MIE_REGISTER_F_VIRTUAL | MIE_REGISTER_F_OP_RESULT;
result->reg_type = ty; result->reg_type = ty;
result->reg_op = op; result->reg_op = op;
result->reg_block = op->op_container;
return result; return result;
} }
@@ -131,3 +134,97 @@ bool mie_op_has_interface(
&op->op_info->op_iface, dialect_name, iface_name); &op->op_info->op_iface, dialect_name, iface_name);
return p != NULL; 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);
}

View File

@@ -3,16 +3,89 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
struct mie_block *mie_region_get_first_block(const struct mie_region *region)
{
b_queue_entry *entry = b_queue_first(&region->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(&region->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 *mie_region_add_block(struct mie_region *region)
{ {
struct mie_block *block = mie_vector_emplace_back( struct mie_block *block = malloc(sizeof *block);
region->r_blocks, &mie_block_vector_ops);
if (!block) { if (!block) {
return NULL; return NULL;
} }
memset(block, 0x0, sizeof *block);
block->b_parent = region; block->b_parent = region;
b_queue_push_back(&region->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(&region->r_blocks, &block->b_entry, &after->b_entry);
return block; return block;
} }

View File

@@ -51,7 +51,8 @@ static void print_block_header_params(
static void print_block_header( static void print_block_header(
struct mie_printer *printer, const struct mie_block *block) 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; return;
} }
@@ -76,10 +77,11 @@ void mie_printer_print_block(
b_stream_push_indent(printer->p_stream, 4); b_stream_push_indent(printer->p_stream, 4);
for (size_t i = 0; i < MIE_VECTOR_COUNT(block->b_ops); i++) { struct mie_op *op = mie_block_get_first_op(block);
const struct mie_op *op = &block->b_ops.items[i]; while (op) {
mie_printer_print_op(printer, op); mie_printer_print_op(printer, op);
b_stream_write_char(printer->p_stream, '\n'); b_stream_write_char(printer->p_stream, '\n');
op = mie_block_get_next_op(block, op);
} }
b_stream_pop_indent(printer->p_stream); b_stream_pop_indent(printer->p_stream);

View File

@@ -96,18 +96,24 @@ static void print_successor_list(
static void print_region_list(struct mie_printer *printer, const struct mie_op *op) 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; return;
} }
b_stream_write_string(printer->p_stream, " (", NULL); 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) { if (i > 0) {
b_stream_write_string(printer->p_stream, ", ", NULL); 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); b_stream_write_string(printer->p_stream, ")", NULL);

View File

@@ -8,15 +8,20 @@ void mie_printer_print_region(
{ {
b_stream_write_string(printer->p_stream, "{\n", NULL); 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; enum mie_print_flags block_flags = 0;
if ((flags & MIE_PRINT_F_EXCLUDE_FIRST_BLOCK_HEADER) && (i == 0)) { if ((flags & MIE_PRINT_F_EXCLUDE_FIRST_BLOCK_HEADER) && (i == 0)) {
block_flags = MIE_PRINT_F_EXCLUDE_BLOCK_HEADER; block_flags = MIE_PRINT_F_EXCLUDE_BLOCK_HEADER;
} }
const struct mie_block *block = &region->r_blocks.items[i];
mie_printer_print_block(printer, block, block_flags); 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); b_stream_write_string(printer->p_stream, "}", NULL);