Files
mie/tool/resolve.c

131 lines
3.3 KiB
C
Raw Normal View History

2026-03-16 12:05:58 +00:00
#include <mie/ctx.h>
#include <mie/ir/op.h>
#include <mie/ir/region.h>
#include <mie/ir/resolve.h>
#include <mie/ir/walk.h>
#include <stdbool.h>
#if 0
static bool resolve_op(struct mie_op *op, struct mie_ctx *ctx)
{
if (mie_op_has_trait(op, "func", "function-like")) {
struct mie_region *region = mie_op_get_first_region(op);
mie_region_refresh_dominance(region);
}
if (!mie_op_resolve_references(op, ctx)) {
return false;
}
return true;
}
#endif
static bool resolve_self_and_successors(struct mie_op *op, struct mie_ctx *ctx)
{
char op_name[128];
enum mie_walker_flags walk_flags
= MIE_WALKER_F_INCLUDE_OPS | MIE_WALKER_F_PREORDER
| MIE_WALKER_F_FORWARD | MIE_WALKER_F_RECURSIVE;
struct mie_walker walker;
mie_walker_begin(&walker, op, walk_flags);
bool result = true;
do {
const struct mie_walk_item *item = mie_walker_get(&walker);
struct mie_op *op = item->i_op;
mie_op_get_name(op, op_name, sizeof op_name);
// printf("resolving op: %p %s... ", item->i_op, op_name);
bool ok = mie_resolve_op_self(op, ctx);
// printf("%s\n", ok ? "OK" : "FAIL");
ok = mie_resolve_op_successors(item->i_op, ctx);
if (!ok) {
result = false;
}
} while (mie_walker_step(&walker) == MIE_SUCCESS);
mie_walker_end(&walker);
return result;
}
static bool resolve_args(struct mie_op *op, struct mie_ctx *ctx)
{
char op_name[128];
enum mie_walker_flags walk_flags
= MIE_WALKER_F_INCLUDE_OPS | MIE_WALKER_F_PREORDER
| MIE_WALKER_F_FORWARD | MIE_WALKER_F_RECURSIVE;
struct mie_walker walker;
mie_walker_begin(&walker, op, walk_flags);
bool result = true;
do {
const struct mie_walk_item *item = mie_walker_get(&walker);
struct mie_op *op = item->i_op;
mie_op_get_name(op, op_name, sizeof op_name);
// printf("resolving args: %p %s... ", item->i_op, op_name);
bool ok = mie_resolve_op_args(op, ctx);
// printf("%s\n", ok ? "OK" : "FAIL");
if (!ok) {
result = false;
}
} while (mie_walker_step(&walker) == MIE_SUCCESS);
mie_walker_end(&walker);
return result;
}
static bool refresh_function_dominance_trees(struct mie_op *op, struct mie_ctx *ctx)
{
char op_name[128];
enum mie_walker_flags walk_flags
= MIE_WALKER_F_INCLUDE_OPS | MIE_WALKER_F_POSTORDER
| MIE_WALKER_F_FORWARD | MIE_WALKER_F_RECURSIVE;
struct mie_walker walker;
mie_walker_begin(&walker, op, walk_flags);
bool result = true;
do {
const struct mie_walk_item *item = mie_walker_get(&walker);
struct mie_op *op = item->i_op;
if (!mie_op_has_trait(op, "func", "function-like")) {
continue;
}
mie_op_get_name(op, op_name, sizeof op_name);
// printf("calculating dom-tree: %p %s...\n", item->i_op, op_name);
struct mie_region *region = mie_op_get_first_region(op);
if (!region) {
/* TODO diagnostic message */
return false;
}
mie_region_refresh_dominance(region);
} while (mie_walker_step(&walker) == MIE_SUCCESS);
mie_walker_end(&walker);
return result;
}
bool resolve_op(struct mie_op *op, struct mie_ctx *ctx)
{
/* first, resolve the op-definitions and block references */
if (!resolve_self_and_successors(op, ctx)) {
return false;
}
/* next, calculation the block dominator tree for all function-like
* ops. */
refresh_function_dominance_trees(op, ctx);
/* next, resolve all op arguments */
if (!resolve_args(op, ctx)) {
return false;
}
return true;
}