tool: add resolution helper functions
This commit is contained in:
130
tool/resolve.c
Normal file
130
tool/resolve.c
Normal file
@@ -0,0 +1,130 @@
|
||||
#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;
|
||||
}
|
||||
Reference in New Issue
Block a user