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.
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define MIE_IR_REGISTER_H_
|
||||
|
||||
#include <mie/name.h>
|
||||
#include <mie/vector.h>
|
||||
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
37
mie/ir/register.c
Normal file
37
mie/ir/register.c
Normal file
@@ -0,0 +1,37 @@
|
||||
#include <assert.h>
|
||||
#include <mie/ir/register.h>
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
|
||||
23
mie/name.c
23
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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1,8 +1,29 @@
|
||||
#include <assert.h>
|
||||
#include <mie/ir/block.h>
|
||||
#include <mie/ir/op.h>
|
||||
#include <mie/ir/register.h>
|
||||
#include <mie/print/printer.h>
|
||||
|
||||
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, ')');
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user