diff --git a/mie/include/mie/ir/walk.h b/mie/include/mie/ir/walk.h index 0df3c04..1f83a1a 100644 --- a/mie/include/mie/ir/walk.h +++ b/mie/include/mie/ir/walk.h @@ -1,6 +1,7 @@ #ifndef MIE_IR_WALK_H_ #define MIE_IR_WALK_H_ +#include #include #include #include @@ -26,11 +27,24 @@ enum mie_walker_flags { MIE_WALKER_F_INCLUDE_BLOCKS = 0x20u, }; -struct mie_walker_item { +enum mie_walk_item_type { + MIE_WALK_ITEM_NONE = 0, + MIE_WALK_ITEM_OP, + MIE_WALK_ITEM_BLOCK, + MIE_WALK_ITEM_REGION, +}; + +struct mie_walk_item { + int _f; + b_queue_entry _e; + enum mie_walk_item_type i_type; + size_t i_index; size_t i_depth; - struct mie_op *i_op; - struct mie_block *i_block; - struct mie_region *i_region; + union { + struct mie_op *i_op; + struct mie_block *i_block; + struct mie_region *i_region; + }; }; MIE_API struct mie_walker *mie_walker_begin( @@ -39,6 +53,6 @@ MIE_API void mie_walker_end(struct mie_walker *walker); MIE_API enum mie_status mie_walker_step(struct mie_walker *walker); -MIE_API struct mie_walker_item *mie_walker_get(struct mie_walker *walker); +MIE_API struct mie_walk_item *mie_walker_get(struct mie_walker *walker); #endif diff --git a/mie/ir/walk.c b/mie/ir/walk.c index 0f07d2b..f2cbe25 100644 --- a/mie/ir/walk.c +++ b/mie/ir/walk.c @@ -1,253 +1,595 @@ +#include #include +#include #include #include #include +#include -#define ITEM_TYPE(f) ((f) & 0x0Fu) +#define WALK_ITEM_F_CHILDREN_VISITED 0x01u +#define WALK_ITEM_F_VISITED 0x02u -enum walk_schedule_item_flags { - SCHED_ITEM_F_NONE = 0, - SCHED_ITEM_F_OP = 0x01u, - SCHED_ITEM_F_BLOCK = 0x02u, - SCHED_ITEM_F_REGION = 0x04u, - - SCHED_ITEM_F_VISITED = 0x10u, - SCHED_ITEM_F_CHILDREN_SCHEDULED = 0x20u, -}; - -struct walk_schedule_item { - enum walk_schedule_item_flags i_flags; - b_queue_entry i_entry; - size_t i_depth; - - union { - struct mie_op *i_op; - struct mie_block *i_block; - struct mie_region *i_region; - }; -}; +#define ITEM_TYPE(f) ((f) & 0x0Fu) struct mie_walker { enum mie_walker_flags w_flags; struct mie_op *w_root; - struct mie_walker_item w_cur; - b_queue w_sched; + b_queue w_stack; }; -static struct walk_schedule_item *op_schedule_item_create(struct mie_op *op) -{ - struct walk_schedule_item *out = malloc(sizeof *out); - if (!out) { - return NULL; - } - - memset(out, 0x0, sizeof *out); - - out->i_flags = SCHED_ITEM_F_OP; - out->i_op = op; - - return out; -} - -static struct walk_schedule_item *block_schedule_item_create(struct mie_block *block) -{ - struct walk_schedule_item *out = malloc(sizeof *out); - if (!out) { - return NULL; - } - - memset(out, 0x0, sizeof *out); - - out->i_flags = SCHED_ITEM_F_BLOCK; - out->i_block = block; - - return out; -} - -static struct walk_schedule_item *region_schedule_item_create( - struct mie_region *region) -{ - struct walk_schedule_item *out = malloc(sizeof *out); - if (!out) { - return NULL; - } - - memset(out, 0x0, sizeof *out); - - out->i_flags = SCHED_ITEM_F_REGION; - out->i_region = region; - - return out; -} - static bool should_ignore_item( - const struct mie_walker *walker, const struct walk_schedule_item *item) + const struct mie_walker *walker, const struct mie_walk_item *item) { - switch (ITEM_TYPE(item->i_flags)) { - case SCHED_ITEM_F_OP: + switch (item->i_type) { + case MIE_WALK_ITEM_OP: return (walker->w_flags & MIE_WALKER_F_INCLUDE_OPS) == 0; - case SCHED_ITEM_F_BLOCK: + case MIE_WALK_ITEM_BLOCK: return (walker->w_flags & MIE_WALKER_F_INCLUDE_BLOCKS) == 0; - case SCHED_ITEM_F_REGION: + case MIE_WALK_ITEM_REGION: return (walker->w_flags & MIE_WALKER_F_INCLUDE_REGIONS) == 0; default: return true; } } -static void schedule_child( - struct mie_walker *walker, struct walk_schedule_item *parent, - struct walk_schedule_item *child, b_queue_entry **ep) +static void push_walk_item( + struct mie_walker *walker, const struct mie_walk_item *item) { -#define REVERSE 0x04u - - enum { - PREORDER = 0x01u, - PREORDER_REVERSE = PREORDER | REVERSE, - POSTORDER = 0x02u, - POSTORDER_REVERSE = POSTORDER | REVERSE, - } mode; - - if (walker->w_flags & MIE_WALKER_F_POSTORDER) { - mode = POSTORDER; - } else { - mode = PREORDER; - } - - if (walker->w_flags & MIE_WALKER_F_BACKWARD) { - mode |= REVERSE; - } - - child->i_depth = parent->i_depth; - if (!should_ignore_item(walker, child)) { - child->i_depth++; - } - - switch (mode) { - case PREORDER: - b_queue_insert_after(&walker->w_sched, &child->i_entry, *ep); - *ep = &child->i_entry; - break; - case PREORDER_REVERSE: - b_queue_insert_after( - &walker->w_sched, &child->i_entry, &parent->i_entry); - *ep = &parent->i_entry; - break; - case POSTORDER: - if (*ep == &parent->i_entry) { - b_queue_insert_before( - &walker->w_sched, &child->i_entry, *ep); - } else { - b_queue_insert_after( - &walker->w_sched, &child->i_entry, *ep); - } - - *ep = &child->i_entry; - break; - case POSTORDER_REVERSE: - b_queue_insert_before(&walker->w_sched, &child->i_entry, *ep); - *ep = &child->i_entry; - break; - default: + struct mie_walk_item *i = malloc(sizeof *i); + if (!i) { return; } -#undef REVERSE + memcpy(i, item, sizeof *i); + b_queue_push_back(&walker->w_stack, &i->_e); } -static enum mie_status schedule_children_of_region( - struct mie_walker *walker, struct walk_schedule_item *item) +static void pop_walk_item(struct mie_walker *walker) { - struct mie_region *region = item->i_region; - - b_queue_entry *tmp = &item->i_entry; - - for (size_t i = 0; i < MIE_VECTOR_COUNT(region->r_blocks); i++) { - struct mie_block *block = ®ion->r_blocks.items[i]; - struct walk_schedule_item *child - = block_schedule_item_create(block); - - schedule_child(walker, item, child, &tmp); + b_queue_entry *entry = b_queue_pop_back(&walker->w_stack); + if (entry) { + struct mie_walk_item *item + = b_unbox(struct mie_walk_item, entry, _e); + free(item); } - - return MIE_SUCCESS; } -static enum mie_status schedule_children_of_block( - struct mie_walker *walker, struct walk_schedule_item *item) +static struct mie_walk_item *current_item(struct mie_walker *walker) { - struct mie_block *block = item->i_block; - - b_queue_entry *tmp = &item->i_entry; - - for (size_t i = 0; i < MIE_VECTOR_COUNT(block->b_ops); i++) { - struct mie_op *op = &block->b_ops.items[i]; - struct walk_schedule_item *child = op_schedule_item_create(op); - - schedule_child(walker, item, child, &tmp); + b_queue_entry *entry = b_queue_last(&walker->w_stack); + if (!entry) { + return NULL; } - return MIE_SUCCESS; + struct mie_walk_item *item = b_unbox(struct mie_walk_item, entry, _e); + return item->i_type != MIE_WALK_ITEM_NONE ? item : NULL; } -static enum mie_status schedule_children_of_op( - struct mie_walker *walker, struct walk_schedule_item *item) +static struct mie_op *get_first_child(struct mie_walker *walker, struct mie_op *op) { - struct mie_op *op = item->i_op; + bool backwards = (walker->w_flags & MIE_WALKER_F_BACKWARD) != 0; - b_queue_entry *tmp = &item->i_entry; + while (1) { + if (MIE_VECTOR_COUNT(op->op_regions) == 0) { + break; + } - for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_regions); i++) { - struct mie_region *region = &op->op_regions.items[i]; - struct walk_schedule_item *child - = region_schedule_item_create(region); + size_t region_index + = backwards ? MIE_VECTOR_COUNT(op->op_regions) - 1 : 0; + struct mie_region *region = &op->op_regions.items[region_index]; + if (MIE_VECTOR_COUNT(region->r_blocks) == 0) { + break; + } - schedule_child(walker, item, child, &tmp); + size_t block_index + = backwards ? MIE_VECTOR_COUNT(region->r_blocks) - 1 : 0; + struct mie_block *block = ®ion->r_blocks.items[block_index]; + if (MIE_VECTOR_COUNT(block->b_ops) == 0) { + break; + } + + size_t op_index + = backwards ? MIE_VECTOR_COUNT(block->b_ops) - 1 : 0; + op = &block->b_ops.items[op_index]; } - return MIE_SUCCESS; + return op; } -static enum mie_status schedule_children( - struct mie_walker *walker, struct walk_schedule_item *item) +static size_t walk_item_get_nr_children(const struct mie_walk_item *item) { - if (item->i_flags & SCHED_ITEM_F_CHILDREN_SCHEDULED) { - return MIE_SUCCESS; + switch (item->i_type) { + case MIE_WALK_ITEM_OP: + return MIE_VECTOR_COUNT(item->i_op->op_regions); + case MIE_WALK_ITEM_BLOCK: + return MIE_VECTOR_COUNT(item->i_block->b_ops); + case MIE_WALK_ITEM_REGION: + return MIE_VECTOR_COUNT(item->i_region->r_blocks); + default: + return 0; + } +} + +static bool should_correct_depth( + struct mie_walker *walker, const struct mie_walk_item *item) +{ + if (should_ignore_item(walker, item)) { + return true; } - enum mie_status status; - - switch (ITEM_TYPE(item->i_flags)) { - case SCHED_ITEM_F_BLOCK: - status = schedule_children_of_block(walker, item); + size_t temp = 0; + switch (item->i_type) { + case MIE_WALK_ITEM_BLOCK: + return false; //(walker->w_flags & MIE_WALKER_F_INCLUDE_OPS) == 0; + default: break; - case SCHED_ITEM_F_REGION: - status = schedule_children_of_region(walker, item); + } + + return false; +} + +static bool walk_item_get_child( + struct mie_walker *walker, const struct mie_walk_item *item, + size_t index, struct mie_walk_item *child) +{ + bool ok = false; + + switch (item->i_type) { + case MIE_WALK_ITEM_OP: + if (MIE_VECTOR_COUNT(item->i_op->op_regions) <= index) { + ok = false; + break; + } + + child->i_type = MIE_WALK_ITEM_REGION; + child->i_region = &item->i_op->op_regions.items[index]; + ok = true; break; - case SCHED_ITEM_F_OP: - status = schedule_children_of_op(walker, item); + case MIE_WALK_ITEM_BLOCK: + if (MIE_VECTOR_COUNT(item->i_block->b_ops) <= index) { + ok = false; + break; + } + + child->i_type = MIE_WALK_ITEM_OP; + child->i_op = &item->i_block->b_ops.items[index]; + ok = true; + break; + case MIE_WALK_ITEM_REGION: + if (MIE_VECTOR_COUNT(item->i_region->r_blocks) <= index) { + ok = false; + break; + } + + child->i_type = MIE_WALK_ITEM_BLOCK; + child->i_block = &item->i_region->r_blocks.items[index]; + ok = true; break; default: - status = MIE_ERR_BAD_STATE; break; } - item->i_flags |= SCHED_ITEM_F_CHILDREN_SCHEDULED; + if (!ok) { + return false; + } + + child->i_depth = item->i_depth + 1; + child->i_index = index; + + if (should_correct_depth(walker, item)) { + child->i_depth--; + } + + return true; +} + +static bool walk_item_get_next_sibling( + const struct mie_walk_item *item, struct mie_walk_item *sibling) +{ + if (item->i_depth == 0) { + return false; + } + + sibling->i_depth = item->i_depth; + sibling->i_type = item->i_type; + sibling->i_index = item->i_index + 1; + + struct mie_region *parent_r = NULL; + struct mie_block *parent_b = NULL; + struct mie_op *parent_o = NULL; + + switch (item->i_type) { + case MIE_WALK_ITEM_OP: + parent_b = item->i_op->op_container; + if (!parent_b) { + return false; + } + + if (item->i_index + 1 >= MIE_VECTOR_COUNT(parent_b->b_ops)) { + return false; + } + + sibling->i_op = &parent_b->b_ops.items[item->i_index + 1]; + return true; + case MIE_WALK_ITEM_BLOCK: + parent_r = item->i_block->b_parent; + if (!parent_r) { + return false; + } + + if (item->i_index + 1 >= MIE_VECTOR_COUNT(parent_r->r_blocks)) { + return false; + } + + sibling->i_block = &parent_r->r_blocks.items[item->i_index + 1]; + return true; + case MIE_WALK_ITEM_REGION: + parent_o = item->i_region->r_parent; + if (!parent_o) { + return false; + } + + if (item->i_index + 1 >= MIE_VECTOR_COUNT(parent_o->op_regions)) { + return false; + } + + sibling->i_region = &parent_o->op_regions.items[item->i_index + 1]; + return true; + default: + return false; + } +} + +static bool walk_item_get_prev_sibling( + const struct mie_walk_item *item, struct mie_walk_item *sibling) +{ + if (item->i_depth == 0 || item->i_index == 0) { + return false; + } + + sibling->i_depth = item->i_depth; + sibling->i_type = item->i_type; + sibling->i_index = item->i_index - 1; + + struct mie_region *parent_r = NULL; + struct mie_block *parent_b = NULL; + struct mie_op *parent_o = NULL; + + switch (item->i_type) { + case MIE_WALK_ITEM_OP: + parent_b = item->i_op->op_container; + if (!parent_b) { + return false; + } + + sibling->i_op = &parent_b->b_ops.items[item->i_index - 1]; + return true; + case MIE_WALK_ITEM_BLOCK: + parent_r = item->i_block->b_parent; + if (!parent_r) { + return false; + } + + sibling->i_block = &parent_r->r_blocks.items[item->i_index - 1]; + return true; + case MIE_WALK_ITEM_REGION: + parent_o = item->i_region->r_parent; + if (!parent_o) { + return false; + } + + sibling->i_region = &parent_o->op_regions.items[item->i_index - 1]; + return true; + default: + return false; + } +} + +static void print_stack(struct mie_walker *walker) +{ + b_queue_entry *entry = b_queue_last(&walker->w_stack); + + while (entry) { + struct mie_walk_item *item + = b_unbox(struct mie_walk_item, entry, _e); + + switch (item->i_type) { + case MIE_WALK_ITEM_OP: + printf("* %zu: op %p", item->i_depth, item->i_op); + if (item->i_op->op_flags & MIE_OP_F_OP_RESOLVED) { + printf(" %s.%s", item->i_op->op_dialect->d_name, + item->i_op->op_info->op_name); + } else { + printf(" %s", item->i_op->op_name); + } + break; + case MIE_WALK_ITEM_BLOCK: + printf("* %zu: block %p %s", item->i_depth, + item->i_block, item->i_block->b_name.n_str); + break; + case MIE_WALK_ITEM_REGION: + printf("* %zu: region %p", item->i_depth, item->i_region); + break; + default: + printf(" unknown"); + break; + } + + printf("\n"); + + entry = b_queue_prev(entry); + } +} + +static bool step_pre_f(struct mie_walker *walker) +{ + /* forward, pre-order traversal: + * if this item has children, we need to visit the first one. + * if this item has no children, we need to visit the next sibling. + * if this is the last sibling, step up until we find an item that + * has a next sibling. + * if no item is found, we are done. */ + + struct mie_walk_item *item = current_item(walker); + struct mie_walk_item next; + + bool ok = false; + size_t nr_children = walk_item_get_nr_children(item); + if (nr_children > 0) { + ok = walk_item_get_child(walker, item, 0, &next); + + if (ok) { + push_walk_item(walker, &next); + } + + return ok; + } + + if (walk_item_get_next_sibling(item, &next)) { + pop_walk_item(walker); + push_walk_item(walker, &next); + return true; + } + + static int i = 0; + while (1) { + pop_walk_item(walker); + struct mie_walk_item *parent = current_item(walker); + if (!parent) { + return false; + } + + ok = walk_item_get_next_sibling(parent, &next); + + if (ok) { + pop_walk_item(walker); + push_walk_item(walker, &next); + break; + } + } + + return ok; +} + +static bool step_pre_b(struct mie_walker *walker) +{ + /* backward, pre-order traversal: + * if this item has children, we need to visit the last one. + * if this item has no children, we need to visit the previous sibling. + * if this is the first sibling, step up until we find an item that + * has a previous sibling. + * if no item is found, we are done. */ + + struct mie_walk_item *item = current_item(walker); + struct mie_walk_item next; + + bool ok = false; + size_t nr_children = walk_item_get_nr_children(item); + if (nr_children > 0) { + ok = walk_item_get_child(walker, item, nr_children - 1, &next); + + if (ok) { + push_walk_item(walker, &next); + } + + return ok; + } + + if (walk_item_get_prev_sibling(item, &next)) { + pop_walk_item(walker); + push_walk_item(walker, &next); + return true; + } + + static int i = 0; + while (1) { + pop_walk_item(walker); + struct mie_walk_item *parent = current_item(walker); + if (!parent) { + return false; + } + + ok = walk_item_get_prev_sibling(parent, &next); + + if (ok) { + pop_walk_item(walker); + push_walk_item(walker, &next); + break; + } + } + + return ok; +} + +static bool step_post_f(struct mie_walker *walker) +{ + /* forward, post-order traversal: + * if this item has children: + * if they have already been visited, visit the item itself + * if they haven't been visited yet, visit the first one. + * if this item has a next sibling, move to the sibling and goto step 1. + * if this item is the last child, we need to visit the parent next. */ + struct mie_walk_item *item = current_item(walker); + item->_f |= WALK_ITEM_F_VISITED; + + struct mie_walk_item next; + bool ok = false; + + while (1) { + item = current_item(walker); + size_t nr_children = walk_item_get_nr_children(item); + + if (nr_children > 0 && !(item->_f & WALK_ITEM_F_CHILDREN_VISITED)) { + ok = walk_item_get_child(walker, item, 0, &next); + + if (ok) { + push_walk_item(walker, &next); + } + + return ok; + } + + if (nr_children == 0 && !(item->_f & WALK_ITEM_F_VISITED)) { + return true; + } + + if (walk_item_get_next_sibling(item, &next)) { + pop_walk_item(walker); + push_walk_item(walker, &next); + continue; + } + + pop_walk_item(walker); + struct mie_walk_item *parent = current_item(walker); + if (parent) { + parent->_f |= WALK_ITEM_F_CHILDREN_VISITED; + } + + return parent != NULL; + } +} + +static bool step_post_b(struct mie_walker *walker) +{ + /* backward, post-order traversal: + * if this item has children: + * if they have already been visited, visit the item itself + * if they haven't been visited yet, visit the last one. + * if this item has a previous sibling, move to the sibling and goto step 1. + * if this item is the first child, we need to visit the parent next. */ + struct mie_walk_item *item = current_item(walker); + item->_f |= WALK_ITEM_F_VISITED; + + struct mie_walk_item next; + bool ok = false; + + while (1) { + item = current_item(walker); + size_t nr_children = walk_item_get_nr_children(item); + + if (nr_children > 0 && !(item->_f & WALK_ITEM_F_CHILDREN_VISITED)) { + ok = walk_item_get_child( + walker, item, nr_children - 1, &next); + + if (ok) { + push_walk_item(walker, &next); + } + + return ok; + } + + if (nr_children == 0 && !(item->_f & WALK_ITEM_F_VISITED)) { + return true; + } + + if (walk_item_get_prev_sibling(item, &next)) { + pop_walk_item(walker); + push_walk_item(walker, &next); + continue; + } + + pop_walk_item(walker); + struct mie_walk_item *parent = current_item(walker); + if (parent) { + parent->_f |= WALK_ITEM_F_CHILDREN_VISITED; + } + + return parent != NULL; + } +} + +static bool step(struct mie_walker *walker) +{ + bool backward = (walker->w_flags & MIE_WALKER_F_BACKWARD) != 0; + bool postorder = (walker->w_flags & MIE_WALKER_F_POSTORDER) != 0; + + if (backward) { + if (postorder) { + return step_post_b(walker); + } + + return step_pre_b(walker); + } + + if (postorder) { + return step_post_f(walker); + } + + return step_pre_f(walker); +} + +static enum mie_status prepare_preorder_traversal(struct mie_walker *walker) +{ + struct mie_walk_item *item = malloc(sizeof *item); + if (!item) { + return MIE_ERR_NO_MEMORY; + } + + memset(item, 0x0, sizeof *item); + item->i_op = walker->w_root; + item->i_type = MIE_WALK_ITEM_OP; + + push_walk_item(walker, item); + return MIE_SUCCESS; } static enum mie_status prepare_postorder_traversal(struct mie_walker *walker) { - b_queue_entry *cur = b_queue_last(&walker->w_sched); - while (cur) { - struct walk_schedule_item *item - = b_unbox(struct walk_schedule_item, cur, i_entry); - schedule_children(walker, item); + struct mie_walk_item item = {}; + item.i_op = walker->w_root; + item.i_type = MIE_WALK_ITEM_OP; - cur = b_queue_prev(cur); + push_walk_item(walker, &item); + + bool backward = walker->w_flags & MIE_WALKER_F_BACKWARD; + bool ok = false; + + while (1) { + struct mie_walk_item *current = current_item(walker); + struct mie_walk_item child; + size_t nr_children = walk_item_get_nr_children(current); + if (!nr_children) { + break; + } + + bool ok = false; + + if (backward) { + ok = walk_item_get_child( + walker, current, nr_children - 1, &child); + } else { + ok = walk_item_get_child(walker, current, 0, &child); + } + + if (!ok) { + break; + } + + push_walk_item(walker, &child); } - return MIE_SUCCESS; + return ok ? MIE_SUCCESS : MIE_ERR_NO_DATA; } struct mie_walker *mie_walker_begin(struct mie_op *op, enum mie_walker_flags flags) @@ -262,11 +604,15 @@ struct mie_walker *mie_walker_begin(struct mie_op *op, enum mie_walker_flags fla out->w_flags = flags; out->w_root = op; - struct walk_schedule_item *item = op_schedule_item_create(op); - b_queue_push_back(&out->w_sched, &item->i_entry); - if (flags & MIE_WALKER_F_POSTORDER) { prepare_postorder_traversal(out); + } else { + prepare_preorder_traversal(out); + } + + struct mie_walk_item *cur = current_item(out); + if (should_ignore_item(out, cur)) { + mie_walker_step(out); } return out; @@ -274,74 +620,23 @@ struct mie_walker *mie_walker_begin(struct mie_op *op, enum mie_walker_flags fla void mie_walker_end(struct mie_walker *walker) { -} - -static struct walk_schedule_item *current_item(struct mie_walker *walker) -{ - b_queue_entry *top = b_queue_first(&walker->w_sched); - if (!top) { - return NULL; - } - - return b_unbox(struct walk_schedule_item, top, i_entry); -} - -static enum mie_status step(struct mie_walker *walker) -{ - struct walk_schedule_item *cur = current_item(walker); - if (!cur) { - return MIE_ERR_NO_DATA; - } - - if (walker->w_flags & MIE_WALKER_F_RECURSIVE || cur->i_depth == 0) { - schedule_children(walker, cur); - } - - b_queue_delete(&walker->w_sched, &cur->i_entry); - free(cur); - - if (!current_item(walker)) { - return MIE_ERR_NO_DATA; - } - - return MIE_SUCCESS; + /* TODO */ } enum mie_status mie_walker_step(struct mie_walker *walker) { - struct walk_schedule_item *cur = current_item(walker); + struct mie_walk_item *cur = current_item(walker); + bool ok = false; + do { - step(walker); + ok = step(walker); cur = current_item(walker); } while (cur && should_ignore_item(walker, cur)); return cur ? MIE_SUCCESS : MIE_ERR_NO_DATA; } -struct mie_walker_item *mie_walker_get(struct mie_walker *walker) +struct mie_walk_item *mie_walker_get(struct mie_walker *walker) { - struct walk_schedule_item *cur = current_item(walker); - if (!cur) { - return NULL; - } - - memset(&walker->w_cur, 0x0, sizeof walker->w_cur); - - walker->w_cur.i_depth = cur->i_depth; - - switch (ITEM_TYPE(cur->i_flags)) { - case SCHED_ITEM_F_OP: - walker->w_cur.i_op = cur->i_op; - break; - case SCHED_ITEM_F_BLOCK: - walker->w_cur.i_block = cur->i_block; - break; - case SCHED_ITEM_F_REGION: - walker->w_cur.i_region = cur->i_region; - break; - default: - return NULL; - } - - return &walker->w_cur; + return current_item(walker); }