Example #1
0
/* 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;
}
Example #2
0
/* 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;
}
Example #3
0
/* 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;
}
Example #4
0
ast_isl ast_gen::generate()
{
    auto ctx = m_model.context;

    if (verbose<ast_gen>::enabled())
        print_isl_ast_options(ctx);

    if (true)
    {
        //isl_options_set_ast_build_separation_bounds
                //(ctx.get(), ISL_AST_BUILD_SEPARATION_BOUNDS_IMPLICIT);
        //isl_options_set_ast_build_scale_strides(ctx, 0);
    }

    ast_isl output;

    auto build = isl_ast_build_from_context(m_schedule.params.copy());

    if (m_options.separate_loops)
    {
        if (m_schedule.tree.get())
        {
            auto root = isl_schedule_get_root(m_schedule.prelude_tree.get());
            root = mark_loop_type_separate(ctx, root);
            m_schedule.tree = isl_schedule_node_get_schedule(root);
            isl_schedule_node_free(root);
        }

        if (m_schedule.prelude_tree.get())
        {
            auto root = isl_schedule_get_root(m_schedule.prelude_tree.get());
            root = mark_loop_type_separate(ctx, root);

            m_schedule.prelude_tree = isl_schedule_node_get_schedule(root);

            isl_schedule_node_free(root);
        }

        if (m_schedule.period_tree.get())
        {
            auto root = isl_schedule_get_root(m_schedule.period_tree.get());
            root = mark_loop_type_separate(ctx, root);

            m_schedule.period_tree = isl_schedule_node_get_schedule(root);

            isl_schedule_node_free(root);
        }
    }

    build = isl_ast_build_set_before_each_for(build, &ast_gen::invoke_before_for, this);
    build = isl_ast_build_set_after_each_for(build, &ast_gen::invoke_after_for, this);

    // Initialize parallel accesses to empty map
    m_model.parallel_accesses = isl::union_map(m_model.context);

    if (m_schedule.tree.get())
    {
        if (verbose<ast_gen>::enabled())
            cout << endl << "** Building AST for entire program." << endl;
        m_allow_parallel_for = false;
        output.full =
                isl_ast_build_node_from_schedule(build, m_schedule.tree.copy());
    }
    if (m_schedule.prelude_tree.get())
    {
        if (verbose<ast_gen>::enabled())
            cout << endl << "** Building AST for prelude." << endl;
        m_allow_parallel_for = false;
        output.prelude =
                isl_ast_build_node_from_schedule(build, m_schedule.prelude_tree.copy());
    }
    if (m_schedule.period_tree.get())
    {
        if (verbose<ast_gen>::enabled())
            cout << endl << "** Building AST for period." << endl;

        m_allow_parallel_for = m_options.parallel | m_options.vectorize;

        int num_sched_dim = 0;

        m_schedule.period.for_each([&](const isl::map & m){
            num_sched_dim = m.get_space().dimension(isl::space::output);
            return false;
        });

        build = set_loop_iterators(build, num_sched_dim, m_options.parallel_dim);

        output.period =
                isl_ast_build_node_from_schedule(build, m_schedule.period_tree.copy());
    }

    isl_ast_build_free(build);

    return output;
}