ir: add some manipulation functions
This commit is contained in:
@@ -15,6 +15,7 @@ struct mie_op;
|
||||
struct mie_printer;
|
||||
struct mie_parser;
|
||||
struct mie_dialect;
|
||||
struct mie_parser_scope;
|
||||
|
||||
#if 0
|
||||
enum mie_op_trait {
|
||||
@@ -103,7 +104,8 @@ struct mie_op_definition {
|
||||
const struct mie_op_result op_results[MIE_OP_MAX_RESULTS];
|
||||
|
||||
enum mie_status (*op_print)(struct mie_printer *, const struct mie_op *);
|
||||
enum mie_status (*op_parse)(struct mie_parser *, struct mie_op *);
|
||||
enum mie_status (*op_parse)(
|
||||
struct mie_parser *, struct mie_parser_scope *, struct mie_op *);
|
||||
};
|
||||
|
||||
MIE_API struct mie_op_definition *mie_op_definition_create(
|
||||
|
||||
@@ -79,10 +79,6 @@ MIE_API void mie_op_cleanup(struct mie_op *op);
|
||||
|
||||
MIE_API size_t mie_op_get_name(const struct mie_op *op, char *out, size_t max);
|
||||
|
||||
MIE_API bool mie_op_resolve_self(struct mie_op *op, struct mie_ctx *ctx);
|
||||
MIE_API bool mie_op_resolve_args(struct mie_op *op, struct mie_ctx *ctx);
|
||||
MIE_API bool mie_op_resolve_successors(struct mie_op *op, struct mie_ctx *ctx);
|
||||
|
||||
MIE_API struct mie_op_arg *mie_op_add_arg(struct mie_op *op);
|
||||
MIE_API struct mie_register *mie_op_add_result(
|
||||
struct mie_op *op, const struct mie_type *ty);
|
||||
@@ -110,6 +106,11 @@ MIE_API struct mie_register *mie_op_get_arg(const struct mie_op *op, size_t inde
|
||||
MIE_API struct mie_register *mie_op_get_result_with_name(
|
||||
const struct mie_op *op, const char *name);
|
||||
|
||||
MIE_API void mie_op_get_args_span(
|
||||
const struct mie_op *op, struct mie_file_span *result);
|
||||
MIE_API void mie_op_get_results_span(
|
||||
const struct mie_op *op, struct mie_file_span *result);
|
||||
|
||||
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);
|
||||
|
||||
|
||||
@@ -32,6 +32,8 @@ MIE_API struct mie_block *mie_region_get_next_block(
|
||||
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_before(
|
||||
struct mie_region *region, struct mie_block *before);
|
||||
MIE_API struct mie_block *mie_region_add_block_after(
|
||||
struct mie_region *region, struct mie_block *after);
|
||||
MIE_API struct mie_block *mie_region_find_block(
|
||||
|
||||
32
mie/ir/op.c
32
mie/ir/op.c
@@ -276,6 +276,38 @@ struct mie_register *mie_op_get_result_with_name(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void mie_op_get_args_span(const struct mie_op *op, struct mie_file_span *result)
|
||||
{
|
||||
memset(result, 0x0, sizeof *result);
|
||||
|
||||
size_t nr = MIE_VECTOR_COUNT(op->op_args);
|
||||
if (!nr) {
|
||||
return;
|
||||
}
|
||||
|
||||
const struct mie_op_arg *first = &op->op_args.items[0];
|
||||
const struct mie_op_arg *last = &op->op_args.items[nr - 1];
|
||||
|
||||
result->s_start = first->arg_span.s_start;
|
||||
result->s_end = last->arg_span.s_end;
|
||||
}
|
||||
|
||||
void mie_op_get_results_span(const struct mie_op *op, struct mie_file_span *result)
|
||||
{
|
||||
memset(result, 0x0, sizeof *result);
|
||||
|
||||
size_t nr = MIE_VECTOR_COUNT(op->op_result);
|
||||
if (!nr) {
|
||||
return;
|
||||
}
|
||||
|
||||
const struct mie_register *first = &op->op_result.items[0];
|
||||
const struct mie_register *last = &op->op_result.items[nr - 1];
|
||||
|
||||
result->s_start = first->reg_span.s_start;
|
||||
result->s_end = last->reg_span.s_end;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
@@ -75,6 +75,27 @@ struct mie_block *mie_region_add_block(struct mie_region *region)
|
||||
return block;
|
||||
}
|
||||
|
||||
struct mie_block *mie_region_add_block_before(
|
||||
struct mie_region *region, struct mie_block *before)
|
||||
{
|
||||
if (before->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_before(®ion->r_blocks, &block->b_entry, &before->b_entry);
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
struct mie_block *mie_region_add_block_after(
|
||||
struct mie_region *region, struct mie_block *after)
|
||||
{
|
||||
@@ -102,7 +123,8 @@ struct mie_block *mie_region_find_block(
|
||||
b_queue_entry *cur = b_queue_first(®ion->r_blocks);
|
||||
while (cur) {
|
||||
struct mie_block *block = b_unbox(struct mie_block, cur, b_entry);
|
||||
if (!strcmp(block->b_name.n_str, name)) {
|
||||
const char *block_name = block->b_name.n_str;
|
||||
if (block_name && !strcmp(block_name, name)) {
|
||||
return block;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ enum register_find_result {
|
||||
REG_FIND_ISOLATED,
|
||||
};
|
||||
|
||||
bool mie_op_resolve_self(struct mie_op *op, struct mie_ctx *ctx)
|
||||
bool mie_resolve_op_self(struct mie_op *op, struct mie_ctx *ctx)
|
||||
{
|
||||
if (op->op_flags & MIE_OP_F_OP_RESOLVED) {
|
||||
return true;
|
||||
@@ -101,6 +101,7 @@ static bool resolve_arg(
|
||||
struct mie_block *block = op->op_container;
|
||||
struct mie_op *search_start = op;
|
||||
struct mie_register *reg = NULL;
|
||||
bool cfg = (block->b_idom != NULL);
|
||||
|
||||
while (block) {
|
||||
reg = mie_block_find_register(block, arg_name, search_start);
|
||||
@@ -126,6 +127,18 @@ static bool resolve_arg(
|
||||
enum register_find_result find_result
|
||||
= find_register_wide(op, arg_name, ®);
|
||||
|
||||
if (!cfg && REG_FIND_UNDOMINATED) {
|
||||
/* this isn't a cfg (yet), so ignore dominance-relaced resolution issues */
|
||||
free(arg->arg_unresolved.reg_name);
|
||||
arg->arg_flags |= MIE_OP_F_ARG_RESOLVED;
|
||||
|
||||
memset(&arg->arg_value, 0x0, sizeof arg->arg_value);
|
||||
arg->arg_value.u_reg = reg;
|
||||
arg->arg_value.u_user = op;
|
||||
b_queue_push_back(®->reg_use, &arg->arg_value.u_entry);
|
||||
return true;
|
||||
}
|
||||
|
||||
struct mie_diag *diag = mie_ctx_push_diag(
|
||||
ctx, op->op_src, &arg->arg_span.s_start, "builtin",
|
||||
MIE_BUILTIN_E_UNRESOLVED_VALUE);
|
||||
@@ -228,7 +241,7 @@ static bool resolve_successor(
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mie_op_resolve_args(struct mie_op *op, struct mie_ctx *ctx)
|
||||
bool mie_resolve_op_args(struct mie_op *op, struct mie_ctx *ctx)
|
||||
{
|
||||
bool ok = true;
|
||||
|
||||
@@ -250,7 +263,7 @@ bool mie_op_resolve_args(struct mie_op *op, struct mie_ctx *ctx)
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool mie_op_resolve_successors(struct mie_op *op, struct mie_ctx *ctx)
|
||||
bool mie_resolve_op_successors(struct mie_op *op, struct mie_ctx *ctx)
|
||||
{
|
||||
bool ok = true;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user