diff -Npur isl_0.22/include/isl/aff.h isl/include/isl/aff.h --- isl_0.22/include/isl/aff.h 2020-04-17 16:49:36.266477000 +0800 +++ isl/include/isl/aff.h 2020-04-29 18:14:39.945681000 +0800 @@ -17,14 +17,19 @@ extern "C" { #endif +__isl_constructor __isl_give isl_aff *isl_aff_zero_on_domain(__isl_take isl_local_space *ls); __isl_give isl_aff *isl_aff_val_on_domain_space(__isl_take isl_space *space, __isl_take isl_val *val); +__isl_constructor __isl_give isl_aff *isl_aff_val_on_domain(__isl_take isl_local_space *ls, __isl_take isl_val *val); + +__isl_export __isl_give isl_aff *isl_aff_var_on_domain(__isl_take isl_local_space *ls, enum isl_dim_type type, unsigned pos); __isl_give isl_aff *isl_aff_nan_on_domain(__isl_take isl_local_space *ls); +__isl_overload __isl_give isl_aff *isl_aff_param_on_domain_space_id( __isl_take isl_space *space, __isl_take isl_id *id); @@ -41,6 +46,7 @@ isl_bool isl_aff_involves_dims(__isl_kee enum isl_dim_type type, unsigned first, unsigned n); __isl_give isl_space *isl_aff_get_domain_space(__isl_keep isl_aff *aff); +__isl_export __isl_give isl_space *isl_aff_get_space(__isl_keep isl_aff *aff); __isl_give isl_local_space *isl_aff_get_domain_local_space( __isl_keep isl_aff *aff); @@ -48,12 +54,14 @@ __isl_give isl_local_space *isl_aff_get_ const char *isl_aff_get_dim_name(__isl_keep isl_aff *aff, enum isl_dim_type type, unsigned pos); +__isl_export __isl_give isl_val *isl_aff_get_constant_val(__isl_keep isl_aff *aff); __isl_give isl_val *isl_aff_get_coefficient_val(__isl_keep isl_aff *aff, enum isl_dim_type type, int pos); int isl_aff_coefficient_sgn(__isl_keep isl_aff *aff, enum isl_dim_type type, int pos); __isl_give isl_val *isl_aff_get_denominator_val(__isl_keep isl_aff *aff); +__isl_export __isl_give isl_aff *isl_aff_set_constant_si(__isl_take isl_aff *aff, int v); __isl_give isl_aff *isl_aff_set_constant_val(__isl_take isl_aff *aff, __isl_take isl_val *v); @@ -61,6 +69,7 @@ __isl_give isl_aff *isl_aff_set_coeffici enum isl_dim_type type, int pos, int v); __isl_give isl_aff *isl_aff_set_coefficient_val(__isl_take isl_aff *aff, enum isl_dim_type type, int pos, __isl_take isl_val *v); +__isl_export __isl_give isl_aff *isl_aff_add_constant_si(__isl_take isl_aff *aff, int v); __isl_overload __isl_give isl_aff *isl_aff_add_constant_val(__isl_take isl_aff *aff, @@ -209,11 +218,13 @@ __isl_give isl_pw_aff *isl_pw_aff_from_a __isl_give isl_pw_aff *isl_pw_aff_empty(__isl_take isl_space *space); __isl_give isl_pw_aff *isl_pw_aff_alloc(__isl_take isl_set *set, __isl_take isl_aff *aff); +__isl_constructor __isl_give isl_pw_aff *isl_pw_aff_zero_on_domain( __isl_take isl_local_space *ls); __isl_give isl_pw_aff *isl_pw_aff_var_on_domain(__isl_take isl_local_space *ls, enum isl_dim_type type, unsigned pos); __isl_give isl_pw_aff *isl_pw_aff_nan_on_domain(__isl_take isl_local_space *ls); +__isl_constructor __isl_give isl_pw_aff *isl_pw_aff_val_on_domain(__isl_take isl_set *domain, __isl_take isl_val *v); __isl_overload @@ -240,6 +251,7 @@ int isl_pw_aff_plain_cmp(__isl_keep isl_ __isl_keep isl_pw_aff *pa2); isl_bool isl_pw_aff_plain_is_equal(__isl_keep isl_pw_aff *pwaff1, __isl_keep isl_pw_aff *pwaff2); +__isl_export isl_bool isl_pw_aff_is_equal(__isl_keep isl_pw_aff *pa1, __isl_keep isl_pw_aff *pa2); @@ -375,7 +387,9 @@ __isl_overload __isl_give isl_pw_aff *isl_pw_aff_pullback_multi_pw_aff( __isl_take isl_pw_aff *pa, __isl_take isl_multi_pw_aff *mpa); +__isl_export isl_size isl_pw_aff_n_piece(__isl_keep isl_pw_aff *pwaff); +__isl_export isl_stat isl_pw_aff_foreach_piece(__isl_keep isl_pw_aff *pwaff, isl_stat (*fn)(__isl_take isl_set *set, __isl_take isl_aff *aff, void *user), void *user); @@ -387,8 +401,11 @@ __isl_give isl_aff *isl_pw_aff_as_aff(__ __isl_give isl_set *isl_set_from_pw_aff(__isl_take isl_pw_aff *pwaff); __isl_give isl_map *isl_map_from_pw_aff(__isl_take isl_pw_aff *pwaff); +__isl_export __isl_give isl_set *isl_pw_aff_pos_set(__isl_take isl_pw_aff *pa); +__isl_export __isl_give isl_set *isl_pw_aff_nonneg_set(__isl_take isl_pw_aff *pwaff); +__isl_export __isl_give isl_set *isl_pw_aff_zero_set(__isl_take isl_pw_aff *pwaff); __isl_give isl_set *isl_pw_aff_non_zero_set(__isl_take isl_pw_aff *pwaff); @@ -411,10 +428,13 @@ __isl_export __isl_give isl_set *isl_pw_aff_gt_set(__isl_take isl_pw_aff *pwaff1, __isl_take isl_pw_aff *pwaff2); +__isl_export __isl_give isl_map *isl_pw_aff_eq_map(__isl_take isl_pw_aff *pa1, __isl_take isl_pw_aff *pa2); +__isl_export __isl_give isl_map *isl_pw_aff_lt_map(__isl_take isl_pw_aff *pa1, __isl_take isl_pw_aff *pa2); +__isl_export __isl_give isl_map *isl_pw_aff_gt_map(__isl_take isl_pw_aff *pa1, __isl_take isl_pw_aff *pa2); @@ -467,9 +487,15 @@ ISL_DECLARE_MULTI_BIND_DOMAIN(aff) __isl_constructor __isl_give isl_multi_aff *isl_multi_aff_from_aff(__isl_take isl_aff *aff); __isl_export +__isl_give isl_multi_aff *isl_multi_aff_identity(__isl_take isl_space *space); +__isl_export __isl_give isl_multi_aff *isl_multi_aff_domain_map(__isl_take isl_space *space); __isl_export __isl_give isl_multi_aff *isl_multi_aff_range_map(__isl_take isl_space *space); +__isl_export +__isl_give isl_multi_aff *isl_multi_aff_wrapped_range_map( + __isl_take isl_space *space); +__isl_export __isl_give isl_multi_aff *isl_multi_aff_project_out_map( __isl_take isl_space *space, enum isl_dim_type type, unsigned first, unsigned n); @@ -533,6 +559,7 @@ ISL_DECLARE_MULTI_PARAM(pw_aff) __isl_export __isl_give isl_pw_multi_aff *isl_pw_multi_aff_zero(__isl_take isl_space *space); +__isl_export __isl_give isl_pw_multi_aff *isl_pw_multi_aff_identity( __isl_take isl_space *space); __isl_give isl_pw_multi_aff *isl_pw_multi_aff_range_map( @@ -559,6 +586,7 @@ isl_bool isl_pw_multi_aff_involves_param __isl_keep isl_id *id); isl_bool isl_pw_multi_aff_involves_dims(__isl_keep isl_pw_multi_aff *pma, enum isl_dim_type type, unsigned first, unsigned n); +__isl_export __isl_give isl_pw_aff *isl_pw_multi_aff_get_pw_aff( __isl_keep isl_pw_multi_aff *pma, int pos); __isl_give isl_pw_multi_aff *isl_pw_multi_aff_set_pw_aff( @@ -575,6 +603,7 @@ isl_bool isl_pw_multi_aff_has_tuple_name enum isl_dim_type type); const char *isl_pw_multi_aff_get_tuple_name(__isl_keep isl_pw_multi_aff *pma, enum isl_dim_type type); +__isl_export __isl_give isl_id *isl_pw_multi_aff_get_tuple_id( __isl_keep isl_pw_multi_aff *pma, enum isl_dim_type type); isl_bool isl_pw_multi_aff_has_tuple_id(__isl_keep isl_pw_multi_aff *pma, @@ -601,6 +630,7 @@ __isl_give isl_pw_multi_aff *isl_pw_mult __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_domain( __isl_take isl_set *set); +__isl_constructor __isl_give isl_pw_multi_aff *isl_pw_multi_aff_multi_val_on_domain( __isl_take isl_set *domain, __isl_take isl_multi_val *mv); @@ -616,6 +646,7 @@ __isl_give isl_pw_multi_aff *isl_pw_mult isl_bool isl_pw_multi_aff_involves_nan(__isl_keep isl_pw_multi_aff *pma); isl_bool isl_pw_multi_aff_plain_is_equal(__isl_keep isl_pw_multi_aff *pma1, __isl_keep isl_pw_multi_aff *pma2); +__isl_export isl_bool isl_pw_multi_aff_is_equal(__isl_keep isl_pw_multi_aff *pma1, __isl_keep isl_pw_multi_aff *pma2); @@ -721,6 +752,7 @@ __isl_export __isl_give isl_multi_aff *isl_pw_multi_aff_as_multi_aff( __isl_take isl_pw_multi_aff *pma); +__isl_overload __isl_give isl_map *isl_map_from_pw_multi_aff(__isl_take isl_pw_multi_aff *pma); __isl_give isl_set *isl_set_from_pw_multi_aff(__isl_take isl_pw_multi_aff *pma); @@ -729,6 +761,7 @@ __isl_give isl_printer *isl_printer_prin __isl_keep isl_pw_multi_aff *pma); __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_set(__isl_take isl_set *set); +__isl_constructor __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_map(__isl_take isl_map *map); __isl_export @@ -758,8 +791,10 @@ __isl_give isl_union_pw_multi_aff *isl_u __isl_take isl_pw_multi_aff *pma); __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_domain( __isl_take isl_union_set *uset); +__isl_constructor __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_multi_val_on_domain( __isl_take isl_union_set *domain, __isl_take isl_multi_val *mv); +__isl_overload __isl_give isl_union_pw_aff *isl_union_pw_aff_param_on_domain_id( __isl_take isl_union_set *domain, __isl_take isl_id *id); __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_copy( @@ -862,8 +897,10 @@ __isl_give isl_union_pw_multi_aff *isl_u __isl_take isl_union_pw_multi_aff *upma1, __isl_take isl_union_pw_multi_aff *upma2); +__isl_overload __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_scale_val( __isl_take isl_union_pw_multi_aff *upma, __isl_take isl_val *val); +__isl_overload __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_scale_down_val( __isl_take isl_union_pw_multi_aff *upma, __isl_take isl_val *val); __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_scale_multi_val( @@ -911,6 +948,7 @@ __isl_give isl_printer *isl_printer_prin __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_union_set( __isl_take isl_union_set *uset); +__isl_overload __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_union_map( __isl_take isl_union_map *umap); @@ -947,6 +985,7 @@ __isl_give isl_multi_pw_aff *isl_multi_p __isl_take isl_multi_pw_aff *mpa, __isl_take isl_set *set); isl_bool isl_multi_pw_aff_is_cst(__isl_keep isl_multi_pw_aff *mpa); +__isl_export isl_bool isl_multi_pw_aff_is_equal(__isl_keep isl_multi_pw_aff *mpa1, __isl_keep isl_multi_pw_aff *mpa2); @@ -967,6 +1006,7 @@ __isl_give isl_multi_pw_aff *isl_multi_p __isl_give isl_set *isl_set_from_multi_pw_aff(__isl_take isl_multi_pw_aff *mpa); __isl_give isl_map *isl_map_from_multi_pw_aff(__isl_take isl_multi_pw_aff *mpa); +__isl_overload __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_multi_pw_aff( __isl_take isl_multi_pw_aff *mpa); __isl_constructor @@ -1001,6 +1041,7 @@ isl_ctx *isl_union_pw_aff_get_ctx(__isl_ __isl_export __isl_give isl_space *isl_union_pw_aff_get_space( __isl_keep isl_union_pw_aff *upa); +__isl_export __isl_give isl_pw_aff_list *isl_union_pw_aff_get_pw_aff_list( __isl_keep isl_union_pw_aff *upa); @@ -1022,13 +1063,16 @@ __isl_give isl_union_pw_aff *isl_union_p __isl_give isl_union_pw_aff *isl_union_pw_aff_empty_ctx(isl_ctx *ctx); __isl_give isl_union_pw_aff *isl_union_pw_aff_empty_space( __isl_take isl_space *space); +__isl_export __isl_give isl_union_pw_aff *isl_union_pw_aff_empty( __isl_take isl_space *space); __isl_constructor __isl_give isl_union_pw_aff *isl_union_pw_aff_from_pw_aff( __isl_take isl_pw_aff *pa); +__isl_constructor __isl_give isl_union_pw_aff *isl_union_pw_aff_val_on_domain( __isl_take isl_union_set *domain, __isl_take isl_val *v); +__isl_constructor __isl_give isl_union_pw_aff *isl_union_pw_aff_aff_on_domain( __isl_take isl_union_set *domain, __isl_take isl_aff *aff); __isl_give isl_union_pw_aff *isl_union_pw_aff_pw_aff_on_domain( @@ -1081,13 +1125,17 @@ __isl_give isl_union_pw_aff *isl_union_p __isl_take isl_union_pw_aff *upa, __isl_take isl_union_pw_multi_aff *upma); +__isl_export __isl_give isl_union_pw_aff *isl_union_pw_aff_floor( __isl_take isl_union_pw_aff *upa); +__isl_overload __isl_give isl_union_pw_aff *isl_union_pw_aff_scale_val( __isl_take isl_union_pw_aff *upa, __isl_take isl_val *v); +__isl_overload __isl_give isl_union_pw_aff *isl_union_pw_aff_scale_down_val( __isl_take isl_union_pw_aff *upa, __isl_take isl_val *v); +__isl_overload __isl_give isl_union_pw_aff *isl_union_pw_aff_mod_val( __isl_take isl_union_pw_aff *upa, __isl_take isl_val *f); @@ -1114,6 +1162,7 @@ __isl_give isl_union_pw_aff *isl_union_p __isl_take isl_union_pw_aff *upa, enum isl_dim_type type, unsigned pos, const char *s); +__isl_export __isl_give isl_union_set *isl_union_pw_aff_zero_union_set( __isl_take isl_union_pw_aff *upa); @@ -1148,14 +1197,17 @@ __isl_give isl_multi_union_pw_aff *isl_m __isl_constructor __isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_multi_pw_aff( __isl_take isl_multi_pw_aff *mpa); +__isl_constructor __isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_multi_val_on_domain( __isl_take isl_union_set *domain, __isl_take isl_multi_val *mv); +__isl_constructor __isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_multi_aff_on_domain( __isl_take isl_union_set *domain, __isl_take isl_multi_aff *ma); __isl_give isl_multi_union_pw_aff * isl_multi_union_pw_aff_pw_multi_aff_on_domain(__isl_take isl_union_set *domain, __isl_take isl_pw_multi_aff *pma); +__isl_export __isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_floor( __isl_take isl_multi_union_pw_aff *mupa); @@ -1184,10 +1236,12 @@ __isl_give isl_multi_union_pw_aff *isl_m __isl_give isl_union_pw_aff *isl_multi_union_pw_aff_apply_aff( __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_aff *aff); +__isl_overload __isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_apply_multi_aff( __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_multi_aff *ma); __isl_give isl_union_pw_aff *isl_multi_union_pw_aff_apply_pw_aff( __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_pw_aff *pa); +__isl_overload __isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_apply_pw_multi_aff( __isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_pw_multi_aff *pma); @@ -1211,6 +1265,7 @@ __isl_give isl_multi_union_pw_aff * isl_multi_union_pw_aff_from_union_pw_multi_aff( __isl_take isl_union_pw_multi_aff *upma); +__isl_export __isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_union_map( __isl_take isl_union_map *umap); __isl_overload diff -Npur isl_0.22/include/isl/aff_type.h isl/include/isl/aff_type.h --- isl_0.22/include/isl/aff_type.h 2020-04-17 16:49:36.266477000 +0800 +++ isl/include/isl/aff_type.h 2020-04-29 18:14:39.941681000 +0800 @@ -10,13 +10,13 @@ extern "C" { struct __isl_subclass(isl_multi_aff) __isl_subclass(isl_pw_aff) isl_aff; typedef struct isl_aff isl_aff; -ISL_DECLARE_EXPORTED_LIST_TYPE(aff) +ISL_DECLARE_EXPORTED_LIST(aff) struct __isl_subclass(isl_multi_pw_aff) __isl_subclass(isl_pw_multi_aff) __isl_subclass(isl_union_pw_aff) isl_pw_aff; typedef struct isl_pw_aff isl_pw_aff; -ISL_DECLARE_EXPORTED_LIST_TYPE(pw_aff) +ISL_DECLARE_EXPORTED_LIST(pw_aff) struct __isl_subclass(isl_multi_union_pw_aff) __isl_subclass(isl_union_pw_multi_aff) isl_union_pw_aff; diff -Npur isl_0.22/include/isl/ast_build.h isl/include/isl/ast_build.h --- isl_0.22/include/isl/ast_build.h 2020-04-17 16:49:36.266477000 +0800 +++ isl/include/isl/ast_build.h 2020-04-29 18:14:39.941681000 +0800 @@ -67,6 +67,7 @@ __isl_null isl_ast_build *isl_ast_build_ __isl_give isl_ast_build *isl_ast_build_set_options( __isl_take isl_ast_build *build, __isl_take isl_union_map *options); +__isl_export __isl_give isl_ast_build *isl_ast_build_set_iterators( __isl_take isl_ast_build *build, __isl_take isl_id_list *iterators); diff -Npur isl_0.22/include/isl/ast.h isl/include/isl/ast.h --- isl_0.22/include/isl/ast.h 2020-04-17 16:49:36.266477000 +0800 +++ isl/include/isl/ast.h 2020-04-29 18:14:39.941681000 +0800 @@ -84,9 +84,11 @@ __isl_give isl_ast_expr *isl_ast_expr_op int pos); __isl_give isl_ast_expr *isl_ast_expr_get_op_arg(__isl_keep isl_ast_expr *expr, int pos); +__isl_export __isl_give isl_ast_expr *isl_ast_expr_set_op_arg(__isl_take isl_ast_expr *expr, int pos, __isl_take isl_ast_expr *arg); +__isl_export isl_bool isl_ast_expr_is_equal(__isl_keep isl_ast_expr *expr1, __isl_keep isl_ast_expr *expr2); @@ -104,12 +106,18 @@ __isl_give isl_ast_node *isl_ast_node_al __isl_give isl_ast_node *isl_ast_node_copy(__isl_keep isl_ast_node *node); __isl_null isl_ast_node *isl_ast_node_free(__isl_take isl_ast_node *node); +__isl_export +__isl_give isl_ast_node *isl_ast_node_from_ast_node_list( + __isl_take isl_ast_node_list *list); + isl_ctx *isl_ast_node_get_ctx(__isl_keep isl_ast_node *node); __isl_subclass(isl_ast_node) enum isl_ast_node_type isl_ast_node_get_type(__isl_keep isl_ast_node *node); +__isl_export __isl_give isl_ast_node *isl_ast_node_set_annotation( __isl_take isl_ast_node *node, __isl_take isl_id *annotation); +__isl_export __isl_give isl_id *isl_ast_node_get_annotation(__isl_keep isl_ast_node *node); __isl_export diff -Npur isl_0.22/include/isl/constraint.h isl/include/isl/constraint.h --- isl_0.22/include/isl/constraint.h 2020-04-17 16:49:36.266477000 +0800 +++ isl/include/isl/constraint.h 2020-04-29 18:14:39.941681000 +0800 @@ -37,6 +37,7 @@ __isl_give isl_constraint *isl_equality_ __isl_give isl_constraint *isl_inequality_alloc(__isl_take isl_local_space *ls); struct isl_constraint *isl_constraint_copy(struct isl_constraint *c); +__isl_constructor __isl_null isl_constraint *isl_constraint_free(__isl_take isl_constraint *c); isl_size isl_basic_map_n_constraint(__isl_keep isl_basic_map *bmap); @@ -45,6 +46,7 @@ isl_stat isl_basic_map_foreach_constrain isl_stat (*fn)(__isl_take isl_constraint *c, void *user), void *user); isl_stat isl_basic_set_foreach_constraint(__isl_keep isl_basic_set *bset, isl_stat (*fn)(__isl_take isl_constraint *c, void *user), void *user); +__isl_export __isl_give isl_constraint_list *isl_basic_map_get_constraint_list( __isl_keep isl_basic_map *bmap); __isl_give isl_constraint_list *isl_basic_set_get_constraint_list( @@ -62,6 +64,7 @@ __isl_give isl_basic_map *isl_basic_map_ __isl_take isl_basic_map *bmap, __isl_take isl_constraint *constraint); __isl_give isl_basic_set *isl_basic_set_add_constraint( __isl_take isl_basic_set *bset, __isl_take isl_constraint *constraint); +__isl_export __isl_give isl_map *isl_map_add_constraint(__isl_take isl_map *map, __isl_take isl_constraint *constraint); __isl_give isl_set *isl_set_add_constraint(__isl_take isl_set *set, @@ -82,9 +85,11 @@ __isl_give isl_space *isl_constraint_get __isl_keep isl_constraint *constraint); __isl_give isl_local_space *isl_constraint_get_local_space( __isl_keep isl_constraint *constraint); +__isl_export isl_size isl_constraint_dim(__isl_keep isl_constraint *constraint, enum isl_dim_type type); +__isl_export isl_bool isl_constraint_involves_dims(__isl_keep isl_constraint *constraint, enum isl_dim_type type, unsigned first, unsigned n); @@ -110,6 +115,7 @@ __isl_give isl_aff *isl_constraint_get_d struct isl_constraint *isl_constraint_negate(struct isl_constraint *constraint); +__isl_export isl_bool isl_constraint_is_equality(__isl_keep isl_constraint *constraint); isl_bool isl_constraint_is_div_constraint( __isl_keep isl_constraint *constraint); @@ -138,6 +144,7 @@ int isl_constraint_cmp_last_non_zero(__i __isl_give isl_printer *isl_printer_print_constraint(__isl_take isl_printer *p, __isl_keep isl_constraint *c); +__isl_export void isl_constraint_dump(__isl_keep isl_constraint *c); #if defined(__cplusplus) diff -Npur isl_0.22/include/isl/id.h isl/include/isl/id.h --- isl_0.22/include/isl/id.h 2020-04-17 16:49:36.266477000 +0800 +++ isl/include/isl/id.h 2020-04-29 18:14:39.941681000 +0800 @@ -17,6 +17,7 @@ ISL_DECLARE_EXPORTED_LIST_FN(id) ISL_DECLARE_MULTI(id) isl_ctx *isl_id_get_ctx(__isl_keep isl_id *id); +__isl_export uint32_t isl_id_get_hash(__isl_keep isl_id *id); __isl_give isl_id *isl_id_alloc(isl_ctx *ctx, diff -Npur isl_0.22/include/isl/ilp.h isl/include/isl/ilp.h --- isl_0.22/include/isl/ilp.h 2020-04-17 16:49:36.266477000 +0800 +++ isl/include/isl/ilp.h 2020-04-29 18:14:39.941681000 +0800 @@ -31,11 +31,15 @@ __isl_give isl_val *isl_set_max_val(__is __isl_give isl_multi_val *isl_union_set_min_multi_union_pw_aff( __isl_keep isl_union_set *uset, __isl_keep isl_multi_union_pw_aff *obj); +__isl_export __isl_give isl_val *isl_union_pw_aff_min_val(__isl_take isl_union_pw_aff *upa); +__isl_export __isl_give isl_val *isl_union_pw_aff_max_val(__isl_take isl_union_pw_aff *upa); +__isl_export __isl_give isl_multi_val *isl_multi_union_pw_aff_min_multi_val( __isl_take isl_multi_union_pw_aff *mupa); +__isl_export __isl_give isl_multi_val *isl_multi_union_pw_aff_max_multi_val( __isl_take isl_multi_union_pw_aff *mupa); diff -Npur isl_0.22/include/isl/list.h isl/include/isl/list.h --- isl_0.22/include/isl/list.h 2020-04-17 16:49:36.270477000 +0800 +++ isl/include/isl/list.h 2020-04-29 18:14:39.945681000 +0800 @@ -43,6 +43,7 @@ __isl_give isl_##EL##_list *isl_##EL##_l __isl_give isl_##EL##_list *isl_##EL##_list_insert( \ __isl_take isl_##EL##_list *list, unsigned pos, \ __isl_take struct isl_##EL *el); \ +EXPORT \ __isl_give isl_##EL##_list *isl_##EL##_list_drop( \ __isl_take isl_##EL##_list *list, unsigned first, unsigned n); \ EXPORT \ @@ -51,6 +52,7 @@ __isl_give isl_##EL##_list *isl_##EL##_l __isl_give isl_##EL##_list *isl_##EL##_list_swap( \ __isl_take isl_##EL##_list *list, unsigned pos1, \ unsigned pos2); \ +EXPORT \ __isl_give isl_##EL##_list *isl_##EL##_list_reverse( \ __isl_take isl_##EL##_list *list); \ EXPORT \ diff -Npur isl_0.22/include/isl/local_space.h isl/include/isl/local_space.h --- isl_0.22/include/isl/local_space.h 2020-04-17 16:49:36.270477000 +0800 +++ isl/include/isl/local_space.h 2020-04-29 18:14:39.945681000 +0800 @@ -10,11 +10,12 @@ extern "C" { #endif -struct isl_local_space; +struct __isl_export isl_local_space; typedef struct isl_local_space isl_local_space; isl_ctx *isl_local_space_get_ctx(__isl_keep isl_local_space *ls); +__isl_constructor __isl_give isl_local_space *isl_local_space_from_space(__isl_take isl_space *dim); __isl_give isl_local_space *isl_local_space_copy( @@ -75,6 +76,7 @@ __isl_give isl_local_space *isl_local_sp __isl_give isl_local_space *isl_local_space_wrap( __isl_take isl_local_space *ls); +__isl_export isl_bool isl_local_space_is_equal(__isl_keep isl_local_space *ls1, __isl_keep isl_local_space *ls2); diff -Npur isl_0.22/include/isl/map.h isl/include/isl/map.h --- isl_0.22/include/isl/map.h 2020-04-17 16:49:36.270477000 +0800 +++ isl/include/isl/map.h 2020-04-29 18:14:39.945681000 +0800 @@ -34,6 +34,7 @@ isl_size isl_basic_map_total_dim(__isl_k isl_size isl_basic_map_dim(__isl_keep isl_basic_map *bmap, enum isl_dim_type type); +__isl_export isl_size isl_map_dim(__isl_keep isl_map *map, enum isl_dim_type type); isl_ctx *isl_basic_map_get_ctx(__isl_keep isl_basic_map *bmap); @@ -56,6 +57,7 @@ isl_bool isl_map_has_tuple_name(__isl_ke enum isl_dim_type type); const char *isl_map_get_tuple_name(__isl_keep isl_map *map, enum isl_dim_type type); +__isl_export __isl_give isl_map *isl_map_set_tuple_name(__isl_take isl_map *map, enum isl_dim_type type, const char *s); const char *isl_basic_map_get_dim_name(__isl_keep isl_basic_map *bmap, @@ -67,6 +69,7 @@ const char *isl_map_get_dim_name(__isl_k __isl_give isl_basic_map *isl_basic_map_set_dim_name( __isl_take isl_basic_map *bmap, enum isl_dim_type type, unsigned pos, const char *s); +__isl_export __isl_give isl_map *isl_map_set_dim_name(__isl_take isl_map *map, enum isl_dim_type type, unsigned pos, const char *s); @@ -81,11 +84,13 @@ isl_bool isl_map_has_dim_id(__isl_keep i enum isl_dim_type type, unsigned pos); __isl_give isl_id *isl_map_get_dim_id(__isl_keep isl_map *map, enum isl_dim_type type, unsigned pos); +__isl_export __isl_give isl_map *isl_map_set_tuple_id(__isl_take isl_map *map, enum isl_dim_type type, __isl_take isl_id *id); __isl_give isl_map *isl_map_reset_tuple_id(__isl_take isl_map *map, enum isl_dim_type type); isl_bool isl_map_has_tuple_id(__isl_keep isl_map *map, enum isl_dim_type type); +__isl_export __isl_give isl_id *isl_map_get_tuple_id(__isl_keep isl_map *map, enum isl_dim_type type); __isl_give isl_map *isl_map_reset_user(__isl_take isl_map *map); @@ -207,6 +212,7 @@ __isl_give isl_basic_map *isl_basic_map_ __isl_take isl_basic_map *bmap2); __isl_give isl_basic_map *isl_basic_map_neg(__isl_take isl_basic_map *bmap); +__isl_export __isl_give isl_map *isl_map_sum(__isl_take isl_map *map1, __isl_take isl_map *map2); __isl_give isl_map *isl_map_neg(__isl_take isl_map *map); @@ -257,6 +263,9 @@ __isl_give isl_pw_multi_aff *isl_map_lex void isl_basic_map_print_internal(__isl_keep isl_basic_map *bmap, FILE *out, int indent); +__isl_give isl_map *isl_map_plain_update_val_if_fixed(__isl_take isl_map *map, + enum isl_dim_type type, unsigned pos); + __isl_give isl_val *isl_basic_map_plain_get_val_if_fixed( __isl_keep isl_basic_map *bmap, enum isl_dim_type type, unsigned pos); @@ -416,6 +425,7 @@ __isl_export __isl_give isl_basic_map *isl_map_polyhedral_hull(__isl_take isl_map *map); __isl_give isl_basic_map *isl_basic_map_add_dims(__isl_take isl_basic_map *bmap, enum isl_dim_type type, unsigned n); +__isl_export __isl_give isl_map *isl_map_add_dims(__isl_take isl_map *map, enum isl_dim_type type, unsigned n); __isl_give isl_basic_map *isl_basic_map_insert_dims( @@ -433,6 +443,7 @@ __isl_give isl_map *isl_map_move_dims(__ __isl_give isl_basic_map *isl_basic_map_project_out( __isl_take isl_basic_map *bmap, enum isl_dim_type type, unsigned first, unsigned n); +__isl_export __isl_give isl_map *isl_map_project_out(__isl_take isl_map *map, enum isl_dim_type type, unsigned first, unsigned n); __isl_export @@ -520,8 +531,10 @@ __isl_give isl_basic_map *isl_basic_map_ __isl_give isl_basic_map *isl_basic_map_from_range( __isl_take isl_basic_set *bset); __isl_give isl_map *isl_map_from_range(__isl_take isl_set *set); +__isl_constructor __isl_give isl_basic_map *isl_basic_map_from_domain_and_range( __isl_take isl_basic_set *domain, __isl_take isl_basic_set *range); +__isl_constructor __isl_give isl_map *isl_map_from_domain_and_range(__isl_take isl_set *domain, __isl_take isl_set *range); __isl_export @@ -565,6 +578,7 @@ isl_bool isl_map_has_equal_space(__isl_k isl_bool isl_basic_map_can_zip(__isl_keep isl_basic_map *bmap); isl_bool isl_map_can_zip(__isl_keep isl_map *map); __isl_give isl_basic_map *isl_basic_map_zip(__isl_take isl_basic_map *bmap); +__isl_export __isl_give isl_map *isl_map_zip(__isl_take isl_map *map); isl_bool isl_basic_map_can_curry(__isl_keep isl_basic_map *bmap); @@ -587,7 +601,7 @@ __isl_give isl_map *isl_basic_map_comput __isl_give isl_map *isl_map_compute_divs(__isl_take isl_map *map); ISL_DEPRECATED __isl_give isl_map *isl_map_align_divs(__isl_take isl_map *map); - +__isl_export __isl_give isl_basic_map *isl_basic_map_drop_constraints_involving_dims( __isl_take isl_basic_map *bmap, enum isl_dim_type type, unsigned first, unsigned n); @@ -600,6 +614,8 @@ __isl_give isl_map *isl_map_drop_constra __isl_give isl_map *isl_map_drop_constraints_not_involving_dims( __isl_take isl_map *map, enum isl_dim_type type, unsigned first, unsigned n); +__isl_give isl_map *isl_map_drop_special_constraints( + __isl_take isl_map *bmap, unsigned first, unsigned n); isl_bool isl_basic_map_involves_dims(__isl_keep isl_basic_map *bmap, enum isl_dim_type type, unsigned first, unsigned n); @@ -629,6 +645,7 @@ __isl_give isl_map *isl_map_gist_params( __isl_give isl_map *isl_map_gist_basic_map(__isl_take isl_map *map, __isl_take isl_basic_map *context); +__isl_export __isl_give isl_stride_info *isl_map_get_range_stride_info( __isl_keep isl_map *map, int pos); __isl_export @@ -642,7 +659,7 @@ isl_bool isl_map_plain_is_equal(__isl_ke __isl_keep isl_map *map2); uint32_t isl_map_get_hash(__isl_keep isl_map *map); - +__isl_export isl_size isl_map_n_basic_map(__isl_keep isl_map *map); __isl_export isl_stat isl_map_foreach_basic_map(__isl_keep isl_map *map, @@ -689,20 +706,24 @@ __isl_give isl_basic_map *isl_basic_map_ enum isl_dim_type c2, enum isl_dim_type c3, enum isl_dim_type c4, enum isl_dim_type c5); +__isl_constructor __isl_give isl_basic_map *isl_basic_map_from_aff(__isl_take isl_aff *aff); +__isl_constructor __isl_give isl_basic_map *isl_basic_map_from_multi_aff( __isl_take isl_multi_aff *maff); __isl_give isl_basic_map *isl_basic_map_from_aff_list( __isl_take isl_space *domain_space, __isl_take isl_aff_list *list); +__isl_constructor __isl_give isl_map *isl_map_from_aff(__isl_take isl_aff *aff); +__isl_constructor __isl_give isl_map *isl_map_from_multi_aff(__isl_take isl_multi_aff *maff); __isl_give isl_pw_aff *isl_map_dim_min(__isl_take isl_map *map, int pos); __isl_give isl_pw_aff *isl_map_dim_max(__isl_take isl_map *map, int pos); ISL_DECLARE_LIST_FN(basic_map) -ISL_DECLARE_LIST_FN(map) +ISL_DECLARE_EXPORTED_LIST_FN(map) #if defined(__cplusplus) } diff -Npur isl_0.22/include/isl/map_type.h isl/include/isl/map_type.h --- isl_0.22/include/isl/map_type.h 2020-04-17 16:49:36.270477000 +0800 +++ isl/include/isl/map_type.h 2020-04-29 18:14:39.945681000 +0800 @@ -13,7 +13,7 @@ typedef struct isl_basic_map isl_basic_m ISL_DECLARE_LIST_TYPE(basic_map) struct __isl_subclass(isl_union_map) isl_map; typedef struct isl_map isl_map; -ISL_DECLARE_LIST_TYPE(map) +ISL_DECLARE_EXPORTED_LIST_TYPE(map) #ifndef isl_basic_set struct __isl_subclass(isl_set) isl_basic_set; @@ -24,11 +24,11 @@ ISL_DECLARE_LIST_TYPE(basic_set) #ifndef isl_set struct __isl_subclass(isl_union_set) isl_set; typedef struct isl_set isl_set; -ISL_DECLARE_LIST_TYPE(set) +ISL_DECLARE_EXPORTED_LIST_TYPE(set) #endif ISL_DECLARE_LIST_FN(basic_set) -ISL_DECLARE_LIST_FN(set) +ISL_DECLARE_EXPORTED_LIST_FN(set) #if defined(__cplusplus) } diff -Npur isl_0.22/include/isl/multi.h isl/include/isl/multi.h --- isl_0.22/include/isl/multi.h 2020-04-17 16:49:36.270477000 +0800 +++ isl/include/isl/multi.h 2020-04-29 18:14:39.945681000 +0800 @@ -36,12 +36,17 @@ isl_size isl_multi_##BASE##_size(__isl_k __isl_export \ __isl_give isl_##BASE *isl_multi_##BASE##_get_at( \ __isl_keep isl_multi_##BASE *multi, int pos); \ +__isl_export \ __isl_give isl_##BASE *isl_multi_##BASE##_get_##BASE( \ __isl_keep isl_multi_##BASE *multi, int pos); \ __isl_export \ __isl_give isl_multi_##BASE *isl_multi_##BASE##_set_at( \ __isl_take isl_multi_##BASE *multi, int pos, \ __isl_take isl_##BASE *el); \ +__isl_export \ +__isl_give isl_##BASE##_list *isl_multi_##BASE##_get_##BASE##_list( \ + __isl_keep isl_multi_##BASE *multi); \ +__isl_export \ __isl_give isl_multi_##BASE *isl_multi_##BASE##_set_##BASE( \ __isl_take isl_multi_##BASE *multi, int pos, \ __isl_take isl_##BASE *el); \ @@ -102,6 +107,7 @@ __isl_overload \ __isl_give isl_multi_##BASE *isl_multi_##BASE##_scale_down_multi_val( \ __isl_take isl_multi_##BASE *multi, \ __isl_take isl_multi_val *mv); \ +__isl_overload \ __isl_give isl_multi_##BASE *isl_multi_##BASE##_mod_multi_val( \ __isl_take isl_multi_##BASE *multi, \ __isl_take isl_multi_val *mv); \ @@ -174,11 +180,13 @@ const char *isl_multi_##BASE##_get_tuple __isl_keep isl_multi_##BASE *multi, enum isl_dim_type type); \ isl_bool isl_multi_##BASE##_has_tuple_id( \ __isl_keep isl_multi_##BASE *multi, enum isl_dim_type type); \ +__isl_export \ __isl_give isl_id *isl_multi_##BASE##_get_tuple_id( \ __isl_keep isl_multi_##BASE *multi, enum isl_dim_type type); \ __isl_give isl_multi_##BASE *isl_multi_##BASE##_set_tuple_name( \ __isl_take isl_multi_##BASE *multi, \ enum isl_dim_type type, const char *s); \ +__isl_export \ __isl_give isl_multi_##BASE *isl_multi_##BASE##_set_tuple_id( \ __isl_take isl_multi_##BASE *multi, \ enum isl_dim_type type, __isl_take isl_id *id); \ diff -Npur isl_0.22/include/isl/schedule.h isl/include/isl/schedule.h --- isl_0.22/include/isl/schedule.h 2020-04-17 16:49:36.270477000 +0800 +++ isl/include/isl/schedule.h 2020-04-29 18:14:39.945681000 +0800 @@ -17,9 +17,16 @@ extern "C" { struct __isl_export isl_schedule_constraints; typedef struct isl_schedule_constraints isl_schedule_constraints; +isl_stat isl_options_set_schedule_nonneg_var_coefficient(isl_ctx *ctx, int val); +int isl_options_get_schedule_nonneg_var_coefficient(isl_ctx *ctx); + isl_stat isl_options_set_schedule_max_coefficient(isl_ctx *ctx, int val); int isl_options_get_schedule_max_coefficient(isl_ctx *ctx); +isl_stat isl_options_set_schedule_unit_max_var_coefficient_sum(isl_ctx *ctx, + int val); +int isl_options_get_schedule_unit_max_var_coefficient_sum(isl_ctx *ctx); + isl_stat isl_options_set_schedule_max_constant_term(isl_ctx *ctx, int val); int isl_options_get_schedule_max_constant_term(isl_ctx *ctx); @@ -104,6 +111,10 @@ __isl_give isl_union_map * isl_schedule_constraints_get_conditional_validity_condition( __isl_keep isl_schedule_constraints *sc); +__isl_export +__isl_give isl_schedule_constraints *isl_schedule_constraints_intersect_domain( + __isl_take isl_schedule_constraints *sc, + __isl_take isl_union_set *domain); __isl_give isl_schedule_constraints *isl_schedule_constraints_apply( __isl_take isl_schedule_constraints *sc, __isl_take isl_union_map *umap); @@ -138,12 +149,14 @@ __isl_export __isl_give isl_union_map *isl_schedule_get_map(__isl_keep isl_schedule *sched); isl_ctx *isl_schedule_get_ctx(__isl_keep isl_schedule *sched); +__isl_export isl_bool isl_schedule_plain_is_equal(__isl_keep isl_schedule *schedule1, __isl_keep isl_schedule *schedule2); __isl_export __isl_give isl_schedule_node *isl_schedule_get_root( __isl_keep isl_schedule *schedule); +__isl_export __isl_give isl_union_set *isl_schedule_get_domain( __isl_keep isl_schedule *schedule); @@ -158,13 +171,16 @@ __isl_give isl_schedule *isl_schedule_ma __isl_give isl_schedule *isl_schedule_insert_context( __isl_take isl_schedule *schedule, __isl_take isl_set *context); +__isl_export __isl_give isl_schedule *isl_schedule_insert_partial_schedule( __isl_take isl_schedule *schedule, __isl_take isl_multi_union_pw_aff *partial); __isl_give isl_schedule *isl_schedule_insert_guard( __isl_take isl_schedule *schedule, __isl_take isl_set *guard); +__isl_export __isl_give isl_schedule *isl_schedule_sequence( __isl_take isl_schedule *schedule1, __isl_take isl_schedule *schedule2); +__isl_export __isl_give isl_schedule *isl_schedule_set( __isl_take isl_schedule *schedule1, __isl_take isl_schedule *schedule2); __isl_give isl_schedule *isl_schedule_intersect_domain( diff -Npur isl_0.22/include/isl/schedule_node.h isl/include/isl/schedule_node.h --- isl_0.22/include/isl/schedule_node.h 2020-04-17 16:49:36.270477000 +0800 +++ isl/include/isl/schedule_node.h 2020-04-29 18:14:39.945681000 +0800 @@ -78,6 +78,7 @@ __isl_export isl_size isl_schedule_node_get_ancestor_child_position( __isl_keep isl_schedule_node *node, __isl_keep isl_schedule_node *ancestor); +__isl_export __isl_give isl_schedule_node *isl_schedule_node_get_child( __isl_keep isl_schedule_node *node, int pos); __isl_export @@ -94,7 +95,7 @@ __isl_give isl_schedule_node *isl_schedu __isl_export __isl_give isl_schedule_node *isl_schedule_node_ancestor( __isl_take isl_schedule_node *node, int generation); -__isl_export + __isl_give isl_schedule_node *isl_schedule_node_child( __isl_take isl_schedule_node *node, int pos); __isl_export @@ -110,20 +111,23 @@ __isl_give isl_schedule_node *isl_schedu __isl_export isl_bool isl_schedule_node_is_subtree_anchored( __isl_keep isl_schedule_node *node); - +__isl_export __isl_give isl_schedule_node *isl_schedule_node_group( __isl_take isl_schedule_node *node, __isl_take isl_id *group_id); __isl_give isl_schedule_node *isl_schedule_node_sequence_splice_child( __isl_take isl_schedule_node *node, int pos); +__isl_export __isl_give isl_space *isl_schedule_node_band_get_space( __isl_keep isl_schedule_node *node); __isl_export __isl_give isl_multi_union_pw_aff *isl_schedule_node_band_get_partial_schedule( __isl_keep isl_schedule_node *node); +__isl_export __isl_give isl_union_map *isl_schedule_node_band_get_partial_schedule_union_map( __isl_keep isl_schedule_node *node); +__isl_export enum isl_ast_loop_type isl_schedule_node_band_member_get_ast_loop_type( __isl_keep isl_schedule_node *node, int pos); __isl_export @@ -133,6 +137,7 @@ __isl_give isl_schedule_node *isl_schedu enum isl_ast_loop_type isl_schedule_node_band_member_get_isolate_ast_loop_type( __isl_keep isl_schedule_node *node, int pos); __isl_give isl_schedule_node * +__isl_export isl_schedule_node_band_member_set_isolate_ast_loop_type( __isl_take isl_schedule_node *node, int pos, enum isl_ast_loop_type type); @@ -181,6 +186,7 @@ __isl_give isl_schedule_node *isl_schedu __isl_export __isl_give isl_schedule_node *isl_schedule_node_band_tile( __isl_take isl_schedule_node *node, __isl_take isl_multi_val *sizes); +__isl_export __isl_give isl_schedule_node *isl_schedule_node_band_sink( __isl_take isl_schedule_node *node); __isl_export @@ -205,16 +211,22 @@ __isl_give isl_union_map *isl_schedule_n __isl_export __isl_give isl_union_set *isl_schedule_node_filter_get_filter( __isl_keep isl_schedule_node *node); +__isl_give isl_schedule_node *isl_schedule_node_filter_set_filter( + __isl_take isl_schedule_node *node, __isl_take isl_union_set *filter); __isl_export __isl_give isl_set *isl_schedule_node_guard_get_guard( __isl_keep isl_schedule_node *node); +__isl_export __isl_give isl_id *isl_schedule_node_mark_get_id( __isl_keep isl_schedule_node *node); +__isl_export isl_size isl_schedule_node_get_schedule_depth( __isl_keep isl_schedule_node *node); +__isl_export __isl_give isl_union_set *isl_schedule_node_get_domain( __isl_keep isl_schedule_node *node); +__isl_export __isl_give isl_union_set *isl_schedule_node_get_universe_domain( __isl_keep isl_schedule_node *node); __isl_export @@ -234,6 +246,7 @@ __isl_give isl_union_map *isl_schedule_n __isl_keep isl_schedule_node *node); __isl_give isl_union_map *isl_schedule_node_get_subtree_expansion( __isl_keep isl_schedule_node *node); +__isl_export __isl_give isl_union_pw_multi_aff *isl_schedule_node_get_subtree_contraction( __isl_keep isl_schedule_node *node); @@ -264,6 +277,7 @@ __isl_give isl_schedule_node *isl_schedu __isl_give isl_schedule_node *isl_schedule_node_cut( __isl_take isl_schedule_node *node); +__isl_export __isl_give isl_schedule_node *isl_schedule_node_delete( __isl_take isl_schedule_node *node); @@ -293,6 +307,27 @@ __isl_give isl_printer *isl_printer_prin void isl_schedule_node_dump(__isl_keep isl_schedule_node *node); __isl_give char *isl_schedule_node_to_str(__isl_keep isl_schedule_node *node); +struct isl_schedule_tree; +typedef struct isl_schedule_tree isl_schedule_tree; + +__isl_export +__isl_give isl_schedule_tree *isl_schedule_node_get_tree( + __isl_keep isl_schedule_node *node); +__isl_export +__isl_give isl_schedule_node *isl_schedule_node_graft_tree( + __isl_take isl_schedule_node *pos, __isl_take isl_schedule_tree *tree); + +__isl_export +__isl_give isl_schedule_tree *isl_schedule_tree_get_child( + __isl_keep isl_schedule_tree *tree, int pos); +__isl_export +__isl_give isl_schedule_tree *isl_schedule_tree_replace_child( + __isl_take isl_schedule_tree *tree, int pos, + __isl_take isl_schedule_tree *new_child); +__isl_export +__isl_null isl_schedule_tree *isl_schedule_tree_free( + __isl_take isl_schedule_tree *tree); + #if defined(__cplusplus) } #endif diff -Npur isl_0.22/include/isl/set.h isl/include/isl/set.h --- isl_0.22/include/isl/set.h 2020-04-17 16:49:36.270477000 +0800 +++ isl/include/isl/set.h 2020-04-29 18:14:39.945681000 +0800 @@ -31,6 +31,7 @@ isl_size isl_basic_set_total_dim(__isl_k isl_size isl_basic_set_dim(__isl_keep isl_basic_set *bset, enum isl_dim_type type); +__isl_export isl_size isl_set_n_dim(__isl_keep isl_set *set); isl_size isl_set_n_param(__isl_keep isl_set *set); isl_size isl_set_dim(__isl_keep isl_set *set, enum isl_dim_type type); @@ -50,10 +51,13 @@ __isl_give isl_local_space *isl_basic_se __isl_keep isl_basic_set *bset); const char *isl_basic_set_get_tuple_name(__isl_keep isl_basic_set *bset); +__isl_export isl_bool isl_set_has_tuple_name(__isl_keep isl_set *set); +__isl_export const char *isl_set_get_tuple_name(__isl_keep isl_set *set); __isl_give isl_basic_set *isl_basic_set_set_tuple_name( __isl_take isl_basic_set *set, const char *s); +__isl_export __isl_give isl_set *isl_set_set_tuple_name(__isl_take isl_set *set, const char *s); const char *isl_basic_set_get_dim_name(__isl_keep isl_basic_set *bset, @@ -78,10 +82,12 @@ isl_bool isl_set_has_dim_id(__isl_keep i enum isl_dim_type type, unsigned pos); __isl_give isl_id *isl_set_get_dim_id(__isl_keep isl_set *set, enum isl_dim_type type, unsigned pos); +__isl_export __isl_give isl_set *isl_set_set_tuple_id(__isl_take isl_set *set, __isl_take isl_id *id); __isl_give isl_set *isl_set_reset_tuple_id(__isl_take isl_set *set); isl_bool isl_set_has_tuple_id(__isl_keep isl_set *set); +__isl_export __isl_give isl_id *isl_set_get_tuple_id(__isl_keep isl_set *set); __isl_give isl_set *isl_set_reset_user(__isl_take isl_set *set); @@ -154,6 +160,7 @@ __isl_give isl_basic_set *isl_basic_set_ enum isl_dim_type type, unsigned pos, __isl_take isl_val *v); __isl_give isl_set *isl_set_fix_si(__isl_take isl_set *set, enum isl_dim_type type, unsigned pos, int value); +__isl_export __isl_give isl_set *isl_set_lower_bound_si(__isl_take isl_set *set, enum isl_dim_type type, unsigned pos, int value); __isl_give isl_basic_set *isl_basic_set_lower_bound_val( @@ -161,6 +168,7 @@ __isl_give isl_basic_set *isl_basic_set_ __isl_take isl_val *value); __isl_give isl_set *isl_set_lower_bound_val(__isl_take isl_set *set, enum isl_dim_type type, unsigned pos, __isl_take isl_val *value); +__isl_export __isl_give isl_set *isl_set_upper_bound_si(__isl_take isl_set *set, enum isl_dim_type type, unsigned pos, int value); __isl_give isl_basic_set *isl_basic_set_upper_bound_val( @@ -227,6 +235,7 @@ __isl_give isl_basic_set *isl_basic_set_ __isl_take isl_basic_set *bset); __isl_export __isl_give isl_set *isl_set_params(__isl_take isl_set *set); +__isl_export __isl_give isl_set *isl_set_from_params(__isl_take isl_set *set); __isl_export @@ -258,6 +267,7 @@ __isl_export __isl_give isl_set *isl_set_empty(__isl_take isl_space *space); __isl_export __isl_give isl_set *isl_set_universe(__isl_take isl_space *space); +__isl_export __isl_give isl_set *isl_set_nat_universe(__isl_take isl_space *dim); __isl_give isl_set *isl_set_copy(__isl_keep isl_set *set); __isl_null isl_set *isl_set_free(__isl_take isl_set *set); @@ -276,6 +286,7 @@ __isl_give isl_basic_set *isl_set_affine __isl_give isl_basic_set *isl_set_convex_hull(__isl_take isl_set *set); __isl_export __isl_give isl_basic_set *isl_set_polyhedral_hull(__isl_take isl_set *set); +__isl_export __isl_give isl_basic_set *isl_set_simple_hull(__isl_take isl_set *set); __isl_export __isl_give isl_basic_set *isl_set_unshifted_simple_hull( @@ -370,6 +381,7 @@ __isl_give isl_basic_set *isl_basic_set_ enum isl_dim_type type, unsigned first, unsigned n); __isl_give isl_set *isl_set_eliminate(__isl_take isl_set *set, enum isl_dim_type type, unsigned first, unsigned n); +__isl_export __isl_give isl_set *isl_set_eliminate_dims(__isl_take isl_set *set, unsigned first, unsigned n); __isl_give isl_set *isl_set_remove_dims(__isl_take isl_set *bset, @@ -406,6 +418,7 @@ isl_bool isl_set_involves_dims(__isl_kee void isl_set_print_internal(__isl_keep isl_set *set, FILE *out, int indent); isl_bool isl_set_plain_is_empty(__isl_keep isl_set *set); +__isl_export isl_bool isl_set_plain_is_universe(__isl_keep isl_set *set); isl_bool isl_set_is_params(__isl_keep isl_set *set); __isl_export @@ -480,6 +493,7 @@ isl_bool isl_set_plain_is_disjoint(__isl uint32_t isl_set_get_hash(struct isl_set *set); +__isl_export isl_size isl_set_n_basic_set(__isl_keep isl_set *set); __isl_export isl_stat isl_set_foreach_basic_set(__isl_keep isl_set *set, @@ -537,6 +551,7 @@ __isl_give isl_basic_set *isl_basic_set_ __isl_give isl_basic_set *isl_basic_set_from_multi_aff( __isl_take isl_multi_aff *ma); +__isl_overload __isl_give isl_set *isl_set_from_multi_aff(__isl_take isl_multi_aff *ma); __isl_give isl_mat *isl_basic_set_reduced_basis(__isl_keep isl_basic_set *bset); @@ -550,7 +565,9 @@ __isl_give isl_basic_set *isl_basic_set_ __isl_take isl_basic_set *bset); __isl_give isl_basic_set *isl_set_solutions(__isl_take isl_set *set); +__isl_export __isl_give isl_pw_aff *isl_set_dim_max(__isl_take isl_set *set, int pos); +__isl_export __isl_give isl_pw_aff *isl_set_dim_min(__isl_take isl_set *set, int pos); __isl_give char *isl_basic_set_to_str(__isl_keep isl_basic_set *bset); diff -Npur isl_0.22/include/isl/space.h isl/include/isl/space.h --- isl_0.22/include/isl/space.h 2020-04-17 16:49:36.270477000 +0800 +++ isl/include/isl/space.h 2020-04-29 18:14:39.945681000 +0800 @@ -26,6 +26,7 @@ __isl_give isl_space *isl_space_alloc(is unsigned nparam, unsigned n_in, unsigned n_out); __isl_give isl_space *isl_space_set_alloc(isl_ctx *ctx, unsigned nparam, unsigned dim); +__isl_constructor __isl_give isl_space *isl_space_params_alloc(isl_ctx *ctx, unsigned nparam); __isl_give isl_space *isl_space_copy(__isl_keep isl_space *dim); __isl_null isl_space *isl_space_free(__isl_take isl_space *space); @@ -34,6 +35,10 @@ isl_bool isl_space_is_params(__isl_keep isl_bool isl_space_is_set(__isl_keep isl_space *space); isl_bool isl_space_is_map(__isl_keep isl_space *space); +__isl_overload +isl_bool isl_space_has_param_id(__isl_keep isl_space *space, + __isl_keep isl_id *id); +__isl_overload __isl_give isl_space *isl_space_add_param_id(__isl_take isl_space *space, __isl_take isl_id *id); @@ -43,12 +48,16 @@ isl_bool isl_space_has_tuple_name(__isl_ enum isl_dim_type type); __isl_keep const char *isl_space_get_tuple_name(__isl_keep isl_space *space, enum isl_dim_type type); +__isl_export +__isl_give isl_space *isl_space_set_set_tuple_id(__isl_take isl_space *space, + __isl_take isl_id *id); __isl_give isl_space *isl_space_set_tuple_id(__isl_take isl_space *space, enum isl_dim_type type, __isl_take isl_id *id); __isl_give isl_space *isl_space_reset_tuple_id(__isl_take isl_space *space, enum isl_dim_type type); isl_bool isl_space_has_tuple_id(__isl_keep isl_space *space, enum isl_dim_type type); +__isl_export __isl_give isl_id *isl_space_get_tuple_id(__isl_keep isl_space *space, enum isl_dim_type type); __isl_give isl_space *isl_space_reset_user(__isl_take isl_space *space); @@ -76,6 +85,7 @@ __isl_keep const char *isl_space_get_dim ISL_DEPRECATED __isl_give isl_space *isl_space_extend(__isl_take isl_space *dim, unsigned nparam, unsigned n_in, unsigned n_out); +__isl_export __isl_give isl_space *isl_space_add_dims(__isl_take isl_space *space, enum isl_dim_type type, unsigned n); __isl_give isl_space *isl_space_move_dims(__isl_take isl_space *space, @@ -85,6 +95,7 @@ __isl_give isl_space *isl_space_insert_d enum isl_dim_type type, unsigned pos, unsigned n); __isl_give isl_space *isl_space_join(__isl_take isl_space *left, __isl_take isl_space *right); +__isl_export __isl_give isl_space *isl_space_product(__isl_take isl_space *left, __isl_take isl_space *right); __isl_give isl_space *isl_space_domain_product(__isl_take isl_space *left, @@ -103,6 +114,7 @@ __isl_give isl_space *isl_space_range_fa __isl_take isl_space *space); __isl_export __isl_give isl_space *isl_space_map_from_set(__isl_take isl_space *space); +__isl_export __isl_give isl_space *isl_space_map_from_domain_and_range( __isl_take isl_space *domain, __isl_take isl_space *range); __isl_give isl_space *isl_space_reverse(__isl_take isl_space *space); @@ -126,12 +138,13 @@ __isl_give isl_space *isl_space_domain_m __isl_give isl_space *isl_space_range_map(__isl_take isl_space *space); __isl_export __isl_give isl_space *isl_space_params(__isl_take isl_space *space); -__isl_overload +__isl_export __isl_give isl_space *isl_space_add_unnamed_tuple_ui( __isl_take isl_space *space, unsigned dim); -__isl_overload +__isl_export __isl_give isl_space *isl_space_add_named_tuple_id_ui( __isl_take isl_space *space, __isl_take isl_id *tuple_id, unsigned dim); +__isl_export __isl_give isl_space *isl_space_set_from_params(__isl_take isl_space *space); __isl_give isl_space *isl_space_align_params(__isl_take isl_space *dim1, @@ -150,13 +163,17 @@ __isl_give isl_space *isl_space_unwrap(_ isl_bool isl_space_can_zip(__isl_keep isl_space *space); __isl_give isl_space *isl_space_zip(__isl_take isl_space *space); +__isl_export isl_bool isl_space_can_curry(__isl_keep isl_space *space); +__isl_export __isl_give isl_space *isl_space_curry(__isl_take isl_space *space); isl_bool isl_space_can_range_curry(__isl_keep isl_space *space); __isl_give isl_space *isl_space_range_curry(__isl_take isl_space *space); +__isl_export isl_bool isl_space_can_uncurry(__isl_keep isl_space *space); +__isl_export __isl_give isl_space *isl_space_uncurry(__isl_take isl_space *space); isl_bool isl_space_is_domain(__isl_keep isl_space *space1, @@ -168,6 +185,7 @@ isl_bool isl_space_is_equal(__isl_keep i __isl_keep isl_space *space2); isl_bool isl_space_has_equal_params(__isl_keep isl_space *space1, __isl_keep isl_space *space2); +__isl_export isl_bool isl_space_has_equal_tuples(__isl_keep isl_space *space1, __isl_keep isl_space *space2); isl_bool isl_space_tuple_is_equal(__isl_keep isl_space *space1, @@ -176,6 +194,7 @@ isl_bool isl_space_tuple_is_equal(__isl_ ISL_DEPRECATED isl_bool isl_space_match(__isl_keep isl_space *space1, enum isl_dim_type type1, __isl_keep isl_space *space2, enum isl_dim_type type2); +__isl_export isl_size isl_space_dim(__isl_keep isl_space *space, enum isl_dim_type type); __isl_export diff -Npur isl_0.22/include/isl/stride_info.h isl/include/isl/stride_info.h --- isl_0.22/include/isl/stride_info.h 2020-04-17 16:49:36.270477000 +0800 +++ isl/include/isl/stride_info.h 2020-04-29 18:14:39.945681000 +0800 @@ -12,11 +12,13 @@ extern "C" { #endif -struct isl_stride_info; +struct __isl_export isl_stride_info; typedef struct isl_stride_info isl_stride_info; isl_ctx *isl_stride_info_get_ctx(__isl_keep isl_stride_info *si); +__isl_export __isl_give isl_val *isl_stride_info_get_stride(__isl_keep isl_stride_info *si); +__isl_export __isl_give isl_aff *isl_stride_info_get_offset(__isl_keep isl_stride_info *si); __isl_null isl_stride_info *isl_stride_info_free( __isl_take isl_stride_info *si); diff -Npur isl_0.22/include/isl/union_map.h isl/include/isl/union_map.h --- isl_0.22/include/isl/union_map.h 2020-04-17 16:49:36.270477000 +0800 +++ isl/include/isl/union_map.h 2020-04-29 18:14:39.945681000 +0800 @@ -29,6 +29,7 @@ __isl_overload __isl_give isl_union_map *isl_union_map_empty_ctx(isl_ctx *ctx); __isl_give isl_union_map *isl_union_map_empty_space( __isl_take isl_space *space); +__isl_export __isl_give isl_union_map *isl_union_map_empty(__isl_take isl_space *space); __isl_give isl_union_map *isl_union_map_copy(__isl_keep isl_union_map *umap); __isl_null isl_union_map *isl_union_map_free(__isl_take isl_union_map *umap); @@ -90,6 +91,7 @@ __isl_give isl_union_map *isl_union_map_ __isl_export __isl_give isl_union_map *isl_union_map_lexmax(__isl_take isl_union_map *umap); +__isl_export __isl_give isl_union_map *isl_union_map_add_map(__isl_take isl_union_map *umap, __isl_take isl_map *map); __isl_export @@ -115,6 +117,7 @@ __isl_give isl_union_map *isl_union_map_ __isl_export __isl_give isl_union_map *isl_union_map_range_product( __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2); +__isl_export __isl_give isl_union_map *isl_union_map_flat_range_product( __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2); __isl_export @@ -255,10 +258,12 @@ isl_bool isl_union_map_is_strict_subset( uint32_t isl_union_map_get_hash(__isl_keep isl_union_map *umap); +__isl_export isl_size isl_union_map_n_map(__isl_keep isl_union_map *umap); __isl_export isl_stat isl_union_map_foreach_map(__isl_keep isl_union_map *umap, isl_stat (*fn)(__isl_take isl_map *map, void *user), void *user); +__isl_export __isl_give isl_map_list *isl_union_map_get_map_list( __isl_keep isl_union_map *umap); __isl_export @@ -274,6 +279,7 @@ __isl_give isl_map *isl_union_map_extrac __isl_take isl_space *dim); __isl_export isl_bool isl_union_map_isa_map(__isl_keep isl_union_map *umap); +__isl_overload __isl_give isl_map *isl_map_from_union_map(__isl_take isl_union_map *umap); __isl_give isl_basic_map *isl_union_map_sample(__isl_take isl_union_map *umap); @@ -299,9 +305,11 @@ __isl_overload __isl_give isl_union_map *isl_union_map_eq_at_multi_union_pw_aff( __isl_take isl_union_map *umap, __isl_take isl_multi_union_pw_aff *mupa); +__isl_overload __isl_give isl_union_map *isl_union_map_lex_lt_at_multi_union_pw_aff( __isl_take isl_union_map *umap, __isl_take isl_multi_union_pw_aff *mupa); +__isl_overload __isl_give isl_union_map *isl_union_map_lex_gt_at_multi_union_pw_aff( __isl_take isl_union_map *umap, __isl_take isl_multi_union_pw_aff *mupa); diff -Npur isl_0.22/include/isl/union_set.h isl/include/isl/union_set.h --- isl_0.22/include/isl/union_set.h 2020-04-17 16:49:36.270477000 +0800 +++ isl/include/isl/union_set.h 2020-04-29 18:14:39.945681000 +0800 @@ -20,6 +20,7 @@ __isl_overload __isl_give isl_union_set *isl_union_set_empty_ctx(isl_ctx *ctx); __isl_give isl_union_set *isl_union_set_empty_space( __isl_take isl_space *space); +__isl_export __isl_give isl_union_set *isl_union_set_empty(__isl_take isl_space *space); __isl_give isl_union_set *isl_union_set_copy(__isl_keep isl_union_set *uset); __isl_null isl_union_set *isl_union_set_free(__isl_take isl_union_set *uset); @@ -59,7 +60,7 @@ __isl_export __isl_give isl_union_set *isl_union_set_lexmin(__isl_take isl_union_set *uset); __isl_export __isl_give isl_union_set *isl_union_set_lexmax(__isl_take isl_union_set *uset); - +__isl_export __isl_give isl_union_set *isl_union_set_add_set(__isl_take isl_union_set *uset, __isl_take isl_set *set); __isl_export @@ -124,6 +125,7 @@ isl_bool isl_union_set_is_strict_subset( uint32_t isl_union_set_get_hash(__isl_keep isl_union_set *uset); +__isl_export isl_size isl_union_set_n_set(__isl_keep isl_union_set *uset); __isl_export isl_stat isl_union_set_foreach_set(__isl_keep isl_union_set *uset, @@ -133,6 +135,7 @@ isl_bool isl_union_set_every_set(__isl_k isl_bool (*test)(__isl_keep isl_set *set, void *user), void *user); __isl_give isl_basic_set_list *isl_union_set_get_basic_set_list( __isl_keep isl_union_set *uset); +__isl_export __isl_give isl_set_list *isl_union_set_get_set_list( __isl_keep isl_union_set *uset); isl_bool isl_union_set_contains(__isl_keep isl_union_set *uset, @@ -142,6 +145,7 @@ __isl_give isl_set *isl_union_set_extrac __isl_take isl_space *dim); __isl_export isl_bool isl_union_set_isa_set(__isl_keep isl_union_set *uset); +__isl_export __isl_give isl_set *isl_set_from_union_set(__isl_take isl_union_set *uset); __isl_export isl_stat isl_union_set_foreach_point(__isl_keep isl_union_set *uset, diff -Npur isl_0.22/interface/cpp.cc isl/interface/cpp.cc --- isl_0.22/interface/cpp.cc 2020-04-17 16:49:36.270477000 +0800 +++ isl/interface/cpp.cc 2020-04-29 18:14:39.945681000 +0800 @@ -253,6 +253,7 @@ void cpp_generator::print_class(ostream print_ptr_decl(os, clazz); print_downcast_decl(os, clazz); print_ctx_decl(os); + print_str_decl(os, clazz); osprintf(os, "\n"); print_persistent_callbacks_decl(os, clazz); print_methods_decl(os, clazz); @@ -467,6 +468,11 @@ void cpp_generator::print_destructor_dec * * Check if the current object is a null pointer. * + * 4) explicit operator bool() + * + * Check if the current object represents a valid isl object, + * i.e., if it is not a null pointer. + * * The functions get() and release() model the value_ptr proposed in * http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3339.pdf. * The copy() function is an extension to allow the user to explicitly @@ -487,6 +493,7 @@ void cpp_generator::print_ptr_decl(ostre osprintf(os, " inline __isl_keep %s *get() const;\n", name); osprintf(os, " inline __isl_give %s *release();\n", name); osprintf(os, " inline bool is_null() const;\n"); + osprintf(os, " inline explicit operator bool() const;\n"); } /* Print a template declaration with given indentation @@ -548,6 +555,14 @@ void cpp_generator::print_ctx_decl(ostre osprintf(os, " inline %sctx ctx() const;\n", ns.c_str()); } +void cpp_generator::print_str_decl(ostream &os, const isl_class &clazz) +{ + if (!clazz.fn_to_str) + return; + + osprintf(os, " inline std::string to_str() const;\n"); +} + /* Add a space to the return type "type" if needed, * i.e., if it is not the type of a pointer. */ @@ -835,6 +850,7 @@ void cpp_generator::print_class_impl(ost print_copy_assignment_impl(os, clazz); print_destructor_impl(os, clazz); print_ptr_impl(os, clazz); + print_str_impl(os, clazz); print_downcast_impl(os, clazz); print_ctx_impl(os, clazz); print_persistent_callbacks_impl(os, clazz); @@ -1328,6 +1344,10 @@ void cpp_generator::print_ptr_impl(ostre osprintf(os, "bool %s::is_null() const {\n", cppname); osprintf(os, " return ptr == nullptr;\n"); osprintf(os, "}\n"); + osprintf(os, "%s::operator bool() const\n", cppname); + osprintf(os, "{\n"); + osprintf(os, " return !is_null();\n"); + osprintf(os, "}\n"); } /* Print implementations for the "as" and "isa" methods, if "clazz" @@ -1379,10 +1399,7 @@ void cpp_generator::print_downcast_impl( if (checked) osprintf(os, " if (isa().is_false())\n"); else - osprintf(os, " if (!isa())\n"); - print_invalid(os, 4, "not an object of the requested subtype", - "return T()"); - osprintf(os, " return T(copy());\n"); + osprintf(os, " return isa() ? T(copy()) : T();\n"); osprintf(os, "}\n"); } @@ -1401,6 +1418,25 @@ void cpp_generator::print_ctx_impl(ostre osprintf(os, "}\n"); } +void cpp_generator::print_str_impl(ostream &os, const isl_class &clazz) +{ + if (!clazz.fn_to_str) + return; + + const char *name = clazz.name.c_str(); + std::string cppstring = type2cpp(clazz); + const char *cppname = cppstring.c_str(); + osprintf(os, "\n"); + osprintf(os, "std::string %s::to_str() const {\n", cppname); + osprintf(os, " char *Tmp = %s_to_str(get());\n", name, name); + osprintf(os, " if (!Tmp)\n"); + osprintf(os, " return \"\";\n"); + osprintf(os, " std::string S(Tmp);\n"); + osprintf(os, " free(Tmp);\n"); + osprintf(os, " return S;\n"); + osprintf(os, "}\n"); +} + /* Print the implementations of the methods needed for the persistent callbacks * of "clazz". */ @@ -2439,6 +2475,7 @@ void cpp_generator::print_callback_local */ static const char *rename_map[][2] = { { "union", "unite" }, + { "delete", "del" }, }; /* Rename method "name" in case the method name in the C++ bindings should not diff -Npur isl_0.22/interface/cpp.h isl/interface/cpp.h --- isl_0.22/interface/cpp.h 2020-04-17 16:49:36.270477000 +0800 +++ isl/interface/cpp.h 2020-04-29 18:14:39.945681000 +0800 @@ -50,6 +50,7 @@ private: const isl_class &super); void print_downcast_decl(ostream &os, const isl_class &clazz); void print_ctx_decl(ostream &os); + void print_str_decl(ostream &os, const isl_class &clazz); void print_persistent_callback_prototype(ostream &os, const isl_class &clazz, FunctionDecl *method, bool is_declaration); @@ -101,6 +102,7 @@ private: void print_ptr_impl(ostream &os, const isl_class &clazz); void print_downcast_impl(ostream &os, const isl_class &clazz); void print_ctx_impl(ostream &os, const isl_class &clazz); + void print_str_impl(ostream &os, const isl_class &clazz); void print_persistent_callbacks_impl(ostream &os, const isl_class &clazz); void print_methods_impl(ostream &os, const isl_class &clazz); diff -Npur isl_0.22/isl_aff.c isl/isl_aff.c --- isl_0.22/isl_aff.c 2020-04-17 16:49:36.242477000 +0800 +++ isl/isl_aff.c 2020-04-29 18:14:39.945681000 +0800 @@ -57,6 +57,21 @@ #include +/* Check that "space" is a set space. + */ +static isl_stat check_space_is_set(__isl_keep isl_space *space) +{ + isl_bool is_set; + + is_set = isl_space_is_set(space); + if (is_set < 0) + return isl_stat_error; + if (!is_set) + isl_die(isl_space_get_ctx(space), isl_error_invalid, + "expecting set space", return isl_stat_error); + return isl_stat_ok; +} + __isl_give isl_aff *isl_aff_alloc_vec(__isl_take isl_local_space *ls, __isl_take isl_vec *v) { @@ -4135,6 +4150,34 @@ __isl_give isl_multi_aff *isl_multi_aff_ return ma; error: isl_space_free(space); + return NULL; +} + +/* Given the space of a wrapped map of the form A[B -> C], + * return the map A[B -> C] -> C. + */ +__isl_give isl_multi_aff *isl_multi_aff_wrapped_range_map( + __isl_take isl_space *space) +{ + isl_bool has_id; + isl_id *id; + isl_multi_aff *ma; + + if (check_space_is_set(space) < 0) + goto error; + has_id = isl_space_has_tuple_id(space, isl_dim_set); + if (has_id < 0) + goto error; + if (!has_id) + return isl_multi_aff_range_map(isl_space_unwrap(space)); + + id = isl_space_get_tuple_id(space, isl_dim_set); + ma = isl_multi_aff_range_map(isl_space_unwrap(space)); + ma = isl_multi_aff_set_tuple_id(ma, isl_dim_in, id); + + return ma; +error: + isl_space_free(space); return NULL; } diff -Npur isl_0.22/isl_ast_codegen.c isl/isl_ast_codegen.c --- isl_0.22/isl_ast_codegen.c 2020-04-17 16:49:36.242477000 +0800 +++ isl/isl_ast_codegen.c 2020-04-29 18:14:39.933681000 +0800 @@ -3644,8 +3644,20 @@ static __isl_give isl_ast_graft_list *ge domain = isl_set_from_union_set(schedule_domain); isolated = isl_ast_build_get_isolated(build); + if (build->depth - build->outer_pos) { + // eliminate the constraint and isolate the piece on the corner + isolated = isl_set_eliminate(isolated, isl_dim_set, build->outer_pos, (build->depth - build->outer_pos)); + if (NULL != build->node) { + isl_size n = isl_schedule_node_band_n_member(build->node); + if (build->outer_pos >= n) { + // eliminate the parent band's constraint + isolated = isl_set_eliminate(isolated, isl_dim_set, (build->outer_pos - n), (build->depth - build->outer_pos)); + } + } + } isolated = isl_set_intersect(isolated, isl_set_copy(domain)); test = isl_ast_build_specialize(build, isl_set_copy(isolated)); + isolated = isl_set_intersect(isolated, isl_set_copy(test)); empty = isl_set_is_empty(test); isl_set_free(test); if (empty < 0) diff -Npur isl_0.22/isl_box.c isl/isl_box.c --- isl_0.22/isl_box.c 2020-04-17 16:49:36.242477000 +0800 +++ isl/isl_box.c 2020-05-17 20:34:22.000000000 +0800 @@ -302,6 +302,13 @@ static isl_stat compute_size_in_directio * Initialize the size with infinity and if no better size is found * then invalidate the box. Otherwise, set the offset and size * in the given direction by those that correspond to the smallest size. + * + * Note that while evaluating the size corresponding to a lower bound, + * an affine expression is constructed from the lower bound. + * This lower bound may therefore not have any unknown local variables. + * Eliminate any unknown local variables up front. + * No such restriction needs to be imposed on the set over which + * the size is computed. */ static __isl_give isl_fixed_box *set_dim_extent(__isl_take isl_fixed_box *box, __isl_keep isl_map *map, int pos) @@ -309,6 +316,7 @@ static __isl_give isl_fixed_box *set_dim struct isl_size_info info; isl_bool valid; isl_ctx *ctx; + isl_basic_set *bset; if (!box || !map) return isl_fixed_box_free(box); @@ -316,16 +324,18 @@ static __isl_give isl_fixed_box *set_dim ctx = isl_map_get_ctx(map); map = isl_map_copy(map); map = isl_map_project_onto(map, isl_dim_out, pos, 1); - map = isl_map_compute_divs(map); info.size = isl_val_infty(ctx); info.offset = NULL; info.pos = isl_map_dim(map, isl_dim_in); info.bset = isl_basic_map_wrap(isl_map_simple_hull(map)); + bset = isl_basic_set_copy(info.bset); + bset = isl_basic_set_remove_unknown_divs(bset); if (info.pos < 0) - info.bset = isl_basic_set_free(info.bset); - if (isl_basic_set_foreach_constraint(info.bset, + bset = isl_basic_set_free(bset); + if (isl_basic_set_foreach_constraint(bset, &compute_size_in_direction, &info) < 0) box = isl_fixed_box_free(box); + isl_basic_set_free(bset); valid = isl_val_is_int(info.size); if (valid < 0) box = isl_fixed_box_free(box); diff -Npur isl_0.22/isl_factorization.c isl/isl_factorization.c --- isl_0.22/isl_factorization.c 2020-04-17 16:49:36.246477000 +0800 +++ isl/isl_factorization.c 2020-04-29 18:14:39.961680000 +0800 @@ -18,8 +18,18 @@ #include #include +/* Return the isl_ctx to which "f" belongs. + */ +isl_ctx *isl_factorizer_get_ctx(__isl_keep isl_factorizer *f) +{ + if (!f) + return NULL; + return isl_basic_set_get_ctx(f->bset); +} + static __isl_give isl_factorizer *isl_factorizer_alloc( - __isl_take isl_morph *morph, int n_group) + __isl_keep isl_basic_set *bset, __isl_take isl_morph *morph, + int n_group) { isl_factorizer *f = NULL; int *len = NULL; @@ -37,6 +47,7 @@ static __isl_give isl_factorizer *isl_fa if (!f) goto error; + f->bset = isl_basic_set_copy(bset); f->morph = morph; f->n_group = n_group; f->len = len; @@ -48,14 +59,16 @@ error: return NULL; } -void isl_factorizer_free(__isl_take isl_factorizer *f) +__isl_null isl_factorizer *isl_factorizer_free(__isl_take isl_factorizer *f) { if (!f) - return; + return NULL; + isl_basic_set_free(f->bset); isl_morph_free(f->morph); free(f->len); free(f); + return NULL; } void isl_factorizer_dump(__isl_take isl_factorizer *f) @@ -77,7 +90,7 @@ void isl_factorizer_dump(__isl_take isl_ __isl_give isl_factorizer *isl_factorizer_identity(__isl_keep isl_basic_set *bset) { - return isl_factorizer_alloc(isl_morph_identity(bset), 0); + return isl_factorizer_alloc(bset, isl_morph_identity(bset), 0); } __isl_give isl_factorizer *isl_factorizer_groups(__isl_keep isl_basic_set *bset, @@ -108,7 +121,7 @@ __isl_give isl_factorizer *isl_factorize space = isl_space_add_dims(space, isl_dim_set, nvar); ran = isl_basic_set_universe(space); morph = isl_morph_alloc(dom, ran, Q, U); - f = isl_factorizer_alloc(morph, n); + f = isl_factorizer_alloc(bset, morph, n); if (!f) return NULL; for (i = 0; i < n; ++i) @@ -326,3 +339,51 @@ error: clear_groups(&g); return NULL; } + +/* Given the factorizer "f" of a basic set, + * call "test" on each resulting factor as long as each call succeeds. + */ +__isl_give isl_bool isl_factorizer_every_factor_basic_set( + __isl_keep isl_factorizer *f, + isl_bool (*test)(__isl_keep isl_basic_set *bset, void *user), + void *user) +{ + int i, n; + isl_bool every = isl_bool_true; + isl_size nparam, nvar; + isl_basic_set *bset; + + if (!f) + return isl_bool_error; + nparam = isl_basic_set_dim(f->bset, isl_dim_param); + nvar = isl_basic_set_dim(f->bset, isl_dim_set); + if (nparam < 0 || nvar < 0) + return isl_bool_error; + + bset = isl_basic_set_copy(f->bset); + bset = isl_morph_basic_set(isl_morph_copy(f->morph), bset); + + for (i = 0, n = 0; i < f->n_group; ++i) { + isl_basic_set *factor; + + factor = isl_basic_set_copy(bset); + factor = isl_basic_set_drop_constraints_involving(factor, + nparam + n + f->len[i], nvar - n - f->len[i]); + factor = isl_basic_set_drop_constraints_involving(factor, + nparam, n); + factor = isl_basic_set_drop(factor, isl_dim_set, + n + f->len[i], nvar - n - f->len[i]); + factor = isl_basic_set_drop(factor, isl_dim_set, 0, n); + every = test(factor, user); + isl_basic_set_free(factor); + + if (every < 0 || !every) + break; + + n += f->len[i]; + } + + isl_basic_set_free(bset); + + return every; +} diff -Npur isl_0.22/isl_factorization.h isl/isl_factorization.h --- isl_0.22/isl_factorization.h 2020-04-17 16:49:36.246477000 +0800 +++ isl/isl_factorization.h 2020-04-29 18:14:39.937681000 +0800 @@ -8,13 +8,14 @@ extern "C" { #endif -/* Data for factorizing a particular basic set. +/* Data for factorizing the basic set "bset". * After applying "morph" to the basic set, there are "n_group" * groups of consecutive set variables, each of length "len[i]", * with 0 <= i < n_group. * If no factorization is possible, then "n_group" is set to 0. */ struct isl_factorizer { + isl_basic_set *bset; isl_morph *morph; int n_group; int *len; @@ -24,9 +25,16 @@ typedef struct isl_factorizer isl_factor __isl_give isl_factorizer *isl_basic_set_factorizer( __isl_keep isl_basic_set *bset); -void isl_factorizer_free(__isl_take isl_factorizer *f); +isl_ctx *isl_factorizer_get_ctx(__isl_keep isl_factorizer *f); + +__isl_null isl_factorizer *isl_factorizer_free(__isl_take isl_factorizer *f); void isl_factorizer_dump(__isl_take isl_factorizer *f); +__isl_give isl_bool isl_factorizer_every_factor_basic_set( + __isl_keep isl_factorizer *f, + isl_bool (*test)(__isl_keep isl_basic_set *bset, void *user), + void *user); + #if defined(__cplusplus) } #endif diff -Npur isl_0.22/isl_farkas.c isl/isl_farkas.c --- isl_0.22/isl_farkas.c 2020-04-17 16:49:36.246477000 +0800 +++ isl/isl_farkas.c 2020-04-29 18:14:39.937681000 +0800 @@ -12,6 +12,9 @@ #include #include #include +#include +#include +#include /* * Let C be a cone and define @@ -222,30 +225,35 @@ static __isl_give isl_basic_set *rationa * As explained above, we add an extra dimension to represent * the coefficient of the constant term when going from solutions * to coefficients (shift == 1) and we drop the extra dimension when going - * in the opposite direction (shift == -1). "space" is the space in which - * the dual should be created. + * in the opposite direction (shift == -1). + * The dual can be created in an arbitrary space. + * The caller is responsible for putting the result in the appropriate space. * * If "bset" is (obviously) empty, then the way this emptiness * is represented by the constraints does not allow for the application * of the standard farkas algorithm. We therefore handle this case * specifically and return the universe basic set. */ -static __isl_give isl_basic_set *farkas(__isl_take isl_space *space, - __isl_take isl_basic_set *bset, int shift) +static __isl_give isl_basic_set *farkas(__isl_take isl_basic_set *bset, + int shift) { int i, j, k; + isl_ctx *ctx; + isl_space *space; isl_basic_set *dual = NULL; isl_size total; + total = isl_basic_set_dim(bset, isl_dim_all); + if (total < 0) + return isl_basic_set_free(bset); + + ctx = isl_basic_set_get_ctx(bset); + space = isl_space_set_alloc(ctx, 0, total + shift); if (isl_basic_set_plain_is_empty(bset)) { isl_basic_set_free(bset); return rational_universe(space); } - total = isl_basic_set_dim(bset, isl_dim_all); - if (total < 0) - space = isl_space_free(space); - dual = isl_basic_set_alloc_space(space, bset->n_eq + bset->n_ineq, total, bset->n_ineq + (shift > 0)); dual = isl_basic_set_set_rational(dual); @@ -307,6 +315,525 @@ error: } /* Construct a basic set containing the tuples of coefficients of all + * valid affine constraints on the given basic set, ignoring + * the space of input and output and without any further decomposition. + */ +static __isl_give isl_basic_set *isl_basic_set_coefficients_base( + __isl_take isl_basic_set *bset) +{ + return farkas(bset, 1); +} + +/* Return the inverse mapping of "morph". + */ +static __isl_give isl_mat *peek_inv(__isl_keep isl_morph *morph) +{ + return morph ? morph->inv : NULL; +} + +/* Return a copy of the inverse mapping of "morph". + */ +static __isl_give isl_mat *get_inv(__isl_keep isl_morph *morph) +{ + return isl_mat_copy(peek_inv(morph)); +} + +/* Information about a single factor within isl_basic_set_coefficients_product. + * + * "start" is the position of the first coefficient (beyond + * the one corresponding to the constant term) in this factor. + * "dim" is the number of coefficients (other than + * the one corresponding to the constant term) in this factor. + * "n_line" is the number of lines in "coeff". + * "n_ray" is the number of rays (other than lines) in "coeff". + * "n_vertex" is the number of vertices in "coeff". + * + * While iterating over the vertices, + * "pos" represents the inequality constraint corresponding + * to the current vertex. + */ +struct isl_coefficients_factor_data { + isl_basic_set *coeff; + int start; + int dim; + int n_line; + int n_ray; + int n_vertex; + int pos; +}; + +/* Internal data structure for isl_basic_set_coefficients_product. + * "n" is the number of factors in the factorization. + * "pos" is the next factor that will be considered. + * "start_next" is the position of the first coefficient (beyond + * the one corresponding to the constant term) in the next factor. + * "factors" contains information about the individual "n" factors. + */ +struct isl_coefficients_product_data { + int n; + int pos; + int start_next; + struct isl_coefficients_factor_data *factors; +}; + +/* Initialize the internal data structure for + * isl_basic_set_coefficients_product. + */ +static isl_stat isl_coefficients_product_data_init(isl_ctx *ctx, + struct isl_coefficients_product_data *data, int n) +{ + data->n = n; + data->pos = 0; + data->start_next = 0; + data->factors = isl_calloc_array(ctx, + struct isl_coefficients_factor_data, n); + if (!data->factors) + return isl_stat_error; + return isl_stat_ok; +} + +/* Free all memory allocated in "data". + */ +static void isl_coefficients_product_data_clear( + struct isl_coefficients_product_data *data) +{ + int i; + + if (data->factors) { + for (i = 0; i < data->n; ++i) { + isl_basic_set_free(data->factors[i].coeff); + } + } + free(data->factors); +} + +/* Does inequality "ineq" in the (dual) basic set "bset" represent a ray? + * In particular, does it have a zero denominator + * (i.e., a zero coefficient for the constant term)? + */ +static int is_ray(__isl_keep isl_basic_set *bset, int ineq) +{ + return isl_int_is_zero(bset->ineq[ineq][1]); +} + +/* isl_factorizer_every_factor_basic_set callback that + * constructs a basic set containing the tuples of coefficients of all + * valid affine constraints on the factor "bset" and + * extracts further information that will be used + * when combining the results over the different factors. + */ +static isl_bool isl_basic_set_coefficients_factor( + __isl_keep isl_basic_set *bset, void *user) +{ + struct isl_coefficients_product_data *data = user; + isl_basic_set *coeff; + isl_size n_eq, n_ineq, dim; + int i, n_ray, n_vertex; + + coeff = isl_basic_set_coefficients_base(isl_basic_set_copy(bset)); + data->factors[data->pos].coeff = coeff; + if (!coeff) + return isl_bool_error; + + dim = isl_basic_set_dim(bset, isl_dim_set); + n_eq = isl_basic_set_n_equality(coeff); + n_ineq = isl_basic_set_n_inequality(coeff); + if (dim < 0 || n_eq < 0 || n_ineq < 0) + return isl_bool_error; + n_ray = n_vertex = 0; + for (i = 0; i < n_ineq; ++i) { + if (is_ray(coeff, i)) + n_ray++; + else + n_vertex++; + } + data->factors[data->pos].start = data->start_next; + data->factors[data->pos].dim = dim; + data->factors[data->pos].n_line = n_eq; + data->factors[data->pos].n_ray = n_ray; + data->factors[data->pos].n_vertex = n_vertex; + data->pos++; + data->start_next += dim; + + return isl_bool_true; +} + +/* Clear an entry in the product, given that there is a "total" number + * of coefficients (other than that of the constant term). + */ +static void clear_entry(isl_int *entry, int total) +{ + isl_seq_clr(entry, 1 + 1 + total); +} + +/* Set the part of the entry corresponding to factor "data", + * from the factor coefficients in "src". + */ +static void set_factor(isl_int *entry, isl_int *src, + struct isl_coefficients_factor_data *data) +{ + isl_seq_cpy(entry + 1 + 1 + data->start, src + 1 + 1, data->dim); +} + +/* Set the part of the entry corresponding to factor "data", + * from the factor coefficients in "src" multiplied by "f". + */ +static void scale_factor(isl_int *entry, isl_int *src, isl_int f, + struct isl_coefficients_factor_data *data) +{ + isl_seq_scale(entry + 1 + 1 + data->start, src + 1 + 1, f, data->dim); +} + +/* Add all lines from the given factor to "bset", + * given that there is a "total" number of coefficients + * (other than that of the constant term). + */ +static __isl_give isl_basic_set *add_lines(__isl_take isl_basic_set *bset, + struct isl_coefficients_factor_data *factor, int total) +{ + int i; + + for (i = 0; i < factor->n_line; ++i) { + int k; + + k = isl_basic_set_alloc_equality(bset); + if (k < 0) + return isl_basic_set_free(bset); + clear_entry(bset->eq[k], total); + set_factor(bset->eq[k], factor->coeff->eq[i], factor); + } + + return bset; +} + +/* Add all rays (other than lines) from the given factor to "bset", + * given that there is a "total" number of coefficients + * (other than that of the constant term). + */ +static __isl_give isl_basic_set *add_rays(__isl_take isl_basic_set *bset, + struct isl_coefficients_factor_data *data, int total) +{ + int i; + int n_ineq = data->n_ray + data->n_vertex; + + for (i = 0; i < n_ineq; ++i) { + int k; + + if (!is_ray(data->coeff, i)) + continue; + + k = isl_basic_set_alloc_inequality(bset); + if (k < 0) + return isl_basic_set_free(bset); + clear_entry(bset->ineq[k], total); + set_factor(bset->ineq[k], data->coeff->ineq[i], data); + } + + return bset; +} + +/* Move to the first vertex of the given factor starting + * at inequality constraint "start", setting factor->pos and + * returning 1 if a vertex is found. + */ +static int factor_first_vertex(struct isl_coefficients_factor_data *factor, + int start) +{ + int j; + int n = factor->n_ray + factor->n_vertex; + + for (j = start; j < n; ++j) { + if (is_ray(factor->coeff, j)) + continue; + factor->pos = j; + return 1; + } + + return 0; +} + +/* Move to the first constraint in each factor starting at "first" + * that represents a vertex. + * In particular, skip the initial constraints that correspond to rays. + */ +static void first_vertex(struct isl_coefficients_product_data *data, int first) +{ + int i; + + for (i = first; i < data->n; ++i) + factor_first_vertex(&data->factors[i], 0); +} + +/* Move to the next vertex in the product. + * In particular, move to the next vertex of the last factor. + * If all vertices of this last factor have already been considered, + * then move to the next vertex of the previous factor(s) + * until a factor is found that still has a next vertex. + * Once such a next vertex has been found, the subsequent + * factors are reset to the first vertex. + * Return 1 if any next vertex was found. + */ +static int next_vertex(struct isl_coefficients_product_data *data) +{ + int i; + + for (i = data->n - 1; i >= 0; --i) { + struct isl_coefficients_factor_data *factor = &data->factors[i]; + + if (!factor_first_vertex(factor, factor->pos + 1)) + continue; + first_vertex(data, i + 1); + return 1; + } + + return 0; +} + +/* Add a vertex to the product "bset" combining the currently selected + * vertices of the factors. + * + * In the dual representation, the constant term is always zero. + * The vertex itself is the sum of the contributions of the factors + * with a shared denominator in position 1. + * + * First compute the shared denominator (lcm) and + * then scale the numerators to this shared denominator. + */ +static __isl_give isl_basic_set *add_vertex(__isl_take isl_basic_set *bset, + struct isl_coefficients_product_data *data) +{ + int i; + int k; + isl_int lcm, f; + + k = isl_basic_set_alloc_inequality(bset); + if (k < 0) + return isl_basic_set_free(bset); + + isl_int_init(lcm); + isl_int_init(f); + isl_int_set_si(lcm, 1); + for (i = 0; i < data->n; ++i) { + struct isl_coefficients_factor_data *factor = &data->factors[i]; + isl_basic_set *coeff = factor->coeff; + int pos = factor->pos; + isl_int_lcm(lcm, lcm, coeff->ineq[pos][1]); + } + isl_int_set_si(bset->ineq[k][0], 0); + isl_int_set(bset->ineq[k][1], lcm); + + for (i = 0; i < data->n; ++i) { + struct isl_coefficients_factor_data *factor = &data->factors[i]; + isl_basic_set *coeff = factor->coeff; + int pos = factor->pos; + isl_int_divexact(f, lcm, coeff->ineq[pos][1]); + scale_factor(bset->ineq[k], coeff->ineq[pos], f, factor); + } + + isl_int_clear(f); + isl_int_clear(lcm); + + return bset; +} + +/* Combine the duals of the factors in the factorization of a basic set + * to form the dual of the entire basic set. + * The dual share the coefficient of the constant term. + * All other coefficients are specific to a factor. + * Any constraint not involving the coefficient of the constant term + * can therefor simply be copied into the appropriate position. + * This includes all equality constraints since the coefficient + * of the constant term can always be increased and therefore + * never appears in an equality constraint. + * The inequality constraints involving the coefficient of + * the constant term need to be combined across factors. + * In particular, if this coefficient needs to be greater than or equal + * to some linear combination of the other coefficients in each factor, + * then it needs to be greater than or equal to the sum of + * these linear combinations across the factors. + * + * Alternatively, the constraints of the dual can be seen + * as the vertices, rays and lines of the original basic set. + * Clearly, rays and lines can simply be copied, + * while vertices needs to be combined across factors. + * This means that the number of rays and lines in the product + * is equal to the sum of the numbers in the factors, + * while the number of vertices is the product + * of the number of vertices in the factors. Note that each + * factor has at least one vertex. + * The only exception is when the factor is the dual of an obviously empty set, + * in which case a universe dual is created. + * In this case, return a universe dual for the product as well. + * + * While constructing the vertices, look for the first combination + * of inequality constraints that represent a vertex, + * construct the corresponding vertex and then move on + * to the next combination of inequality constraints until + * all combinations have been considered. + */ +static __isl_give isl_basic_set *construct_product(isl_ctx *ctx, + struct isl_coefficients_product_data *data) +{ + int i; + int n_line, n_ray, n_vertex; + int total; + isl_space *space; + isl_basic_set *product; + + if (!data->factors) + return NULL; + + total = data->start_next; + + n_line = 0; + n_ray = 0; + n_vertex = 1; + for (i = 0; i < data->n; ++i) { + n_line += data->factors[i].n_line; + n_ray += data->factors[i].n_ray; + n_vertex *= data->factors[i].n_vertex; + } + + space = isl_space_set_alloc(ctx, 0, 1 + total); + if (n_vertex == 0) + return rational_universe(space); + product = isl_basic_set_alloc_space(space, 0, n_line, n_ray + n_vertex); + product = isl_basic_set_set_rational(product); + + for (i = 0; i < data->n; ++i) + product = add_lines(product, &data->factors[i], total); + for (i = 0; i < data->n; ++i) + product = add_rays(product, &data->factors[i], total); + + first_vertex(data, 0); + do { + product = add_vertex(product, data); + } while (next_vertex(data)); + + return product; +} + +/* Given a factorization "f" of a basic set, + * construct a basic set containing the tuples of coefficients of all + * valid affine constraints on the product of the factors, ignoring + * the space of input and output. + * Note that this product may not be equal to the original basic set, + * if a non-trivial transformation is involved. + * This is handled by the caller. + * + * Compute the tuples of coefficients for each factor separately and + * then combine the results. + */ +static __isl_give isl_basic_set *isl_basic_set_coefficients_product( + __isl_take isl_factorizer *f) +{ + struct isl_coefficients_product_data data; + isl_ctx *ctx; + isl_basic_set *coeff; + isl_bool every; + + ctx = isl_factorizer_get_ctx(f); + if (isl_coefficients_product_data_init(ctx, &data, f->n_group) < 0) + f = isl_factorizer_free(f); + every = isl_factorizer_every_factor_basic_set(f, + &isl_basic_set_coefficients_factor, &data); + isl_factorizer_free(f); + if (every >= 0) + coeff = construct_product(ctx, &data); + else + coeff = NULL; + isl_coefficients_product_data_clear(&data); + + return coeff; +} + +/* Given a factorization "f" of a basic set, + * construct a basic set containing the tuples of coefficients of all + * valid affine constraints on the basic set, ignoring + * the space of input and output. + * + * The factorization may involve a linear transformation of the basic set. + * In particular, the transformed basic set is formulated + * in terms of x' = U x, i.e., x = V x', with V = U^{-1}. + * The dual is then computed in terms of y' with y'^t [z; x'] >= 0. + * Plugging in y' = [1 0; 0 V^t] y yields + * y^t [1 0; 0 V] [z; x'] >= 0, i.e., y^t [z; x] >= 0, which is + * the desired set of coefficients y. + * Note that this transformation to y' only needs to be applied + * if U is not the identity matrix. + */ +static __isl_give isl_basic_set *isl_basic_set_coefficients_morphed_product( + __isl_take isl_factorizer *f) +{ + isl_bool is_identity; + isl_space *space; + isl_mat *inv; + isl_multi_aff *ma; + isl_basic_set *coeff; + + if (!f) + goto error; + is_identity = isl_mat_is_scaled_identity(peek_inv(f->morph)); + if (is_identity < 0) + goto error; + if (is_identity) + return isl_basic_set_coefficients_product(f); + + inv = get_inv(f->morph); + inv = isl_mat_transpose(inv); + inv = isl_mat_lin_to_aff(inv); + + coeff = isl_basic_set_coefficients_product(f); + space = isl_space_map_from_set(isl_basic_set_get_space(coeff)); + ma = isl_multi_aff_from_aff_mat(space, inv); + coeff = isl_basic_set_preimage_multi_aff(coeff, ma); + + return coeff; +error: + isl_factorizer_free(f); + return NULL; +} + +/* Construct a basic set containing the tuples of coefficients of all + * valid affine constraints on the given basic set, ignoring + * the space of input and output. + * + * The caller has already checked that "bset" does not involve + * any local variables. It may have parameters, though. + * Treat them as regular variables internally. + * This is especially important for the factorization, + * since the (original) parameters should be taken into account + * explicitly in this factorization. + * + * Check if the basic set can be factorized. + * If so, compute constraints on the coefficients of the factors + * separately and combine the results. + * Otherwise, compute the results for the input basic set as a whole. + */ +static __isl_give isl_basic_set *basic_set_coefficients( + __isl_take isl_basic_set *bset) +{ + isl_factorizer *f; + isl_size nparam; + + nparam = isl_basic_set_dim(bset, isl_dim_param); + if (nparam < 0) + return isl_basic_set_free(bset); + bset = isl_basic_set_move_dims(bset, isl_dim_set, 0, + isl_dim_param, 0, nparam); + + f = isl_basic_set_factorizer(bset); + if (!f) + return isl_basic_set_free(bset); + if (f->n_group > 0) { + isl_basic_set_free(bset); + return isl_basic_set_coefficients_morphed_product(f); + } + isl_factorizer_free(f); + return isl_basic_set_coefficients_base(bset); +} + +/* Construct a basic set containing the tuples of coefficients of all * valid affine constraints on the given basic set. */ __isl_give isl_basic_set *isl_basic_set_coefficients( @@ -324,7 +851,9 @@ __isl_give isl_basic_set *isl_basic_set_ space = isl_basic_set_get_space(bset); space = isl_space_coefficients(space); - return farkas(space, bset, 1); + bset = basic_set_coefficients(bset); + bset = isl_basic_set_reset_space(bset, space); + return bset; error: isl_basic_set_free(bset); return NULL; @@ -349,7 +878,9 @@ __isl_give isl_basic_set *isl_basic_set_ space = isl_basic_set_get_space(bset); space = isl_space_solutions(space); - return farkas(space, bset, -1); + bset = farkas(bset, -1); + bset = isl_basic_set_reset_space(bset, space); + return bset; error: isl_basic_set_free(bset); return NULL; diff -Npur isl_0.22/isl_map.c isl/isl_map.c --- isl_0.22/isl_map.c 2020-04-17 16:49:36.250477000 +0800 +++ isl/isl_map.c 2020-04-29 18:14:39.933681000 +0800 @@ -3162,6 +3162,133 @@ __isl_give isl_set *isl_set_drop_constra return isl_map_drop_constraints_not_involving_dims(set, type, first, n); } + +/* Drop all constraints in bmap that do not involve any of the dimensions + * first to first + n - 1 of the given type. + */ +__isl_give isl_basic_map *isl_basic_map_drop_special_constraints( + __isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos) +{ + int i, j; + unsigned begin, num; + isl_size n_in, n_out, total; + long int min = 0; + long int max = 0; + long int val = 0; + + if (!bmap) + return NULL; + + if (bmap->n_div) + return bmap; + + if (isl_basic_map_check_range(bmap, type, pos, 1) < 0) + return bmap; + + n_in = isl_basic_map_dim(bmap, isl_dim_in); + n_out = isl_basic_map_dim(bmap, isl_dim_out); + if (n_in < n_out) + return bmap; + + bmap = isl_basic_map_cow(bmap); + pos += isl_basic_map_offset(bmap, type); + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total <= 0) + return bmap; + for (i = bmap->n_eq - 1; i >= 0; --i) { + if (isl_int_is_zero(bmap->eq[i][pos])) + continue; + + if (isl_seq_first_non_zero(bmap->eq[i] + 1, pos - 1) != -1) + continue; + + if (isl_seq_first_non_zero(bmap->eq[i] + pos + 1, total - pos) != -1) + continue; + + if (isl_int_is_one(bmap->eq[i][pos])) { + min = max = -isl_int_get_si(bmap->eq[i][0]); + break; + } + } + + for (i = bmap->n_ineq - 1; i >= 0; --i) { + if (isl_int_is_zero(bmap->ineq[i][pos])) + continue; + + if (isl_seq_first_non_zero(bmap->ineq[i] + 1, pos - 1) != -1) + continue; + + if (isl_seq_first_non_zero(bmap->ineq[i] + pos + 1, total - pos) != -1) + continue; + + if (isl_int_is_one(bmap->ineq[i][pos])) + min = -isl_int_get_si(bmap->ineq[i][0]); + + if (isl_int_is_negone(bmap->ineq[i][pos])) + max = isl_int_get_si(bmap->ineq[i][0]); + } + + begin = isl_basic_map_offset(bmap, isl_dim_out) - n_out; + num = n_out * 2; + + for (i = bmap->n_eq - 1; i >= 0; --i) { + if (isl_int_is_zero(bmap->eq[i][pos])) + continue; + + if (isl_seq_first_non_zero(bmap->eq[i] + begin, num) == -1) + continue; + + isl_int_set_si(bmap->eq[i][pos], 0); + } + + for (i = bmap->n_ineq - 1; i >= 0; --i) { + if (isl_int_is_zero(bmap->ineq[i][pos])) + continue; + + j = isl_seq_first_non_zero(bmap->ineq[i] + begin, num); + if (j == -1) + continue; + + val = 0; + int sgn = isl_int_sgn(bmap->ineq[i][begin + j]); + if (sgn > 0) { + val = isl_int_get_si(bmap->ineq[i][pos]) * min; + } + if (sgn < 0) { + val = isl_int_get_si(bmap->ineq[i][pos]) * max; + } + isl_int_set_si(bmap->ineq[i][pos], 0); + if (val != 0) { + val += isl_int_get_si(bmap->ineq[i][0]); + isl_int_set_si(bmap->ineq[i][0], val); + } + } + return bmap; +} + +__isl_give isl_map *isl_map_drop_special_constraints( + __isl_take isl_map *map, unsigned first, unsigned n) +{ + int i; + unsigned j; + + if (isl_map_check_range(map, isl_dim_in, first, n) < 0) + return isl_map_free(map); + + map = isl_map_cow(map); + if (!map) + return NULL; + + for (i = 0; i < map->n; ++i) { + for (j = first; j < first + n; ++j) { + isl_basic_map *bmap = map->p[i]; + map->p[i] = isl_basic_map_drop_special_constraints(bmap, isl_dim_in, j); + } + } + return map; +} + /* Does local variable "div" of "bmap" have a complete explicit representation? * Having a complete explicit representation requires not only * an explicit representation, but also that all local variables @@ -9695,6 +9822,66 @@ isl_bool isl_basic_map_plain_is_fixed(__ isl_basic_map_offset(bmap, type) - 1 + pos, val); } +__isl_give isl_basic_map *isl_basic_map_plain_update_fixed_var( + __isl_take isl_basic_map *bmap, unsigned pos) +{ + int i; + int d; + isl_size total; + + total = isl_basic_map_dim(bmap, isl_dim_all); + if (total < 0) + return bmap; + for (i = 0, d = total-1; i < bmap->n_eq && d+1 > pos; ++i) { + for (; d+1 > pos; --d) + if (!isl_int_is_zero(bmap->eq[i][1+d])) + break; + if (d != pos) + continue; + if (isl_seq_first_non_zero(bmap->eq[i]+1, d) != -1) + break; + if (isl_seq_first_non_zero(bmap->eq[i]+1+d+1, total-d-1) != -1) + break; + if (!isl_int_is_one(bmap->eq[i][1+d])) + break; + if (!isl_int_is_zero(bmap->eq[i][0])) { + isl_int_sub_ui(bmap->eq[i][0], bmap->eq[i][0], 1); + } + break; + } + return bmap; +} + + +__isl_give isl_basic_map *isl_basic_map_plain_update_val_if_fixed(__isl_take isl_basic_map *bmap, + enum isl_dim_type type, unsigned pos) +{ + if (isl_basic_map_check_range(bmap, type, pos, 1) < 0) + return bmap; + return isl_basic_map_plain_update_fixed_var(bmap, + isl_basic_map_offset(bmap, type) - 1 + pos); +} + +/* If "map" obviously lies on a hyperplane where the given dimension + * has a fixed value, then update the fixed value use (value + 1). + */ +__isl_give isl_map *isl_map_plain_update_val_if_fixed(__isl_take isl_map *map, + enum isl_dim_type type, unsigned pos) +{ + int i; + if (!map) + return map; + if (map->n == 0) + return map; + if (isl_map_check_range(map, type, pos, 1) < 0) + return map; + + for (i = 0; i < map->n; ++i) { + map->p[i] = isl_basic_map_plain_update_val_if_fixed(map->p[i], type, pos); + } + return map; +} + /* If "bmap" obviously lies on a hyperplane where the given dimension * has a fixed value, then return that value. * Otherwise return NaN. diff -Npur isl_0.22/isl_multi_templ.c isl/isl_multi_templ.c --- isl_0.22/isl_multi_templ.c 2020-04-17 16:49:36.254477000 +0800 +++ isl/isl_multi_templ.c 2020-04-29 18:14:39.937681000 +0800 @@ -258,6 +258,25 @@ __isl_give MULTI(BASE) *FN(FN(MULTI(BASE return FN(MULTI(BASE),set_at)(multi, pos, el); } +/* Return the base expressions of "multi" as a list. + */ +__isl_give LIST(EL) *FN(FN(MULTI(BASE),get),LIST(BASE))( + __isl_keep MULTI(BASE) *multi) +{ + int i; + LIST(EL) *list; + + if (!multi) + return NULL; + list = FN(LIST(EL),alloc)(FN(MULTI(BASE),get_ctx(multi)), multi->n); + for (i = 0; i < multi->n; ++i) { + EL *el = FN(FN(MULTI(BASE),get),BASE)(multi, i); + list = FN(LIST(EL),add)(list, el); + } + + return list; +} + /* Reset the space of "multi". This function is called from isl_pw_templ.c * and doesn't know if the space of an element object is represented * directly or through its domain. It therefore passes along both, diff -Npur isl_0.22/isl_options.c isl/isl_options.c --- isl_0.22/isl_options.c 2020-04-17 16:49:36.254477000 +0800 +++ isl/isl_options.c 2020-04-29 18:14:39.937681000 +0800 @@ -137,10 +137,19 @@ ISL_ARG_BOOL(struct isl_options, coalesc ISL_ARG_BOOL(struct isl_options, coalesce_preserve_locals, 0, "coalesce-preserve-locals", 0, "preserve local variables during coalescing") + +ISL_ARG_BOOL(struct isl_options, schedule_nonneg_var_coefficient, 0, + "schedule-nonneg-var-coefficient", 0, "Only consider schedules " + "where the coefficients of the variable dimensions " + "are non-negative.") ISL_ARG_INT(struct isl_options, schedule_max_coefficient, 0, "schedule-max-coefficient", "limit", -1, "Only consider schedules " "where the coefficients of the variable and parameter dimensions " "do not exceed . A value of -1 allows arbitrary coefficients.") +ISL_ARG_BOOL(struct isl_options, schedule_unit_max_var_coefficient_sum, 0, + "schedule-unit-max-var-coefficient-sum", 0, + "bound the sum of the coefficients of the variables by one " + "for each statement") ISL_ARG_INT(struct isl_options, schedule_max_constant_term, 0, "schedule-max-constant-term", "limit", -1, "Only consider schedules " "where the coefficients of the constant dimension do not exceed " @@ -167,7 +176,7 @@ ISL_ARG_BOOL(struct isl_options, schedul "schedule-separate-components", 1, "separate components in dependence graph") ISL_ARG_BOOL(struct isl_options, schedule_whole_component, 0, - "schedule-whole-component", 0, + "schedule-whole-component", 1, "try and compute schedule for entire component first") ISL_ARG_CHOICE(struct isl_options, schedule_algorithm, 0, "schedule-algorithm", isl_schedule_algorithm_choice, @@ -255,10 +264,20 @@ ISL_CTX_GET_BOOL_DEF(isl_options, struct gbr_only_first) ISL_CTX_SET_INT_DEF(isl_options, struct isl_options, isl_options_args, + schedule_nonneg_var_coefficient) +ISL_CTX_GET_INT_DEF(isl_options, struct isl_options, isl_options_args, + schedule_nonneg_var_coefficient) + +ISL_CTX_SET_INT_DEF(isl_options, struct isl_options, isl_options_args, schedule_max_coefficient) ISL_CTX_GET_INT_DEF(isl_options, struct isl_options, isl_options_args, schedule_max_coefficient) +ISL_CTX_SET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + schedule_unit_max_var_coefficient_sum) +ISL_CTX_GET_BOOL_DEF(isl_options, struct isl_options, isl_options_args, + schedule_unit_max_var_coefficient_sum) + ISL_CTX_SET_INT_DEF(isl_options, struct isl_options, isl_options_args, schedule_max_constant_term) ISL_CTX_GET_INT_DEF(isl_options, struct isl_options, isl_options_args, diff -Npur isl_0.22/isl_options_private.h isl/isl_options_private.h --- isl_0.22/isl_options_private.h 2020-04-17 16:49:36.254477000 +0800 +++ isl/isl_options_private.h 2020-04-29 18:14:39.937681000 +0800 @@ -34,9 +34,11 @@ struct isl_options { int convex; int coalesce_bounded_wrapping; + int schedule_nonneg_var_coefficient; int coalesce_preserve_locals; int schedule_max_coefficient; + int schedule_unit_max_var_coefficient_sum; int schedule_max_constant_term; int schedule_parametric; int schedule_outer_coincidence; diff -Npur isl_0.22/isl_polynomial.c isl/isl_polynomial.c --- isl_0.22/isl_polynomial.c 2020-04-17 16:49:36.254477000 +0800 +++ isl/isl_polynomial.c 2020-04-29 18:14:39.937681000 +0800 @@ -4756,6 +4756,32 @@ static __isl_give isl_pw_qpolynomial *co return isl_pw_qpolynomial_alloc(isl_set_from_basic_set(bset), qp); } +/* Internal data structure for multiplicative_call_factor_pw_qpolynomial. + * "fn" is the function that is called on each factor. + * "pwpq" collects the results. + */ +struct isl_multiplicative_call_data_pw_qpolynomial { + __isl_give isl_pw_qpolynomial *(*fn)(__isl_take isl_basic_set *bset); + isl_pw_qpolynomial *pwqp; +}; + +/* isl_factorizer_every_factor_basic_set callback that applies + * data->fn to the factor "bset" and multiplies in the result + * in data->pwqp. + */ +static isl_bool multiplicative_call_factor_pw_qpolynomial( + __isl_keep isl_basic_set *bset, void *user) +{ + struct isl_multiplicative_call_data_pw_qpolynomial *data = user; + + bset = isl_basic_set_copy(bset); + data->pwqp = isl_pw_qpolynomial_mul(data->pwqp, data->fn(bset)); + if (!data->pwqp) + return isl_bool_error; + + return isl_bool_true; +} + /* Factor bset, call fn on each of the factors and return the product. * * If no factors can be found, simply call fn on the input. @@ -4766,14 +4792,12 @@ static __isl_give isl_pw_qpolynomial *co __isl_take isl_basic_set *bset, __isl_give isl_pw_qpolynomial *(*fn)(__isl_take isl_basic_set *bset)) { - int i, n; + struct isl_multiplicative_call_data_pw_qpolynomial data = { fn }; isl_space *space; isl_set *set; isl_factorizer *f; isl_qpolynomial *qp; - isl_pw_qpolynomial *pwqp; - isl_size nparam; - isl_size nvar; + isl_bool every; f = isl_basic_set_factorizer(bset); if (!f) @@ -4783,42 +4807,21 @@ static __isl_give isl_pw_qpolynomial *co return fn(bset); } - nparam = isl_basic_set_dim(bset, isl_dim_param); - nvar = isl_basic_set_dim(bset, isl_dim_set); - if (nparam < 0 || nvar < 0) - bset = isl_basic_set_free(bset); - space = isl_basic_set_get_space(bset); space = isl_space_params(space); set = isl_set_universe(isl_space_copy(space)); qp = isl_qpolynomial_one_on_domain(space); - pwqp = isl_pw_qpolynomial_alloc(set, qp); - - bset = isl_morph_basic_set(isl_morph_copy(f->morph), bset); + data.pwqp = isl_pw_qpolynomial_alloc(set, qp); - for (i = 0, n = 0; i < f->n_group; ++i) { - isl_basic_set *bset_i; - isl_pw_qpolynomial *pwqp_i; - - bset_i = isl_basic_set_copy(bset); - bset_i = isl_basic_set_drop_constraints_involving(bset_i, - nparam + n + f->len[i], nvar - n - f->len[i]); - bset_i = isl_basic_set_drop_constraints_involving(bset_i, - nparam, n); - bset_i = isl_basic_set_drop(bset_i, isl_dim_set, - n + f->len[i], nvar - n - f->len[i]); - bset_i = isl_basic_set_drop(bset_i, isl_dim_set, 0, n); - - pwqp_i = fn(bset_i); - pwqp = isl_pw_qpolynomial_mul(pwqp, pwqp_i); - - n += f->len[i]; - } + every = isl_factorizer_every_factor_basic_set(f, + &multiplicative_call_factor_pw_qpolynomial, &data); + if (every < 0) + data.pwqp = isl_pw_qpolynomial_free(data.pwqp); isl_basic_set_free(bset); isl_factorizer_free(f); - return pwqp; + return data.pwqp; error: isl_basic_set_free(bset); return NULL; diff -Npur isl_0.22/isl_schedule_constraints.c isl/isl_schedule_constraints.c --- isl_0.22/isl_schedule_constraints.c 2020-04-17 16:49:36.258477000 +0800 +++ isl/isl_schedule_constraints.c 2020-04-29 18:14:39.937681000 +0800 @@ -157,6 +157,19 @@ error: return NULL; } +/* Intersect the domain of "sc" with "domain". + */ +__isl_give isl_schedule_constraints *isl_schedule_constraints_intersect_domain( + __isl_take isl_schedule_constraints *sc, + __isl_take isl_union_set *domain) +{ + isl_union_set *sc_domain; + + sc_domain = isl_schedule_constraints_get_domain(sc); + sc_domain = isl_union_set_intersect(sc_domain, domain); + return isl_schedule_constraints_set_domain(sc, sc_domain); +} + /* Replace the context of "sc" by "context". */ __isl_give isl_schedule_constraints *isl_schedule_constraints_set_context( diff -Npur isl_0.22/isl_scheduler.c isl/isl_scheduler.c --- isl_0.22/isl_scheduler.c 2020-04-17 16:49:36.258477000 +0800 +++ isl/isl_scheduler.c 2020-04-29 18:14:39.937681000 +0800 @@ -73,6 +73,7 @@ * nvar is the dimension of the (compressed) domain * nparam is the number of parameters or 0 if we are not constructing * a parametric schedule + * nonneg is set if the coefficients of the variables should be non-negative * * If compressed is set, then hull represents the constraints * that were used to derive the compression, while compress and @@ -115,6 +116,7 @@ struct isl_sched_node { int start; int nvar; int nparam; + int nonneg; int scc; int cluster; @@ -1928,30 +1930,53 @@ static isl_size coef_var_offset(__isl_ke return offset; } +/* Return the number of variables needed in the (I)LP + * for encoding a single variable coefficient of "node". + * Each coefficient is encoded as a difference between two non-negative + * variables (if the coefficients of "node" are allowed to take on + * negative values) or directly as a single non-negative variable. + */ +static int coef_per_var(struct isl_sched_node *node) +{ + return node->nonneg ? 1 : 2; +} + +/* Return the number of variables needed for "node" within the (I)LP. + * + * Within each node, the coefficients have the following order: + * - c_i_x + * - c_i_n (if parametric) + * - c_i_0 + */ +static int node_coef_size(struct isl_sched_node *node) +{ + return coef_per_var(node) * node->nvar + node->nparam + 1; +} + /* Return the offset of the coefficient of the constant term of "node" * within the (I)LP. * * Within each node, the coefficients have the following order: - * - positive and negative parts of c_i_x + * - c_i_x * - c_i_n (if parametric) * - c_i_0 */ static int node_cst_coef_offset(struct isl_sched_node *node) { - return node->start + 2 * node->nvar + node->nparam; + return node->start + coef_per_var(node) * node->nvar + node->nparam; } /* Return the offset of the coefficients of the parameters of "node" * within the (I)LP. * * Within each node, the coefficients have the following order: - * - positive and negative parts of c_i_x + * - c_i_x * - c_i_n (if parametric) * - c_i_0 */ static int node_par_coef_offset(struct isl_sched_node *node) { - return node->start + 2 * node->nvar; + return node->start + coef_per_var(node) * node->nvar; } /* Return the offset of the coefficients of the variables of "node" @@ -1968,14 +1993,57 @@ static int node_var_coef_offset(struct i } /* Return the position of the pair of variables encoding - * coefficient "i" of "node". + * coefficient "i" of "node", within the sequence of coefficients + * of the variables of "node". * * The order of these variable pairs is the opposite of * that of the coefficients, with 2 variables per coefficient. */ +static int node_local_var_coef_pos(struct isl_sched_node *node, int i) +{ + return coef_per_var(node) * (node->nvar - 1 - i); +} + +/* Return the position of the pair of variables encoding + * coefficient "i" of "node". + */ static int node_var_coef_pos(struct isl_sched_node *node, int i) { - return node_var_coef_offset(node) + 2 * (node->nvar - 1 - i); + return node_var_coef_offset(node) + node_local_var_coef_pos(node, i); +} + +/* Update "dim_map" for mapping the coefficients of the variables in "node" + * to the corresponding positions in the LP. + * "offset" is the offset of the coefficients for the variables + * in the input constraints. + * "s" is the sign of the mapping. + * + * This part of the mapping essentially plugs in + * (c_i_x^+ - c_i_x^-) if s = 1 and + * (-c_i_x^+ + c_i_x^-) if s = -1 + * for the variable coefficients c_x. + * In the LP, the c_i_x^- appear before their c_i_x^+ counterpart. + * Furthermore, the order of these pairs is the opposite of that + * of the corresponding coefficients. + * + * If the coefficients are expected to be non-negative, then + * only a single variable is used in the encoding (c_i_x^- = 0 is omitted). + */ +static __isl_give isl_dim_map *node_var_dim_map(struct isl_sched_node *node, + int offset, int s, __isl_take isl_dim_map *dim_map) +{ + int pos; + + pos = node_var_coef_pos(node, 0); + if (node->nonneg) { + isl_dim_map_range(dim_map, pos, -1, offset, 1, node->nvar, s); + } else { + isl_dim_map_range(dim_map, pos, -2, offset, 1, node->nvar, -s); + isl_dim_map_range(dim_map, pos + 1, -2, + offset, 1, node->nvar, s); + } + + return dim_map; } /* Construct an isl_dim_map for mapping constraints on coefficients @@ -1991,9 +2059,6 @@ static int node_var_coef_pos(struct isl_ * (0, -c_i_x^+ + c_i_x^-) if s = -1 or * (0, 0, c_i_x^+ - c_i_x^-) if s = 1 and * (0, 0, -c_i_x^+ + c_i_x^-) if s = -1. - * In graph->lp, the c_i_x^- appear before their c_i_x^+ counterpart. - * Furthermore, the order of these pairs is the opposite of that - * of the corresponding coefficients. * * The caller can extend the mapping to also map the other coefficients * (and therefore not plug in 0). @@ -2002,7 +2067,6 @@ static __isl_give isl_dim_map *intra_dim struct isl_sched_graph *graph, struct isl_sched_node *node, int offset, int s) { - int pos; isl_size total; isl_dim_map *dim_map; @@ -2010,10 +2074,8 @@ static __isl_give isl_dim_map *intra_dim if (!node || total < 0) return NULL; - pos = node_var_coef_pos(node, 0); dim_map = isl_dim_map_alloc(ctx, total); - isl_dim_map_range(dim_map, pos, -2, offset, 1, node->nvar, -s); - isl_dim_map_range(dim_map, pos + 1, -2, offset, 1, node->nvar, s); + dim_map = node_var_dim_map(node, offset, s, dim_map); return dim_map; } @@ -2032,9 +2094,6 @@ static __isl_give isl_dim_map *intra_dim * -(c_i_x^+ - c_i_x^-), c_j_x^+ - c_j_x^-) if s = 1 and * (-c_j_0 + c_i_0, -c_j_n + c_i_n, * c_i_x^+ - c_i_x^-, -(c_j_x^+ - c_j_x^-)) if s = -1. - * In graph->lp, the c_*^- appear before their c_*^+ counterpart. - * Furthermore, the order of these pairs is the opposite of that - * of the corresponding coefficients. * * The caller can further extend the mapping. */ @@ -2056,19 +2115,13 @@ static __isl_give isl_dim_map *inter_dim isl_dim_map_range(dim_map, pos, 0, 0, 0, 1, s); pos = node_par_coef_offset(dst); isl_dim_map_range(dim_map, pos, 1, 1, 1, dst->nparam, s); - pos = node_var_coef_pos(dst, 0); - isl_dim_map_range(dim_map, pos, -2, offset + src->nvar, 1, - dst->nvar, -s); - isl_dim_map_range(dim_map, pos + 1, -2, offset + src->nvar, 1, - dst->nvar, s); + dim_map = node_var_dim_map(dst, offset + src->nvar, s, dim_map); pos = node_cst_coef_offset(src); isl_dim_map_range(dim_map, pos, 0, 0, 0, 1, -s); pos = node_par_coef_offset(src); isl_dim_map_range(dim_map, pos, 1, 1, 1, src->nparam, -s); - pos = node_var_coef_pos(src, 0); - isl_dim_map_range(dim_map, pos, -2, offset, 1, src->nvar, s); - isl_dim_map_range(dim_map, pos + 1, -2, offset, 1, src->nvar, -s); + dim_map = node_var_dim_map(src, offset, -s, dim_map); return dim_map; } @@ -2842,6 +2895,63 @@ static isl_stat add_bound_coefficient_co return isl_stat_ok; } +/* Count the number of constraints that will be added by + * add_bound_coefficient_sum_constraints and increment *n_eq and *n_ineq + * accordingly. + * + * In practice, add_bound_coefficient_sum_constraints only adds + * inequality constraints. + */ +static isl_stat count_bound_coefficient_sum_constraints(isl_ctx *ctx, + struct isl_sched_graph *graph, int *n_eq, int *n_ineq) +{ + if (!isl_options_get_schedule_unit_max_var_coefficient_sum(ctx)) + return isl_stat_ok; + + *n_ineq += graph->n; + + return isl_stat_ok; +} + +/* If the schedule_unit_max_var_coefficient_sum option is set, + * then add a constraint for each node that ensures that + * the sum of the variables used in the encoding of the coefficients of + * the variables of the node is bounded by one. + * When a coefficient is encoded as a difference between two non-negative + * variables, this means that the absolute values of the coefficients + * are bounded by one. + * A non-negative coefficient is encoded as itself, in which case + * it is the coefficient itself that is bounded by one. + */ +static isl_stat add_bound_coefficient_sum_constraints(isl_ctx *ctx, + struct isl_sched_graph *graph) +{ + int i; + int total; + + if (!isl_options_get_schedule_unit_max_var_coefficient_sum(ctx)) + return isl_stat_ok; + + total = isl_basic_set_dim(graph->lp, isl_dim_set); + + for (i = 0; i < graph->n; ++i) { + int j, k; + int pos; + struct isl_sched_node *node = &graph->node[i]; + + k = isl_basic_set_alloc_inequality(graph->lp); + if (k < 0) + return isl_stat_error; + isl_seq_clr(graph->lp->ineq[k], 1 + total); + pos = 1 + node_var_coef_offset(node); + for (j = 0; j < coef_per_var(node) * node->nvar; ++j) + isl_int_set_si(graph->lp->ineq[k][pos + j], -1); + isl_int_set_si(graph->lp->ineq[k][0], 1); + } + + return isl_stat_ok; +} + /* Add a constraint to graph->lp that equates the value at position * "sum_pos" to the sum of the "n" values starting at "first". */ @@ -2916,7 +3026,7 @@ static isl_stat add_var_sum_constraint(s struct isl_sched_node *node = &graph->node[i]; int pos = 1 + node_var_coef_offset(node); - for (j = 0; j < 2 * node->nvar; ++j) + for (j = 0; j < coef_per_var(node) * node->nvar; ++j) isl_int_set_si(graph->lp->eq[k][pos + j], 1); } @@ -2975,7 +3085,7 @@ static isl_stat setup_lp(isl_ctx *ctx, s if (node_update_vmap(node) < 0) return isl_stat_error; node->start = total; - total += 1 + node->nparam + 2 * node->nvar; + total += node_coef_size(node); } if (count_constraints(graph, &n_eq, &n_ineq, use_coincidence) < 0) @@ -2984,6 +3094,9 @@ static isl_stat setup_lp(isl_ctx *ctx, s return isl_stat_error; if (count_bound_coefficient_constraints(ctx, graph, &n_eq, &n_ineq) < 0) return isl_stat_error; + if (count_bound_coefficient_sum_constraints(ctx, graph, + &n_eq, &n_ineq) < 0) + return isl_stat_error; space = isl_space_set_alloc(ctx, 0, total); isl_basic_set_free(graph->lp); @@ -3001,6 +3114,8 @@ static isl_stat setup_lp(isl_ctx *ctx, s return isl_stat_error; if (add_bound_coefficient_constraints(ctx, graph) < 0) return isl_stat_error; + if (add_bound_coefficient_sum_constraints(ctx, graph) < 0) + return isl_stat_error; if (add_all_validity_constraints(graph, use_coincidence) < 0) return isl_stat_error; if (add_all_proximity_constraints(graph, use_coincidence) < 0) @@ -3059,14 +3174,16 @@ static int needs_row(struct isl_sched_gr /* Construct a non-triviality region with triviality directions * corresponding to the rows of "indep". - * The rows of "indep" are expressed in terms of the schedule coefficients c_i, + * The rows of "indep" are expressed in terms of the schedule coefficients c_i + * of "node", * while the triviality directions are expressed in terms of * pairs of non-negative variables c^+_i - c^-_i, with c^-_i appearing - * before c^+_i. Furthermore, - * the pairs of non-negative variables representing the coefficients - * are stored in the opposite order. + * before c^+_i. + * If the coefficients are forced to be non-negative, + * then c^-_i = 0 is omitted from the encoding. */ -static __isl_give isl_mat *construct_trivial(__isl_keep isl_mat *indep) +static __isl_give isl_mat *construct_trivial(struct isl_sched_node *node, + __isl_keep isl_mat *indep) { isl_ctx *ctx; isl_mat *mat; @@ -3079,14 +3196,19 @@ static __isl_give isl_mat *construct_tri return NULL; ctx = isl_mat_get_ctx(indep); - mat = isl_mat_alloc(ctx, n, 2 * n_var); + mat = isl_mat_alloc(ctx, n, coef_per_var(node) * n_var); if (!mat) return NULL; for (i = 0; i < n; ++i) { for (j = 0; j < n_var; ++j) { - int nj = n_var - 1 - j; - isl_int_neg(mat->row[i][2 * nj], indep->row[i][j]); - isl_int_set(mat->row[i][2 * nj + 1], indep->row[i][j]); + int pos = node_local_var_coef_pos(node, j); + if (node->nonneg) { + isl_int_set(mat->row[i][pos], indep->row[i][j]); + } else { + isl_int_neg(mat->row[i][pos], indep->row[i][j]); + isl_int_set(mat->row[i][pos + 1], + indep->row[i][j]); + } } } @@ -3112,7 +3234,7 @@ static __isl_give isl_vec *solve_lp(isl_ graph->region[i].pos = node_var_coef_offset(node); if (needs_row(graph, node)) - trivial = construct_trivial(node->indep); + trivial = construct_trivial(node, node->indep); else trivial = isl_mat_zero(ctx, 0, 0); graph->region[i].trivial = trivial; @@ -3130,8 +3252,9 @@ static __isl_give isl_vec *solve_lp(isl_ * Each schedule coefficient c_i_x is represented as the difference * between two non-negative variables c_i_x^+ - c_i_x^-. * The c_i_x^- appear before their c_i_x^+ counterpart. - * Furthermore, the order of these pairs is the opposite of that - * of the corresponding coefficients. + * + * If the coefficients are forced to be non-negative, + * then the c_i_x^- = 0 are omitted from the encoding. * * Return c_i_x = c_i_x^+ - c_i_x^- */ @@ -3148,10 +3271,14 @@ static __isl_give isl_vec *extract_var_c if (!csol) return NULL; - pos = 1 + node_var_coef_offset(node); - for (i = 0; i < node->nvar; ++i) - isl_int_sub(csol->el[node->nvar - 1 - i], - sol->el[pos + 2 * i + 1], sol->el[pos + 2 * i]); + for (i = 0; i < node->nvar; ++i) { + pos = 1 + node_var_coef_pos(node, i); + if (node->nonneg) + isl_int_set(csol->el[i], sol->el[pos]); + else + isl_int_sub(csol->el[i], + sol->el[pos + 1], sol->el[pos]); + } return csol; } @@ -4412,7 +4539,7 @@ static isl_stat setup_carry_lp(isl_ctx * for (i = 0; i < graph->n; ++i) { struct isl_sched_node *node = &graph->node[graph->sorted[i]]; node->start = total; - total += 1 + node->nparam + 2 * node->nvar; + total += node_coef_size(node); } if (count_all_constraints(intra, inter, &n_eq, &n_ineq) < 0) @@ -5806,6 +5933,17 @@ static __isl_give isl_schedule_node *com return isl_schedule_node_free(node); if (isl_options_get_schedule_outer_coincidence(ctx)) return carry_coincidence(node, graph); + //fix isl scheduling bug for l2_loss + isl_vec *sol; + sol = compute_carrying_sol(ctx, graph, 1, 0); + if (!sol) + return isl_schedule_node_free(node); + if (sol->size == 0) { + isl_vec_free(sol); + if (graph->scc > 1) + return compute_component_schedule(node, graph, 1); + return sort_statements(node, graph, initialized); + } return carry_dependences(node, graph); } @@ -5846,7 +5984,7 @@ static __isl_give isl_schedule_node *com * Since there are only a finite number of dependences, * there will only be a finite number of iterations. */ -static isl_stat compute_schedule_wcc_band(isl_ctx *ctx, +static isl_stat compute_schedule_wcc_band_core(isl_ctx *ctx, struct isl_sched_graph *graph) { int has_coincidence; @@ -5907,6 +6045,67 @@ static isl_stat compute_schedule_wcc_ban return isl_stat_ok; } + +/* Set the nonneg fields of the nodes in "graph". + * + * If the "schedule_nonneg_var_coefficient" option is set, + * then all nodes have their nonneg fields set. + * Otherwise, it is set based on the additional constraints + * on the coefficients of the variables, if any. + */ +static isl_stat graph_set_nonneg(isl_ctx *ctx, struct isl_sched_graph *graph) +{ + int i; + int nonneg; + + nonneg = isl_options_get_schedule_nonneg_var_coefficient(ctx); + for (i = 0; i < graph->n; ++i) { + struct isl_sched_node *node = &graph->node[i]; + + if (nonneg) + node->nonneg = 1; + } + + return isl_stat_ok; +} + +/* Clear the nonneg fields of the nodes in "graph". + */ +static isl_stat graph_clear_nonneg(isl_ctx *ctx, struct isl_sched_graph *graph) +{ + int i; + + for (i = 0; i < graph->n; ++i) { + struct isl_sched_node *node = &graph->node[i]; + + node->nonneg = 0; + } + + return isl_stat_ok; +} + +/* Construct a band of schedule rows for a connected dependence graph. + * The caller is responsible for determining the strongly connected + * components and calling compute_maxvar first. + * + * Locally set the nonneg fields of the nodes for use in the LP encoding. + * The markings are cleared afterwards in case the graph is reused + * to carry dependences. + */ +static isl_stat compute_schedule_wcc_band(isl_ctx *ctx, + struct isl_sched_graph *graph) +{ + isl_stat r; + + r = graph_set_nonneg(ctx, graph); + if (r >= 0) + r = compute_schedule_wcc_band_core(ctx, graph); + if (r >= 0) + r = graph_clear_nonneg(ctx, graph); + + return r; +} + /* Compute a schedule for a connected dependence graph by considering * the graph as a whole and return the updated schedule node. * diff -Npur isl_0.22/isl_space.c isl/isl_space.c --- isl_0.22/isl_space.c 2020-04-17 16:49:36.258477000 +0800 +++ isl/isl_space.c 2020-04-29 18:14:39.941681000 +0800 @@ -599,6 +599,20 @@ error: return NULL; } +/* Replace the tuple identifier of the set space "space" by "id". + */ +__isl_give isl_space *isl_space_set_set_tuple_id(__isl_take isl_space *space, + __isl_take isl_id *id) +{ + if (isl_space_check_is_set(space) < 0) + goto error; + return isl_space_set_tuple_id(space, isl_dim_set, id); +error: + isl_space_free(space); + isl_id_free(id); + return NULL; +} + __isl_give isl_space *isl_space_reset_tuple_id(__isl_take isl_space *space, enum isl_dim_type type) { @@ -1140,6 +1154,17 @@ error: return NULL; } +/* Does "id" appear as a parameter in "space"? + */ +isl_bool isl_space_has_param_id(__isl_keep isl_space *space, + __isl_keep isl_id *id) +{ + if (!space || !id) + return isl_bool_error; + + return isl_space_find_dim_by_id(space, isl_dim_param, id) >= 0; +} + /* Add a parameter with identifier "id" to "space", provided * it does not already appear in "space". */