#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; }