/* Return an array of "n" elements with information extracted from * the "n" children of "node" starting at "first", all of which * are known to be filtered leaves. */ struct ppcg_grouping_leaf *extract_leaves(__isl_keep isl_schedule_node *node, int first, int n) { int i; isl_ctx *ctx; struct ppcg_grouping_leaf *leaves; if (!node) return NULL; ctx = isl_schedule_node_get_ctx(node); leaves = isl_calloc_array(ctx, struct ppcg_grouping_leaf, n); if (!leaves) return NULL; for (i = 0; i < n; ++i) { isl_schedule_node *child; isl_union_set *domain; child = isl_schedule_node_get_child(node, first + i); child = isl_schedule_node_child(child, 0); domain = isl_schedule_node_get_domain(child); leaves[i].domain = isl_union_set_copy(domain); leaves[i].list = isl_union_set_list_from_union_set(domain); leaves[i].prefix = get_prefix(child); isl_schedule_node_free(child); } return leaves; }
/* Construct a schedule with "domain" as domain, that executes * the elements of "list" in order (as a sequence). */ static __isl_give isl_schedule *schedule_from_domain_and_list( __isl_keep isl_union_set *domain, __isl_keep isl_union_set_list *list) { isl_schedule *schedule; isl_schedule_node *node; schedule = isl_schedule_from_domain(isl_union_set_copy(domain)); node = isl_schedule_get_root(schedule); isl_schedule_free(schedule); node = isl_schedule_node_child(node, 0); list = isl_union_set_list_copy(list); node = isl_schedule_node_insert_sequence(node, list); schedule = isl_schedule_node_get_schedule(node); isl_schedule_node_free(node); return schedule; }
/* If "node" is a sequence, then check if it has any consecutive * leaves that should be merged together and store the results * in "grouping". * * In particular, call group_subsequence on each consecutive * sequence of (filtered) leaves among the children of "node". */ static isl_bool detect_groups(__isl_keep isl_schedule_node *node, void *user) { int i, n, first; isl_bool has_only_leaves; struct ppcg_grouping *grouping = user; if (isl_schedule_node_get_type(node) != isl_schedule_node_sequence) return isl_bool_true; n = isl_schedule_node_n_children(node); if (n < 0) return isl_bool_error; first = -1; for (i = 0; i < n; ++i) { isl_schedule_node *child; enum isl_schedule_node_type type; child = isl_schedule_node_get_child(node, i); child = isl_schedule_node_child(child, 0); type = isl_schedule_node_get_type(child); isl_schedule_node_free(child); if (first >= 0 && type != isl_schedule_node_leaf) { if (group_subsequence(node, first, i - first, grouping) < 0) return isl_bool_error; first = -1; } if (first < 0 && type == isl_schedule_node_leaf) first = i; } if (first >= 0) { if (group_subsequence(node, first, n - first, grouping) < 0) return isl_bool_error; } return isl_bool_true; }
isl_schedule_node * mark_loop_type_separate(const isl::context & ctx, isl_schedule_node * node) { isl::printer p(ctx); auto type = isl_schedule_node_get_type(node); if (type == isl_schedule_node_band) { int dims = isl_schedule_node_band_n_member(node); for (int d = 0; d < dims; ++d) { node = isl_schedule_node_band_member_set_ast_loop_type (node, d, isl_ast_loop_separate); } } int n_children = isl_schedule_node_n_children(node); for (int c = 0; c < n_children; ++c) { node = isl_schedule_node_child(node, c); node = mark_loop_type_separate(ctx, node); node = isl_schedule_node_parent(node); } return node; }