basis_reduction_templ.c \
isl_pw_templ.c \
isl_union_templ.c \
+ isl.py \
doc/chicago.bst \
doc/chicago.sty \
doc/implementation.tex \
gitversion.h: @GIT_HEAD@
echo '#define GIT_HEAD_ID "'@GIT_HEAD_VERSION@'"' > $@
+
+install-data-local: $(srcdir)/isl.py
+ @libisl=`sed -ne "/^library_names=/{s/.*='//;s/'$$//;s/ .*//;p}" \
+ $(builddir)/libisl.la`; \
+ case $$libisl in \
+ '') echo Cannot find isl library name. GDB bindings not installed.;; \
+ *) echo $(INSTALL_DATA) $(srcdir)/isl.py $(libdir)/$$libisl-gdb.py; \
+ $(INSTALL_DATA) $(srcdir)/isl.py $(libdir)/$$libisl-gdb.py; esac
=back
+=head3 Changes since isl-0.05
+
+=over
+
+=item * The functions C<isl_printer_print_basic_set> and
+C<isl_printer_print_basic_map> no longer print a newline.
+
+=back
+
=head1 Installation
The source of C<isl> can be obtained either as a tarball
__isl_give isl_union_map *isl_union_map_coalesce(
__isl_take isl_union_map *umap);
+=item * Detecting equalities
+
+ __isl_give isl_basic_set *isl_basic_set_detect_equalities(
+ __isl_take isl_basic_set *bset);
+ __isl_give isl_basic_map *isl_basic_map_detect_equalities(
+ __isl_take isl_basic_map *bmap);
+ __isl_give isl_set *isl_set_detect_equalities(
+ __isl_take isl_set *set);
+ __isl_give isl_map *isl_map_detect_equalities(
+ __isl_take isl_map *map);
+ __isl_give isl_union_set *isl_union_set_detect_equalities(
+ __isl_take isl_union_set *uset);
+ __isl_give isl_union_map *isl_union_map_detect_equalities(
+ __isl_take isl_union_map *umap);
+
+Simplify the representation of a set or relation by detecting implicit
+equalities.
+
=item * Convex hull
__isl_give isl_basic_set *isl_set_convex_hull(
__isl_take isl_set *set);
__isl_give isl_basic_map *isl_map_simple_hull(
__isl_take isl_map *map);
+ __isl_give isl_union_map *isl_union_map_simple_hull(
+ __isl_take isl_union_map *umap);
These functions compute a single basic set or relation
that contains the whole input set or relation.
set or relation. If there is any such internal structure in the input,
then the name of the space is also removed.
+ __isl_give isl_basic_set *isl_basic_set_flatten(
+ __isl_take isl_basic_set *bset);
__isl_give isl_set *isl_set_flatten(
__isl_take isl_set *set);
__isl_give isl_map *isl_map_flatten(
__isl_take isl_union_map *umap1,
__isl_take isl_union_map *umap2);
+=item * Cartesian Product
+
+ __isl_give isl_set *isl_set_product(
+ __isl_take isl_set *set1,
+ __isl_take isl_set *set2);
+ __isl_give isl_union_set *isl_union_set_product(
+ __isl_take isl_union_set *uset1,
+ __isl_take isl_union_set *uset2);
+ __isl_give isl_basic_map *isl_basic_map_range_product(
+ __isl_take isl_basic_map *bmap1,
+ __isl_take isl_basic_map *bmap2);
+ __isl_give isl_map *isl_map_range_product(
+ __isl_take isl_map *map1,
+ __isl_take isl_map *map2);
+ __isl_give isl_union_map *isl_union_map_range_product(
+ __isl_take isl_union_map *umap1,
+ __isl_take isl_union_map *umap2);
+ __isl_give isl_map *isl_map_product(
+ __isl_take isl_map *map1,
+ __isl_take isl_map *map2);
+ __isl_give isl_union_map *isl_union_map_product(
+ __isl_take isl_union_map *umap1,
+ __isl_take isl_union_map *umap2);
+
+The above functions compute the cross product of the given
+sets or relations. The domains and ranges of the results
+are wrapped maps between domains and ranges of the inputs.
+To obtain a ``flat'' product, use the following functions
+instead.
+
+ __isl_give isl_set *isl_set_flat_product(
+ __isl_take isl_set *set1,
+ __isl_take isl_set *set2);
+ __isl_give isl_map *isl_map_flat_product(
+ __isl_take isl_map *map1,
+ __isl_take isl_map *map2);
+
=item * Simplification
__isl_give isl_basic_set *isl_basic_set_gist(
to simplify the quasipolynomial reductions associated to each cell.
__isl_give isl_pw_qpolynomial_fold *
+ isl_set_apply_pw_qpolynomial_fold(
+ __isl_take isl_set *set,
+ __isl_take isl_pw_qpolynomial_fold *pwf,
+ int *tight);
+ __isl_give isl_pw_qpolynomial_fold *
isl_map_apply_pw_qpolynomial_fold(
__isl_take isl_map *map,
__isl_take isl_pw_qpolynomial_fold *pwf,
int *tight);
__isl_give isl_union_pw_qpolynomial_fold *
+ isl_union_set_apply_union_pw_qpolynomial_fold(
+ __isl_take isl_union_set *uset,
+ __isl_take isl_union_pw_qpolynomial_fold *upwf,
+ int *tight);
+ __isl_give isl_union_pw_qpolynomial_fold *
isl_union_map_apply_union_pw_qpolynomial_fold(
__isl_take isl_union_map *umap,
__isl_take isl_union_pw_qpolynomial_fold *upwf,
int *tight);
-These functions
+The functions taking a map
compose the given map with the given piecewise quasipolynomial reduction.
That is, compute a bound (of the same type as C<pwf> or C<upwf> itself)
over all elements in the intersection of the range of the map
and the domain of the piecewise quasipolynomial reduction
as a function of an element in the domain of the map.
+The functions taking a set compute a bound over all elements in the
+intersection of the set and the domain of the
+piecewise quasipolynomial reduction.
=head2 Dependence Analysis
void isl_constraint_get_coefficient(__isl_keep isl_constraint *constraint,
enum isl_dim_type type, int pos, isl_int *v);
void isl_constraint_set_constant(__isl_keep isl_constraint *constraint, isl_int v);
+void isl_constraint_set_constant_si(__isl_keep isl_constraint *constraint,
+ int v);
void isl_constraint_set_coefficient(__isl_keep isl_constraint *constraint,
enum isl_dim_type type, int pos, isl_int v);
+void isl_constraint_set_coefficient_si(__isl_keep isl_constraint *constraint,
+ enum isl_dim_type type, int pos, int v);
__isl_give isl_div *isl_constraint_div(__isl_keep isl_constraint *constraint,
int pos);
isl_error_none = 0,
isl_error_unknown,
isl_error_internal,
- isl_error_invalid
+ isl_error_invalid,
+ isl_error_unsupported
};
struct isl_ctx {
int ref;
__isl_give isl_dim *isl_dim_join(__isl_take isl_dim *left,
__isl_take isl_dim *right);
struct isl_dim *isl_dim_product(struct isl_dim *left, struct isl_dim *right);
+__isl_give isl_dim *isl_dim_range_product(__isl_take isl_dim *left,
+ __isl_take isl_dim *right);
struct isl_dim *isl_dim_map(struct isl_dim *dim);
__isl_give isl_dim *isl_dim_reverse(__isl_take isl_dim *dim);
__isl_give isl_dim *isl_dim_drop(__isl_take isl_dim *dim,
FILE *input, int nparam);
__isl_give isl_map *isl_map_read_from_str(isl_ctx *ctx,
const char *str, int nparam);
+void isl_basic_map_dump(__isl_keep isl_basic_map *bmap);
void isl_basic_map_print(__isl_keep isl_basic_map *bmap, FILE *out, int indent,
const char *prefix, const char *suffix, unsigned output_format);
+void isl_map_dump(__isl_keep isl_map *map);
void isl_map_print(__isl_keep isl_map *map, FILE *out, int indent,
unsigned output_format);
__isl_give isl_printer *isl_printer_print_basic_map(
void *user),
void *user);
-void isl_basic_map_dump(__isl_keep isl_basic_map *bmap, FILE *out, int indent);
+void isl_basic_map_print_internal(__isl_keep isl_basic_map *bmap,
+ FILE *out, int indent);
struct isl_basic_map *isl_map_copy_basic_map(struct isl_map *map);
__isl_give isl_map *isl_map_drop_basic_map(__isl_take isl_map *map,
__isl_give isl_map *isl_map_apply_range(
__isl_take isl_map *map1,
__isl_take isl_map *map2);
-struct isl_map *isl_map_product(struct isl_map *map1, struct isl_map *map2);
+__isl_give isl_map *isl_map_product(__isl_take isl_map *map1,
+ __isl_take isl_map *map2);
+__isl_give isl_basic_map *isl_basic_map_range_product(
+ __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2);
+__isl_give isl_map *isl_map_range_product(__isl_take isl_map *map1,
+ __isl_take isl_map *map2);
__isl_give isl_map *isl_map_flat_product(__isl_take isl_map *map1,
__isl_take isl_map *map2);
__isl_give isl_map *isl_map_intersect(__isl_take isl_map *map1,
__isl_give isl_basic_map *isl_basic_set_unwrap(__isl_take isl_basic_set *bset);
__isl_give isl_map *isl_set_unwrap(__isl_take isl_set *set);
__isl_give isl_map *isl_map_flatten(__isl_take isl_map *map);
+__isl_give isl_basic_set *isl_basic_set_flatten(__isl_take isl_basic_set *bset);
__isl_give isl_set *isl_set_flatten(__isl_take isl_set *set);
__isl_give isl_map *isl_set_flatten_map(__isl_take isl_set *set);
__isl_give isl_set *isl_map_domain(__isl_take isl_map *bmap);
__isl_give isl_map *isl_map_compute_divs(__isl_take isl_map *map);
__isl_give isl_map *isl_map_align_divs(__isl_take isl_map *map);
-void isl_map_dump(__isl_keep isl_map *map, FILE *out, int indent);
+void isl_map_print_internal(__isl_keep isl_map *map, FILE *out, int indent);
int isl_map_fast_input_is_fixed(struct isl_map *map,
unsigned in, isl_int *val);
int bernstein_triangulate;
int pip_symmetry;
+
+ #define ISL_CONVEX_HULL_WRAP 0
+ #define ISL_CONVEX_HULL_FM 1
+ int convex;
};
ISL_ARG_DECL(isl_options, struct isl_options, isl_options_arg)
__isl_take isl_qpolynomial *qp2);
__isl_give isl_qpolynomial *isl_qpolynomial_pow(__isl_take isl_qpolynomial *qp,
unsigned power);
+__isl_give isl_qpolynomial *isl_qpolynomial_add_isl_int(
+ __isl_take isl_qpolynomial *qp, isl_int v);
__isl_give isl_qpolynomial *isl_qpolynomial_insert_dims(
__isl_take isl_qpolynomial *qp, enum isl_dim_type type,
__isl_take isl_printer *p, __isl_keep isl_qpolynomial *qp);
void isl_qpolynomial_print(__isl_keep isl_qpolynomial *qp, FILE *out,
unsigned output_format);
+void isl_qpolynomial_dump(__isl_keep isl_qpolynomial *qp);
struct isl_pw_qpolynomial;
typedef struct isl_pw_qpolynomial isl_pw_qpolynomial;
__isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp);
void isl_pw_qpolynomial_print(__isl_keep isl_pw_qpolynomial *pwqp, FILE *out,
unsigned output_format);
+void isl_pw_qpolynomial_dump(__isl_keep isl_pw_qpolynomial *pwqp);
__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_coalesce(
__isl_take isl_pw_qpolynomial *pwqp);
struct isl_qpolynomial_fold;
typedef struct isl_qpolynomial_fold isl_qpolynomial_fold;
+isl_ctx *isl_qpolynomial_fold_get_ctx(__isl_keep isl_qpolynomial_fold *fold);
enum isl_fold isl_qpolynomial_fold_get_type(__isl_keep isl_qpolynomial_fold *fold);
__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_empty(enum isl_fold type,
__isl_keep isl_qpolynomial_fold *fold,
int (*fn)(__isl_take isl_qpolynomial *qp, void *user), void *user);
+__isl_give isl_printer *isl_printer_print_qpolynomial_fold(
+ __isl_take isl_printer *p, __isl_keep isl_qpolynomial_fold *fold);
void isl_qpolynomial_fold_print(__isl_keep isl_qpolynomial_fold *fold, FILE *out,
unsigned output_format);
+void isl_qpolynomial_fold_dump(__isl_keep isl_qpolynomial_fold *fold);
struct isl_pw_qpolynomial_fold;
typedef struct isl_pw_qpolynomial_fold isl_pw_qpolynomial_fold;
__isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf);
void isl_pw_qpolynomial_fold_print(__isl_keep isl_pw_qpolynomial_fold *pwf,
FILE *out, unsigned output_format);
+void isl_pw_qpolynomial_fold_dump(__isl_keep isl_pw_qpolynomial_fold *pwf);
__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_coalesce(
__isl_take isl_pw_qpolynomial_fold *pwf);
__isl_take isl_pw_qpolynomial *pwqp, enum isl_fold type, int *tight);
__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_bound(
__isl_take isl_pw_qpolynomial_fold *pwf, int *tight);
+__isl_give isl_pw_qpolynomial_fold *isl_set_apply_pw_qpolynomial_fold(
+ __isl_take isl_set *set, __isl_take isl_pw_qpolynomial_fold *pwf,
+ int *tight);
__isl_give isl_pw_qpolynomial_fold *isl_map_apply_pw_qpolynomial_fold(
__isl_take isl_map *map, __isl_take isl_pw_qpolynomial_fold *pwf,
int *tight);
__isl_give isl_union_pw_qpolynomial_fold *isl_union_pw_qpolynomial_bound(
__isl_take isl_union_pw_qpolynomial *upwqp,
enum isl_fold type, int *tight);
+__isl_give isl_union_pw_qpolynomial_fold *isl_union_set_apply_union_pw_qpolynomial_fold(
+ __isl_take isl_union_set *uset,
+ __isl_take isl_union_pw_qpolynomial_fold *upwf, int *tight);
__isl_give isl_union_pw_qpolynomial_fold *isl_union_map_apply_union_pw_qpolynomial_fold(
__isl_take isl_union_map *umap,
__isl_take isl_union_pw_qpolynomial_fold *upwf, int *tight);
struct isl_basic_set *isl_basic_set_interval(struct isl_ctx *ctx,
isl_int min, isl_int max);
struct isl_basic_set *isl_basic_set_positive_orthant(struct isl_dim *dims);
-void isl_basic_set_dump(__isl_keep isl_basic_set *bset,
+void isl_basic_set_print_internal(__isl_keep isl_basic_set *bset,
FILE *out, int indent);
struct isl_basic_set *isl_basic_set_swap_vars(
struct isl_basic_set *bset, unsigned n);
struct isl_basic_set *isl_basic_set_simplify(struct isl_basic_set *bset);
__isl_give isl_basic_set *isl_basic_set_detect_equalities(
__isl_take isl_basic_set *bset);
-struct isl_basic_set *isl_basic_set_product(struct isl_basic_set_list *list);
+__isl_give isl_basic_set *isl_basic_set_list_product(
+ __isl_take struct isl_basic_set_list *list);
__isl_give isl_basic_set *isl_basic_set_read_from_file(isl_ctx *ctx,
FILE *input, int nparam);
FILE *input, int nparam);
__isl_give isl_set *isl_set_read_from_str(isl_ctx *ctx,
const char *str, int nparam);
+void isl_basic_set_dump(__isl_keep isl_basic_set *bset);
+void isl_set_dump(__isl_keep isl_set *set);
__isl_give isl_printer *isl_printer_print_basic_set(
__isl_take isl_printer *printer, __isl_keep isl_basic_set *bset);
__isl_give isl_printer *isl_printer_print_set(__isl_take isl_printer *printer,
__isl_give isl_set *isl_set_union(
__isl_take isl_set *set1,
__isl_take isl_set *set2);
-struct isl_set *isl_set_product(struct isl_set *set1, struct isl_set *set2);
+__isl_give isl_set *isl_set_product(__isl_take isl_set *set1,
+ __isl_take isl_set *set2);
__isl_give isl_set *isl_set_flat_product(__isl_take isl_set *set1,
__isl_take isl_set *set2);
__isl_give isl_set *isl_set_intersect(
enum isl_dim_type type, unsigned first, unsigned n);
__isl_give isl_set *isl_set_remove_divs_involving_dims(__isl_take isl_set *set,
enum isl_dim_type type, unsigned first, unsigned n);
+__isl_give isl_set *isl_set_remove_unknown_divs(__isl_take isl_set *set);
__isl_give isl_set *isl_set_remove_divs(__isl_take isl_set *set);
__isl_give isl_set *isl_set_split_dims(__isl_take isl_set *set,
enum isl_dim_type type, unsigned first, unsigned n);
-void isl_set_dump(__isl_keep isl_set *set, FILE *out, int indent);
+void isl_set_print_internal(__isl_keep isl_set *set, FILE *out, int indent);
struct isl_set *isl_set_swap_vars(struct isl_set *set, unsigned n);
int isl_set_fast_is_empty(__isl_keep isl_set *set);
int isl_set_fast_is_universe(__isl_keep isl_set *set);
enum isl_token_type type;
unsigned int on_new_line : 1;
+ unsigned is_keyword : 1;
int line;
int col;
__isl_take isl_union_map *umap);
__isl_give isl_union_map *isl_union_map_range_map(
__isl_take isl_union_map *umap);
+__isl_give isl_union_map *isl_union_map_from_domain(
+ __isl_take isl_union_set *uset);
+__isl_give isl_union_map *isl_union_map_from_range(
+ __isl_take isl_union_set *uset);
__isl_give isl_union_map *isl_union_map_affine_hull(
__isl_take isl_union_map *umap);
__isl_give isl_union_map *isl_union_map_polyhedral_hull(
__isl_take isl_union_map *umap);
+__isl_give isl_union_map *isl_union_map_simple_hull(
+ __isl_take isl_union_map *umap);
__isl_give isl_union_map *isl_union_map_coalesce(
__isl_take isl_union_map *umap);
__isl_give isl_union_map *isl_union_map_compute_divs(
__isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2);
__isl_give isl_union_map *isl_union_map_product(__isl_take isl_union_map *umap1,
__isl_take isl_union_map *umap2);
+__isl_give isl_union_map *isl_union_map_range_product(
+ __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2);
__isl_give isl_union_map *isl_union_map_gist(__isl_take isl_union_map *umap,
__isl_take isl_union_map *context);
__isl_give isl_union_map *isl_union_map_from_domain_and_range(
__isl_take isl_union_set *domain, __isl_take isl_union_set *range);
+__isl_give isl_union_map *isl_union_map_detect_equalities(
+ __isl_keep isl_union_map *umap);
__isl_give isl_union_set *isl_union_map_deltas(__isl_take isl_union_map *umap);
__isl_give isl_union_map *isl_union_set_identity(__isl_take isl_union_set *uset);
const char *str);
__isl_give isl_printer *isl_printer_print_union_map(__isl_take isl_printer *p,
__isl_keep isl_union_map *umap);
+void isl_union_map_dump(__isl_keep isl_union_map *umap);
__isl_give isl_union_set *isl_union_map_wrap(__isl_take isl_union_map *umap);
__isl_give isl_union_map *isl_union_set_unwrap(__isl_take isl_union_set *uset);
isl_ctx *isl_union_set_get_ctx(__isl_keep isl_union_set *uset);
__isl_give isl_dim *isl_union_set_get_dim(__isl_keep isl_union_set *uset);
+__isl_give isl_union_set *isl_union_set_detect_equalities(
+ __isl_take isl_union_set *uset);
__isl_give isl_union_set *isl_union_set_affine_hull(
__isl_take isl_union_set *uset);
__isl_give isl_union_set *isl_union_set_polyhedral_hull(
__isl_take isl_union_set *uset);
+__isl_give isl_union_set *isl_union_set_simple_hull(
+ __isl_take isl_union_set *uset);
__isl_give isl_union_set *isl_union_set_coalesce(
__isl_take isl_union_set *uset);
__isl_give isl_union_set *isl_union_set_compute_divs(
const char *str);
__isl_give isl_printer *isl_printer_print_union_set(__isl_take isl_printer *p,
__isl_keep isl_union_set *uset);
+void isl_union_set_dump(__isl_keep isl_union_set *uset);
#if defined(__cplusplus)
}
#include <isl/int.h>
#include <isl/ctx.h>
#include <isl/blk.h>
+#include <isl/printer.h>
#if defined(__cplusplus)
extern "C" {
struct isl_vec *isl_vec_cow(struct isl_vec *vec);
void isl_vec_free(struct isl_vec *vec);
-void isl_vec_dump(struct isl_vec *vec, FILE *out, int indent);
+void isl_vec_dump(__isl_keep isl_vec *vec);
+__isl_give isl_printer *isl_printer_print_vec(__isl_take isl_printer *printer,
+ __isl_keep isl_vec *vec);
void isl_vec_lcm(struct isl_vec *vec, isl_int *lcm);
struct isl_vec *isl_vec_ceil(struct isl_vec *vec);
--- /dev/null
+import gdb
+import re
+
+# GDB Pretty Printers for most isl objects
+class IslObjectPrinter:
+ """Print an isl object"""
+ def __init__ (self, val, type):
+ self.val = val
+ self.type = type
+
+ def to_string (self):
+ # Cast val to a void pointer to stop gdb using this pretty
+ # printer for the pointer which would lead to an infinite loop.
+ void_ptr = gdb.lookup_type('void').pointer()
+ value = str(self.val.cast(void_ptr))
+ printer = gdb.parse_and_eval("isl_printer_to_str(isl_"
+ + str(self.type)
+ + "_get_ctx(" + value + "))")
+ printer = gdb.parse_and_eval("isl_printer_print_"
+ + str(self.type) + "("
+ + str(printer) + ", "
+ + value + ")")
+ string = gdb.parse_and_eval("(char*)isl_printer_get_str("
+ + str(printer) + ")")
+ gdb.parse_and_eval("isl_printer_free(" + str(printer) + ")")
+ return string
+
+ def display_hint (self):
+ return 'string'
+
+class IslIntPrinter:
+ """Print an isl_int """
+ def __init__ (self, val):
+ self.val = val
+
+ def to_string (self):
+ # Cast val to a void pointer to stop gdb using this pretty
+ # printer for the pointer which would lead to an infinite loop.
+ void_ptr = gdb.lookup_type('void').pointer()
+ value = str(self.val.cast(void_ptr))
+
+ context = gdb.parse_and_eval("isl_ctx_alloc()")
+ printer = gdb.parse_and_eval("isl_printer_to_str("
+ + str(context) + ")")
+ printer = gdb.parse_and_eval("isl_printer_print_isl_int("
+ + str(printer) + ", "
+ + value + ")")
+ string = gdb.parse_and_eval("(char*)isl_printer_get_str("
+ + str(printer) + ")")
+ gdb.parse_and_eval("isl_printer_free(" + str(printer) + ")")
+ gdb.parse_and_eval("isl_ctx_free(" + str(context) + ")")
+ return string
+
+ def display_hint (self):
+ return 'string'
+
+class IslPrintCommand (gdb.Command):
+ """Print an isl value."""
+ def __init__ (self):
+ super (IslPrintCommand, self).__init__ ("islprint",
+ gdb.COMMAND_OBSCURE)
+ def invoke (self, arg, from_tty):
+ arg = gdb.parse_and_eval(arg);
+ printer = str_lookup_function(arg)
+
+ if printer == None:
+ print "No isl printer for this type"
+ return
+
+ print printer.to_string()
+
+IslPrintCommand()
+
+def str_lookup_function (val):
+ if val.type.code != gdb.TYPE_CODE_PTR:
+ if str(val.type) == "isl_int":
+ return IslIntPrinter(val)
+ else:
+ return None
+
+ lookup_tag = val.type.target()
+ regex = re.compile ("^isl_(.*)$")
+
+ if lookup_tag == None:
+ return None
+
+ m = regex.match (str(lookup_tag))
+
+ if m:
+ # Those types of printers defined in isl.
+ if m.group(1) in ["basic_set", "set", "union_set", "basic_map",
+ "map", "union_map", "qpolynomial",
+ "pw_qpolynomial", "pw_qpolynomial_fold",
+ "union_pw_qpolynomial",
+ "union_pw_qpolynomial_fold"]:
+ return IslObjectPrinter(val, m.group(1))
+ return None
+
+# Do not register the pretty printer.
+# gdb.current_objfile().pretty_printers.append(str_lookup_function)
isl_int_set(constraint->line[0][0], v);
}
+void isl_constraint_set_constant_si(__isl_keep isl_constraint *constraint,
+ int v)
+{
+ if (!constraint)
+ return;
+ isl_int_set_si(constraint->line[0][0], v);
+}
+
void isl_constraint_set_coefficient(struct isl_constraint *constraint,
enum isl_dim_type type, int pos, isl_int v)
{
isl_int_set(constraint->line[0][offset(constraint, type) + pos], v);
}
+void isl_constraint_set_coefficient_si(__isl_keep isl_constraint *constraint,
+ enum isl_dim_type type, int pos, int v)
+{
+ if (!constraint)
+ return;
+
+ isl_assert(constraint->ctx, pos < n(constraint, type), return);
+ isl_int_set_si(constraint->line[0][offset(constraint, type) + pos], v);
+}
+
void isl_constraint_clear(struct isl_constraint *constraint)
{
unsigned total;
isl_basic_set *lin, *aff;
int bounded1, bounded2;
+ if (bset1->ctx->opt->convex == ISL_CONVEX_HULL_FM)
+ return convex_hull_pair_elim(bset1, bset2);
+
aff = isl_set_affine_hull(isl_basic_set_union(isl_basic_set_copy(bset1),
isl_basic_set_copy(bset2)));
if (!aff)
if (isl_set_n_dim(set) == 1)
return convex_hull_1d(set);
- if (isl_set_is_bounded(set))
+ if (isl_set_is_bounded(set) &&
+ set->ctx->opt->convex == ISL_CONVEX_HULL_WRAP)
return uset_convex_hull_wrap(set);
lin = uset_combined_lineality_space(isl_set_copy(set));
return NULL;
}
+__isl_give isl_dim *isl_dim_range_product(__isl_take isl_dim *left,
+ __isl_take isl_dim *right)
+{
+ isl_dim *dom, *ran1, *ran2, *nest;
+
+ if (!left || !right)
+ goto error;
+
+ isl_assert(left->ctx, match(left, isl_dim_param, right, isl_dim_param),
+ goto error);
+ if (!isl_dim_match(left, isl_dim_in, right, isl_dim_in))
+ isl_die(left->ctx, isl_error_invalid,
+ "domains need to match", goto error);
+
+ dom = isl_dim_domain(isl_dim_copy(left));
+
+ ran1 = isl_dim_range(left);
+ ran2 = isl_dim_range(right);
+ nest = isl_dim_wrap(isl_dim_join(isl_dim_reverse(ran1), ran2));
+
+ return isl_dim_join(isl_dim_reverse(dom), nest);
+error:
+ isl_dim_free(left);
+ isl_dim_free(right);
+ return NULL;
+}
+
struct isl_dim *isl_dim_map(struct isl_dim *dim)
{
struct isl_name **names = NULL;
return NULL;
}
+isl_ctx *isl_qpolynomial_fold_get_ctx(__isl_keep isl_qpolynomial_fold *fold)
+{
+ return fold ? fold->dim->ctx : NULL;
+}
+
__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_reset_dim(
__isl_take isl_qpolynomial_fold *fold, __isl_take isl_dim *dim)
{
return NULL;
}
+__isl_give isl_pw_qpolynomial_fold *isl_set_apply_pw_qpolynomial_fold(
+ __isl_take isl_set *set, __isl_take isl_pw_qpolynomial_fold *pwf,
+ int *tight)
+{
+ isl_map *map;
+
+ map = isl_map_from_range(set);
+ return isl_map_apply_pw_qpolynomial_fold(map, pwf, tight);
+}
+
struct isl_apply_fold_data {
isl_union_pw_qpolynomial_fold *upwf;
isl_union_pw_qpolynomial_fold *res;
return NULL;
}
+__isl_give isl_union_pw_qpolynomial_fold *isl_union_set_apply_union_pw_qpolynomial_fold(
+ __isl_take isl_union_set *uset,
+ __isl_take isl_union_pw_qpolynomial_fold *upwf, int *tight)
+{
+ return isl_union_map_apply_union_pw_qpolynomial_fold(uset, upwf, tight);
+}
+
/* Reorder the dimension of "fold" according to the given reordering.
*/
__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_realign(
return -1;
}
+/* Given an affine expression aff, return an affine expression
+ * for aff % d, with d the next token on the stream, which is
+ * assumed to be a constant.
+ *
+ * We introduce an integer division q = [aff/d] and the result
+ * is set to aff - d q.
+ */
+static __isl_give isl_vec *affine_mod(struct isl_stream *s,
+ struct vars *v, __isl_take isl_vec *aff)
+{
+ struct isl_token *tok;
+ struct variable *var;
+ isl_vec *mod;
+
+ tok = isl_stream_next_token(s);
+ if (!tok || tok->type != ISL_TOKEN_VALUE) {
+ isl_stream_error(s, tok, "expecting constant value");
+ goto error;
+ }
+
+ if (vars_add_anon(v) < 0)
+ goto error;
+
+ var = v->v;
+
+ var->def = isl_vec_alloc(s->ctx, 2 + v->n);
+ if (!var->def)
+ goto error;
+ isl_seq_cpy(var->def->el + 1, aff->el, aff->size);
+ isl_int_set_si(var->def->el[1 + aff->size], 0);
+ isl_int_set(var->def->el[0], tok->u.v);
+
+ mod = isl_vec_alloc(v->ctx, 1 + v->n);
+ if (!mod)
+ goto error;
+
+ isl_seq_cpy(mod->el, aff->el, aff->size);
+ isl_int_neg(mod->el[aff->size], tok->u.v);
+
+ isl_vec_free(aff);
+ isl_token_free(tok);
+ return mod;
+error:
+ isl_vec_free(aff);
+ isl_token_free(tok);
+ return NULL;
+}
+
static struct isl_vec *accept_affine(struct isl_stream *s, struct vars *v);
static int read_div_definition(struct isl_stream *s, struct vars *v);
isl_stream_error(s, tok, "expecting factor");
goto error;
}
+ if (isl_stream_eat_if_available(s, '%'))
+ return affine_mod(s, v, aff);
if (isl_stream_eat_if_available(s, '*')) {
isl_int f;
isl_int_init(f);
isl_stream_push_token(s, tok);
return 1;
}
- if (tok->type != ISL_TOKEN_IDENT) {
+ if (tok->type != ISL_TOKEN_IDENT && !tok->is_keyword) {
isl_stream_push_token(s, tok);
return 0;
}
char *name = NULL;
tok = isl_stream_next_token(s);
- if (tok && tok->type == ISL_TOKEN_IDENT) {
+ if (tok && (tok->type == ISL_TOKEN_IDENT || tok->is_keyword)) {
name = strdup(tok->u.s);
if (!name)
goto error;
type, first, n);
}
+/* Return true if the definition of the given div is unknown or depends
+ * on unknown divs.
+ */
+static int div_is_unknown(__isl_keep isl_basic_map *bmap, int div)
+{
+ int i;
+ unsigned div_offset = isl_basic_map_offset(bmap, isl_dim_div);
+
+ if (isl_int_is_zero(bmap->div[div][0]))
+ return 1;
+
+ for (i = bmap->n_div - 1; i >= 0; --i) {
+ if (isl_int_is_zero(bmap->div[div][1 + div_offset + i]))
+ continue;
+ if (div_is_unknown(bmap, i))
+ return 1;
+ }
+
+ return 0;
+}
+
+/* Remove all divs that are unknown or defined in terms of unknown divs.
+ */
+__isl_give isl_basic_map *isl_basic_map_remove_unknown_divs(
+ __isl_take isl_basic_map *bmap)
+{
+ int i;
+
+ if (!bmap)
+ return NULL;
+
+ for (i = bmap->n_div - 1; i >= 0; --i) {
+ if (!div_is_unknown(bmap, i))
+ continue;
+ bmap = isl_basic_map_remove_dims(bmap, isl_dim_div, i, 1);
+ }
+
+ return bmap;
+error:
+ isl_basic_map_free(bmap);
+ return NULL;
+}
+
+__isl_give isl_map *isl_map_remove_unknown_divs(__isl_take isl_map *map)
+{
+ int i;
+
+ if (!map)
+ return NULL;
+ if (map->n == 0)
+ return map;
+
+ map = isl_map_cow(map);
+ if (!map)
+ return NULL;
+
+ for (i = 0; i < map->n; ++i) {
+ map->p[i] = isl_basic_map_remove_unknown_divs(map->p[i]);
+ if (!map->p[i])
+ goto error;
+ }
+ return map;
+error:
+ isl_map_free(map);
+ return NULL;
+}
+
+__isl_give isl_set *isl_set_remove_unknown_divs(__isl_take isl_set *set)
+{
+ return (isl_set *)isl_map_remove_unknown_divs((isl_map *)set);
+}
+
__isl_give isl_basic_set *isl_basic_set_remove_dims(
__isl_take isl_basic_set *bset,
enum isl_dim_type type, unsigned first, unsigned n)
}
}
-void isl_basic_set_dump(struct isl_basic_set *bset, FILE *out, int indent)
+void isl_basic_set_print_internal(struct isl_basic_set *bset,
+ FILE *out, int indent)
{
if (!bset) {
fprintf(out, "null basic set\n");
dump((struct isl_basic_map *)bset, out, indent);
}
-void isl_basic_map_dump(struct isl_basic_map *bmap, FILE *out, int indent)
+void isl_basic_map_print_internal(struct isl_basic_map *bmap,
+ FILE *out, int indent)
{
if (!bmap) {
fprintf(out, "null basic map\n");
free(set);
}
-void isl_set_dump(struct isl_set *set, FILE *out, int indent)
+void isl_set_print_internal(struct isl_set *set, FILE *out, int indent)
{
int i;
for (i = 0; i < set->n; ++i) {
fprintf(out, "%*s", indent, "");
fprintf(out, "basic set %d:\n", i);
- isl_basic_set_dump(set->p[i], out, indent+4);
+ isl_basic_set_print_internal(set->p[i], out, indent+4);
}
}
-void isl_map_dump(struct isl_map *map, FILE *out, int indent)
+void isl_map_print_internal(struct isl_map *map, FILE *out, int indent)
{
int i;
for (i = 0; i < map->n; ++i) {
fprintf(out, "%*s", indent, "");
fprintf(out, "basic map %d:\n", i);
- isl_basic_map_dump(map->p[i], out, indent+4);
+ isl_basic_map_print_internal(map->p[i], out, indent+4);
}
}
struct isl_basic_map *bmap, struct isl_basic_set *bset)
{
struct isl_basic_map *bmap_domain;
- struct isl_dim *dim;
if (!bmap || !bset)
goto error;
goto error;
bmap = isl_basic_map_extend_dim(bmap, isl_dim_copy(bmap->dim),
bset->n_div, bset->n_eq, bset->n_ineq);
- dim = isl_dim_reverse(isl_dim_copy(bset->dim));
- bmap_domain = isl_basic_map_from_basic_set(bset, dim);
+ bmap_domain = isl_basic_map_from_domain(bset);
bmap = add_constraints(bmap, bmap_domain, 0, 0);
bmap = isl_basic_map_simplify(bmap);
res = isl_basic_map_alloc_dim(res_dim,
bmap->n_div, bmap->n_eq, bmap->n_ineq);
res = add_constraints_dim_map(res, bmap, dim_map);
- res = isl_basic_map_simplify(res);
return isl_basic_map_finalize(res);
}
dom, empty);
}
-/* Given a basic map "bmap", compute the lexicograhically minimal
+/* Given a basic map "bmap", compute the lexicographically minimal
* (or maximal) image element for each domain element in dom.
* Set *empty to those elements in dom that do not have an image element.
*
return NULL;
}
-/* Given a map "map", compute the lexicograhically minimal
+/* Given a map "map", compute the lexicographically minimal
* (or maximal) image element for each domain element in dom.
* Set *empty to those elements in dom that do not have an image element.
*
*
* Let res^k and todo^k be the results after k steps and let i = k + 1.
* Assume we are computing the lexicographical maximum.
- * We first intersect basic map i with a relation that maps elements
- * to elements that are lexicographically larger than the image elements
- * in res^k and the compute the maximum image element of this intersection.
- * The result ("better") corresponds to those image elements in basic map i
- * that are better than what we had before. The remainder ("keep") are the
- * domain elements for which the image element in res_k was better.
- * We also compute the lexicographical maximum of basic map i in todo^k.
- * res^i is the result of the operation + better + those elements in
- * res^k that we should keep
- * todo^i is the remainder of the maximum operation on todo^k.
+ * We first compute the lexicographically maximal element in basic map i.
+ * This results in a partial solution res_i and a subset todo_i.
+ * Then we combine these results with those obtain for the first k basic maps
+ * to obtain a result that is valid for the first k+1 basic maps.
+ * In particular, the set where there is no solution is the set where
+ * there is no solution for the first k basic maps and also no solution
+ * for the ith basic map, i.e.,
+ *
+ * todo^i = todo^k * todo_i
+ *
+ * On dom(res^k) * dom(res_i), we need to pick the larger of the two
+ * solutions, arbitrarily breaking ties in favor of res^k.
+ * That is, when res^k(a) >= res_i(a), we pick res^k and
+ * when res^k(a) < res_i(a), we pick res_i. (Here, ">=" and "<" denote
+ * the lexicographic order.)
+ * In practice, we compute
+ *
+ * res^k * (res_i . "<=")
+ *
+ * and
+ *
+ * res_i * (res^k . "<")
+ *
+ * Finally, we consider the symmetric difference of dom(res^k) and dom(res_i),
+ * where only one of res^k and res_i provides a solution and we simply pick
+ * that one, i.e.,
+ *
+ * res^k * todo_i
+ * and
+ * res_i * todo^k
+ *
+ * Note that we only compute these intersections when dom(res^k) intersects
+ * dom(res_i). Otherwise, the only effect of these intersections is to
+ * potentially break up res^k and res_i into smaller pieces.
+ * We want to avoid such splintering as much as possible.
+ * In fact, an earlier implementation of this function would look for
+ * better results in the domain of res^k and for extra results in todo^k,
+ * but this would always result in a splintering according to todo^k,
+ * even when the domain of basic map i is disjoint from the domains of
+ * the previous basic maps.
*/
static __isl_give isl_map *isl_map_partial_lexopt(
__isl_take isl_map *map, __isl_take isl_set *dom,
isl_set_copy(dom), &todo, max);
for (i = 1; i < map->n; ++i) {
- struct isl_map *lt;
- struct isl_map *better;
- struct isl_set *keep;
- struct isl_map *res_i;
- struct isl_set *todo_i;
- struct isl_dim *dim = isl_map_get_dim(res);
-
- dim = isl_dim_range(dim);
- if (max)
- lt = isl_map_lex_lt(dim);
- else
- lt = isl_map_lex_gt(dim);
- lt = isl_map_apply_range(isl_map_copy(res), lt);
- lt = isl_map_intersect(lt,
- isl_map_from_basic_map(isl_basic_map_copy(map->p[i])));
- better = isl_map_partial_lexopt(lt,
- isl_map_domain(isl_map_copy(res)),
- &keep, max);
+ isl_map *lt, *le;
+ isl_map *res_i;
+ isl_set *todo_i;
+ isl_dim *dim = isl_dim_range(isl_map_get_dim(res));
res_i = basic_map_partial_lexopt(isl_basic_map_copy(map->p[i]),
- todo, &todo_i, max);
+ isl_set_copy(dom), &todo_i, max);
+
+ if (max) {
+ lt = isl_map_lex_lt(isl_dim_copy(dim));
+ le = isl_map_lex_le(dim);
+ } else {
+ lt = isl_map_lex_gt(isl_dim_copy(dim));
+ le = isl_map_lex_ge(dim);
+ }
+ lt = isl_map_apply_range(isl_map_copy(res), lt);
+ lt = isl_map_intersect(lt, isl_map_copy(res_i));
+ le = isl_map_apply_range(isl_map_copy(res_i), le);
+ le = isl_map_intersect(le, isl_map_copy(res));
+
+ if (!isl_map_is_empty(lt) || !isl_map_is_empty(le)) {
+ res = isl_map_intersect_domain(res,
+ isl_set_copy(todo_i));
+ res_i = isl_map_intersect_domain(res_i,
+ isl_set_copy(todo));
+ }
- res = isl_map_intersect_domain(res, keep);
res = isl_map_union_disjoint(res, res_i);
- res = isl_map_union_disjoint(res, better);
- todo = todo_i;
+ res = isl_map_union_disjoint(res, lt);
+ res = isl_map_union_disjoint(res, le);
+
+ todo = isl_set_intersect(todo, todo_i);
}
isl_set_free(dom);
/* Return the Cartesian product of the basic sets in list (in the given order).
*/
-struct isl_basic_set *isl_basic_set_product(struct isl_basic_set_list *list)
+__isl_give isl_basic_set *isl_basic_set_list_product(
+ __isl_take struct isl_basic_set_list *list)
{
int i;
unsigned dim;
return NULL;
}
-/* Given two maps A -> B and C -> D, construct a map [A -> C] -> [B -> D]
- */
-struct isl_map *isl_map_product(struct isl_map *map1, struct isl_map *map2)
+__isl_give isl_basic_map *isl_basic_map_range_product(
+ __isl_take isl_basic_map *bmap1, __isl_take isl_basic_map *bmap2)
+{
+ isl_dim *dim_result = NULL;
+ isl_basic_map *bmap;
+ unsigned in, out1, out2, nparam, total, pos;
+ struct isl_dim_map *dim_map1, *dim_map2;
+
+ if (!bmap1 || !bmap2)
+ goto error;
+
+ dim_result = isl_dim_range_product(isl_dim_copy(bmap1->dim),
+ isl_dim_copy(bmap2->dim));
+
+ in = isl_basic_map_dim(bmap1, isl_dim_in);
+ out1 = isl_basic_map_n_out(bmap1);
+ out2 = isl_basic_map_n_out(bmap2);
+ nparam = isl_basic_map_n_param(bmap1);
+
+ total = nparam + in + out1 + out2 + bmap1->n_div + bmap2->n_div;
+ dim_map1 = isl_dim_map_alloc(bmap1->ctx, total);
+ dim_map2 = isl_dim_map_alloc(bmap1->ctx, total);
+ isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_param, pos = 0);
+ isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_param, pos = 0);
+ isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_in, pos += nparam);
+ isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_in, pos);
+ isl_dim_map_dim(dim_map1, bmap1->dim, isl_dim_out, pos += in);
+ isl_dim_map_dim(dim_map2, bmap2->dim, isl_dim_out, pos += out1);
+ isl_dim_map_div(dim_map1, bmap1, pos += out2);
+ isl_dim_map_div(dim_map2, bmap2, pos += bmap1->n_div);
+
+ bmap = isl_basic_map_alloc_dim(dim_result,
+ bmap1->n_div + bmap2->n_div,
+ bmap1->n_eq + bmap2->n_eq,
+ bmap1->n_ineq + bmap2->n_ineq);
+ bmap = add_constraints_dim_map(bmap, bmap1, dim_map1);
+ bmap = add_constraints_dim_map(bmap, bmap2, dim_map2);
+ bmap = isl_basic_map_simplify(bmap);
+ return isl_basic_map_finalize(bmap);
+error:
+ isl_basic_map_free(bmap1);
+ isl_basic_map_free(bmap2);
+ return NULL;
+}
+
+static __isl_give isl_map *map_product(__isl_take isl_map *map1,
+ __isl_take isl_map *map2,
+ __isl_give isl_dim *(*dim_product)(__isl_take isl_dim *left,
+ __isl_take isl_dim *right),
+ __isl_give isl_basic_map *(*basic_map_product)(
+ __isl_take isl_basic_map *left, __isl_take isl_basic_map *right))
{
unsigned flags = 0;
struct isl_map *result;
ISL_F_ISSET(map2, ISL_MAP_DISJOINT))
ISL_FL_SET(flags, ISL_MAP_DISJOINT);
- result = isl_map_alloc_dim(isl_dim_product(isl_dim_copy(map1->dim),
- isl_dim_copy(map2->dim)),
+ result = isl_map_alloc_dim(dim_product(isl_dim_copy(map1->dim),
+ isl_dim_copy(map2->dim)),
map1->n * map2->n, flags);
if (!result)
goto error;
for (i = 0; i < map1->n; ++i)
for (j = 0; j < map2->n; ++j) {
struct isl_basic_map *part;
- part = isl_basic_map_product(
- isl_basic_map_copy(map1->p[i]),
- isl_basic_map_copy(map2->p[j]));
+ part = basic_map_product(isl_basic_map_copy(map1->p[i]),
+ isl_basic_map_copy(map2->p[j]));
if (isl_basic_map_is_empty(part))
isl_basic_map_free(part);
else
return NULL;
}
+/* Given two maps A -> B and C -> D, construct a map [A -> C] -> [B -> D]
+ */
+struct isl_map *isl_map_product(struct isl_map *map1, struct isl_map *map2)
+{
+ return map_product(map1, map2, &isl_dim_product, &isl_basic_map_product);
+}
+
/* Given two maps A -> B and C -> D, construct a map (A, C) -> (B, D)
*/
__isl_give isl_map *isl_map_flat_product(__isl_take isl_map *map1,
return (isl_set *)isl_map_flat_product((isl_map *)set1, (isl_map *)set2);
}
+/* Given two maps A -> B and C -> D, construct a map (A * C) -> [B -> D]
+ */
+__isl_give isl_map *isl_map_range_product(__isl_take isl_map *map1,
+ __isl_take isl_map *map2)
+{
+ return map_product(map1, map2, &isl_dim_range_product,
+ &isl_basic_map_range_product);
+}
+
uint32_t isl_basic_map_get_hash(__isl_keep isl_basic_map *bmap)
{
int i;
return isl_basic_set_vars_get_sign(bset, first, n, signs);
}
+/* Check if the given basic map is obviously single-valued.
+ * In particular, for each output dimension, check that there is
+ * an equality that defines the output dimension in terms of
+ * earlier dimensions.
+ */
+int isl_basic_map_fast_is_single_valued(__isl_keep isl_basic_map *bmap)
+{
+ int i, j;
+ unsigned total;
+ unsigned n_out;
+ unsigned o_out;
+
+ if (!bmap)
+ return -1;
+
+ total = 1 + isl_basic_map_total_dim(bmap);
+ n_out = isl_basic_map_dim(bmap, isl_dim_out);
+ o_out = isl_basic_map_offset(bmap, isl_dim_out);
+
+ for (i = 0; i < n_out; ++i) {
+ for (j = 0; j < bmap->n_eq; ++j) {
+ if (isl_int_is_zero(bmap->eq[j][o_out + i]))
+ continue;
+ if (isl_seq_first_non_zero(bmap->eq[j] + o_out + i + 1,
+ total - (o_out + i + 1)) == -1)
+ break;
+ }
+ if (j >= bmap->n_eq)
+ return 0;
+ }
+
+ return 1;
+}
+
+/* Check if the given map is obviously single-valued.
+ */
+int isl_map_fast_is_single_valued(__isl_keep isl_map *map)
+{
+ int sv;
+
+ if (!map)
+ return -1;
+ if (map->n == 0)
+ return 1;
+ if (map->n >= 2)
+ return 0;
+
+ return isl_basic_map_fast_is_single_valued(map->p[0]);
+}
+
/* Check if the given map is single-valued.
* We simply compute
*
isl_map *id;
int sv;
+ sv = isl_map_fast_is_single_valued(map);
+ if (sv < 0 || sv)
+ return sv;
+
test = isl_map_reverse(isl_map_copy(map));
test = isl_map_apply_range(test, isl_map_copy(map));
return NULL;
}
+__isl_give isl_basic_set *isl_basic_set_flatten(__isl_take isl_basic_set *bset)
+{
+ return (isl_basic_set *)isl_basic_map_flatten((isl_basic_map *)bset);
+}
+
__isl_give isl_map *isl_map_flatten(__isl_take isl_map *map)
{
int i;
* a negative value is treated as an error, but the calling
* function can interpret the results based on the state of dc.
*
- * Assumes that both bmap and map have known divs.
+ * Assumes that map has known divs.
*
* The difference is computed by a backtracking algorithm.
* Each level corresponds to a basic map in "map".
/* Return 1 if "bmap" contains a single element.
*/
-int isl_basic_map_is_singleton(__isl_keep isl_basic_map *bmap)
+int isl_basic_map_fast_is_singleton(__isl_keep isl_basic_map *bmap)
{
if (!bmap)
return -1;
/* Return 1 if "map" contains a single element.
*/
-int isl_map_is_singleton(__isl_keep isl_map *map)
+int isl_map_fast_is_singleton(__isl_keep isl_map *map)
{
if (!map)
return -1;
if (map->n != 1)
return 0;
- return isl_basic_map_is_singleton(map->p[0]);
+ return isl_basic_map_fast_is_singleton(map->p[0]);
}
/* Given a singleton basic map, extract the single element
/* Return 1 is the singleton map "map1" is a subset of "map2",
* i.e., if the single element of "map1" is also an element of "map2".
+ * Assumes "map2" has known divs.
*/
static int map_is_singleton_subset(__isl_keep isl_map *map1,
__isl_keep isl_map *map2)
if (isl_map_fast_is_universe(map2))
return 1;
- map1 = isl_map_compute_divs(isl_map_copy(map1));
map2 = isl_map_compute_divs(isl_map_copy(map2));
- if (isl_map_is_singleton(map1)) {
+ if (isl_map_fast_is_singleton(map1)) {
is_subset = map_is_singleton_subset(map1, map2);
- isl_map_free(map1);
isl_map_free(map2);
return is_subset;
}
is_subset = map_diff_is_empty(map1, map2);
- isl_map_free(map1);
isl_map_free(map2);
return is_subset;
return morph;
}
+
+__isl_give isl_vec *isl_morph_vec(__isl_take isl_morph *morph,
+ __isl_take isl_vec *vec)
+{
+ if (!morph)
+ goto error;
+
+ vec = isl_mat_vec_product(isl_mat_copy(morph->map), vec);
+
+ isl_morph_free(morph);
+ return vec;
+error:
+ isl_morph_free(morph);
+ isl_vec_free(vec);
+ return NULL;
+}
__isl_take isl_basic_set *bset);
__isl_give isl_set *isl_morph_set(__isl_take isl_morph *morph,
__isl_take isl_set *set);
+__isl_give isl_vec *isl_morph_vec(__isl_take isl_morph *morph,
+ __isl_take isl_vec *vec);
#if defined(__cplusplus)
}
{0}
};
+static struct isl_arg_choice convex[] = {
+ {"wrap", ISL_CONVEX_HULL_WRAP},
+ {"fm", ISL_CONVEX_HULL_FM},
+ {0}
+};
+
static void print_version(void)
{
printf("%s", isl_version());
"triangulate domains during Bernstein expansion")
ISL_ARG_BOOL(struct isl_options, pip_symmetry, 0, "pip-symmetry", 1,
"detect simple symmetries in PIP input")
+ISL_ARG_CHOICE(struct isl_options, convex, 0, "convex-hull", \
+ convex, ISL_CONVEX_HULL_WRAP, "convex hull algorithm to use")
ISL_ARG_VERSION(print_version)
ISL_ARG_END
};
p = isl_printer_print_str(p, " : ");
p = print_disjunct(bmap, bmap->dim, p, 0, latex);
p = isl_printer_print_str(p, " }");
- p = isl_printer_end_line(p);
return p;
}
p = isl_printer_print_str(p, " : ");
p = print_disjunct((isl_basic_map *)bset, bset->dim, p, 1, latex);
p = isl_printer_print_str(p, " }");
- p = isl_printer_end_line(p);
return p;
}
isl_printer_free(printer);
}
+void isl_basic_map_dump(__isl_keep isl_basic_map *bmap)
+{
+ isl_printer *printer;
+
+ if (!bmap)
+ return;
+
+ printer = isl_printer_to_file(isl_basic_map_get_ctx(bmap), stderr);
+ printer = isl_printer_print_basic_map(printer, bmap);
+ printer = isl_printer_end_line(printer);
+
+ isl_printer_free(printer);
+}
+
+void isl_basic_set_dump(__isl_keep isl_basic_set *bset)
+{
+ isl_printer *printer;
+
+ if (!bset)
+ return;
+
+ printer = isl_printer_to_file(isl_basic_set_get_ctx(bset), stderr);
+ printer = isl_printer_print_basic_set(printer, bset);
+ printer = isl_printer_end_line(printer);
+
+ isl_printer_free(printer);
+}
+
+void isl_map_dump(__isl_keep isl_map *map)
+{
+ isl_printer *printer;
+
+ if (!map)
+ return;
+
+ printer = isl_printer_to_file(isl_map_get_ctx(map), stderr);
+ printer = isl_printer_print_map(printer, map);
+ printer = isl_printer_end_line(printer);
+
+ isl_printer_free(printer);
+}
+
+void isl_set_dump(__isl_keep isl_set *set)
+{
+ isl_printer *printer;
+
+ if (!set)
+ return;
+
+ printer = isl_printer_to_file(isl_set_get_ctx(set), stderr);
+ printer = isl_printer_print_set(printer, set);
+ printer = isl_printer_end_line(printer);
+
+ isl_printer_free(printer);
+}
+
void isl_union_map_dump(__isl_keep isl_union_map *umap)
{
isl_printer *printer;
isl_printer_free(printer);
}
+void isl_qpolynomial_dump(__isl_keep isl_qpolynomial *qp)
+{
+ isl_printer *printer;
+
+ if (!qp)
+ return;
+
+ printer = isl_printer_to_file(isl_qpolynomial_get_ctx(qp), stderr);
+ printer = isl_printer_print_qpolynomial(printer, qp);
+ printer = isl_printer_end_line(printer);
+
+ isl_printer_free(printer);
+}
+
+void isl_qpolynomial_fold_dump(__isl_keep isl_qpolynomial_fold *fold)
+{
+ isl_printer *printer;
+
+ if (!fold)
+ return;
+
+ printer = isl_printer_to_file(isl_qpolynomial_fold_get_ctx(fold),
+ stderr);
+ printer = isl_printer_print_qpolynomial_fold(printer, fold);
+ printer = isl_printer_end_line(printer);
+
+ isl_printer_free(printer);
+}
+
+void isl_pw_qpolynomial_dump(__isl_keep isl_pw_qpolynomial *pwqp)
+{
+ isl_printer *printer;
+
+ if (!pwqp)
+ return;
+
+ printer = isl_printer_to_file(isl_pw_qpolynomial_get_ctx(pwqp), stderr);
+ printer = isl_printer_print_pw_qpolynomial(printer, pwqp);
+ printer = isl_printer_end_line(printer);
+
+ isl_printer_free(printer);
+}
+
+void isl_pw_qpolynomial_fold_dump(__isl_keep isl_pw_qpolynomial_fold *pwf)
+{
+ isl_printer *printer;
+
+ if (!pwf)
+ return;
+
+ printer = isl_printer_to_file(
+ isl_pw_qpolynomial_fold_get_ctx(pwf), stderr);
+ printer = isl_printer_print_pw_qpolynomial_fold(printer, pwf);
+ printer = isl_printer_end_line(printer);
+
+ isl_printer_free(printer);
+}
+
void isl_union_pw_qpolynomial_fold_dump(
__isl_keep isl_union_pw_qpolynomial_fold *upwf)
{
return p;
}
-__isl_give isl_printer *isl_printer_print_qpolynomial_fold(
- __isl_take isl_printer *p, __isl_keep isl_qpolynomial_fold *fold)
-{
- if (!p || !fold)
- goto error;
- p = qpolynomial_fold_print(fold, p);
- return p;
-error:
- isl_printer_free(p);
- return NULL;
-}
-
void isl_qpolynomial_fold_print(__isl_keep isl_qpolynomial_fold *fold,
FILE *out, unsigned output_format)
{
return p;
}
+__isl_give isl_printer *isl_printer_print_qpolynomial_fold(
+ __isl_take isl_printer *p, __isl_keep isl_qpolynomial_fold *fold)
+{
+ if (!p || !fold)
+ goto error;
+ if (p->output_format == ISL_FORMAT_ISL)
+ return qpolynomial_fold_print(fold, p);
+ else if (p->output_format == ISL_FORMAT_C)
+ return print_qpolynomial_fold_c(p, fold->dim, fold);
+ isl_die(p->ctx, isl_error_unsupported, "unsupported output format",
+ goto error);
+error:
+ isl_printer_free(p);
+ return NULL;
+}
+
static __isl_give isl_printer *print_pw_qpolynomial_fold_c(
__isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf)
{
return NULL;
}
+__isl_give struct isl_upoly *isl_upoly_cst_add_isl_int(
+ __isl_take struct isl_upoly *up, isl_int v)
+{
+ struct isl_upoly_cst *cst;
+
+ up = isl_upoly_cow(up);
+ if (!up)
+ return NULL;
+
+ cst = isl_upoly_as_cst(up);
+
+ isl_int_addmul(cst->n, cst->d, v);
+
+ return up;
+}
+
+__isl_give struct isl_upoly *isl_upoly_add_isl_int(
+ __isl_take struct isl_upoly *up, isl_int v)
+{
+ struct isl_upoly_rec *rec;
+
+ if (!up)
+ return NULL;
+
+ if (isl_upoly_is_cst(up))
+ return isl_upoly_cst_add_isl_int(up, v);
+
+ up = isl_upoly_cow(up);
+ rec = isl_upoly_as_rec(up);
+ if (!rec)
+ goto error;
+
+ rec->p[0] = isl_upoly_add_isl_int(rec->p[0], v);
+ if (!rec->p[0])
+ goto error;
+
+ return up;
+error:
+ isl_upoly_free(up);
+ return NULL;
+}
+
__isl_give struct isl_upoly *isl_upoly_neg_cst(__isl_take struct isl_upoly *up)
{
struct isl_upoly_cst *cst;
__isl_take isl_qpolynomial *qp1,
__isl_take isl_qpolynomial *qp2)
{
- return isl_qpolynomial_add(qp1, qp2);
+ qp1 = isl_qpolynomial_add(qp1, qp2);
+ qp1 = isl_qpolynomial_gist(qp1, isl_set_copy(dom));
+ return qp1;
}
__isl_give isl_qpolynomial *isl_qpolynomial_sub(__isl_take isl_qpolynomial *qp1,
return isl_qpolynomial_add(qp1, isl_qpolynomial_neg(qp2));
}
+__isl_give isl_qpolynomial *isl_qpolynomial_add_isl_int(
+ __isl_take isl_qpolynomial *qp, isl_int v)
+{
+ if (isl_int_is_zero(v))
+ return qp;
+
+ qp = isl_qpolynomial_cow(qp);
+ if (!qp)
+ return NULL;
+
+ qp->upoly = isl_upoly_add_isl_int(qp->upoly, v);
+ if (!qp->upoly)
+ goto error;
+
+ return qp;
+error:
+ isl_qpolynomial_free(qp);
+ return NULL;
+
+}
+
__isl_give isl_qpolynomial *isl_qpolynomial_neg(__isl_take isl_qpolynomial *qp)
{
qp = isl_qpolynomial_cow(qp);
#include "isl_equalities.h"
#include "isl_tab.h"
#include "isl_basis_reduction.h"
+#include <isl_factorization.h>
#include <isl_point_private.h>
static struct isl_vec *empty_sample(struct isl_basic_set *bset)
return NULL;
}
+static struct isl_vec *sample_bounded(struct isl_basic_set *bset);
+
+/* Compute a sample point of the given basic set, based on the given,
+ * non-trivial factorization.
+ */
+static __isl_give isl_vec *factored_sample(__isl_take isl_basic_set *bset,
+ __isl_take isl_factorizer *f)
+{
+ int i, n;
+ isl_vec *sample = NULL;
+ isl_ctx *ctx;
+ unsigned nparam;
+ unsigned nvar;
+
+ ctx = isl_basic_set_get_ctx(bset);
+ if (!ctx)
+ goto error;
+
+ nparam = isl_basic_set_dim(bset, isl_dim_param);
+ nvar = isl_basic_set_dim(bset, isl_dim_set);
+
+ sample = isl_vec_alloc(ctx, 1 + isl_basic_set_total_dim(bset));
+ if (!sample)
+ goto error;
+ isl_int_set_si(sample->el[0], 1);
+
+ bset = isl_morph_basic_set(isl_morph_copy(f->morph), bset);
+
+ for (i = 0, n = 0; i < f->n_group; ++i) {
+ isl_basic_set *bset_i;
+ isl_vec *sample_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);
+
+ sample_i = sample_bounded(bset_i);
+ if (!sample_i)
+ goto error;
+ if (sample_i->size == 0) {
+ isl_basic_set_free(bset);
+ isl_factorizer_free(f);
+ isl_vec_free(sample);
+ return sample_i;
+ }
+ isl_seq_cpy(sample->el + 1 + nparam + n,
+ sample_i->el + 1, f->len[i]);
+ isl_vec_free(sample_i);
+
+ n += f->len[i];
+ }
+
+ f->morph = isl_morph_inverse(f->morph);
+ sample = isl_morph_vec(isl_morph_copy(f->morph), sample);
+
+ isl_basic_set_free(bset);
+ isl_factorizer_free(f);
+ return sample;
+error:
+ isl_basic_set_free(bset);
+ isl_factorizer_free(f);
+ isl_vec_free(sample);
+ return NULL;
+}
+
/* Given a basic set that is known to be bounded, find and return
* an integer point in the basic set, if there is any.
*
struct isl_ctx *ctx;
struct isl_vec *sample;
struct isl_tab *tab = NULL;
+ isl_factorizer *f;
if (!bset)
return NULL;
if (bset->n_eq > 0)
return sample_eq(bset, sample_bounded);
+ f = isl_basic_set_factorizer(bset);
+ if (!f)
+ goto error;
+ if (f->n_group != 0)
+ return factored_sample(bset, f);
+ isl_factorizer_free(f);
+
ctx = bset->ctx;
tab = isl_tab_from_basic_set(bset);
tok->line = line;
tok->col = col;
tok->on_new_line = on_new_line;
+ tok->is_keyword = 0;
return tok;
}
return;
if (tok->type == ISL_TOKEN_VALUE)
isl_int_clear(tok->u.v);
- else if (tok->type == ISL_TOKEN_IDENT || tok->type == ISL_TOKEN_STRING)
+ else if (tok->type == ISL_TOKEN_IDENT ||
+ tok->type == ISL_TOKEN_STRING ||
+ tok->is_keyword)
free(tok->u.s);
free(tok);
}
fprintf(stderr, "got '%c'\n", tok->type);
else if (tok->type == ISL_TOKEN_IDENT)
fprintf(stderr, "got ident '%s'\n", tok->u.s);
+ else if (tok->is_keyword)
+ fprintf(stderr, "got keyword '%s'\n", tok->u.s);
else
fprintf(stderr, "got token type %d\n", tok->type);
}
isl_stream_ungetc(s, c);
isl_stream_push_char(s, '\0');
tok->type = check_keywords(s);
- if (tok->type == ISL_TOKEN_IDENT)
- tok->u.s = strdup(s->buffer);
+ if (tok->type != ISL_TOKEN_IDENT)
+ tok->is_keyword = 1;
+ tok->u.s = strdup(s->buffer);
+ if (!tok->u.s)
+ goto error;
return tok;
}
if (c == '"') {
tab->mat->n_row = r;
tab->mat->n_col = c;
if (tab->bmap)
- isl_basic_map_dump(tab->bmap, out, indent);
+ isl_basic_map_print_internal(tab->bmap, out, indent);
}
isl_map_free(map);
isl_map_free(map2);
+ str = "{[new,old] -> [new+1-2*[(new+1)/2],old+1-2*[(old+1)/2]]}";
+ map = isl_map_read_from_str(ctx, str, -1);
+ str = "{[new,old] -> [(new+1)%2,(old+1)%2]}";
+ map2 = isl_map_read_from_str(ctx, str, -1);
+ assert(isl_map_is_equal(map, map2));
+ isl_map_free(map);
+ isl_map_free(map2);
+
test_parse_pwqp(ctx, "{ [i] -> i + [ (i + [i/3])/2 ] }");
}
fclose(input);
}
-void test_convex_hull(struct isl_ctx *ctx)
+void test_convex_hull_algo(struct isl_ctx *ctx, int convex)
{
const char *str1, *str2;
isl_set *set1, *set2;
+ int orig_convex = ctx->opt->convex;
+ ctx->opt->convex = convex;
test_convex_hull_case(ctx, "convex0");
test_convex_hull_case(ctx, "convex1");
assert(isl_set_is_equal(set1, set2));
isl_set_free(set1);
isl_set_free(set2);
+
+ ctx->opt->convex = orig_convex;
+}
+
+void test_convex_hull(struct isl_ctx *ctx)
+{
+ test_convex_hull_algo(ctx, ISL_CONVEX_HULL_FM);
+ test_convex_hull_algo(ctx, ISL_CONVEX_HULL_WRAP);
}
void test_gist_case(struct isl_ctx *ctx, const char *name)
void test_lexmin(struct isl_ctx *ctx)
{
const char *str;
- isl_map *map;
+ isl_map *map, *map2;
isl_set *set;
isl_set *set2;
set = isl_set_intersect(set, set2);
assert(!isl_set_is_empty(set));
isl_set_free(set);
+
+ str = "{ [x] -> [y] : x <= y <= 10; [x] -> [5] : -8 <= x <= 8 }";
+ map = isl_map_read_from_str(ctx, str, -1);
+ map = isl_map_lexmin(map);
+ str = "{ [x] -> [5] : 6 <= x <= 8; "
+ "[x] -> [x] : x <= 5 or (9 <= x <= 10) }";
+ map2 = isl_map_read_from_str(ctx, str, -1);
+ assert(isl_map_is_equal(map, map2));
+ isl_map_free(map);
+ isl_map_free(map2);
+
+ str = "{ [x] -> [y] : 4y = x or 4y = -1 + x or 4y = -2 + x }";
+ map = isl_map_read_from_str(ctx, str, -1);
+ map2 = isl_map_copy(map);
+ map = isl_map_lexmin(map);
+ assert(isl_map_is_equal(map, map2));
+ isl_map_free(map);
+ isl_map_free(map2);
+
+ str = "{ [x] -> [y] : x = 4y; [x] -> [y] : x = 2y }";
+ map = isl_map_read_from_str(ctx, str, -1);
+ map = isl_map_lexmin(map);
+ str = "{ [x] -> [y] : (4y = x and x >= 0) or "
+ "(exists (e0 = [(x)/4], e1 = [(-2 + x)/4]: 2y = x and "
+ "4e1 = -2 + x and 4e0 <= -1 + x and 4e0 >= -3 + x)) or "
+ "(exists (e0 = [(x)/4]: 2y = x and 4e0 = x and x <= -4)) }";
+ map2 = isl_map_read_from_str(ctx, str, -1);
+ assert(isl_map_is_equal(map, map2));
+ isl_map_free(map);
+ isl_map_free(map2);
}
struct must_may {
return isl_union_map_product(uset1, uset2);
}
+static int range_product_entry(void **entry, void *user)
+{
+ struct isl_union_map_bin_data *data = user;
+ isl_map *map2 = *entry;
+
+ map2 = isl_map_range_product(isl_map_copy(data->map),
+ isl_map_copy(map2));
+
+ data->res = isl_union_map_add_map(data->res, map2);
+
+ return 0;
+}
+
+__isl_give isl_union_map *isl_union_map_range_product(
+ __isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2)
+{
+ return bin_op(umap1, umap2, &range_product_entry);
+}
+
__isl_give isl_union_map *isl_union_map_from_range(
__isl_take isl_union_set *uset)
{
return isl_union_map_polyhedral_hull(uset);
}
+static int simple_entry(void **entry, void *user)
+{
+ isl_map **map = (isl_map **)entry;
+
+ *map = isl_map_from_basic_map(isl_map_simple_hull(*map));
+
+ return *map ? 0 : -1;
+}
+
+__isl_give isl_union_map *isl_union_map_simple_hull(
+ __isl_take isl_union_map *umap)
+{
+ return un_op(umap, &simple_entry);
+}
+
+__isl_give isl_union_set *isl_union_set_simple_hull(
+ __isl_take isl_union_set *uset)
+{
+ return isl_union_map_simple_hull(uset);
+}
+
static int inplace_entry(void **entry, void *user)
{
__isl_give isl_map *(*fn)(__isl_take isl_map *) = user;
return isl_union_map_coalesce(uset);
}
+__isl_give isl_union_map *isl_union_map_detect_equalities(
+ __isl_take isl_union_map *umap)
+{
+ return inplace(umap, &isl_map_detect_equalities);
+}
+
+__isl_give isl_union_set *isl_union_set_detect_equalities(
+ __isl_take isl_union_set *uset)
+{
+ return isl_union_map_detect_equalities(uset);
+}
+
__isl_give isl_union_map *isl_union_map_compute_divs(
__isl_take isl_union_map *umap)
{
free(vec);
}
-void isl_vec_dump(struct isl_vec *vec, FILE *out, int indent)
+__isl_give isl_printer *isl_printer_print_vec(__isl_take isl_printer *printer,
+ __isl_keep isl_vec *vec)
{
int i;
- if (!vec) {
- fprintf(out, "%*snull vec\n", indent, "");
- return;
- }
+ if (!printer || !vec)
+ goto error;
- fprintf(out, "%*s[", indent, "");
+ printer = isl_printer_print_str(printer, "[");
for (i = 0; i < vec->size; ++i) {
if (i)
- fprintf(out, ",");
- isl_int_print(out, vec->el[i], 0);
+ printer = isl_printer_print_str(printer, ",");
+ printer = isl_printer_print_isl_int(printer, vec->el[i]);
}
- fprintf(out, "]\n");
+ printer = isl_printer_print_str(printer, "]");
+
+ return printer;
+error:
+ isl_printer_free(printer);
+ return NULL;
+}
+
+void isl_vec_dump(struct isl_vec *vec)
+{
+ isl_printer *printer;
+
+ if (!vec)
+ return;
+
+ printer = isl_printer_to_file(vec->ctx, stderr);
+ printer = isl_printer_print_vec(printer, vec);
+ printer = isl_printer_end_line(printer);
+
+ isl_printer_free(printer);
}
__isl_give isl_vec *isl_vec_clr(__isl_take isl_vec *vec)
isl_int opt;
unsigned dim;
enum isl_lp_result res;
+ isl_printer *p;
isl_int_init(opt);
bset = isl_basic_set_read_from_file(ctx, stdin, 0);
fprintf(stdout, "unbounded\n");
break;
case isl_lp_ok:
- isl_vec_dump(sol, stdout, 0);
- isl_int_print(stdout, opt, 0);
- fprintf(stdout, "\n");
+ p = isl_printer_to_file(ctx, stdout);
+ p = isl_printer_print_vec(p, sol);
+ p = isl_printer_end_line(p);
+ p = isl_printer_print_isl_int(p, opt);
+ p = isl_printer_end_line(p);
+ isl_printer_free(p);
}
isl_basic_set_free(bset);
isl_vec_free(obj);
struct isl_ctx *ctx = isl_ctx_alloc();
struct isl_basic_set *bset;
struct isl_vec *sample;
+ isl_printer *p;
bset = isl_basic_set_read_from_file(ctx, stdin, 0);
sample = isl_basic_set_sample_vec(isl_basic_set_copy(bset));
- isl_vec_dump(sample, stdout, 0);
+ p = isl_printer_to_file(ctx, stdout);
+ p = isl_printer_print_vec(p, sample);
+ p = isl_printer_end_line(p);
+ isl_printer_free(p);
assert(sample);
if (sample->size > 0)
assert(isl_basic_set_contains(bset, sample));