diff --git a/tool/resolve.c b/tool/resolve.c new file mode 100644 index 0000000..f4c759a --- /dev/null +++ b/tool/resolve.c @@ -0,0 +1,130 @@ +#include +#include +#include +#include +#include +#include + +#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; +} diff --git a/tool/resolve.h b/tool/resolve.h new file mode 100644 index 0000000..f8415ac --- /dev/null +++ b/tool/resolve.h @@ -0,0 +1,14 @@ +#ifndef TOOL_RESOLVE_H_ +#define TOOL_RESOLVE_H_ + +#include + +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