From 55161cd6c8d0b2bb185322acf38fd9474ecc212c Mon Sep 17 00:00:00 2001 From: Max Wash Date: Sun, 18 Jan 2026 22:58:17 +0000 Subject: [PATCH] mie: re-implement vectors of blocks and registers using vector move callbacks vector move callbacks allow mie_name instances to be stored in movable memory, as the internal bst pointers can now be fixed during vector resize operations. --- mie/dialect/arith/op/cmpi.c | 2 +- mie/dialect/func/op/func.c | 4 ++-- mie/include/mie/ir/block.h | 4 +++- mie/include/mie/ir/op.h | 2 +- mie/include/mie/ir/region.h | 2 +- mie/include/mie/ir/register.h | 6 ++++++ mie/include/mie/name.h | 18 +++++++++++------ mie/include/mie/parse/parser.h | 2 +- mie/ir/region.c | 11 +--------- mie/ir/register.c | 37 ++++++++++++++++++++++++++++++++++ mie/ir/walk.c | 2 +- mie/name.c | 23 +++++++++++++++++++++ mie/parse/parser.c | 21 ++++++------------- mie/print/block.c | 25 +++++++++++++++++++++-- mie/print/op.c | 4 ++-- mie/print/region.c | 2 +- mie/vector.c | 2 +- 17 files changed, 122 insertions(+), 45 deletions(-) create mode 100644 mie/ir/register.c diff --git a/mie/dialect/arith/op/cmpi.c b/mie/dialect/arith/op/cmpi.c index f6c1c2f..70fcffb 100644 --- a/mie/dialect/arith/op/cmpi.c +++ b/mie/dialect/arith/op/cmpi.c @@ -14,7 +14,7 @@ static enum mie_status print(struct mie_printer *printer, const struct mie_op *o const struct mie_op_arg *left = &op->op_args.items[0]; const struct mie_op_arg *right = &op->op_args.items[1]; - const struct mie_register *result = op->op_result.items[0]; + const struct mie_register *result = &op->op_result.items[0]; const struct mie_attribute *pred_attr = mie_attribute_map_get(&op->op_attrib, "predicate"); long long pred; diff --git a/mie/dialect/func/op/func.c b/mie/dialect/func/op/func.c index 69f46a1..a9c755d 100644 --- a/mie/dialect/func/op/func.c +++ b/mie/dialect/func/op/func.c @@ -27,14 +27,14 @@ static enum mie_status print(struct mie_printer *printer, const struct mie_op *o b_stream_write_fmt(printer->p_stream, NULL, " @%s(", sym_name_cstr); const struct mie_region *code = &op->op_regions.items[0]; - const struct mie_block *entry = code->r_blocks.items[0]; + const struct mie_block *entry = &code->r_blocks.items[0]; for (size_t i = 0; i < MIE_VECTOR_COUNT(entry->b_params); i++) { if (i > 0) { b_stream_write_string(printer->p_stream, ", ", NULL); } - const struct mie_register *param = entry->b_params.items[i]; + const struct mie_register *param = &entry->b_params.items[i]; mie_printer_print_register(printer, param, MIE_PRINT_F_INCLUDE_TYPE); } diff --git a/mie/include/mie/ir/block.h b/mie/include/mie/ir/block.h index 73b23f5..7848503 100644 --- a/mie/include/mie/ir/block.h +++ b/mie/include/mie/ir/block.h @@ -12,10 +12,12 @@ struct mie_register; struct mie_block { struct mie_name b_name; - MIE_VECTOR_DECLARE(struct mie_register *, b_params); + MIE_VECTOR_DECLARE(struct mie_register, b_params); MIE_VECTOR_DECLARE(struct mie_op, b_ops); }; +extern struct mie_vector_ops mie_block_vector_ops; + MIE_API struct mie_op *mie_block_add_op(struct mie_block *block); #endif diff --git a/mie/include/mie/ir/op.h b/mie/include/mie/ir/op.h index 997a43b..af6d66c 100644 --- a/mie/include/mie/ir/op.h +++ b/mie/include/mie/ir/op.h @@ -63,7 +63,7 @@ struct mie_op { MIE_VECTOR_DECLARE(struct mie_op_successor, op_successors); struct mie_attribute_map op_attrib; MIE_VECTOR_DECLARE(struct mie_op_arg, op_args); - MIE_VECTOR_DECLARE(struct mie_register *, op_result); + MIE_VECTOR_DECLARE(struct mie_register, op_result); }; MIE_API struct mie_op *mie_op_create(void); diff --git a/mie/include/mie/ir/region.h b/mie/include/mie/ir/region.h index d190a1b..f8870c8 100644 --- a/mie/include/mie/ir/region.h +++ b/mie/include/mie/ir/region.h @@ -9,7 +9,7 @@ struct mie_block; struct mie_region { struct mie_name_map *r_names; - MIE_VECTOR_DECLARE(struct mie_block *, r_blocks); + MIE_VECTOR_DECLARE(struct mie_block, r_blocks); }; MIE_API struct mie_block *mie_region_add_block(struct mie_region *region); diff --git a/mie/include/mie/ir/register.h b/mie/include/mie/ir/register.h index bf0176b..3c06b3d 100644 --- a/mie/include/mie/ir/register.h +++ b/mie/include/mie/ir/register.h @@ -2,6 +2,7 @@ #define MIE_IR_REGISTER_H_ #include +#include struct mie_target_register; @@ -48,4 +49,9 @@ struct mie_register { struct mie_op *reg_op; }; +extern struct mie_vector_ops mie_register_vector_ops; + +MIE_API void mie_register_move(struct mie_register *dest, struct mie_register *src); +MIE_API void mie_register_cleanup(struct mie_register *reg); + #endif diff --git a/mie/include/mie/name.h b/mie/include/mie/name.h index 370044b..24136e1 100644 --- a/mie/include/mie/name.h +++ b/mie/include/mie/name.h @@ -35,16 +35,26 @@ struct mie_name_map_entry { }; }; +struct mie_name_bucket { + struct mie_name_map_entry b_base; + b_queue b_names; +}; + /* stores a unique name, and forms a binary tree of similar entries. * this struct is designed to be embedded directly within a larger struct * (rather than just as a pointer), allowing the larger struct to be part * of a name map. Because of this, mie_name CANNOT be used in any memory that * may be re-allocated. If a mie_name is moved after it is added to a * mie_name_map, the internal bst pointers that make up the map will be - * invalidated, causing some very obscure memory-related errors. */ + * invalidated, causing some very obscure memory-related errors. + * + * if mie_name IS stored in movable memory, care must be taken to use + * mie_name_move rather than memcpy/memmove to move the mie_name from + * one location to another. */ struct mie_name { struct mie_name_map_entry n_base; struct mie_name_map *n_parent; + struct mie_name_bucket *n_bucket; char *n_str; /* if this name was read from a file, these structs can be used to @@ -52,11 +62,6 @@ struct mie_name { struct mie_file_span n_start, n_end; }; -struct mie_name_bucket { - struct mie_name_map_entry b_base; - b_queue b_names; -}; - struct mie_name_map { const struct mie_name_map *m_parent; b_btree m_entries; @@ -73,6 +78,7 @@ extern struct mie_name *mie_name_map_put( struct mie_name_map *map, struct mie_name *entry, const char *hint, enum mie_name_map_flags flags); +extern void mie_name_move(struct mie_name *dst, struct mie_name *src); extern void mie_name_destroy(struct mie_name *name); #endif diff --git a/mie/include/mie/parse/parser.h b/mie/include/mie/parse/parser.h index 64c06a8..dd22ffd 100644 --- a/mie/include/mie/parse/parser.h +++ b/mie/include/mie/parse/parser.h @@ -102,7 +102,7 @@ MIE_API bool mie_parser_parse_register( struct mie_register *out); MIE_API bool mie_parser_parse_register_list( struct mie_parser *ctx, struct mie_name_map *names, - MIE_VECTOR_REF_PARAM(struct mie_register *, out)); + MIE_VECTOR_REF_PARAM(struct mie_register, out)); MIE_API bool mie_parser_parse_region( struct mie_parser *ctx, struct mie_region *region); diff --git a/mie/ir/region.c b/mie/ir/region.c index 3300240..49d179a 100644 --- a/mie/ir/region.c +++ b/mie/ir/region.c @@ -5,14 +5,5 @@ struct mie_block *mie_region_add_block(struct mie_region *region) { - struct mie_block *block = malloc(sizeof *block); - if (!block) { - return NULL; - } - - memset(block, 0x0, sizeof *block); - - mie_vector_push_back(region->r_blocks, &block, NULL); - - return block; + return mie_vector_emplace_back(region->r_blocks, &mie_block_vector_ops); } diff --git a/mie/ir/register.c b/mie/ir/register.c new file mode 100644 index 0000000..a3158eb --- /dev/null +++ b/mie/ir/register.c @@ -0,0 +1,37 @@ +#include +#include + +static enum mie_status cleanup(void *p) +{ + mie_register_cleanup(p); + return MIE_SUCCESS; +} + +static enum mie_status move(void *dst, void *src, size_t itemsz) +{ + assert(itemsz == sizeof(struct mie_register)); + struct mie_register *dest_reg = dst, *src_reg = src; + mie_register_move(dest_reg, src_reg); + return MIE_SUCCESS; +} + +struct mie_vector_ops mie_register_vector_ops = { + .v_destroy = cleanup, + .v_move = move, +}; + +void mie_register_move(struct mie_register *dest, struct mie_register *src) +{ + memmove(dest, src, sizeof *dest); + + if (src->reg_flags & MIE_REGISTER_F_VIRTUAL) { + mie_name_move(&dest->reg_name, &src->reg_name); + } +} + +void mie_register_cleanup(struct mie_register *reg) +{ + if (reg->reg_flags & MIE_REGISTER_F_VIRTUAL) { + mie_name_destroy(®->reg_name); + } +} diff --git a/mie/ir/walk.c b/mie/ir/walk.c index 637479a..0f07d2b 100644 --- a/mie/ir/walk.c +++ b/mie/ir/walk.c @@ -163,7 +163,7 @@ static enum mie_status schedule_children_of_region( b_queue_entry *tmp = &item->i_entry; for (size_t i = 0; i < MIE_VECTOR_COUNT(region->r_blocks); i++) { - struct mie_block *block = region->r_blocks.items[i]; + struct mie_block *block = ®ion->r_blocks.items[i]; struct walk_schedule_item *child = block_schedule_item_create(block); diff --git a/mie/name.c b/mie/name.c index 58caac5..1f12970 100644 --- a/mie/name.c +++ b/mie/name.c @@ -88,6 +88,7 @@ static b_status put_name_in_bucket( } b_queue_push_back(&bucket->b_names, &name->n_base.e_entry); + name->n_bucket = bucket; return B_SUCCESS; } @@ -125,6 +126,8 @@ static b_status put_name(struct mie_name_map *map, struct mie_name *name) b_queue_push_back(&bucket->b_names, &existing_name->n_base.e_entry); b_queue_push_back(&bucket->b_names, &name->n_base.e_entry); + existing_name->n_bucket = name->n_bucket = bucket; + put_entry(&map->m_entries, &bucket->b_base); return B_SUCCESS; @@ -279,6 +282,26 @@ struct mie_name *mie_name_map_put( return NULL; } +void mie_name_move(struct mie_name *dst, struct mie_name *src) +{ + if (!src->n_parent) { + memmove(dst, src, sizeof *src); + return; + } + + memmove(dst, src, sizeof *src); + + if (src->n_bucket) { + b_queue_move( + &src->n_bucket->b_names, &dst->n_base.e_entry, + &src->n_base.e_entry); + } else { + b_btree_move( + &src->n_parent->m_entries, &dst->n_base.e_node, + &src->n_base.e_node); + } +} + void mie_name_destroy(struct mie_name *name) { struct mie_name_map *parent = name->n_parent; diff --git a/mie/parse/parser.c b/mie/parse/parser.c index e0ec63d..82a8f56 100644 --- a/mie/parse/parser.c +++ b/mie/parse/parser.c @@ -717,7 +717,7 @@ bool mie_parser_parse_register( bool mie_parser_parse_register_list( struct mie_parser *ctx, struct mie_name_map *names, - MIE_VECTOR_REF_PARAM(struct mie_register *, out)) + MIE_VECTOR_REF_PARAM(struct mie_register, out)) { bool ok = false; struct mie_register *reg = NULL; @@ -728,12 +728,7 @@ bool mie_parser_parse_register_list( return false; } - reg = calloc(1, sizeof *reg); - if (!reg) { - return false; - } - - mie_vector_ref_push_back(out, ®, NULL); + reg = mie_vector_ref_emplace_back(out, &mie_register_vector_ops); if (!mie_parser_parse_register(ctx, names, reg)) { return false; @@ -754,11 +749,7 @@ bool mie_parser_parse_register_list( return false; } - reg = calloc(1, sizeof *reg); - if (!reg) { - return false; - } - mie_vector_ref_push_back(out, ®, NULL); + reg = mie_vector_ref_emplace_back(out, &mie_register_vector_ops); if (!mie_parser_parse_register(ctx, names, reg)) { return false; @@ -898,8 +889,8 @@ static bool parse_block_parameters( } for (size_t i = 0; i < MIE_VECTOR_COUNT(block_params); i++) { - struct mie_register *param_reg = calloc(1, sizeof *param_reg); - mie_vector_push_back(block->b_params, ¶m_reg, NULL); + struct mie_register *param_reg = mie_vector_emplace_back( + block->b_params, &mie_register_vector_ops); param_reg->reg_flags = block_params.items[i].arg_unresolved.reg_flags | MIE_REGISTER_F_BLOCK_PARAM; @@ -1162,7 +1153,7 @@ static bool parse_generic_op( } for (size_t i = 0; i < MIE_VECTOR_COUNT(func_type->func_out); i++) { - dest->op_result.items[i]->reg_type = func_type->func_out.items[i]; + dest->op_result.items[i].reg_type = func_type->func_out.items[i]; } return true; diff --git a/mie/print/block.c b/mie/print/block.c index e915ad6..f875748 100644 --- a/mie/print/block.c +++ b/mie/print/block.c @@ -1,8 +1,29 @@ +#include #include #include #include #include +static enum mie_status cleanup(void *p) +{ + return MIE_SUCCESS; +} + +static enum mie_status move(void *dst, void *src, size_t itemsz) +{ + assert(itemsz == sizeof(struct mie_block)); + struct mie_block *dest_block = dst, *src_block = src; + memmove(dest_block, src_block, sizeof *src_block); + mie_name_move(&dest_block->b_name, &src_block->b_name); + + return MIE_SUCCESS; +} + +struct mie_vector_ops mie_block_vector_ops = { + .v_destroy = cleanup, + .v_move = move, +}; + static void print_block_header_params( struct mie_printer *printer, const struct mie_block *block) { @@ -17,11 +38,11 @@ static void print_block_header_params( b_stream_write_string(printer->p_stream, ", ", NULL); } - mie_printer_print_register(printer, block->b_params.items[i], 0); + mie_printer_print_register(printer, &block->b_params.items[i], 0); b_stream_write_string(printer->p_stream, ": ", NULL); - mie_printer_print_type(printer, block->b_params.items[i]->reg_type); + mie_printer_print_type(printer, block->b_params.items[i].reg_type); } b_stream_write_char(printer->p_stream, ')'); diff --git a/mie/print/op.c b/mie/print/op.c index 72c3544..d5fce8b 100644 --- a/mie/print/op.c +++ b/mie/print/op.c @@ -179,7 +179,7 @@ static void print_type_signature( b_stream_write_string(printer->p_stream, ", ", NULL); } - type = op->op_result.items[i]->reg_type; + type = op->op_result.items[i].reg_type; mie_printer_print_type(printer, type); } @@ -225,7 +225,7 @@ void mie_printer_print_op(struct mie_printer *printer, const struct mie_op *op) b_stream_write_string(printer->p_stream, ", ", NULL); } - mie_printer_print_register(printer, op->op_result.items[i], 0); + mie_printer_print_register(printer, &op->op_result.items[i], 0); } if (MIE_VECTOR_COUNT(op->op_result) > 0) { diff --git a/mie/print/region.c b/mie/print/region.c index 8538ad7..08e5916 100644 --- a/mie/print/region.c +++ b/mie/print/region.c @@ -15,7 +15,7 @@ void mie_printer_print_region( block_flags = MIE_PRINT_F_EXCLUDE_BLOCK_HEADER; } - const struct mie_block *block = region->r_blocks.items[i]; + const struct mie_block *block = ®ion->r_blocks.items[i]; mie_printer_print_block(printer, block, block_flags); } diff --git a/mie/vector.c b/mie/vector.c index e9ddd83..601b8cb 100644 --- a/mie/vector.c +++ b/mie/vector.c @@ -209,7 +209,7 @@ void *__mie_vector_emplace_back( void *p = 0; vector_wrap(&v, vector, item_size, count, max); - p = vector_emplace_back(&v, NULL); + p = vector_emplace_back(&v, ops); vector_unwrap(&v, vector, item_size, count, max); return p;