Update isl to 88d60cfe1 'add isl_ast_expr_call'

For Polly the two interesting changes are short_circuit && and || AST
expressions as well as the introduction of isl_ast_build_expr_from_set,
a well defined interface to compute ast expressions from constraint sets.

llvm-svn: 230636
This commit is contained in:
Tobias Grosser 2015-02-26 15:08:35 +00:00
parent 4af7449659
commit fa6cdc8a59
9 changed files with 154 additions and 35 deletions

View File

@ -8625,12 +8625,24 @@ the context of an C<isl_ast_build>.
__isl_give isl_ast_expr *isl_ast_expr_div(
__isl_take isl_ast_expr *expr1,
__isl_take isl_ast_expr *expr2);
__isl_give isl_ast_expr *isl_ast_expr_pdiv_q(
__isl_take isl_ast_expr *expr1,
__isl_take isl_ast_expr *expr2);
__isl_give isl_ast_expr *isl_ast_expr_pdiv_r(
__isl_take isl_ast_expr *expr1,
__isl_take isl_ast_expr *expr2);
__isl_give isl_ast_expr *isl_ast_expr_and(
__isl_take isl_ast_expr *expr1,
__isl_take isl_ast_expr *expr2)
__isl_give isl_ast_expr *isl_ast_expr_and_then(
__isl_take isl_ast_expr *expr1,
__isl_take isl_ast_expr *expr2)
__isl_give isl_ast_expr *isl_ast_expr_or(
__isl_take isl_ast_expr *expr1,
__isl_take isl_ast_expr *expr2)
__isl_give isl_ast_expr *isl_ast_expr_or_else(
__isl_take isl_ast_expr *expr1,
__isl_take isl_ast_expr *expr2)
__isl_give isl_ast_expr *isl_ast_expr_eq(
__isl_take isl_ast_expr *expr1,
__isl_take isl_ast_expr *expr2);
@ -8649,12 +8661,20 @@ the context of an C<isl_ast_build>.
__isl_give isl_ast_expr *isl_ast_expr_access(
__isl_take isl_ast_expr *array,
__isl_take isl_ast_expr_list *indices);
__isl_give isl_ast_expr *isl_ast_expr_call(
__isl_take isl_ast_expr *function,
__isl_take isl_ast_expr_list *arguments);
The function C<isl_ast_expr_address_of> can be applied to an
C<isl_ast_expr> of type C<isl_ast_op_access> only. It is meant
to represent the address of the C<isl_ast_expr_access>.
to represent the address of the C<isl_ast_expr_access>. The function
C<isl_ast_expr_and_then> as well as C<isl_ast_expr_or_else> are short-circuit
versions of C<isl_ast_expr_and> and C<isl_ast_expr_or>, respectively.
#include <isl/ast_build.h>
__isl_give isl_ast_expr *isl_ast_build_expr_from_set(
__isl_keep isl_ast_build *build,
__isl_take isl_set *set);
__isl_give isl_ast_expr *isl_ast_build_expr_from_pw_aff(
__isl_keep isl_ast_build *build,
__isl_take isl_pw_aff *pa);
@ -8675,7 +8695,8 @@ to represent the address of the C<isl_ast_expr_access>.
__isl_keep isl_ast_build *build,
__isl_take isl_multi_pw_aff *mpa);
The domains of C<pa>, C<mpa> and C<pma> should correspond
The set <set> and
the domains of C<pa>, C<mpa> and C<pma> should correspond
to the schedule space of C<build>.
The tuple id of C<mpa> or C<pma> is used as the array being accessed or
the function being called.

View File

@ -30,10 +30,18 @@ __isl_give isl_ast_expr *isl_ast_expr_mul(__isl_take isl_ast_expr *expr1,
__isl_take isl_ast_expr *expr2);
__isl_give isl_ast_expr *isl_ast_expr_div(__isl_take isl_ast_expr *expr1,
__isl_take isl_ast_expr *expr2);
__isl_give isl_ast_expr *isl_ast_expr_pdiv_q(__isl_take isl_ast_expr *expr1,
__isl_take isl_ast_expr *expr2);
__isl_give isl_ast_expr *isl_ast_expr_pdiv_r(__isl_take isl_ast_expr *expr1,
__isl_take isl_ast_expr *expr2);
__isl_give isl_ast_expr *isl_ast_expr_and(__isl_take isl_ast_expr *expr1,
__isl_take isl_ast_expr *expr2);
__isl_give isl_ast_expr *isl_ast_expr_and_then(__isl_take isl_ast_expr *expr1,
__isl_take isl_ast_expr *expr2);
__isl_give isl_ast_expr *isl_ast_expr_or(__isl_take isl_ast_expr *expr1,
__isl_take isl_ast_expr *expr2);
__isl_give isl_ast_expr *isl_ast_expr_or_else(__isl_take isl_ast_expr *expr1,
__isl_take isl_ast_expr *expr2);
__isl_give isl_ast_expr *isl_ast_expr_le(__isl_take isl_ast_expr *expr1,
__isl_take isl_ast_expr *expr2);
__isl_give isl_ast_expr *isl_ast_expr_lt(__isl_take isl_ast_expr *expr1,
@ -46,6 +54,8 @@ __isl_give isl_ast_expr *isl_ast_expr_eq(__isl_take isl_ast_expr *expr1,
__isl_take isl_ast_expr *expr2);
__isl_give isl_ast_expr *isl_ast_expr_access(__isl_take isl_ast_expr *array,
__isl_take isl_ast_expr_list *indices);
__isl_give isl_ast_expr *isl_ast_expr_call(__isl_take isl_ast_expr *function,
__isl_take isl_ast_expr_list *arguments);
__isl_give isl_ast_expr *isl_ast_expr_address_of(__isl_take isl_ast_expr *expr);
__isl_give isl_ast_expr *isl_ast_expr_copy(__isl_keep isl_ast_expr *expr);

View File

@ -79,6 +79,8 @@ __isl_give isl_ast_build *isl_ast_build_set_create_leaf(
__isl_give isl_ast_node *(*fn)(__isl_take isl_ast_build *build,
void *user), void *user);
__isl_give isl_ast_expr *isl_ast_build_expr_from_set(
__isl_keep isl_ast_build *build, __isl_take isl_set *set);
__isl_give isl_ast_expr *isl_ast_build_expr_from_pw_aff(
__isl_keep isl_ast_build *build, __isl_take isl_pw_aff *pa);
__isl_give isl_ast_expr *isl_ast_build_access_from_pw_multi_aff(

View File

@ -571,6 +571,26 @@ __isl_give isl_ast_expr *isl_ast_expr_div(__isl_take isl_ast_expr *expr1,
return isl_ast_expr_alloc_binary(isl_ast_op_div, expr1, expr2);
}
/* Create an expression representing the quotient of the integer
* division of "expr1" by "expr2", where "expr1" is known to be
* non-negative.
*/
__isl_give isl_ast_expr *isl_ast_expr_pdiv_q(__isl_take isl_ast_expr *expr1,
__isl_take isl_ast_expr *expr2)
{
return isl_ast_expr_alloc_binary(isl_ast_op_pdiv_q, expr1, expr2);
}
/* Create an expression representing the remainder of the integer
* division of "expr1" by "expr2", where "expr1" is known to be
* non-negative.
*/
__isl_give isl_ast_expr *isl_ast_expr_pdiv_r(__isl_take isl_ast_expr *expr1,
__isl_take isl_ast_expr *expr2)
{
return isl_ast_expr_alloc_binary(isl_ast_op_pdiv_r, expr1, expr2);
}
/* Create an expression representing the conjunction of "expr1" and "expr2".
*/
__isl_give isl_ast_expr *isl_ast_expr_and(__isl_take isl_ast_expr *expr1,
@ -579,6 +599,15 @@ __isl_give isl_ast_expr *isl_ast_expr_and(__isl_take isl_ast_expr *expr1,
return isl_ast_expr_alloc_binary(isl_ast_op_and, expr1, expr2);
}
/* Create an expression representing the conjunction of "expr1" and "expr2",
* where "expr2" is evaluated only if "expr1" is evaluated to true.
*/
__isl_give isl_ast_expr *isl_ast_expr_and_then(__isl_take isl_ast_expr *expr1,
__isl_take isl_ast_expr *expr2)
{
return isl_ast_expr_alloc_binary(isl_ast_op_and_then, expr1, expr2);
}
/* Create an expression representing the disjunction of "expr1" and "expr2".
*/
__isl_give isl_ast_expr *isl_ast_expr_or(__isl_take isl_ast_expr *expr1,
@ -587,6 +616,15 @@ __isl_give isl_ast_expr *isl_ast_expr_or(__isl_take isl_ast_expr *expr1,
return isl_ast_expr_alloc_binary(isl_ast_op_or, expr1, expr2);
}
/* Create an expression representing the disjunction of "expr1" and "expr2",
* where "expr2" is evaluated only if "expr1" is evaluated to false.
*/
__isl_give isl_ast_expr *isl_ast_expr_or_else(__isl_take isl_ast_expr *expr1,
__isl_take isl_ast_expr *expr2)
{
return isl_ast_expr_alloc_binary(isl_ast_op_or_else, expr1, expr2);
}
/* Create an expression representing "expr1" less than or equal to "expr2".
*/
__isl_give isl_ast_expr *isl_ast_expr_le(__isl_take isl_ast_expr *expr1,
@ -627,40 +665,59 @@ __isl_give isl_ast_expr *isl_ast_expr_eq(__isl_take isl_ast_expr *expr1,
return isl_ast_expr_alloc_binary(isl_ast_op_eq, expr1, expr2);
}
/* Create an expression of type "type" with as arguments "arg0" followed
* by "arguments".
*/
static __isl_give isl_ast_expr *ast_expr_with_arguments(
enum isl_ast_op_type type, __isl_take isl_ast_expr *arg0,
__isl_take isl_ast_expr_list *arguments)
{
int i, n;
isl_ctx *ctx;
isl_ast_expr *res = NULL;
if (!arg0 || !arguments)
goto error;
ctx = isl_ast_expr_get_ctx(arg0);
n = isl_ast_expr_list_n_ast_expr(arguments);
res = isl_ast_expr_alloc_op(ctx, type, 1 + n);
if (!res)
goto error;
for (i = 0; i < n; ++i) {
isl_ast_expr *arg;
arg = isl_ast_expr_list_get_ast_expr(arguments, i);
res->u.op.args[1 + i] = arg;
if (!arg)
goto error;
}
res->u.op.args[0] = arg0;
isl_ast_expr_list_free(arguments);
return res;
error:
isl_ast_expr_free(arg0);
isl_ast_expr_list_free(arguments);
isl_ast_expr_free(res);
return NULL;
}
/* Create an expression representing an access to "array" with index
* expressions "indices".
*/
__isl_give isl_ast_expr *isl_ast_expr_access(__isl_take isl_ast_expr *array,
__isl_take isl_ast_expr_list *indices)
{
int i, n;
isl_ctx *ctx;
isl_ast_expr *access = NULL;
return ast_expr_with_arguments(isl_ast_op_access, array, indices);
}
if (!array || !indices)
goto error;
ctx = isl_ast_expr_get_ctx(array);
n = isl_ast_expr_list_n_ast_expr(indices);
access = isl_ast_expr_alloc_op(ctx, isl_ast_op_access, 1 + n);
if (!access)
goto error;
for (i = 0; i < n; ++i) {
isl_ast_expr *index;
index = isl_ast_expr_list_get_ast_expr(indices, i);
access->u.op.args[1 + i] = index;
if (!index)
goto error;
}
access->u.op.args[0] = array;
isl_ast_expr_list_free(indices);
return access;
error:
isl_ast_expr_free(array);
isl_ast_expr_list_free(indices);
isl_ast_expr_free(access);
return NULL;
/* Create an expression representing a call to "function" with argument
* expressions "arguments".
*/
__isl_give isl_ast_expr *isl_ast_expr_call(__isl_take isl_ast_expr *function,
__isl_take isl_ast_expr_list *arguments)
{
return ast_expr_with_arguments(isl_ast_op_call, function, arguments);
}
/* For each subexpression of "expr" of type isl_ast_expr_id,

View File

@ -1894,7 +1894,8 @@ __isl_give isl_set *isl_ast_build_compute_gist(
if (!build)
goto error;
set = isl_set_preimage_multi_aff(set,
if (!isl_set_is_params(set))
set = isl_set_preimage_multi_aff(set,
isl_multi_aff_copy(build->values));
set = isl_set_gist(set, isl_set_copy(build->domain));

View File

@ -1497,8 +1497,10 @@ static int expr_from_set(__isl_take isl_basic_set *bset, void *user)
* The result is simplified in terms of build->domain.
*
* If "set" is an (obviously) empty set, then return the expression "0".
*
* "set" lives in the internal schedule space.
*/
__isl_give isl_ast_expr *isl_ast_build_expr_from_set(
__isl_give isl_ast_expr *isl_ast_build_expr_from_set_internal(
__isl_keep isl_ast_build *build, __isl_take isl_set *set)
{
struct isl_expr_from_set_data data = { build, 1, NULL };
@ -1514,6 +1516,32 @@ __isl_give isl_ast_expr *isl_ast_build_expr_from_set(
return data.res;
}
/* Construct an isl_ast_expr that evaluates the conditions defining "set".
* The result is simplified in terms of build->domain.
*
* If "set" is an (obviously) empty set, then return the expression "0".
*
* "set" lives in the external schedule space.
*
* The internal AST expression generation assumes that there are
* no unknown divs, so make sure an explicit representation is available.
* Since the set comes from the outside, it may have constraints that
* are redundant with respect to the build domain. Remove them first.
*/
__isl_give isl_ast_expr *isl_ast_build_expr_from_set(
__isl_keep isl_ast_build *build, __isl_take isl_set *set)
{
if (isl_ast_build_need_schedule_map(build)) {
isl_multi_aff *ma;
ma = isl_ast_build_get_schedule_map_multi_aff(build);
set = isl_set_preimage_multi_aff(set, ma);
}
set = isl_set_compute_divs(set);
set = isl_ast_build_compute_gist(build, set);
return isl_ast_build_expr_from_set_internal(build, set);
}
struct isl_from_pw_aff_data {
isl_ast_build *build;
int n;
@ -1560,7 +1588,7 @@ static int ast_expr_from_pw_aff(__isl_take isl_set *set,
ternary = isl_ast_expr_alloc_op(ctx, isl_ast_op_select, 3);
gist = isl_set_gist(isl_set_copy(set), isl_set_copy(data->dom));
arg = isl_ast_build_expr_from_set(data->build, gist);
arg = isl_ast_build_expr_from_set_internal(data->build, gist);
ternary = isl_ast_expr_set_op_arg(ternary, 0, arg);
build = isl_ast_build_copy(data->build);
build = isl_ast_build_restrict_generated(build, set);

View File

@ -6,7 +6,7 @@
__isl_give isl_ast_expr *isl_ast_build_expr_from_basic_set(
__isl_keep isl_ast_build *build, __isl_take isl_basic_set *bset);
__isl_give isl_ast_expr *isl_ast_build_expr_from_set(
__isl_give isl_ast_expr *isl_ast_build_expr_from_set_internal(
__isl_keep isl_ast_build *build, __isl_take isl_set *set);
__isl_give isl_ast_expr *isl_ast_build_expr_from_pw_aff_internal(

View File

@ -986,7 +986,7 @@ static __isl_give isl_ast_graft *set_for_cond_from_set(
if (!graft)
return NULL;
cond = isl_ast_build_expr_from_set(build, isl_set_copy(set));
cond = isl_ast_build_expr_from_set_internal(build, isl_set_copy(set));
graft->node->u.f.cond = cond;
if (!graft->node->u.f.cond)
return isl_ast_graft_free(graft);

View File

@ -278,7 +278,7 @@ static __isl_give isl_ast_node *ast_node_insert_if(
isl_ast_node *if_node;
isl_ast_expr *expr;
expr = isl_ast_build_expr_from_set(build, guard);
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);