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;
|
||||||
|
}
|
||||||
14
tool/resolve.h
Normal file
14
tool/resolve.h
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#ifndef TOOL_RESOLVE_H_
|
||||||
|
#define TOOL_RESOLVE_H_
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
struct mie_op;
|
||||||
|
struct mie_ctx;
|
||||||
|
|
||||||
|
extern bool resolve_op_self(struct mie_op *op, struct mie_ctx *ctx);
|
||||||
|
extern bool resolve_op_successors(struct mie_op *op, struct mie_ctx *ctx);
|
||||||
|
|
||||||
|
extern bool resolve_op(struct mie_op *op, struct mie_ctx *ctx);
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user