Exemplo n.º 1
0
isl_ast_build * ast_gen::set_loop_iterators(isl_ast_build * ast, int count, int parallel_loop)
{
    auto ctx = isl_ast_build_get_ctx(ast);

    isl_id_list * ids = isl_id_list_alloc(ctx, count);

    for(int i = 0; i < count; ++i)
    {
        auto name = string("c") + to_string(i);

        if (verbose<ast_gen>::enabled())
            cout << "Adding iterator: " << name << endl;

        void * data = nullptr;
        if (i == parallel_loop)
        {
            if (verbose<ast_gen>::enabled())
                cout << "(parallel)" << endl;
            data = &m_parallel_loop_id;
        }

        auto id = isl_id_alloc(ctx, name.c_str(), data);

        ids = isl_id_list_add(ids, id);
    }

    ast = isl_ast_build_set_iterators(ast, ids);

    return ast;
}
Exemplo n.º 2
0
/* Insert an if node around "node" testing the condition encoded
 * in guard "guard".
 *
 * If the user does not want any disjunctions in the if conditions
 * and if "guard" does involve a disjunction, then we make the different
 * disjuncts disjoint and insert an if node corresponding to each disjunct
 * around a copy of "node".  The result is then a block node containing
 * this sequence of guarded copies of "node".
 */
static __isl_give isl_ast_node *ast_node_insert_if(
	__isl_take isl_ast_node *node, __isl_take isl_set *guard,
	__isl_keep isl_ast_build *build)
{
	struct isl_insert_if_data data;
	isl_ctx *ctx;

	ctx = isl_ast_build_get_ctx(build);
	if (isl_options_get_ast_build_allow_or(ctx) ||
	    isl_set_n_basic_set(guard) <= 1) {
		isl_ast_node *if_node;
		isl_ast_expr *expr;

		expr = isl_ast_build_expr_from_set_internal(build, guard);

		if_node = isl_ast_node_alloc_if(expr);
		return isl_ast_node_if_set_then(if_node, node);
	}

	guard = isl_set_make_disjoint(guard);

	data.list = isl_ast_node_list_alloc(ctx, 0);
	data.node = node;
	data.build = build;
	if (isl_set_foreach_basic_set(guard, &insert_if, &data) < 0)
		data.list = isl_ast_node_list_free(data.list);

	isl_set_free(guard);
	isl_ast_node_free(data.node);
	return isl_ast_node_alloc_block(data.list);
}
Exemplo n.º 3
0
/* Extract a common guard from the grafts in "list" that can be hoisted
 * out of the current level.  If no such guard can be found, then return
 * a universal set.
 *
 * If all the grafts in the list have the same guard and if this guard
 * is independent of the current level, then it can be hoisted out.
 * If there is only one graft in the list and if its guard
 * depends on the current level, then we eliminate this level and
 * return the result.
 *
 * Otherwise, we return the unshifted simple hull of the guards.
 * In order to be able to hoist as many constraints as possible,
 * but at the same time avoid hoisting constraints that did not
 * appear in the guards in the first place, we intersect the guards
 * with all the information that is available (i.e., the domain
 * from the build and the enforced constraints of the graft) and
 * compute the unshifted hull of the result using only constraints
 * from the original guards.
 * In particular, intersecting the guards with other known information
 * allows us to hoist guards that are only explicit is some of
 * the grafts and implicit in the others.
 *
 * The special case for equal guards is needed in case those guards
 * are non-convex.  Taking the simple hull would remove information
 * and would not allow for these guards to be hoisted completely.
 */
__isl_give isl_set *isl_ast_graft_list_extract_hoistable_guard(
	__isl_keep isl_ast_graft_list *list, __isl_keep isl_ast_build *build)
{
	int i, n;
	int equal;
	isl_ctx *ctx;
	isl_set *guard;
	isl_set_list *set_list;
	isl_basic_set *hull;

	if (!list || !build)
		return NULL;

	n = isl_ast_graft_list_n_ast_graft(list);
	if (n == 0)
		return isl_set_universe(isl_ast_build_get_space(build, 1));

	equal = equal_independent_guards(list, build);
	if (equal < 0)
		return NULL;

	if (equal || n == 1) {
		isl_ast_graft *graft_0;

		graft_0 = isl_ast_graft_list_get_ast_graft(list, 0);
		if (!graft_0)
			return NULL;
		guard = isl_set_copy(graft_0->guard);
		if (!equal)
			guard = hoist_guard(guard, build);
		isl_ast_graft_free(graft_0);
		return guard;
	}

	ctx = isl_ast_build_get_ctx(build);
	set_list = isl_set_list_alloc(ctx, n);
	guard = isl_set_empty(isl_ast_build_get_space(build, 1));
	for (i = 0; i < n; ++i) {
		isl_ast_graft *graft;
		isl_basic_set *enforced;
		isl_set *guard_i;

		graft = isl_ast_graft_list_get_ast_graft(list, i);
		enforced = isl_ast_graft_get_enforced(graft);
		guard_i = isl_set_copy(graft->guard);
		isl_ast_graft_free(graft);
		set_list = isl_set_list_add(set_list, isl_set_copy(guard_i));
		guard_i = isl_set_intersect(guard_i,
					    isl_set_from_basic_set(enforced));
		guard_i = isl_set_intersect(guard_i,
					    isl_ast_build_get_domain(build));
		guard = isl_set_union(guard, guard_i);
	}
	hull = isl_set_unshifted_simple_hull_from_set_list(guard, set_list);
	guard = isl_set_from_basic_set(hull);
	return hoist_guard(guard, build);
}
Exemplo n.º 4
0
/* For each graft in "list",
 * insert an if node around graft->node testing the condition encoded
 * in graft->guard, assuming graft->guard involves any conditions.
 *
 * We keep track of a list of generated if nodes that can be extended
 * without changing the order of the elements in "list".
 * If the guard of a graft is a subset of either the guard or its complement
 * of one of those if nodes, then the node
 * of the new graft is inserted into the then or else branch of the last graft
 * and the current graft is discarded.
 * The guard of the node is then simplified based on the conditions
 * enforced at that then or else branch.
 * Otherwise, the current graft is appended to the list.
 *
 * We only construct else branches if allowed by the user.
 */
static __isl_give isl_ast_graft_list *insert_pending_guard_nodes(
	__isl_take isl_ast_graft_list *list,
	__isl_keep isl_ast_build *build)
{
	int i, j, n, n_if;
	int allow_else;
	isl_ctx *ctx;
	isl_ast_graft_list *res;
	struct isl_if_node *if_node = NULL;

	if (!build || !list)
		return isl_ast_graft_list_free(list);

	ctx = isl_ast_build_get_ctx(build);
	n = isl_ast_graft_list_n_ast_graft(list);

	allow_else = isl_options_get_ast_build_allow_else(ctx);

	n_if = 0;
	if (n > 1) {
		if_node = isl_alloc_array(ctx, struct isl_if_node, n - 1);
		if (!if_node)
			return isl_ast_graft_list_free(list);
	}