Update isl to isl-0.18-1047-g4a20ef8

This update:

  - Removes several deprecated functions (e.g., isl_band).
  - Improves the pretty-printing of sets by detecting modulos and "false"
    equalities.
  - Minor improvements to coalescing and increased robustness of the isl
    scheduler.

This update does not yet include isl commit isl-0.18-90-gd00cb45
(isl_pw_*_alloc: add missing check for compatible spaces, Wed Sep 6 12:18:04
2017 +0200), as this additional check is too tight and unfortunately causes
two test case failures in Polly. A patch has been submitted to isl and will be
included in the next isl update for Polly.

llvm-svn: 325557
This commit is contained in:
Tobias Grosser 2018-02-20 07:26:42 +00:00
parent 85476dc45a
commit fa8079d0dc
170 changed files with 4144 additions and 5474 deletions

View File

@ -186,7 +186,6 @@ if (POLLY_BUNDLED_ISL)
isl/isl_ast.c
isl/isl_ast_codegen.c
isl/isl_ast_graft.c
isl/isl_band.c
isl/isl_bernstein.c
isl/isl_blk.c
isl/isl_bound.c
@ -242,6 +241,7 @@ if (POLLY_BUNDLED_ISL)
isl/isl_set_list.c
isl/isl_sort.c
isl/isl_space.c
isl/isl_stride.c
isl/isl_stream.c
isl/isl_tab.c
isl/isl_tab_pip.c

View File

@ -1 +1 @@
isl-0.18-812-g565da6e
isl-0.18-1047-g4a20ef8

View File

@ -19,7 +19,6 @@ TESTS = isl_test codegen_test.sh pip_test.sh bound_test.sh isl_test_int \
if IMATH_FOR_MP
MP_SRC = \
isl_hide_deprecated.h \
isl_imath.c \
isl_imath.h \
isl_int_imath.h \
@ -42,7 +41,6 @@ else
MP_SRC += isl_val_imath.c
endif
DEPRECATED_SRC =
MP_INCLUDE_H =
endif
@ -57,7 +55,6 @@ MP_SRC = \
isl_gmp.c \
isl_val_gmp.c
DEPRECATED_SRC = isl_ast_int.c
MP_INCLUDE_H = include/isl/val_gmp.h
endif
@ -66,7 +63,6 @@ AM_CFLAGS = @WARNING_FLAGS@
libisl_la_SOURCES = \
$(MP_SRC) \
$(DEPRECATED_SRC) \
isl_aff.c \
isl_aff_private.h \
isl_affine_hull.c \
@ -80,8 +76,6 @@ libisl_la_SOURCES = \
isl_ast_codegen.c \
isl_ast_graft.c \
isl_ast_graft_private.h \
isl_band.c \
isl_band_private.h \
isl_basis_reduction.h \
basis_reduction_tab.c \
isl_bernstein.c \
@ -175,6 +169,7 @@ libisl_la_SOURCES = \
isl_stream_private.h \
isl_seq.c \
isl_seq.h \
isl_stride.c \
isl_tab.c \
isl_tab.h \
isl_tab_pip.c \
@ -277,7 +272,6 @@ pkginclude_HEADERS = \
include/isl/ast.h \
include/isl/ast_type.h \
include/isl/ast_build.h \
include/isl/band.h \
include/isl/constraint.h \
include/isl/ctx.h \
include/isl/flow.h \
@ -325,21 +319,6 @@ pkginclude_HEADERS = \
include/isl/vec.h \
include/isl/version.h \
include/isl/vertices.h
deprecateddir = $(pkgincludedir)/deprecated
deprecated_HEADERS = \
include/isl/deprecated/int.h \
include/isl/deprecated/aff_int.h \
include/isl/deprecated/ast_int.h \
include/isl/deprecated/constraint_int.h \
include/isl/deprecated/ilp_int.h \
include/isl/deprecated/map_int.h \
include/isl/deprecated/mat_int.h \
include/isl/deprecated/point_int.h \
include/isl/deprecated/polynomial_int.h \
include/isl/deprecated/set_int.h \
include/isl/deprecated/union_map_int.h \
include/isl/deprecated/val_int.h \
include/isl/deprecated/vec_int.h
BUILT_SOURCES = gitversion.h
@ -372,6 +351,7 @@ EXTRA_DIST = \
isl_multi_apply_union_set.c \
isl_multi_cmp.c \
isl_multi_coalesce.c \
isl_multi_dims.c \
isl_multi_floor.c \
isl_multi_gist.c \
isl_multi_hash.c \
@ -387,13 +367,14 @@ EXTRA_DIST = \
set_to_map.c \
set_from_map.c \
isl_tab_lexopt_templ.c \
uset_to_umap.c \
isl_union_macro.h \
isl_union_templ.c \
isl_union_single.c \
isl_union_multi.c \
isl_union_eval.c \
isl_union_neg.c \
isl.py \
libisl-gdb.py \
doc/CodingStyle \
doc/SubmittingPatches \
doc/implementation.tex \
@ -409,8 +390,8 @@ EXTRA_DIST = \
imath/imrat.c \
imath/imrat.h \
interface/all.h \
interface/isl.h.top \
interface/isl.py.top \
interface/isl_test_python.py \
test_inputs
dist-hook:
@ -424,15 +405,17 @@ pkgconfig_DATA = $(pkgconfig_libfile)
gitversion.h: @GIT_HEAD@
$(AM_V_GEN)echo '#define GIT_HEAD_ID "'@GIT_HEAD_VERSION@'"' > $@
install-data-local: $(srcdir)/isl.py
install-data-local: $(srcdir)/libisl-gdb.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 \
*) echo $(INSTALL_DATA) $(srcdir)/libisl-gdb.py \
$(DESTDIR)$(libdir)/$$libisl-gdb.py; \
test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"; \
$(INSTALL_DATA) $(srcdir)/isl.py $(DESTDIR)$(libdir)/$$libisl-gdb.py; esac
$(INSTALL_DATA) $(srcdir)/libisl-gdb.py \
$(DESTDIR)$(libdir)/$$libisl-gdb.py; \
esac
uninstall-local:
@libisl=`sed -ne "/^library_names=/{s/.*='//;s/'$$//;s/ .*//;p;}" \

View File

@ -117,8 +117,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_c___attribute__.m4 \
$(top_srcdir)/m4/ax_compiler_vendor.m4 \
$(top_srcdir)/m4/ax_create_pkgconfig_info.m4 \
$(top_srcdir)/m4/ax_create_stdint_h.m4 \
$(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
$(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \
$(top_srcdir)/m4/ax_detect_clang.m4 \
$(top_srcdir)/m4/ax_detect_git_head.m4 \
$(top_srcdir)/m4/ax_detect_gmp.m4 \
@ -134,8 +132,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_c___attribute__.m4 \
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \
$(am__configure_deps) $(deprecated_HEADERS) \
$(am__pkginclude_HEADERS_DIST) $(am__DIST_COMMON)
$(am__configure_deps) $(am__pkginclude_HEADERS_DIST) \
$(am__DIST_COMMON)
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
configure.lineno config.status.lineno
mkinstalldirs = $(install_sh) -d
@ -171,26 +169,25 @@ am__uninstall_files_from_dir = { \
$(am__cd) "$$dir" && rm -f $$files; }; \
}
am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" \
"$(DESTDIR)$(deprecateddir)" "$(DESTDIR)$(pkgincludedir)" \
"$(DESTDIR)$(pkgincludedir)"
"$(DESTDIR)$(pkgincludedir)" "$(DESTDIR)$(pkgincludedir)"
LTLIBRARIES = $(lib_LTLIBRARIES)
libisl_la_DEPENDENCIES =
am__libisl_la_SOURCES_DIST = mp_get_memory_functions.c isl_int_gmp.h \
isl_gmp.c isl_val_gmp.c isl_hide_deprecated.h isl_imath.c \
isl_imath.h isl_int_imath.h imath_wrap/gmp_compat.h \
imath_wrap/imath.h imath_wrap/imrat.h imath_wrap/wrap.h \
imath_wrap/gmp_compat.c imath_wrap/imath.c imath_wrap/imrat.c \
isl_int_sioimath.h isl_int_sioimath.c isl_val_sioimath.c \
isl_val_imath.c isl_ast_int.c isl_aff.c isl_aff_private.h \
isl_affine_hull.c isl_arg.c isl_ast.c isl_ast_private.h \
isl_ast_build.c isl_ast_build_private.h isl_ast_build_expr.c \
isl_gmp.c isl_val_gmp.c isl_imath.c isl_imath.h \
isl_int_imath.h imath_wrap/gmp_compat.h imath_wrap/imath.h \
imath_wrap/imrat.h imath_wrap/wrap.h imath_wrap/gmp_compat.c \
imath_wrap/imath.c imath_wrap/imrat.c isl_int_sioimath.h \
isl_int_sioimath.c isl_val_sioimath.c isl_val_imath.c \
isl_aff.c isl_aff_private.h isl_affine_hull.c isl_arg.c \
isl_ast.c isl_ast_private.h isl_ast_build.c \
isl_ast_build_private.h isl_ast_build_expr.c \
isl_ast_build_expr.h isl_ast_codegen.c isl_ast_graft.c \
isl_ast_graft_private.h isl_band.c isl_band_private.h \
isl_basis_reduction.h basis_reduction_tab.c isl_bernstein.c \
isl_bernstein.h isl_blk.c isl_blk.h isl_bound.c isl_bound.h \
isl_coalesce.c isl_constraint.c isl_constraint_private.h \
isl_convex_hull.c isl_ctx.c isl_ctx_private.h isl_deprecated.c \
isl_dim_map.h isl_dim_map.c isl_equalities.c isl_equalities.h \
isl_ast_graft_private.h isl_basis_reduction.h \
basis_reduction_tab.c isl_bernstein.c isl_bernstein.h \
isl_blk.c isl_blk.h isl_bound.c isl_bound.h isl_coalesce.c \
isl_constraint.c isl_constraint_private.h isl_convex_hull.c \
isl_ctx.c isl_ctx_private.h isl_deprecated.c isl_dim_map.h \
isl_dim_map.c isl_equalities.c isl_equalities.h \
isl_factorization.c isl_factorization.h isl_farkas.c isl_ffs.c \
isl_flow.c isl_fold.c isl_hash.c isl_hash_private.h \
isl_id_to_ast_expr.c isl_id_to_id.c isl_id_to_pw_aff.c \
@ -211,8 +208,8 @@ am__libisl_la_SOURCES_DIST = mp_get_memory_functions.c isl_int_gmp.h \
isl_schedule_constraints.c isl_schedule_constraints.h \
isl_scheduler.c isl_set_list.c isl_sort.c isl_sort.h \
isl_space.c isl_space_private.h isl_stream.c \
isl_stream_private.h isl_seq.c isl_seq.h isl_tab.c isl_tab.h \
isl_tab_pip.c isl_tarjan.c isl_tarjan.h \
isl_stream_private.h isl_seq.c isl_seq.h isl_stride.c \
isl_tab.c isl_tab.h isl_tab_pip.c isl_tarjan.c isl_tarjan.h \
isl_transitive_closure.c isl_union_map.c \
isl_union_map_private.h isl_union_set_private.h isl_val.c \
isl_val_private.h isl_vec_private.h isl_vec.c isl_version.c \
@ -232,26 +229,25 @@ am__dirstamp = $(am__leading_dot)dirstamp
@GMP_FOR_MP_FALSE@@IMATH_FOR_MP_TRUE@ $(am__objects_3)
@GMP_FOR_MP_TRUE@am__objects_4 = $(am__objects_1) isl_gmp.lo \
@GMP_FOR_MP_TRUE@ isl_val_gmp.lo
@GMP_FOR_MP_TRUE@am__objects_5 = isl_ast_int.lo
am_libisl_la_OBJECTS = $(am__objects_4) $(am__objects_5) isl_aff.lo \
isl_affine_hull.lo isl_arg.lo isl_ast.lo isl_ast_build.lo \
isl_ast_build_expr.lo isl_ast_codegen.lo isl_ast_graft.lo \
isl_band.lo basis_reduction_tab.lo isl_bernstein.lo isl_blk.lo \
isl_bound.lo isl_coalesce.lo isl_constraint.lo \
isl_convex_hull.lo isl_ctx.lo isl_deprecated.lo isl_dim_map.lo \
isl_equalities.lo isl_factorization.lo isl_farkas.lo \
isl_ffs.lo isl_flow.lo isl_fold.lo isl_hash.lo \
isl_id_to_ast_expr.lo isl_id_to_id.lo isl_id_to_pw_aff.lo \
isl_ilp.lo isl_input.lo isl_local.lo isl_local_space.lo \
isl_lp.lo isl_map.lo isl_map_list.lo isl_map_simplify.lo \
isl_map_subtract.lo isl_map_to_basic_set.lo isl_mat.lo \
isl_morph.lo isl_id.lo isl_obj.lo isl_options.lo isl_output.lo \
isl_point.lo isl_polynomial.lo isl_printer.lo print.lo \
isl_range.lo isl_reordering.lo isl_sample.lo isl_scan.lo \
isl_schedule.lo isl_schedule_band.lo isl_schedule_node.lo \
isl_schedule_read.lo isl_schedule_tree.lo \
isl_schedule_constraints.lo isl_scheduler.lo isl_set_list.lo \
isl_sort.lo isl_space.lo isl_stream.lo isl_seq.lo isl_tab.lo \
am_libisl_la_OBJECTS = $(am__objects_4) isl_aff.lo isl_affine_hull.lo \
isl_arg.lo isl_ast.lo isl_ast_build.lo isl_ast_build_expr.lo \
isl_ast_codegen.lo isl_ast_graft.lo basis_reduction_tab.lo \
isl_bernstein.lo isl_blk.lo isl_bound.lo isl_coalesce.lo \
isl_constraint.lo isl_convex_hull.lo isl_ctx.lo \
isl_deprecated.lo isl_dim_map.lo isl_equalities.lo \
isl_factorization.lo isl_farkas.lo isl_ffs.lo isl_flow.lo \
isl_fold.lo isl_hash.lo isl_id_to_ast_expr.lo isl_id_to_id.lo \
isl_id_to_pw_aff.lo isl_ilp.lo isl_input.lo isl_local.lo \
isl_local_space.lo isl_lp.lo isl_map.lo isl_map_list.lo \
isl_map_simplify.lo isl_map_subtract.lo \
isl_map_to_basic_set.lo isl_mat.lo isl_morph.lo isl_id.lo \
isl_obj.lo isl_options.lo isl_output.lo isl_point.lo \
isl_polynomial.lo isl_printer.lo print.lo isl_range.lo \
isl_reordering.lo isl_sample.lo isl_scan.lo isl_schedule.lo \
isl_schedule_band.lo isl_schedule_node.lo isl_schedule_read.lo \
isl_schedule_tree.lo isl_schedule_constraints.lo \
isl_scheduler.lo isl_set_list.lo isl_sort.lo isl_space.lo \
isl_stream.lo isl_seq.lo isl_stride.lo isl_tab.lo \
isl_tab_pip.lo isl_tarjan.lo isl_transitive_closure.lo \
isl_union_map.lo isl_val.lo isl_vec.lo isl_version.lo \
isl_vertices.lo
@ -420,29 +416,28 @@ DATA = $(pkgconfig_DATA)
am__pkginclude_HEADERS_DIST = include/isl/val_gmp.h include/isl/aff.h \
include/isl/aff_type.h include/isl/arg.h include/isl/ast.h \
include/isl/ast_type.h include/isl/ast_build.h \
include/isl/band.h include/isl/constraint.h include/isl/ctx.h \
include/isl/flow.h include/isl/id.h \
include/isl/id_to_ast_expr.h include/isl/id_to_id.h \
include/isl/id_to_pw_aff.h include/isl/ilp.h \
include/isl/hash.h include/isl/hmap.h include/isl/hmap_templ.c \
include/isl/list.h include/isl/local_space.h include/isl/lp.h \
include/isl/mat.h include/isl/map.h \
include/isl/map_to_basic_set.h include/isl/map_type.h \
include/isl/maybe.h include/isl/maybe_ast_expr.h \
include/isl/maybe_basic_set.h include/isl/maybe_id.h \
include/isl/maybe_pw_aff.h include/isl/maybe_templ.h \
include/isl/multi.h include/isl/obj.h include/isl/options.h \
include/isl/point.h include/isl/polynomial.h \
include/isl/polynomial_type.h include/isl/printer.h \
include/isl/printer_type.h include/isl/schedule.h \
include/isl/schedule_node.h include/isl/schedule_type.h \
include/isl/set.h include/isl/set_type.h include/isl/space.h \
include/isl/constraint.h include/isl/ctx.h include/isl/flow.h \
include/isl/id.h include/isl/id_to_ast_expr.h \
include/isl/id_to_id.h include/isl/id_to_pw_aff.h \
include/isl/ilp.h include/isl/hash.h include/isl/hmap.h \
include/isl/hmap_templ.c include/isl/list.h \
include/isl/local_space.h include/isl/lp.h include/isl/mat.h \
include/isl/map.h include/isl/map_to_basic_set.h \
include/isl/map_type.h include/isl/maybe.h \
include/isl/maybe_ast_expr.h include/isl/maybe_basic_set.h \
include/isl/maybe_id.h include/isl/maybe_pw_aff.h \
include/isl/maybe_templ.h include/isl/multi.h \
include/isl/obj.h include/isl/options.h include/isl/point.h \
include/isl/polynomial.h include/isl/polynomial_type.h \
include/isl/printer.h include/isl/printer_type.h \
include/isl/schedule.h include/isl/schedule_node.h \
include/isl/schedule_type.h include/isl/set.h \
include/isl/set_type.h include/isl/space.h \
include/isl/stream.h include/isl/union_map.h \
include/isl/union_map_type.h include/isl/union_set.h \
include/isl/union_set_type.h include/isl/val.h \
include/isl/vec.h include/isl/version.h include/isl/vertices.h
HEADERS = $(deprecated_HEADERS) $(nodist_pkginclude_HEADERS) \
$(pkginclude_HEADERS)
HEADERS = $(nodist_pkginclude_HEADERS) $(pkginclude_HEADERS)
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
distclean-recursive maintainer-clean-recursive
am__recursive_targets = \
@ -713,7 +708,6 @@ CLANG_LIBS = @CLANG_LIBS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXX11FLAGS = @CXX11FLAGS@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
@ -733,7 +727,6 @@ GIT_HEAD = @GIT_HEAD@
GIT_HEAD_ID = @GIT_HEAD_ID@
GIT_HEAD_VERSION = @GIT_HEAD_VERSION@
GREP = @GREP@
HAVE_CXX11 = @HAVE_CXX11@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
@ -773,6 +766,11 @@ PDFLATEX = @PDFLATEX@
PERL = @PERL@
POD2HTML = @POD2HTML@
PRTDIAG = @PRTDIAG@
PYTHON = @PYTHON@
PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
PYTHON_PLATFORM = @PYTHON_PLATFORM@
PYTHON_PREFIX = @PYTHON_PREFIX@
PYTHON_VERSION = @PYTHON_VERSION@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
@ -825,9 +823,13 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
pkgconfig_libdir = @pkgconfig_libdir@
pkgconfig_libfile = @pkgconfig_libfile@
pkgpyexecdir = @pkgpyexecdir@
pkgpythondir = @pkgpythondir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
pyexecdir = @pyexecdir@
pythondir = @pythondir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
@ -850,15 +852,12 @@ lib_LTLIBRARIES = libisl.la
@GMP_FOR_MP_TRUE@ isl_gmp.c \
@GMP_FOR_MP_TRUE@ isl_val_gmp.c
@IMATH_FOR_MP_TRUE@MP_SRC = isl_hide_deprecated.h isl_imath.c \
@IMATH_FOR_MP_TRUE@ isl_imath.h isl_int_imath.h \
@IMATH_FOR_MP_TRUE@MP_SRC = isl_imath.c isl_imath.h isl_int_imath.h \
@IMATH_FOR_MP_TRUE@ imath_wrap/gmp_compat.h imath_wrap/imath.h \
@IMATH_FOR_MP_TRUE@ imath_wrap/imrat.h imath_wrap/wrap.h \
@IMATH_FOR_MP_TRUE@ imath_wrap/gmp_compat.c imath_wrap/imath.c \
@IMATH_FOR_MP_TRUE@ imath_wrap/imrat.c $(am__append_3) \
@IMATH_FOR_MP_TRUE@ $(am__append_4)
@GMP_FOR_MP_TRUE@DEPRECATED_SRC = isl_ast_int.c
@IMATH_FOR_MP_TRUE@DEPRECATED_SRC =
@GMP_FOR_MP_TRUE@MP_INCLUDE_H = include/isl/val_gmp.h
@IMATH_FOR_MP_TRUE@MP_INCLUDE_H =
@GMP_FOR_MP_TRUE@@NEED_GET_MEMORY_FUNCTIONS_TRUE@GET_MEMORY_FUNCTIONS = mp_get_memory_functions.c
@ -866,7 +865,6 @@ AM_CPPFLAGS = -I. -I$(srcdir) -I$(srcdir)/include -Iinclude/ @MP_CPPFLAGS@
AM_CFLAGS = @WARNING_FLAGS@
libisl_la_SOURCES = \
$(MP_SRC) \
$(DEPRECATED_SRC) \
isl_aff.c \
isl_aff_private.h \
isl_affine_hull.c \
@ -880,8 +878,6 @@ libisl_la_SOURCES = \
isl_ast_codegen.c \
isl_ast_graft.c \
isl_ast_graft_private.h \
isl_band.c \
isl_band_private.h \
isl_basis_reduction.h \
basis_reduction_tab.c \
isl_bernstein.c \
@ -975,6 +971,7 @@ libisl_la_SOURCES = \
isl_stream_private.h \
isl_seq.c \
isl_seq.h \
isl_stride.c \
isl_tab.c \
isl_tab.h \
isl_tab_pip.c \
@ -1074,7 +1071,6 @@ pkginclude_HEADERS = \
include/isl/ast.h \
include/isl/ast_type.h \
include/isl/ast_build.h \
include/isl/band.h \
include/isl/constraint.h \
include/isl/ctx.h \
include/isl/flow.h \
@ -1123,22 +1119,6 @@ pkginclude_HEADERS = \
include/isl/version.h \
include/isl/vertices.h
deprecateddir = $(pkgincludedir)/deprecated
deprecated_HEADERS = \
include/isl/deprecated/int.h \
include/isl/deprecated/aff_int.h \
include/isl/deprecated/ast_int.h \
include/isl/deprecated/constraint_int.h \
include/isl/deprecated/ilp_int.h \
include/isl/deprecated/map_int.h \
include/isl/deprecated/mat_int.h \
include/isl/deprecated/point_int.h \
include/isl/deprecated/polynomial_int.h \
include/isl/deprecated/set_int.h \
include/isl/deprecated/union_map_int.h \
include/isl/deprecated/val_int.h \
include/isl/deprecated/vec_int.h
BUILT_SOURCES = gitversion.h
CLEANFILES = \
gitversion.h
@ -1169,6 +1149,7 @@ EXTRA_DIST = \
isl_multi_apply_union_set.c \
isl_multi_cmp.c \
isl_multi_coalesce.c \
isl_multi_dims.c \
isl_multi_floor.c \
isl_multi_gist.c \
isl_multi_hash.c \
@ -1184,13 +1165,14 @@ EXTRA_DIST = \
set_to_map.c \
set_from_map.c \
isl_tab_lexopt_templ.c \
uset_to_umap.c \
isl_union_macro.h \
isl_union_templ.c \
isl_union_single.c \
isl_union_multi.c \
isl_union_eval.c \
isl_union_neg.c \
isl.py \
libisl-gdb.py \
doc/CodingStyle \
doc/SubmittingPatches \
doc/implementation.tex \
@ -1206,8 +1188,8 @@ EXTRA_DIST = \
imath/imrat.c \
imath/imrat.h \
interface/all.h \
interface/isl.h.top \
interface/isl.py.top \
interface/isl_test_python.py \
test_inputs
pkgconfigdir = $(pkgconfig_libdir)
@ -1424,8 +1406,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_ast_build_expr.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_ast_codegen.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_ast_graft.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_ast_int.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_band.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_bernstein.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_blk.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_bound.Plo@am__quote@
@ -1483,6 +1463,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_sort.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_space.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_stream.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_stride.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_tab.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_tab_pip.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isl_tarjan.Plo@am__quote@
@ -1565,27 +1546,6 @@ uninstall-pkgconfigDATA:
@list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir)
install-deprecatedHEADERS: $(deprecated_HEADERS)
@$(NORMAL_INSTALL)
@list='$(deprecated_HEADERS)'; test -n "$(deprecateddir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(deprecateddir)'"; \
$(MKDIR_P) "$(DESTDIR)$(deprecateddir)" || exit 1; \
fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
done | $(am__base_list) | \
while read files; do \
echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(deprecateddir)'"; \
$(INSTALL_HEADER) $$files "$(DESTDIR)$(deprecateddir)" || exit $$?; \
done
uninstall-deprecatedHEADERS:
@$(NORMAL_UNINSTALL)
@list='$(deprecated_HEADERS)'; test -n "$(deprecateddir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(deprecateddir)'; $(am__uninstall_files_from_dir)
install-nodist_pkgincludeHEADERS: $(nodist_pkginclude_HEADERS)
@$(NORMAL_INSTALL)
@list='$(nodist_pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
@ -2146,7 +2106,7 @@ all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(DATA) $(HEADERS) \
isl_config.h
installdirs: installdirs-recursive
installdirs-am:
for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(deprecateddir)" "$(DESTDIR)$(pkgincludedir)" "$(DESTDIR)$(pkgincludedir)"; do \
for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(pkgincludedir)" "$(DESTDIR)$(pkgincludedir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: $(BUILT_SOURCES)
@ -2212,9 +2172,8 @@ info: info-recursive
info-am:
install-data-am: install-data-local install-deprecatedHEADERS \
install-nodist_pkgincludeHEADERS install-pkgconfigDATA \
install-pkgincludeHEADERS
install-data-am: install-data-local install-nodist_pkgincludeHEADERS \
install-pkgconfigDATA install-pkgincludeHEADERS
install-dvi: install-dvi-recursive
@ -2262,9 +2221,9 @@ ps: ps-recursive
ps-am:
uninstall-am: uninstall-deprecatedHEADERS uninstall-libLTLIBRARIES \
uninstall-local uninstall-nodist_pkgincludeHEADERS \
uninstall-pkgconfigDATA uninstall-pkgincludeHEADERS
uninstall-am: uninstall-libLTLIBRARIES uninstall-local \
uninstall-nodist_pkgincludeHEADERS uninstall-pkgconfigDATA \
uninstall-pkgincludeHEADERS
.MAKE: $(am__recursive_targets) all check check-am install install-am \
install-strip
@ -2279,10 +2238,9 @@ uninstall-am: uninstall-deprecatedHEADERS uninstall-libLTLIBRARIES \
distclean-libtool distclean-tags distcleancheck distdir \
distuninstallcheck dvi dvi-am html html-am info info-am \
install install-am install-data install-data-am \
install-data-local install-deprecatedHEADERS install-dvi \
install-dvi-am install-exec install-exec-am install-html \
install-html-am install-info install-info-am \
install-libLTLIBRARIES install-man \
install-data-local install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-libLTLIBRARIES install-man \
install-nodist_pkgincludeHEADERS install-pdf install-pdf-am \
install-pkgconfigDATA install-pkgincludeHEADERS install-ps \
install-ps-am install-strip installcheck installcheck-am \
@ -2290,9 +2248,9 @@ uninstall-am: uninstall-deprecatedHEADERS uninstall-libLTLIBRARIES \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
recheck tags tags-am uninstall uninstall-am \
uninstall-deprecatedHEADERS uninstall-libLTLIBRARIES \
uninstall-local uninstall-nodist_pkgincludeHEADERS \
uninstall-pkgconfigDATA uninstall-pkgincludeHEADERS
uninstall-libLTLIBRARIES uninstall-local \
uninstall-nodist_pkgincludeHEADERS uninstall-pkgconfigDATA \
uninstall-pkgincludeHEADERS
.PRECIOUS: Makefile
@ -2305,15 +2263,17 @@ dist-hook:
gitversion.h: @GIT_HEAD@
$(AM_V_GEN)echo '#define GIT_HEAD_ID "'@GIT_HEAD_VERSION@'"' > $@
install-data-local: $(srcdir)/isl.py
install-data-local: $(srcdir)/libisl-gdb.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 \
*) echo $(INSTALL_DATA) $(srcdir)/libisl-gdb.py \
$(DESTDIR)$(libdir)/$$libisl-gdb.py; \
test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"; \
$(INSTALL_DATA) $(srcdir)/isl.py $(DESTDIR)$(libdir)/$$libisl-gdb.py; esac
$(INSTALL_DATA) $(srcdir)/libisl-gdb.py \
$(DESTDIR)$(libdir)/$$libisl-gdb.py; \
esac
uninstall-local:
@libisl=`sed -ne "/^library_names=/{s/.*='//;s/'$$//;s/ .*//;p;}" \

View File

@ -812,6 +812,241 @@ AC_LANG_POP([C])])
# For backward compatibility.
AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
# Copyright (C) 1999-2014 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# AM_PATH_PYTHON([MINIMUM-VERSION], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
# ---------------------------------------------------------------------------
# Adds support for distributing Python modules and packages. To
# install modules, copy them to $(pythondir), using the python_PYTHON
# automake variable. To install a package with the same name as the
# automake package, install to $(pkgpythondir), or use the
# pkgpython_PYTHON automake variable.
#
# The variables $(pyexecdir) and $(pkgpyexecdir) are provided as
# locations to install python extension modules (shared libraries).
# Another macro is required to find the appropriate flags to compile
# extension modules.
#
# If your package is configured with a different prefix to python,
# users will have to add the install directory to the PYTHONPATH
# environment variable, or create a .pth file (see the python
# documentation for details).
#
# If the MINIMUM-VERSION argument is passed, AM_PATH_PYTHON will
# cause an error if the version of python installed on the system
# doesn't meet the requirement. MINIMUM-VERSION should consist of
# numbers and dots only.
AC_DEFUN([AM_PATH_PYTHON],
[
dnl Find a Python interpreter. Python versions prior to 2.0 are not
dnl supported. (2.0 was released on October 16, 2000).
m4_define_default([_AM_PYTHON_INTERPRETER_LIST],
[python python2 python3 python3.3 python3.2 python3.1 python3.0 python2.7 dnl
python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0])
AC_ARG_VAR([PYTHON], [the Python interpreter])
m4_if([$1],[],[
dnl No version check is needed.
# Find any Python interpreter.
if test -z "$PYTHON"; then
AC_PATH_PROGS([PYTHON], _AM_PYTHON_INTERPRETER_LIST, :)
fi
am_display_PYTHON=python
], [
dnl A version check is needed.
if test -n "$PYTHON"; then
# If the user set $PYTHON, use it and don't search something else.
AC_MSG_CHECKING([whether $PYTHON version is >= $1])
AM_PYTHON_CHECK_VERSION([$PYTHON], [$1],
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])
AC_MSG_ERROR([Python interpreter is too old])])
am_display_PYTHON=$PYTHON
else
# Otherwise, try each interpreter until we find one that satisfies
# VERSION.
AC_CACHE_CHECK([for a Python interpreter with version >= $1],
[am_cv_pathless_PYTHON],[
for am_cv_pathless_PYTHON in _AM_PYTHON_INTERPRETER_LIST none; do
test "$am_cv_pathless_PYTHON" = none && break
AM_PYTHON_CHECK_VERSION([$am_cv_pathless_PYTHON], [$1], [break])
done])
# Set $PYTHON to the absolute path of $am_cv_pathless_PYTHON.
if test "$am_cv_pathless_PYTHON" = none; then
PYTHON=:
else
AC_PATH_PROG([PYTHON], [$am_cv_pathless_PYTHON])
fi
am_display_PYTHON=$am_cv_pathless_PYTHON
fi
])
if test "$PYTHON" = :; then
dnl Run any user-specified action, or abort.
m4_default([$3], [AC_MSG_ERROR([no suitable Python interpreter found])])
else
dnl Query Python for its version number. Getting [:3] seems to be
dnl the best way to do this; it's what "site.py" does in the standard
dnl library.
AC_CACHE_CHECK([for $am_display_PYTHON version], [am_cv_python_version],
[am_cv_python_version=`$PYTHON -c "import sys; sys.stdout.write(sys.version[[:3]])"`])
AC_SUBST([PYTHON_VERSION], [$am_cv_python_version])
dnl Use the values of $prefix and $exec_prefix for the corresponding
dnl values of PYTHON_PREFIX and PYTHON_EXEC_PREFIX. These are made
dnl distinct variables so they can be overridden if need be. However,
dnl general consensus is that you shouldn't need this ability.
AC_SUBST([PYTHON_PREFIX], ['${prefix}'])
AC_SUBST([PYTHON_EXEC_PREFIX], ['${exec_prefix}'])
dnl At times (like when building shared libraries) you may want
dnl to know which OS platform Python thinks this is.
AC_CACHE_CHECK([for $am_display_PYTHON platform], [am_cv_python_platform],
[am_cv_python_platform=`$PYTHON -c "import sys; sys.stdout.write(sys.platform)"`])
AC_SUBST([PYTHON_PLATFORM], [$am_cv_python_platform])
# Just factor out some code duplication.
am_python_setup_sysconfig="\
import sys
# Prefer sysconfig over distutils.sysconfig, for better compatibility
# with python 3.x. See automake bug#10227.
try:
import sysconfig
except ImportError:
can_use_sysconfig = 0
else:
can_use_sysconfig = 1
# Can't use sysconfig in CPython 2.7, since it's broken in virtualenvs:
# <https://github.com/pypa/virtualenv/issues/118>
try:
from platform import python_implementation
if python_implementation() == 'CPython' and sys.version[[:3]] == '2.7':
can_use_sysconfig = 0
except ImportError:
pass"
dnl Set up 4 directories:
dnl pythondir -- where to install python scripts. This is the
dnl site-packages directory, not the python standard library
dnl directory like in previous automake betas. This behavior
dnl is more consistent with lispdir.m4 for example.
dnl Query distutils for this directory.
AC_CACHE_CHECK([for $am_display_PYTHON script directory],
[am_cv_python_pythondir],
[if test "x$prefix" = xNONE
then
am_py_prefix=$ac_default_prefix
else
am_py_prefix=$prefix
fi
am_cv_python_pythondir=`$PYTHON -c "
$am_python_setup_sysconfig
if can_use_sysconfig:
sitedir = sysconfig.get_path('purelib', vars={'base':'$am_py_prefix'})
else:
from distutils import sysconfig
sitedir = sysconfig.get_python_lib(0, 0, prefix='$am_py_prefix')
sys.stdout.write(sitedir)"`
case $am_cv_python_pythondir in
$am_py_prefix*)
am__strip_prefix=`echo "$am_py_prefix" | sed 's|.|.|g'`
am_cv_python_pythondir=`echo "$am_cv_python_pythondir" | sed "s,^$am__strip_prefix,$PYTHON_PREFIX,"`
;;
*)
case $am_py_prefix in
/usr|/System*) ;;
*)
am_cv_python_pythondir=$PYTHON_PREFIX/lib/python$PYTHON_VERSION/site-packages
;;
esac
;;
esac
])
AC_SUBST([pythondir], [$am_cv_python_pythondir])
dnl pkgpythondir -- $PACKAGE directory under pythondir. Was
dnl PYTHON_SITE_PACKAGE in previous betas, but this naming is
dnl more consistent with the rest of automake.
AC_SUBST([pkgpythondir], [\${pythondir}/$PACKAGE])
dnl pyexecdir -- directory for installing python extension modules
dnl (shared libraries)
dnl Query distutils for this directory.
AC_CACHE_CHECK([for $am_display_PYTHON extension module directory],
[am_cv_python_pyexecdir],
[if test "x$exec_prefix" = xNONE
then
am_py_exec_prefix=$am_py_prefix
else
am_py_exec_prefix=$exec_prefix
fi
am_cv_python_pyexecdir=`$PYTHON -c "
$am_python_setup_sysconfig
if can_use_sysconfig:
sitedir = sysconfig.get_path('platlib', vars={'platbase':'$am_py_prefix'})
else:
from distutils import sysconfig
sitedir = sysconfig.get_python_lib(1, 0, prefix='$am_py_prefix')
sys.stdout.write(sitedir)"`
case $am_cv_python_pyexecdir in
$am_py_exec_prefix*)
am__strip_prefix=`echo "$am_py_exec_prefix" | sed 's|.|.|g'`
am_cv_python_pyexecdir=`echo "$am_cv_python_pyexecdir" | sed "s,^$am__strip_prefix,$PYTHON_EXEC_PREFIX,"`
;;
*)
case $am_py_exec_prefix in
/usr|/System*) ;;
*)
am_cv_python_pyexecdir=$PYTHON_EXEC_PREFIX/lib/python$PYTHON_VERSION/site-packages
;;
esac
;;
esac
])
AC_SUBST([pyexecdir], [$am_cv_python_pyexecdir])
dnl pkgpyexecdir -- $(pyexecdir)/$(PACKAGE)
AC_SUBST([pkgpyexecdir], [\${pyexecdir}/$PACKAGE])
dnl Run any user-specified action.
$2
fi
])
# AM_PYTHON_CHECK_VERSION(PROG, VERSION, [ACTION-IF-TRUE], [ACTION-IF-FALSE])
# ---------------------------------------------------------------------------
# Run ACTION-IF-TRUE if the Python interpreter PROG has version >= VERSION.
# Run ACTION-IF-FALSE otherwise.
# This test uses sys.hexversion instead of the string equivalent (first
# word of sys.version), in order to cope with versions such as 2.2c1.
# This supports Python 2.0 or higher. (2.0 was released on October 16, 2000).
AC_DEFUN([AM_PYTHON_CHECK_VERSION],
[prog="import sys
# split strings by '.' and convert to numeric. Append some zeros
# because we need at least 4 digits for the hex conversion.
# map returns an iterator in Python 3.0 and a list in 2.x
minver = list(map(int, '$2'.split('.'))) + [[0, 0, 0]]
minverhex = 0
# xrange is not present in Python 3.0 and range returns an iterator
for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[[i]]
sys.exit(sys.hexversion < minverhex)"
AS_IF([AM_RUN_LOG([$1 -c "$prog"])], [$3], [$4])])
# Copyright (C) 2001-2014 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
@ -1156,8 +1391,6 @@ m4_include([m4/ax_check_compiler_flags.m4])
m4_include([m4/ax_compiler_vendor.m4])
m4_include([m4/ax_create_pkgconfig_info.m4])
m4_include([m4/ax_create_stdint_h.m4])
m4_include([m4/ax_cxx_compile_stdcxx.m4])
m4_include([m4/ax_cxx_compile_stdcxx_11.m4])
m4_include([m4/ax_detect_clang.m4])
m4_include([m4/ax_detect_git_head.m4])
m4_include([m4/ax_detect_gmp.m4])

View File

@ -1,11 +1,10 @@
#include <assert.h>
#include <isl/stream.h>
#include <isl_map_private.h>
#include <isl_polynomial_private.h>
#include <isl/polynomial.h>
#include <isl_scan.h>
#include <isl/val.h>
#include <isl/options.h>
#include <isl/deprecated/point_int.h>
#include <isl/deprecated/polynomial_int.h>
struct bound_options {
struct isl_options *isl;
@ -63,7 +62,7 @@ static isl_stat verify_point(__isl_take isl_point *pnt, void *user)
int i;
unsigned nparam;
struct verify_point_bound *vpb = (struct verify_point_bound *) user;
isl_int t;
isl_val *v;
isl_ctx *ctx;
isl_pw_qpolynomial_fold *pwf;
isl_val *bound = NULL;
@ -89,14 +88,12 @@ static isl_stat verify_point(__isl_take isl_point *pnt, void *user)
ctx = isl_point_get_ctx(pnt);
p = isl_printer_to_file(ctx, out);
isl_int_init(t);
pwf = isl_pw_qpolynomial_fold_copy(vpb->pwf);
nparam = isl_pw_qpolynomial_fold_dim(pwf, isl_dim_param);
for (i = 0; i < nparam; ++i) {
isl_point_get_coordinate(pnt, isl_dim_param, i, &t);
pwf = isl_pw_qpolynomial_fold_fix_dim(pwf, isl_dim_param, i, t);
v = isl_point_get_coordinate_val(pnt, isl_dim_param, i);
pwf = isl_pw_qpolynomial_fold_fix_val(pwf, isl_dim_param, i, v);
}
bound = isl_pw_qpolynomial_fold_eval(
@ -133,8 +130,9 @@ static isl_stat verify_point(__isl_take isl_point *pnt, void *user)
for (i = 0; i < nparam; ++i) {
if (i)
p = isl_printer_print_str(p, ", ");
isl_point_get_coordinate(pnt, isl_dim_param, i, &t);
p = isl_printer_print_isl_int(p, t);
v = isl_point_get_coordinate_val(pnt, isl_dim_param, i);
p = isl_printer_print_val(p, v);
isl_val_free(v);
}
p = isl_printer_print_str(p, ") = ");
p = isl_printer_print_val(p, bound);
@ -163,8 +161,6 @@ error:
isl_point_free(pnt);
isl_set_free(dom);
isl_int_clear(t);
isl_printer_free(p);
if (!ok)

View File

@ -23,6 +23,7 @@
#include <isl/ast.h>
#include <isl/ast_build.h>
#include <isl/options.h>
#include <isl/space.h>
#include <isl/set.h>
#include <isl/union_set.h>
#include <isl/union_map.h>

File diff suppressed because it is too large Load Diff

View File

@ -25,20 +25,11 @@ AX_CC_MAXOPT
AX_GCC_WARN_UNUSED_RESULT
AX_C___ATTRIBUTE__
# CXX11FLAGS contains the flags (if any) added by AX_CXX_COMPILE_STDCXX_11
# Original state of CXX and CXXCPP is preserved because CXX11FLAGS
# is only needed for compiling interface/isl_test_cpp
AC_SUBST(CXX11FLAGS)
ac_save_CXX="$CXX"
ac_save_CXXCPP="$CXXCPP"
AX_CXX_COMPILE_STDCXX_11([noext], [optional])
CXX11FLAGS=${CXX#$ac_save_CXX}
CXX="$ac_save_CXX"
CXXCPP="$ac_save_CXXCPP"
AC_PROG_GREP
AC_PROG_LIBTOOL
AC_PROG_SED
AM_PATH_PYTHON([2.5], [], [:])
AM_CONDITIONAL([HAVE_PYTHON], [test "$PYTHON" != :])
AC_CHECK_PROG(PERL, perl, perl, [])
AC_CHECK_PROG(PDFLATEX, pdflatex, pdflatex, [])
@ -79,7 +70,6 @@ fi
AM_CONDITIONAL(IMATH_FOR_MP, test x$with_int = ximath -o x$with_int = ximath-32)
AM_CONDITIONAL(GMP_FOR_MP, test x$with_int = xgmp)
AM_CONDITIONAL(HAVE_CXX11, test "x$HAVE_CXX11" = "x1")
AM_CONDITIONAL(SMALL_INT_OPT, test "x$with_int" == "ximath-32")
AS_IF([test "x$with_int" == "ximath-32"], [
AC_DEFINE([USE_SMALL_INT_OPT], [], [Use small integer optimization])

View File

@ -95,8 +95,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_c___attribute__.m4 \
$(top_srcdir)/m4/ax_compiler_vendor.m4 \
$(top_srcdir)/m4/ax_create_pkgconfig_info.m4 \
$(top_srcdir)/m4/ax_create_stdint_h.m4 \
$(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
$(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \
$(top_srcdir)/m4/ax_detect_clang.m4 \
$(top_srcdir)/m4/ax_detect_git_head.m4 \
$(top_srcdir)/m4/ax_detect_gmp.m4 \
@ -155,7 +153,6 @@ CLANG_LIBS = @CLANG_LIBS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXX11FLAGS = @CXX11FLAGS@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
@ -175,7 +172,6 @@ GIT_HEAD = @GIT_HEAD@
GIT_HEAD_ID = @GIT_HEAD_ID@
GIT_HEAD_VERSION = @GIT_HEAD_VERSION@
GREP = @GREP@
HAVE_CXX11 = @HAVE_CXX11@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
@ -215,6 +211,11 @@ PDFLATEX = @PDFLATEX@
PERL = @PERL@
POD2HTML = @POD2HTML@
PRTDIAG = @PRTDIAG@
PYTHON = @PYTHON@
PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
PYTHON_PLATFORM = @PYTHON_PLATFORM@
PYTHON_PREFIX = @PYTHON_PREFIX@
PYTHON_VERSION = @PYTHON_VERSION@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
@ -267,9 +268,13 @@ oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
pkgconfig_libdir = @pkgconfig_libdir@
pkgconfig_libfile = @pkgconfig_libfile@
pkgpyexecdir = @pkgpyexecdir@
pkgpythondir = @pkgpythondir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
pyexecdir = @pyexecdir@
pythondir = @pythondir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@

View File

@ -586,9 +586,6 @@ in which the object was created.
isl_ctx *isl_schedule_node_get_ctx(
__isl_keep isl_schedule_node *node);
#include <isl/band.h>
isl_ctx *isl_band_get_ctx(__isl_keep isl_band *band);
#include <isl/ast_build.h>
isl_ctx *isl_ast_build_get_ctx(
__isl_keep isl_ast_build *build);
@ -843,18 +840,27 @@ the last error in the corresponding C<isl_ctx> and the function in which the
error was triggered returns a value indicating that some error has
occurred. In case of functions returning a pointer, this value is
C<NULL>. In case of functions returning an C<isl_bool> or an
C<isl_stat>, this valus is C<isl_bool_error> or C<isl_stat_error>.
C<isl_stat>, this value is C<isl_bool_error> or C<isl_stat_error>.
An error does not corrupt internal state,
such that isl can continue to be used. C<isl> also provides functions to
read the last error and to reset the memory that stores the last error. The
read the last error, including the specific error message,
the isl source file where the error occurred and the line number,
and to reset all information about the last error. The
last error is only stored for information purposes. Its presence does not
change the behavior of C<isl>. Hence, resetting an error is not required to
continue to use isl, but only to observe new errors.
#include <isl/ctx.h>
enum isl_error isl_ctx_last_error(isl_ctx *ctx);
const char *isl_ctx_last_error_msg(isl_ctx *ctx);
const char *isl_ctx_last_error_file(isl_ctx *ctx);
int isl_ctx_last_error_line(isl_ctx *ctx);
void isl_ctx_reset_error(isl_ctx *ctx);
If no error has occurred since the last call to C<isl_ctx_reset_error>,
then the functions C<isl_ctx_last_error_msg> and
C<isl_ctx_last_error_file> return C<NULL>.
Another option is to continue on error. This is similar to warn on error mode,
except that C<isl> does not print any warning. This allows a program to
implement its own error reporting.
@ -1171,6 +1177,16 @@ an C<isl_union_pw_qpolynomial> and
an C<isl_union_pw_qpolynomial_fold>
only have parameters.
Additional parameters can be added to a space using the following function.
#include <isl/space.h>
__isl_give isl_space *isl_space_add_param_id(
__isl_take isl_space *space,
__isl_take isl_id *id);
If a parameter with the given identifier already appears in the space,
then it is not added again.
The identifiers or names of the individual dimensions of spaces
may be set or read off using the following functions on spaces
or objects that live in spaces.
@ -2174,19 +2190,30 @@ no explicit representation is known.
To iterate over all the sets or maps in a union set or map, use
#include <isl/union_set.h>
isl_stat isl_union_set_foreach_set(
__isl_keep isl_union_set *uset,
isl_stat (*fn)(__isl_take isl_set *set, void *user),
void *user);
#include <isl/union_map.h>
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_bool isl_union_map_every_map(
__isl_keep isl_union_map *umap,
isl_bool (*test)(__isl_keep isl_map *map,
void *user),
void *user);
These functions call the callback function once for each
(pair of) space(s) for which there are elements in the input.
The argument to the callback contains all elements in the input
with that (pair of) space(s).
The C<isl_union_map_every_map> variant check whether each
call to the callback returns true and stops checking as soon as one
of these calls returns false.
The number of sets or maps in a union set or map can be obtained
from
@ -2214,9 +2241,9 @@ To iterate over all the basic sets or maps in a set or map, use
void *user),
void *user);
The callback function C<fn> should return 0 if successful and
-1 if an error occurs. In the latter case, or if any other error
occurs, the above functions will return -1.
The callback function C<fn> should return C<isl_stat_ok> if successful and
C<isl_stat_error> if an error occurs. In the latter case, or if any other error
occurs, the above functions will return C<isl_stat_error>.
It should be noted that C<isl> does not guarantee that
the basic sets or maps passed to C<fn> are disjoint.
@ -2273,9 +2300,10 @@ To iterate over the constraints of a basic set or map, use
__isl_null isl_constraint *isl_constraint_free(
__isl_take isl_constraint *c);
Again, the callback function C<fn> should return 0 if successful and
-1 if an error occurs. In the latter case, or if any other error
occurs, the above functions will return -1.
Again, the callback function C<fn> should return C<isl_stat_ok>
if successful and
C<isl_stat_error> if an error occurs. In the latter case, or if any other error
occurs, the above functions will return C<isl_stat_error>.
The constraint C<c> represents either an equality or an inequality.
Use the following function to find out whether a constraint
represents an equality. If not, it represents an inequality.
@ -2424,11 +2452,11 @@ the following functions.
The function C<fn> is called for each integer point in
C<set> with as second argument the last argument of
the C<isl_set_foreach_point> call. The function C<fn>
should return C<0> on success and C<-1> on failure.
should return C<isl_stat_ok> on success and C<isl_stat_error> on failure.
In the latter case, C<isl_set_foreach_point> will stop
enumerating and return C<-1> as well.
enumerating and return C<isl_stat_error> as well.
If the enumeration is performed successfully and to completion,
then C<isl_set_foreach_point> returns C<0>.
then C<isl_set_foreach_point> returns C<isl_stat_ok>.
To obtain a single point of a (basic or union) set, use
@ -2464,7 +2492,7 @@ parameters and set variables, addition, subtraction and
integer division by an integer constant.
For example, the quasi-affine expression
[n] -> { [x] -> [2*floor((4 n + x)/9] }
[n] -> { [x] -> [2*floor((4 n + x)/9)] }
maps C<x> to C<2*floor((4 n + x)/9>.
A quasipolynomial is a polynomial expression in quasi-affine
@ -2474,7 +2502,7 @@ division of an expression involving multiplications.
Here is an example of a quasipolynomial that is not
quasi-affine expression
[n] -> { [x] -> (n*floor((4 n + x)/9) }
[n] -> { [x] -> (n*floor((4 n + x)/9)) }
Note that the external representations of quasi-affine expressions
and quasipolynomials are different. Quasi-affine expressions
@ -2500,7 +2528,7 @@ typically represent a failure to represent a result
as a quasi-affine expression.
The zero quasi affine expression or the quasi affine expression
that is equal to a given value or
that is equal to a given value, parameter or
a specified dimension on a given domain can be created using
#include <isl/aff.h>
@ -2509,12 +2537,18 @@ a specified dimension on a given domain can be created using
__isl_give isl_aff *isl_aff_val_on_domain(
__isl_take isl_local_space *ls,
__isl_take isl_val *val);
__isl_give isl_aff *isl_aff_param_on_domain_space_id(
__isl_take isl_space *space,
__isl_take isl_id *id);
__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);
The space passed to C<isl_aff_param_on_domain_space_id>
is required to have a parameter with the given identifier.
Quasi affine expressions can be copied and freed using
#include <isl/aff.h>
@ -2842,7 +2876,7 @@ function.
Similarly,
a multiple union piecewise affine expression can be created from
a multiple value with a given domain or
a multiple affine expression with a given domain
a (piecewise) multiple affine expression with a given domain
using the following functions.
#include <isl/aff.h>
@ -2854,6 +2888,10 @@ using the following functions.
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);
Multiple expressions can be copied and freed using
the following functions.
@ -3147,8 +3185,8 @@ use the following functions.
__isl_take isl_qpolynomial_fold *fold,
void *user), void *user);
As usual, the function C<fn> should return C<0> on success
and C<-1> on failure. The difference between
As usual, the function C<fn> should return C<isl_stat_ok> on success
and C<isl_stat_error> on failure. The difference between
C<isl_pw_qpolynomial_foreach_piece> and
C<isl_pw_qpolynomial_foreach_lifted_piece> is that
C<isl_pw_qpolynomial_foreach_lifted_piece> will first
@ -3266,16 +3304,29 @@ of the sets in the union set and collect the results.
isl_union_pw_multi_aff_multi_val_on_domain(
__isl_take isl_union_set *domain,
__isl_take isl_multi_val *mv);
__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);
The C<id> argument of C<isl_union_pw_aff_param_on_domain_id>
is the identifier of a parameter that may or may not already
be present in C<domain>.
An C<isl_union_pw_aff> that is equal to a (parametric) affine
or piecewise affine
expression on a given domain can be created using the following
function.
functions.
#include <isl/aff.h>
__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(
__isl_take isl_union_set *domain,
__isl_take isl_pw_aff *pa);
A base expression can be added to a union expression using
the following functions.
@ -3794,6 +3845,7 @@ contains any integer points. The ``plain'' variants do not perform
any computations, but simply check if the given set or relation
is already known to be empty.
#include <isl/set.h>
isl_bool isl_basic_set_plain_is_empty(
__isl_keep isl_basic_set *bset);
isl_bool isl_basic_set_is_empty(
@ -3801,8 +3853,12 @@ is already known to be empty.
isl_bool isl_set_plain_is_empty(
__isl_keep isl_set *set);
isl_bool isl_set_is_empty(__isl_keep isl_set *set);
#include <isl/union_set.h>
isl_bool isl_union_set_is_empty(
__isl_keep isl_union_set *uset);
#include <isl/map.h>
isl_bool isl_basic_map_plain_is_empty(
__isl_keep isl_basic_map *bmap);
isl_bool isl_basic_map_is_empty(
@ -3810,6 +3866,10 @@ is already known to be empty.
isl_bool isl_map_plain_is_empty(
__isl_keep isl_map *map);
isl_bool isl_map_is_empty(__isl_keep isl_map *map);
#include <isl/union_map.h>
isl_bool isl_union_map_plain_is_empty(
__isl_keep isl_union_map *umap);
isl_bool isl_union_map_is_empty(
__isl_keep isl_union_map *umap);
@ -3907,6 +3967,35 @@ C<*residue>.
If the dimension does not attain only a single value and if no modulo
can be found then assign C<1> to C<*modulo> and C<1> to C<*residue>.
#include <isl/set.h>
__isl_give isl_stride_info *isl_set_get_stride_info(
__isl_keep isl_set *set, int pos);
__isl_give isl_val *isl_set_get_stride(
__isl_keep isl_set *set, int pos);
Check if the values of the given set dimension are equal to
some affine expression of the other dimensions (the offset)
modulo some integer stride.
If no more specific information can be found, then the stride
is taken to be one and the offset is taken to be the zero expression.
The function C<isl_set_get_stride_info> performs the same
computation but only returns the stride.
Otherwise,
the stride and offset can be extracted from the returned object
using the following functions.
#include <isl/set.h>
__isl_give isl_val *isl_stride_info_get_stride(
__isl_keep isl_stride_info *si);
__isl_give isl_aff *isl_stride_info_get_offset(
__isl_keep isl_stride_info *si);
The stride info object can be released using the following function.
#include <isl/set.h>
__isl_null isl_stride_info *isl_stride_info_free(
__isl_take isl_stride_info *si);
=item * Dependence
To check whether the description of a set, relation or function depends
@ -4436,6 +4525,9 @@ parameters.
__isl_give isl_union_map *isl_union_map_project_out(
__isl_take isl_union_map *umap,
enum isl_dim_type type, unsigned first, unsigned n);
__isl_give isl_union_map *
isl_union_map_project_out_all_params(
__isl_take isl_union_map *umap);
__isl_give isl_set *isl_union_map_params(
__isl_take isl_union_map *umap);
__isl_give isl_union_set *isl_union_map_domain(
@ -4449,9 +4541,15 @@ parameters.
#include <isl/aff.h>
__isl_give isl_aff *isl_aff_project_domain_on_params(
__isl_take isl_aff *aff);
__isl_give isl_multi_aff *
isl_multi_aff_project_domain_on_params(
__isl_take isl_multi_aff *ma);
__isl_give isl_pw_aff *
isl_pw_aff_project_domain_on_params(
__isl_take isl_pw_aff *pa);
__isl_give isl_multi_pw_aff *
isl_multi_pw_aff_project_domain_on_params(
__isl_take isl_multi_pw_aff *mpa);
__isl_give isl_pw_multi_aff *
isl_pw_multi_aff_project_domain_on_params(
__isl_take isl_pw_multi_aff *pma);
@ -4546,13 +4644,18 @@ without removing the dimensions.
=item * Constructing a set from a parameter domain
A zero-dimensional space or (basic) set can be constructed
A zero-dimensional (local) space or (basic) set can be constructed
on a given parameter domain using the following functions.
#include <isl/space.h>
__isl_give isl_space *isl_space_set_from_params(
__isl_take isl_space *space);
#include <isl/local_space.h>
__isl_give isl_local_space *
isl_local_space_set_from_params(
__isl_take isl_local_space *ls);
#include <isl/set.h>
__isl_give isl_basic_set *isl_basic_set_from_params(
__isl_take isl_basic_set *bset);
@ -4588,6 +4691,10 @@ flat anonymous space.
__isl_take isl_set *set);
#include <isl/union_map.h>
__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_from_domain_and_range(
__isl_take isl_union_set *domain,
@ -4598,6 +4705,8 @@ flat anonymous space.
__isl_take isl_multi_val *mv);
#include <isl/aff.h>
__isl_give isl_aff *isl_aff_from_range(
__isl_take isl_aff *aff);
__isl_give isl_multi_aff *isl_multi_aff_from_range(
__isl_take isl_multi_aff *ma);
__isl_give isl_pw_aff *isl_pw_aff_from_range(
@ -4663,6 +4772,11 @@ flat anonymous space.
__isl_take isl_pw_qpolynomial *pwqp,
enum isl_dim_type type, unsigned n,
__isl_take isl_val *v);
__isl_give isl_pw_qpolynomial_fold *
isl_pw_qpolynomial_fold_fix_val(
__isl_take isl_pw_qpolynomial_fold *pwf,
enum isl_dim_type type, unsigned n,
__isl_take isl_val *v);
Intersect the set, relation or function domain
with the hyperplane where the given
@ -4758,6 +4872,18 @@ dimensions have opposite values.
Intersect the relation with the half-space where the given
dimensions satisfy the given ordering.
#include <isl/union_set.h>
__isl_give isl_union_map *isl_union_map_remove_map_if(
__isl_take isl_union_map *umap,
isl_bool (*fn)(__isl_keep isl_map *map,
void *user), void *user);
This function calls the callback function once for each
pair of spaces for which there are elements in the input.
If the callback returns C<isl_bool_true>, then all those elements
are removed from the result. The only remaining elements in the output
are then those for which the callback returns C<isl_bool_false>.
=item * Locus
#include <isl/aff.h>
@ -5156,6 +5282,16 @@ The result is C<NULL> in case of an error, the optimal value in case
there is one, negative infinity or infinity if the problem is unbounded and
NaN if the problem is empty.
#include <isl/ilp.h>
__isl_give isl_val *isl_basic_set_dim_max_val(
__isl_take isl_basic_set *bset, int pos);
Return the maximal value attained by the given set dimension,
independently of the parameter values and of any other dimensions.
The result is C<NULL> in case of an error, the optimal value in case
there is one, infinity if the problem is unbounded and
NaN if the input is empty.
=item * Parametric optimization
__isl_give isl_pw_aff *isl_set_dim_min(
@ -5301,6 +5437,12 @@ Remove any internal structure of domain (and range) of the given
set or relation. If there is any such internal structure in the input,
then the name of the space is also removed.
#include <isl/space.h>
__isl_give isl_space *isl_space_flatten_domain(
__isl_take isl_space *space);
__isl_give isl_space *isl_space_flatten_range(
__isl_take isl_space *space);
#include <isl/local_space.h>
__isl_give isl_local_space *
isl_local_space_flatten_domain(
@ -7648,10 +7790,14 @@ Vectors can be created, copied and freed using the following functions.
#include <isl/vec.h>
__isl_give isl_vec *isl_vec_alloc(isl_ctx *ctx,
unsigned size);
__isl_give isl_vec *isl_vec_zero(isl_ctx *ctx,
unsigned size);
__isl_give isl_vec *isl_vec_copy(__isl_keep isl_vec *vec);
__isl_null isl_vec *isl_vec_free(__isl_take isl_vec *vec);
Note that the elements of a newly created vector may have arbitrary values.
Note that the elements of a vector created by C<isl_vec_alloc>
may have arbitrary values.
A vector created by C<isl_vec_zero> has elements with value zero.
The elements can be changed and inspected using the following functions.
int isl_vec_size(__isl_keep isl_vec *vec);
@ -7700,8 +7846,11 @@ The elements can be changed and inspected using the following functions.
__isl_take isl_mat *mat, int row, int col,
__isl_take isl_val *v);
C<isl_mat_get_element> will return a negative value if anything went wrong.
In that case, the value of C<*v> is undefined.
The following function computes the rank of a matrix.
The return value may be -1 if some error occurred.
#include <isl/mat.h>
int isl_mat_rank(__isl_keep isl_mat *mat);
The following function can be used to compute the (right) inverse
of a matrix, i.e., a matrix such that the product of the original
@ -7716,6 +7865,29 @@ the original and the kernel (in that order) is the zero matrix.
__isl_give isl_mat *isl_mat_right_kernel(__isl_take isl_mat *mat);
The following function computes a basis for the space spanned
by the rows of a matrix.
__isl_give isl_mat *isl_mat_row_basis(
__isl_take isl_mat *mat);
The following function computes rows that extend a basis of C<mat1>
to a basis that also covers C<mat2>.
__isl_give isl_mat *isl_mat_row_basis_extension(
__isl_take isl_mat *mat1,
__isl_take isl_mat *mat2);
The following function checks whether there is no linear dependence
among the combined rows of "mat1" and "mat2" that is not already present
in "mat1" or "mat2" individually.
If "mat1" and "mat2" have linearly independent rows by themselves,
then this means that there is no linear dependence among all rows together.
isl_bool isl_mat_has_linearly_independent_rows(
__isl_keep isl_mat *mat1,
__isl_keep isl_mat *mat2);
=head2 Bounds on Piecewise Quasipolynomials and Piecewise Quasipolynomial Reductions
The following functions determine
@ -7906,6 +8078,8 @@ active domain elements for which an AST needs to be generated.
The conditions under which some domain elements are still active
may however not be completely described by the outer AST nodes
generated at that point.
Since an extension node references the outer band nodes, any tree
containing an extension node is considered to be anchored.
An extension node may also appear as the root of a schedule tree,
when it is intended to be inserted into another tree
@ -7921,6 +8095,8 @@ The guard describes constraints on the parameters and
the schedule dimensions of outer
bands that need to be enforced by the outer nodes
in the generated AST.
That is, the part of the AST that is generated from descendants
of the guard node can assume that these constraints are satisfied.
The space of the guard is that of the flat product of the outer
band nodes. In particular, if there are no outer band nodes, then
this space is the unnamed zero-dimensional space.
@ -8104,7 +8280,7 @@ C<isl_schedule_to_str> prints the schedule in flow format.
The schedule tree can be traversed through the use of
C<isl_schedule_node> objects that point to a particular
position in the schedule tree. Whenever a C<isl_schedule_node>
is use to modify a node in the schedule tree, the original schedule
is used to modify a node in the schedule tree, the original schedule
tree is left untouched and the modifications are performed to a copy
of the tree. The returned C<isl_schedule_node> then points to
this modified copy of the tree.
@ -8246,6 +8422,16 @@ of the given node should be visited. In particular, if the callback
returns a positive value, then the children are visited, but if
the callback returns zero, then the children are not visited.
The following functions checks whether
all descendants of a specific node (including the node itself)
satisfy a user-specified test.
#include <isl/schedule_node.h>
isl_bool isl_schedule_node_every_descendant(
__isl_keep isl_schedule_node *node,
isl_bool (*test)(__isl_keep isl_schedule_node *node,
void *user), void *user)
The ancestors of a node in a schedule tree can be visited from
the root down to and including the parent of the node using
the following function.
@ -8695,7 +8881,7 @@ The resulting outer band node contains the first C<pos> dimensions of
the schedule of C<node> while the inner band contains the remaining dimensions.
The schedules of the two band nodes live in anonymous spaces.
The loop AST generation type options and the isolate option
are split over the the two band nodes.
are split over the two band nodes.
A band node can be moved down to the leaves of the subtree rooted
at the band node using the following function.
@ -9248,7 +9434,7 @@ considered adjacent to each other if the entire wrapped relation matches.
In particular, a relation with a tag will never be considered adjacent
to a relation without a tag.
The function C<isl_schedule_constraints_compute_schedule> takes
The function C<isl_schedule_constraints_apply> takes
schedule constraints that are defined on some set of domain elements
and transforms them to schedule constraints on the elements
to which these domain elements are mapped by the given transformation.
@ -10449,7 +10635,7 @@ They can be set using the following function.
#include <isl/ast_build.h>
__isl_give isl_ast_build *
isl_ast_build_set_options(
__isl_take isl_ast_build *control,
__isl_take isl_ast_build *build,
__isl_take isl_union_map *options);
The options are encoded in an C<isl_union_map>.
@ -10639,7 +10825,7 @@ Additional control is available through the following functions.
#include <isl/ast_build.h>
__isl_give isl_ast_build *
isl_ast_build_set_iterators(
__isl_take isl_ast_build *control,
__isl_take isl_ast_build *build,
__isl_take isl_id_list *iterators);
The function C<isl_ast_build_set_iterators> allows the user to
@ -10657,7 +10843,7 @@ names are automatically generated.
#include <isl/ast_build.h>
__isl_give isl_ast_build *
isl_ast_build_set_create_leaf(
__isl_take isl_ast_build *control,
__isl_take isl_ast_build *build,
__isl_give isl_ast_node *(*fn)(
__isl_take isl_ast_build *build,
void *user), void *user);
@ -10740,7 +10926,7 @@ pre-order, while the second will be called in depth-first post-order.
Since the callback set by C<isl_ast_build_set_before_each_mark>
is called before the mark AST node is actually constructed, it is passed
the identifier of the mark node.
All callbacks should C<NULL> (or -1) on failure.
All callbacks should C<NULL> (or C<isl_stat_error>) on failure.
The given C<isl_ast_build> can be used to create new
C<isl_ast_expr> objects using C<isl_ast_build_expr_from_pw_aff>
or C<isl_ast_build_call_from_pw_multi_aff>.

View File

@ -20,6 +20,8 @@ __isl_give isl_aff *isl_aff_val_on_domain(__isl_take isl_local_space *ls,
__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_give isl_aff *isl_aff_param_on_domain_space_id(
__isl_take isl_space *space, __isl_take isl_id *id);
__isl_give isl_aff *isl_aff_copy(__isl_keep isl_aff *aff);
__isl_null isl_aff *isl_aff_free(__isl_take isl_aff *aff);
@ -80,6 +82,8 @@ isl_bool isl_aff_is_nan(__isl_keep isl_aff *aff);
__isl_give isl_aff *isl_aff_get_div(__isl_keep isl_aff *aff, int pos);
__isl_give isl_aff *isl_aff_from_range(__isl_take isl_aff *aff);
__isl_export
__isl_give isl_aff *isl_aff_neg(__isl_take isl_aff *aff);
__isl_export
@ -636,6 +640,8 @@ __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_domain(
__isl_take isl_union_set *uset);
__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_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(
__isl_keep isl_union_pw_multi_aff *upma);
__isl_null isl_union_pw_multi_aff *isl_union_pw_multi_aff_free(
@ -861,6 +867,8 @@ __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_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(
__isl_take isl_union_set *domain, __isl_take isl_pw_aff *pa);
__isl_give isl_union_pw_aff *isl_union_pw_aff_add_pw_aff(
__isl_take isl_union_pw_aff *upa, __isl_take isl_pw_aff *pa);
@ -959,6 +967,9 @@ __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_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_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_floor(
__isl_take isl_multi_union_pw_aff *mupa);

View File

@ -1,56 +0,0 @@
#ifndef ISL_BAND_H
#define ISL_BAND_H
#include <isl/printer.h>
#include <isl/list.h>
#include <isl/union_map_type.h>
#include <isl/vec.h>
#if defined(__cplusplus)
extern "C" {
#endif
struct isl_band;
typedef struct isl_band isl_band;
ISL_DECLARE_LIST(band)
__isl_give isl_band *isl_band_copy(__isl_keep isl_band *band);
__isl_null isl_band *isl_band_free(__isl_take isl_band *band);
isl_ctx *isl_band_get_ctx(__isl_keep isl_band *band);
int isl_band_has_children(__isl_keep isl_band *band);
__isl_give isl_band_list *isl_band_get_children(
__isl_keep isl_band *band);
__isl_give isl_union_map *isl_band_get_prefix_schedule(
__isl_keep isl_band *band);
__isl_give isl_union_map *isl_band_get_partial_schedule(
__isl_keep isl_band *band);
__isl_give isl_union_map *isl_band_get_suffix_schedule(
__isl_keep isl_band *band);
isl_stat isl_options_set_tile_scale_tile_loops(isl_ctx *ctx, int val);
int isl_options_get_tile_scale_tile_loops(isl_ctx *ctx);
isl_stat isl_options_set_tile_shift_point_loops(isl_ctx *ctx, int val);
int isl_options_get_tile_shift_point_loops(isl_ctx *ctx);
int isl_band_tile(__isl_keep isl_band *band, __isl_take isl_vec *sizes);
int isl_band_split(__isl_keep isl_band *band, int pos);
int isl_band_n_member(__isl_keep isl_band *band);
int isl_band_member_is_coincident(__isl_keep isl_band *band, int pos);
int isl_band_list_foreach_band(__isl_keep isl_band_list *list,
int (*fn)(__isl_keep isl_band *band, void *user), void *user);
__isl_give isl_printer *isl_printer_print_band(__isl_take isl_printer *p,
__isl_keep isl_band *band);
void isl_band_dump(__isl_keep isl_band *band);
#if defined(__cplusplus)
}
#endif
#endif

View File

@ -36,7 +36,6 @@ __isl_give isl_constraint *isl_constraint_alloc_inequality(
__isl_give isl_constraint *isl_equality_alloc(__isl_take isl_local_space *ls);
__isl_give isl_constraint *isl_inequality_alloc(__isl_take isl_local_space *ls);
struct isl_constraint *isl_constraint_cow(struct isl_constraint *c);
struct isl_constraint *isl_constraint_copy(struct isl_constraint *c);
__isl_null isl_constraint *isl_constraint_free(__isl_take isl_constraint *c);

View File

@ -248,6 +248,9 @@ isl_stat prefix ## _set_ ## field(isl_ctx *ctx, const char *val) \
ISL_CTX_SET_INT_DEF(prefix,st,args,field)
enum isl_error isl_ctx_last_error(isl_ctx *ctx);
const char *isl_ctx_last_error_msg(isl_ctx *ctx);
const char *isl_ctx_last_error_file(isl_ctx *ctx);
int isl_ctx_last_error_line(isl_ctx *ctx);
void isl_ctx_reset_error(isl_ctx *ctx);
void isl_ctx_set_error(isl_ctx *ctx, enum isl_error error);

View File

@ -1,45 +0,0 @@
#ifndef ISL_DEPRECATED_AFF_INT_H
#define ISL_DEPRECATED_AFF_INT_H
#include <isl/deprecated/int.h>
#include <isl/aff_type.h>
#if defined(__cplusplus)
extern "C" {
#endif
int isl_aff_get_constant(__isl_keep isl_aff *aff, isl_int *v);
int isl_aff_get_coefficient(__isl_keep isl_aff *aff,
enum isl_dim_type type, int pos, isl_int *v);
isl_stat isl_aff_get_denominator(__isl_keep isl_aff *aff, isl_int *v);
__isl_give isl_aff *isl_aff_set_constant(__isl_take isl_aff *aff, isl_int v);
__isl_give isl_aff *isl_aff_set_coefficient(__isl_take isl_aff *aff,
enum isl_dim_type type, int pos, isl_int v);
__isl_give isl_aff *isl_aff_set_denominator(__isl_take isl_aff *aff, isl_int v);
__isl_give isl_aff *isl_aff_add_constant(__isl_take isl_aff *aff, isl_int v);
__isl_give isl_aff *isl_aff_add_constant_num(__isl_take isl_aff *aff,
isl_int v);
__isl_give isl_aff *isl_aff_add_coefficient(__isl_take isl_aff *aff,
enum isl_dim_type type, int pos, isl_int v);
__isl_give isl_aff *isl_aff_mod(__isl_take isl_aff *aff, isl_int mod);
__isl_give isl_aff *isl_aff_scale(__isl_take isl_aff *aff, isl_int f);
__isl_give isl_aff *isl_aff_scale_down(__isl_take isl_aff *aff, isl_int f);
__isl_give isl_pw_aff *isl_pw_aff_mod(__isl_take isl_pw_aff *pwaff,
isl_int mod);
__isl_give isl_pw_aff *isl_pw_aff_scale(__isl_take isl_pw_aff *pwaff,
isl_int f);
__isl_give isl_pw_aff *isl_pw_aff_scale_down(__isl_take isl_pw_aff *pwaff,
isl_int f);
__isl_give isl_multi_aff *isl_multi_aff_scale(__isl_take isl_multi_aff *maff,
isl_int f);
#if defined(__cplusplus)
}
#endif
#endif

View File

@ -1,17 +0,0 @@
#ifndef ISL_DEPRECATED_AST_INT_H
#define ISL_DEPRECATED_AST_INT_H
#include <isl/deprecated/int.h>
#include <isl/ast.h>
#if defined(__cplusplus)
extern "C" {
#endif
int isl_ast_expr_get_int(__isl_keep isl_ast_expr *expr, isl_int *v);
#if defined(__cplusplus)
}
#endif
#endif

View File

@ -1,25 +0,0 @@
#ifndef ISL_DEPRECATED_CONSTRAINT_INT_H
#define ISL_DEPRECATED_CONSTRAINT_INT_H
#include <isl/deprecated/int.h>
#include <isl/constraint.h>
#if defined(__cplusplus)
extern "C" {
#endif
void isl_constraint_get_constant(__isl_keep isl_constraint *constraint,
isl_int *v);
void isl_constraint_get_coefficient(__isl_keep isl_constraint *constraint,
enum isl_dim_type type, int pos, isl_int *v);
__isl_give isl_constraint *isl_constraint_set_constant(
__isl_take isl_constraint *constraint, isl_int v);
__isl_give isl_constraint *isl_constraint_set_coefficient(
__isl_take isl_constraint *constraint,
enum isl_dim_type type, int pos, isl_int v);
#if defined(__cplusplus)
}
#endif
#endif

View File

@ -1,23 +0,0 @@
#ifndef ISL_DEPRECATED_ILP_INT_H
#define ISL_DEPRECATED_ILP_INT_H
#include <isl/deprecated/int.h>
#include <isl/lp.h>
#include <isl/ilp.h>
#if defined(__cplusplus)
extern "C" {
#endif
enum isl_lp_result isl_basic_set_max(__isl_keep isl_basic_set *bset,
__isl_keep isl_aff *obj, isl_int *opt);
enum isl_lp_result isl_set_min(__isl_keep isl_set *set,
__isl_keep isl_aff *obj, isl_int *opt);
enum isl_lp_result isl_set_max(__isl_keep isl_set *set,
__isl_keep isl_aff *obj, isl_int *opt);
#if defined(__cplusplus)
}
#endif
#endif

View File

@ -1,136 +0,0 @@
/*
* Copyright 2008-2009 Katholieke Universiteit Leuven
*
* Use of this software is governed by the MIT license
*
* Written by Sven Verdoolaege, K.U.Leuven, Departement
* Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
*/
#ifndef ISL_DEPRECATED_INT_H
#define ISL_DEPRECATED_INT_H
#include <isl/hash.h>
#include <string.h>
#include <gmp.h>
#if defined(__cplusplus)
#include <iostream>
#endif
#if defined(__cplusplus)
extern "C" {
#endif
#ifndef mp_get_memory_functions
void mp_get_memory_functions(
void *(**alloc_func_ptr) (size_t),
void *(**realloc_func_ptr) (void *, size_t, size_t),
void (**free_func_ptr) (void *, size_t));
#endif
/* isl_int is the basic integer type. It currently always corresponds
* to a gmp mpz_t, but in the future, different types such as long long
* or cln::cl_I will be supported.
*/
typedef mpz_t isl_int;
#define isl_int_init(i) mpz_init(i)
#define isl_int_clear(i) mpz_clear(i)
#define isl_int_set(r,i) mpz_set(r,i)
#define isl_int_set_gmp(r,i) mpz_set(r,i)
#define isl_int_set_si(r,i) mpz_set_si(r,i)
#define isl_int_set_ui(r,i) mpz_set_ui(r,i)
#define isl_int_get_gmp(i,g) mpz_set(g,i)
#define isl_int_get_si(r) mpz_get_si(r)
#define isl_int_get_ui(r) mpz_get_ui(r)
#define isl_int_get_d(r) mpz_get_d(r)
#define isl_int_get_str(r) mpz_get_str(0, 10, r)
typedef void (*isl_int_print_gmp_free_t)(void *, size_t);
#define isl_int_free_str(s) \
do { \
isl_int_print_gmp_free_t gmp_free; \
mp_get_memory_functions(NULL, NULL, &gmp_free); \
(*gmp_free)(s, strlen(s) + 1); \
} while (0)
#define isl_int_abs(r,i) mpz_abs(r,i)
#define isl_int_neg(r,i) mpz_neg(r,i)
#define isl_int_swap(i,j) mpz_swap(i,j)
#define isl_int_swap_or_set(i,j) mpz_swap(i,j)
#define isl_int_add_ui(r,i,j) mpz_add_ui(r,i,j)
#define isl_int_sub_ui(r,i,j) mpz_sub_ui(r,i,j)
#define isl_int_add(r,i,j) mpz_add(r,i,j)
#define isl_int_sub(r,i,j) mpz_sub(r,i,j)
#define isl_int_mul(r,i,j) mpz_mul(r,i,j)
#define isl_int_mul_2exp(r,i,j) mpz_mul_2exp(r,i,j)
#define isl_int_mul_ui(r,i,j) mpz_mul_ui(r,i,j)
#define isl_int_pow_ui(r,i,j) mpz_pow_ui(r,i,j)
#define isl_int_addmul(r,i,j) mpz_addmul(r,i,j)
#define isl_int_submul(r,i,j) mpz_submul(r,i,j)
#define isl_int_gcd(r,i,j) mpz_gcd(r,i,j)
#define isl_int_lcm(r,i,j) mpz_lcm(r,i,j)
#define isl_int_divexact(r,i,j) mpz_divexact(r,i,j)
#define isl_int_divexact_ui(r,i,j) mpz_divexact_ui(r,i,j)
#define isl_int_tdiv_q(r,i,j) mpz_tdiv_q(r,i,j)
#define isl_int_cdiv_q(r,i,j) mpz_cdiv_q(r,i,j)
#define isl_int_fdiv_q(r,i,j) mpz_fdiv_q(r,i,j)
#define isl_int_fdiv_r(r,i,j) mpz_fdiv_r(r,i,j)
#define isl_int_fdiv_q_ui(r,i,j) mpz_fdiv_q_ui(r,i,j)
#define isl_int_read(r,s) mpz_set_str(r,s,10)
#define isl_int_print(out,i,width) \
do { \
char *s; \
s = mpz_get_str(0, 10, i); \
fprintf(out, "%*s", width, s); \
isl_int_free_str(s); \
} while (0)
#define isl_int_sgn(i) mpz_sgn(i)
#define isl_int_cmp(i,j) mpz_cmp(i,j)
#define isl_int_cmp_si(i,si) mpz_cmp_si(i,si)
#define isl_int_eq(i,j) (mpz_cmp(i,j) == 0)
#define isl_int_ne(i,j) (mpz_cmp(i,j) != 0)
#define isl_int_lt(i,j) (mpz_cmp(i,j) < 0)
#define isl_int_le(i,j) (mpz_cmp(i,j) <= 0)
#define isl_int_gt(i,j) (mpz_cmp(i,j) > 0)
#define isl_int_ge(i,j) (mpz_cmp(i,j) >= 0)
#define isl_int_abs_eq(i,j) (mpz_cmpabs(i,j) == 0)
#define isl_int_abs_ne(i,j) (mpz_cmpabs(i,j) != 0)
#define isl_int_abs_lt(i,j) (mpz_cmpabs(i,j) < 0)
#define isl_int_abs_gt(i,j) (mpz_cmpabs(i,j) > 0)
#define isl_int_abs_ge(i,j) (mpz_cmpabs(i,j) >= 0)
#define isl_int_is_zero(i) (isl_int_sgn(i) == 0)
#define isl_int_is_one(i) (isl_int_cmp_si(i,1) == 0)
#define isl_int_is_negone(i) (isl_int_cmp_si(i,-1) == 0)
#define isl_int_is_pos(i) (isl_int_sgn(i) > 0)
#define isl_int_is_neg(i) (isl_int_sgn(i) < 0)
#define isl_int_is_nonpos(i) (isl_int_sgn(i) <= 0)
#define isl_int_is_nonneg(i) (isl_int_sgn(i) >= 0)
#define isl_int_is_divisible_by(i,j) mpz_divisible_p(i,j)
uint32_t isl_gmp_hash(mpz_t v, uint32_t hash);
#define isl_int_hash(v,h) isl_gmp_hash(v,h)
#if defined(__cplusplus)
}
#endif
#if defined(__cplusplus)
extern "C" { typedef void (*isl_gmp_free_t)(void *, size_t); }
static inline std::ostream &operator<<(std::ostream &os, isl_int i)
{
char *s;
s = mpz_get_str(0, 10, i);
os << s;
isl_int_free_str(s);
return os;
}
#endif
#endif

View File

@ -1,25 +0,0 @@
#ifndef ISL_DEPRECATED_MAP_INT_H
#define ISL_DEPRECATED_MAP_INT_H
#include <isl/deprecated/int.h>
#include <isl/map_type.h>
#if defined(__cplusplus)
extern "C" {
#endif
isl_bool isl_basic_map_plain_is_fixed(__isl_keep isl_basic_map *bmap,
enum isl_dim_type type, unsigned pos, isl_int *val);
__isl_give isl_map *isl_map_fix(__isl_take isl_map *map,
enum isl_dim_type type, unsigned pos, isl_int value);
isl_bool isl_map_plain_is_fixed(__isl_keep isl_map *map,
enum isl_dim_type type, unsigned pos, isl_int *val);
__isl_give isl_map *isl_map_fixed_power(__isl_take isl_map *map, isl_int exp);
#if defined(__cplusplus)
}
#endif
#endif

View File

@ -1,19 +0,0 @@
#ifndef ISL_DEPRECATED_MAT_INT_H
#define ISL_DEPRECATED_MAT_INT_H
#include <isl/deprecated/int.h>
#include <isl/mat.h>
#if defined(__cplusplus)
extern "C" {
#endif
int isl_mat_get_element(__isl_keep isl_mat *mat, int row, int col, isl_int *v);
__isl_give isl_mat *isl_mat_set_element(__isl_take isl_mat *mat,
int row, int col, isl_int v);
#if defined(__cplusplus)
}
#endif
#endif

View File

@ -1,20 +0,0 @@
#ifndef ISL_DEPRECATED_POINT_INT_H
#define ISL_DEPRECATED_POINT_INT_H
#include <isl/deprecated/int.h>
#include <isl/point.h>
#if defined(__cplusplus)
extern "C" {
#endif
int isl_point_get_coordinate(__isl_keep isl_point *pnt,
enum isl_dim_type type, int pos, isl_int *v);
__isl_give isl_point *isl_point_set_coordinate(__isl_take isl_point *pnt,
enum isl_dim_type type, int pos, isl_int v);
#if defined(__cplusplus)
}
#endif
#endif

View File

@ -1,32 +0,0 @@
#ifndef ISL_DEPRECATED_POLYNOMIAL_INT_H
#define ISL_DEPRECATED_POLYNOMIAL_INT_H
#include <isl/deprecated/int.h>
#include <isl/polynomial.h>
#if defined(__cplusplus)
extern "C" {
#endif
__isl_give isl_qpolynomial *isl_qpolynomial_rat_cst_on_domain(
__isl_take isl_space *space, const isl_int n, const isl_int d);
int isl_qpolynomial_is_cst(__isl_keep isl_qpolynomial *qp,
isl_int *n, isl_int *d);
__isl_give isl_qpolynomial *isl_qpolynomial_scale(
__isl_take isl_qpolynomial *qp, isl_int v);
void isl_term_get_num(__isl_keep isl_term *term, isl_int *n);
void isl_term_get_den(__isl_keep isl_term *term, isl_int *d);
__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_scale(
__isl_take isl_qpolynomial_fold *fold, isl_int v);
__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_fix_dim(
__isl_take isl_pw_qpolynomial_fold *pwf,
enum isl_dim_type type, unsigned n, isl_int v);
#if defined(__cplusplus)
}
#endif
#endif

View File

@ -1,27 +0,0 @@
#ifndef ISL_DEPRECATED_SET_INT_H
#define ISL_DEPRECATED_SET_INT_H
#include <isl/deprecated/int.h>
#include <isl/set_type.h>
#if defined(__cplusplus)
extern "C" {
#endif
__isl_give isl_basic_set *isl_basic_set_fix(__isl_take isl_basic_set *bset,
enum isl_dim_type type, unsigned pos, isl_int value);
__isl_give isl_set *isl_set_lower_bound(__isl_take isl_set *set,
enum isl_dim_type type, unsigned pos, isl_int value);
__isl_give isl_set *isl_set_upper_bound(__isl_take isl_set *set,
enum isl_dim_type type, unsigned pos, isl_int value);
__isl_give isl_set *isl_set_fix(__isl_take isl_set *set,
enum isl_dim_type type, unsigned pos, isl_int value);
isl_bool isl_set_plain_is_fixed(__isl_keep isl_set *set,
enum isl_dim_type type, unsigned pos, isl_int *val);
#if defined(__cplusplus)
}
#endif
#endif

View File

@ -1,18 +0,0 @@
#ifndef ISL_DEPRECATED_UNION_MAP_INT_H
#define ISL_DEPRECATED_UNION_MAP_INT_H
#include <isl/deprecated/int.h>
#include <isl/union_map_type.h>
#if defined(__cplusplus)
extern "C" {
#endif
__isl_give isl_union_map *isl_union_map_fixed_power(
__isl_take isl_union_map *umap, isl_int exp);
#if defined(__cplusplus)
}
#endif
#endif

View File

@ -1,18 +0,0 @@
#ifndef ISL_DEPRECATED_VAL_INT_H
#define ISL_DEPRECATED_VAL_INT_H
#include <isl/deprecated/int.h>
#include <isl/val.h>
#if defined(__cplusplus)
extern "C" {
#endif
__isl_give isl_val *isl_val_int_from_isl_int(isl_ctx *ctx, isl_int n);
int isl_val_get_num_isl_int(__isl_keep isl_val *v, isl_int *n);
#if defined(__cplusplus)
}
#endif
#endif

View File

@ -1,22 +0,0 @@
#ifndef ISL_DEPRECATED_VEC_INT_H
#define ISL_DEPRECATED_VEC_INT_H
#include <isl/deprecated/int.h>
#include <isl/vec.h>
#if defined(__cplusplus)
extern "C" {
#endif
int isl_vec_get_element(__isl_keep isl_vec *vec, int pos, isl_int *v);
__isl_give isl_vec *isl_vec_set_element(__isl_take isl_vec *vec,
int pos, isl_int v);
__isl_give isl_vec *isl_vec_set(__isl_take isl_vec *vec, isl_int v);
__isl_give isl_vec *isl_vec_fdiv_r(__isl_take isl_vec *vec, isl_int m);
#if defined(__cplusplus)
}
#endif
#endif

View File

@ -31,6 +31,10 @@ __isl_give isl_val *isl_set_max_val(__isl_keep isl_set *set,
__isl_give isl_multi_val *isl_union_set_min_multi_union_pw_aff(
__isl_keep isl_union_set *set, __isl_keep isl_multi_union_pw_aff *obj);
__isl_export
__isl_give isl_val *isl_basic_set_dim_max_val(__isl_take isl_basic_set *bset,
int pos);
#if defined(__cplusplus)
}
#endif

View File

@ -66,6 +66,8 @@ __isl_give isl_local_space *isl_local_space_drop_dims(
__isl_give isl_local_space *isl_local_space_insert_dims(
__isl_take isl_local_space *ls,
enum isl_dim_type type, unsigned first, unsigned n);
__isl_give isl_local_space *isl_local_space_set_from_params(
__isl_take isl_local_space *ls);
__isl_give isl_local_space *isl_local_space_intersect(
__isl_take isl_local_space *ls1, __isl_take isl_local_space *ls2);

View File

@ -119,8 +119,8 @@ __isl_give isl_basic_map *isl_basic_map_less_at(__isl_take isl_space *dim,
unsigned pos);
__isl_give isl_basic_map *isl_basic_map_more_at(__isl_take isl_space *dim,
unsigned pos);
__isl_give isl_basic_map *isl_basic_map_empty(__isl_take isl_space *dim);
__isl_give isl_basic_map *isl_basic_map_universe(__isl_take isl_space *dim);
__isl_give isl_basic_map *isl_basic_map_empty(__isl_take isl_space *space);
__isl_give isl_basic_map *isl_basic_map_universe(__isl_take isl_space *space);
__isl_give isl_basic_map *isl_basic_map_nat_universe(__isl_take isl_space *dim);
__isl_give isl_basic_map *isl_basic_map_remove_redundancies(
__isl_take isl_basic_map *bmap);
@ -281,9 +281,9 @@ isl_bool isl_basic_map_is_subset(__isl_keep isl_basic_map *bmap1,
isl_bool isl_basic_map_is_strict_subset(__isl_keep isl_basic_map *bmap1,
__isl_keep isl_basic_map *bmap2);
__isl_give isl_map *isl_map_universe(__isl_take isl_space *dim);
__isl_give isl_map *isl_map_universe(__isl_take isl_space *space);
__isl_give isl_map *isl_map_nat_universe(__isl_take isl_space *dim);
__isl_give isl_map *isl_map_empty(__isl_take isl_space *dim);
__isl_give isl_map *isl_map_empty(__isl_take isl_space *space);
__isl_give isl_map *isl_map_identity(__isl_take isl_space *dim);
__isl_give isl_map *isl_map_lex_lt_first(__isl_take isl_space *dim, unsigned n);
__isl_give isl_map *isl_map_lex_le_first(__isl_take isl_space *dim, unsigned n);

View File

@ -27,12 +27,10 @@ isl_ctx *isl_mat_get_ctx(__isl_keep isl_mat *mat);
__isl_give isl_mat *isl_mat_alloc(isl_ctx *ctx,
unsigned n_row, unsigned n_col);
__isl_give isl_mat *isl_mat_dup(__isl_keep isl_mat *mat);
struct isl_mat *isl_mat_extend(struct isl_mat *mat,
unsigned n_row, unsigned n_col);
struct isl_mat *isl_mat_identity(struct isl_ctx *ctx, unsigned n_row);
__isl_give isl_mat *isl_mat_copy(__isl_keep isl_mat *mat);
__isl_give isl_mat *isl_mat_cow(__isl_take isl_mat *mat);
__isl_null isl_mat *isl_mat_free(__isl_take isl_mat *mat);
int isl_mat_rows(__isl_keep isl_mat *mat);
@ -94,6 +92,9 @@ __isl_give isl_mat *isl_mat_add_zero_rows(__isl_take isl_mat *mat, unsigned n);
void isl_mat_col_add(__isl_keep isl_mat *mat, int dst_col, int src_col);
__isl_give isl_mat *isl_mat_unimodular_complete(__isl_take isl_mat *M, int row);
__isl_give isl_mat *isl_mat_row_basis(__isl_take isl_mat *mat);
__isl_give isl_mat *isl_mat_row_basis_extension(
__isl_take isl_mat *mat1, __isl_take isl_mat *mat2);
__isl_give isl_mat *isl_mat_from_row_vec(__isl_take isl_vec *vec);
__isl_give isl_mat *isl_mat_concat(__isl_take isl_mat *top,
@ -102,7 +103,10 @@ __isl_give isl_mat *isl_mat_vec_concat(__isl_take isl_mat *top,
__isl_take isl_vec *bot);
isl_bool isl_mat_is_equal(__isl_keep isl_mat *mat1, __isl_keep isl_mat *mat2);
isl_bool isl_mat_has_linearly_independent_rows(__isl_keep isl_mat *mat1,
__isl_keep isl_mat *mat2);
int isl_mat_rank(__isl_keep isl_mat *mat);
int isl_mat_initial_non_zero_cols(__isl_keep isl_mat *mat);
void isl_mat_print_internal(__isl_keep isl_mat *mat, FILE *out, int indent);

View File

@ -38,7 +38,7 @@ int isl_multi_##BASE##_find_dim_by_id( \
__isl_keep isl_multi_##BASE *multi, enum isl_dim_type type, \
__isl_keep isl_id *id); \
__isl_give isl_id *isl_multi_##BASE##_get_dim_id( \
__isl_take isl_multi_##BASE *multi, \
__isl_keep isl_multi_##BASE *multi, \
enum isl_dim_type type, unsigned pos); \
__isl_give isl_multi_##BASE *isl_multi_##BASE##_set_dim_name( \
__isl_take isl_multi_##BASE *multi, \
@ -134,7 +134,10 @@ __isl_give isl_multi_##BASE *isl_multi_##BASE##_insert_dims( \
unsigned first, unsigned n); \
__isl_give isl_multi_##BASE *isl_multi_##BASE##_add_dims( \
__isl_take isl_multi_##BASE *multi, enum isl_dim_type type, \
unsigned n);
unsigned n); \
__isl_give isl_multi_##BASE * \
isl_multi_##BASE##_project_domain_on_params( \
__isl_take isl_multi_##BASE *multi);
#define ISL_DECLARE_MULTI_WITH_DOMAIN(BASE) \
__isl_export \

View File

@ -316,6 +316,10 @@ __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_substitute(
enum isl_dim_type type, unsigned first, unsigned n,
__isl_keep isl_qpolynomial **subs);
__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_fix_val(
__isl_take isl_pw_qpolynomial_fold *pwf,
enum isl_dim_type type, unsigned n, __isl_take isl_val *v);
__isl_give isl_val *isl_qpolynomial_fold_eval(
__isl_take isl_qpolynomial_fold *fold, __isl_take isl_point *pnt);

View File

@ -5,10 +5,10 @@
#include <isl/union_map_type.h>
#include <isl/schedule_type.h>
#include <isl/aff_type.h>
#include <isl/band.h>
#include <isl/space.h>
#include <isl/set_type.h>
#include <isl/list.h>
#include <isl/printer_type.h>
#if defined(__cplusplus)
extern "C" {
@ -183,9 +183,6 @@ __isl_give isl_schedule *isl_schedule_expand(__isl_take isl_schedule *schedule,
__isl_take isl_union_pw_multi_aff *contraction,
__isl_take isl_schedule *expansion);
__isl_give isl_band_list *isl_schedule_get_band_forest(
__isl_keep isl_schedule *schedule);
__isl_give isl_schedule *isl_schedule_read_from_file(isl_ctx *ctx, FILE *input);
__isl_constructor
__isl_give isl_schedule *isl_schedule_read_from_str(isl_ctx *ctx,
@ -195,9 +192,6 @@ __isl_give isl_printer *isl_printer_print_schedule(__isl_take isl_printer *p,
void isl_schedule_dump(__isl_keep isl_schedule *schedule);
__isl_give char *isl_schedule_to_str(__isl_keep isl_schedule *schedule);
int isl_schedule_foreach_band(__isl_keep isl_schedule *sched,
int (*fn)(__isl_keep isl_band *band, void *user), void *user);
#if defined(__cplusplus)
}
#endif

View File

@ -37,6 +37,9 @@ isl_stat isl_schedule_node_foreach_descendant_top_down(
__isl_keep isl_schedule_node *node,
isl_bool (*fn)(__isl_keep isl_schedule_node *node, void *user),
void *user);
isl_bool isl_schedule_node_every_descendant(__isl_keep isl_schedule_node *node,
isl_bool (*test)(__isl_keep isl_schedule_node *node, void *user),
void *user);
isl_stat isl_schedule_node_foreach_ancestor_top_down(
__isl_keep isl_schedule_node *node,
isl_stat (*fn)(__isl_keep isl_schedule_node *node, void *user),

View File

@ -91,8 +91,8 @@ int isl_basic_set_is_rational(__isl_keep isl_basic_set *bset);
__isl_null isl_basic_set *isl_basic_set_free(__isl_take isl_basic_set *bset);
__isl_give isl_basic_set *isl_basic_set_copy(__isl_keep isl_basic_set *bset);
__isl_give isl_basic_set *isl_basic_set_empty(__isl_take isl_space *dim);
__isl_give isl_basic_set *isl_basic_set_universe(__isl_take isl_space *dim);
__isl_give isl_basic_set *isl_basic_set_empty(__isl_take isl_space *space);
__isl_give isl_basic_set *isl_basic_set_universe(__isl_take isl_space *space);
__isl_give isl_basic_set *isl_basic_set_nat_universe(__isl_take isl_space *dim);
__isl_give isl_basic_set *isl_basic_set_positive_orthant(
__isl_take isl_space *space);
@ -236,8 +236,8 @@ isl_bool isl_basic_set_is_subset(__isl_keep isl_basic_set *bset1,
isl_bool isl_basic_set_plain_is_equal(__isl_keep isl_basic_set *bset1,
__isl_keep isl_basic_set *bset2);
__isl_give isl_set *isl_set_empty(__isl_take isl_space *dim);
__isl_give isl_set *isl_set_universe(__isl_take isl_space *dim);
__isl_give isl_set *isl_set_empty(__isl_take isl_space *space);
__isl_give isl_set *isl_set_universe(__isl_take isl_space *space);
__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);
@ -312,9 +312,6 @@ __isl_give isl_set *isl_set_insert_dims(__isl_take isl_set *set,
enum isl_dim_type type, unsigned pos, unsigned n);
__isl_give isl_basic_set *isl_basic_set_add_dims(__isl_take isl_basic_set *bset,
enum isl_dim_type type, unsigned n);
ISL_DEPRECATED
__isl_give isl_basic_set *isl_basic_set_add(__isl_take isl_basic_set *bset,
enum isl_dim_type type, unsigned n);
__isl_give isl_set *isl_set_add_dims(__isl_take isl_set *set,
enum isl_dim_type type, unsigned n);
__isl_give isl_basic_set *isl_basic_set_move_dims(__isl_take isl_basic_set *bset,
@ -430,6 +427,17 @@ __isl_give isl_set *isl_set_gist_params(__isl_take isl_set *set,
isl_stat isl_set_dim_residue_class_val(__isl_keep isl_set *set,
int pos, __isl_give isl_val **modulo, __isl_give isl_val **residue);
struct isl_stride_info;
typedef struct isl_stride_info isl_stride_info;
__isl_give isl_val *isl_stride_info_get_stride(__isl_keep isl_stride_info *si);
__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);
__isl_give isl_stride_info *isl_set_get_stride_info(__isl_keep isl_set *set,
int pos);
__isl_export
__isl_give isl_val *isl_set_get_stride(__isl_keep isl_set *set, int pos);
__isl_export
__isl_give isl_set *isl_set_coalesce(__isl_take isl_set *set);

View File

@ -44,6 +44,9 @@ isl_bool isl_space_is_params(__isl_keep isl_space *space);
isl_bool isl_space_is_set(__isl_keep isl_space *space);
isl_bool isl_space_is_map(__isl_keep isl_space *space);
__isl_give isl_space *isl_space_add_param_id(__isl_take isl_space *space,
__isl_take isl_id *id);
__isl_give isl_space *isl_space_set_tuple_name(__isl_take isl_space *dim,
enum isl_dim_type type, const char *s);
isl_bool isl_space_has_tuple_name(__isl_keep isl_space *space,
@ -167,11 +170,11 @@ isl_bool isl_space_tuple_is_equal(__isl_keep isl_space *space1,
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_DEPRECATED
int isl_space_tuple_match(__isl_keep isl_space *space1, enum isl_dim_type type1,
__isl_keep isl_space *space2, enum isl_dim_type type2);
unsigned isl_space_dim(__isl_keep isl_space *dim, enum isl_dim_type type);
__isl_give isl_space *isl_space_flatten_domain(__isl_take isl_space *space);
__isl_give isl_space *isl_space_flatten_range(__isl_take isl_space *space);
__isl_give char *isl_space_to_str(__isl_keep isl_space *space);
__isl_give isl_printer *isl_printer_print_space(__isl_take isl_printer *p,
__isl_keep isl_space *dim);

View File

@ -24,7 +24,7 @@ __isl_give isl_union_map *isl_union_map_from_basic_map(
__isl_take isl_basic_map *bmap);
__isl_constructor
__isl_give isl_union_map *isl_union_map_from_map(__isl_take isl_map *map);
__isl_give isl_union_map *isl_union_map_empty(__isl_take isl_space *dim);
__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);
@ -55,8 +55,10 @@ __isl_give isl_union_map *isl_union_map_range_map(
__isl_take isl_union_map *umap);
__isl_give isl_union_map *isl_union_set_wrapped_domain_map(
__isl_take isl_union_set *uset);
__isl_export
__isl_give isl_union_map *isl_union_map_from_domain(
__isl_take isl_union_set *uset);
__isl_export
__isl_give isl_union_map *isl_union_map_from_range(
__isl_take isl_union_set *uset);
@ -196,9 +198,13 @@ __isl_give isl_union_map *isl_union_set_identity(__isl_take isl_union_set *uset)
__isl_give isl_union_map *isl_union_map_project_out(
__isl_take isl_union_map *umap,
enum isl_dim_type type, unsigned first, unsigned n);
__isl_export
__isl_give isl_union_map *isl_union_map_project_out_all_params(
__isl_take isl_union_map *umap);
__isl_give isl_union_map *isl_union_map_remove_divs(
__isl_take isl_union_map *bmap);
isl_bool isl_union_map_plain_is_empty(__isl_keep isl_union_map *umap);
__isl_export
isl_bool isl_union_map_is_empty(__isl_keep isl_union_map *umap);
__isl_export
@ -228,6 +234,11 @@ int 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_bool isl_union_map_every_map(__isl_keep isl_union_map *umap,
isl_bool (*test)(__isl_keep isl_map *map, void *user), void *user);
__isl_give isl_union_map *isl_union_map_remove_map_if(
__isl_take isl_union_map *umap,
isl_bool (*fn)(__isl_keep isl_map *map, void *user), void *user);
isl_bool isl_union_map_contains(__isl_keep isl_union_map *umap,
__isl_keep isl_space *space);
__isl_give isl_map *isl_union_map_extract_map(__isl_keep isl_union_map *umap,
@ -253,6 +264,7 @@ __isl_give isl_union_map *isl_union_map_lex_gt_union_map(
__isl_give isl_union_map *isl_union_map_lex_ge_union_map(
__isl_take isl_union_map *umap1, __isl_take isl_union_map *umap2);
__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);

View File

@ -16,7 +16,7 @@ __isl_give isl_union_set *isl_union_set_from_basic_set(
__isl_take isl_basic_set *bset);
__isl_constructor
__isl_give isl_union_set *isl_union_set_from_set(__isl_take isl_set *set);
__isl_give isl_union_set *isl_union_set_empty(__isl_take isl_space *dim);
__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);
@ -80,10 +80,13 @@ __isl_give isl_union_set *isl_union_set_gist_params(
__isl_export
__isl_give isl_union_set *isl_union_set_apply(
__isl_take isl_union_set *uset, __isl_take isl_union_map *umap);
__isl_overload
__isl_give isl_union_set *isl_union_set_preimage_multi_aff(
__isl_take isl_union_set *uset, __isl_take isl_multi_aff *ma);
__isl_overload
__isl_give isl_union_set *isl_union_set_preimage_pw_multi_aff(
__isl_take isl_union_set *uset, __isl_take isl_pw_multi_aff *pma);
__isl_overload
__isl_give isl_union_set *isl_union_set_preimage_union_pw_multi_aff(
__isl_take isl_union_set *uset,
__isl_take isl_union_pw_multi_aff *upma);

View File

@ -24,6 +24,7 @@ struct isl_vec;
typedef struct isl_vec isl_vec;
__isl_give isl_vec *isl_vec_alloc(isl_ctx *ctx, unsigned size);
__isl_give isl_vec *isl_vec_zero(isl_ctx *ctx, unsigned size);
__isl_give isl_vec *isl_vec_copy(__isl_keep isl_vec *vec);
__isl_null isl_vec *isl_vec_free(__isl_take isl_vec *vec);

View File

@ -1,95 +0,0 @@
/// These are automatically generated C++ bindings for isl.
///
/// isl is a library for computing with integer sets and maps described by
/// Presburger formulas. On top of this, isl provides various tools for
/// polyhedral compilation, ranging from dependence analysis over scheduling
/// to AST generation.
#ifndef ISL_CPP_NOEXCEPTIONS
#define ISL_CPP_NOEXCEPTIONS
#include <isl/aff.h>
#include <isl/ast_build.h>
#include <isl/flow.h>
#include <isl/ilp.h>
#include <isl/map.h>
#include <isl/schedule.h>
#include <isl/schedule_node.h>
#include <isl/set.h>
#include <isl/union_map.h>
#include <isl/union_set.h>
#include <isl/val.h>
#include <functional>
#include <string>
namespace isl {
inline namespace noexceptions {
#define ISLPP_STRINGIZE_(X) #X
#define ISLPP_STRINGIZE(X) ISLPP_STRINGIZE_(X)
#define ISLPP_ASSERT(test, message) \
do { \
if (test) \
break; \
fputs("Assertion \"" #test "\" failed at " __FILE__ \
":" ISLPP_STRINGIZE(__LINE__) "\n " message "\n", \
stderr); \
} while (0)
class boolean {
private:
isl_bool val;
friend isl::boolean manage(isl_bool val);
boolean(isl_bool val): val(val) {}
public:
boolean()
: val(isl_bool_error) {}
/* implicit */ boolean(bool val)
: val(val ? isl_bool_true : isl_bool_false) {}
bool is_error() const { return val == isl_bool_error; }
bool is_false() const { return val == isl_bool_false; }
bool is_true() const { return val == isl_bool_true; }
explicit operator bool() const {
ISLPP_ASSERT(!is_error(), "IMPLEMENTATION ERROR: Unhandled error state");
return is_true();
}
boolean operator!() const {
if (is_error())
return *this;
return !is_true();
}
};
inline isl::boolean manage(isl_bool val) {
return isl::boolean(val);
}
class ctx {
isl_ctx *ptr;
public:
/* implicit */ ctx(isl_ctx *ctx)
: ptr(ctx) {}
isl_ctx *release() {
auto tmp = ptr;
ptr = nullptr;
return tmp;
}
isl_ctx *get() {
return ptr;
}
};
enum class stat {
ok = isl_stat_ok,
error = isl_stat_error
};
}
} // namespace isl

View File

@ -0,0 +1,201 @@
# Copyright 2016-2017 Tobias Grosser
#
# Use of this software is governed by the MIT license
#
# Written by Tobias Grosser, Weststrasse 47, CH-8003, Zurich
import sys
import isl
# Test that isl objects can be constructed.
#
# This tests:
# - construction from a string
# - construction from an integer
# - static constructor without a parameter
# - conversion construction
#
# The tests to construct from integers and strings cover functionality that
# is also tested in the parameter type tests, but here the presence of
# multiple overloaded constructors and overload resolution is tested.
#
def test_constructors():
zero1 = isl.val("0")
assert(zero1.is_zero())
zero2 = isl.val(0)
assert(zero2.is_zero())
zero3 = isl.val.zero()
assert(zero3.is_zero())
bs = isl.basic_set("{ [1] }")
result = isl.set("{ [1] }")
s = isl.set(bs)
assert(s.is_equal(result))
# Test integer function parameters for a particular integer value.
#
def test_int(i):
val_int = isl.val(i)
val_str = isl.val(str(i))
assert(val_int.eq(val_str))
# Test integer function parameters.
#
# Verify that extreme values and zero work.
#
def test_parameters_int():
test_int(sys.maxsize)
test_int(-sys.maxsize - 1)
test_int(0)
# Test isl objects parameters.
#
# Verify that isl objects can be passed as lvalue and rvalue parameters.
# Also verify that isl object parameters are automatically type converted if
# there is an inheritance relation. Finally, test function calls without
# any additional parameters, apart from the isl object on which
# the method is called.
#
def test_parameters_obj():
a = isl.set("{ [0] }")
b = isl.set("{ [1] }")
c = isl.set("{ [2] }")
expected = isl.set("{ [i] : 0 <= i <= 2 }")
tmp = a.union(b)
res_lvalue_param = tmp.union(c)
assert(res_lvalue_param.is_equal(expected))
res_rvalue_param = a.union(b).union(c)
assert(res_rvalue_param.is_equal(expected))
a2 = isl.basic_set("{ [0] }")
assert(a.is_equal(a2))
two = isl.val(2)
half = isl.val("1/2")
res_only_this_param = two.inv()
assert(res_only_this_param.eq(half))
# Test different kinds of parameters to be passed to functions.
#
# This includes integer and isl object parameters.
#
def test_parameters():
test_parameters_int()
test_parameters_obj()
# Test that isl objects are returned correctly.
#
# This only tests that after combining two objects, the result is successfully
# returned.
#
def test_return_obj():
one = isl.val("1")
two = isl.val("2")
three = isl.val("3")
res = one.add(two)
assert(res.eq(three))
# Test that integer values are returned correctly.
#
def test_return_int():
one = isl.val("1")
neg_one = isl.val("-1")
zero = isl.val("0")
assert(one.sgn() > 0)
assert(neg_one.sgn() < 0)
assert(zero.sgn() == 0)
# Test that isl_bool values are returned correctly.
#
# In particular, check the conversion to bool in case of true and false.
#
def test_return_bool():
empty = isl.set("{ : false }")
univ = isl.set("{ : }")
b_true = empty.is_empty()
b_false = univ.is_empty()
assert(b_true)
assert(not b_false)
# Test that strings are returned correctly.
# Do so by calling overloaded isl.ast_build.from_expr methods.
#
def test_return_string():
context = isl.set("[n] -> { : }")
build = isl.ast_build.from_context(context)
pw_aff = isl.pw_aff("[n] -> { [n] }")
set = isl.set("[n] -> { : n >= 0 }")
expr = build.expr_from(pw_aff)
expected_string = "n"
assert(expected_string == expr.to_C_str())
expr = build.expr_from(set)
expected_string = "n >= 0"
assert(expected_string == expr.to_C_str())
# Test that return values are handled correctly.
#
# Test that isl objects, integers, boolean values, and strings are
# returned correctly.
#
def test_return():
test_return_obj()
test_return_int()
test_return_bool()
test_return_string()
# Test that foreach functions are modeled correctly.
#
# Verify that closures are correctly called as callback of a 'foreach'
# function and that variables captured by the closure work correctly. Also
# check that the foreach function handles exceptions thrown from
# the closure and that it propagates the exception.
#
def test_foreach():
s = isl.set("{ [0]; [1]; [2] }")
list = []
def add(bs):
list.append(bs)
s.foreach_basic_set(add)
assert(len(list) == 3)
assert(list[0].is_subset(s))
assert(list[1].is_subset(s))
assert(list[2].is_subset(s))
assert(not list[0].is_equal(list[1]))
assert(not list[0].is_equal(list[2]))
assert(not list[1].is_equal(list[2]))
def fail(bs):
raise "fail"
caught = False
try:
s.foreach_basic_set(fail)
except:
caught = True
assert(caught)
# Test the isl Python interface
#
# This includes:
# - Object construction
# - Different parameter types
# - Different return types
# - Foreach functions
#
test_constructors()
test_parameters()
test_return()
test_foreach()

View File

@ -1,100 +0,0 @@
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)

View File

@ -27,7 +27,6 @@
#include <isl_seq.h>
#include <isl/set.h>
#include <isl_val_private.h>
#include <isl/deprecated/aff_int.h>
#include <isl_config.h>
#undef BASE
@ -225,6 +224,30 @@ __isl_give isl_pw_aff *isl_pw_aff_var_on_domain(__isl_take isl_local_space *ls,
return isl_pw_aff_from_aff(isl_aff_var_on_domain(ls, type, pos));
}
/* Return an affine expression that is equal to the parameter
* in the domain space "space" with identifier "id".
*/
__isl_give isl_aff *isl_aff_param_on_domain_space_id(
__isl_take isl_space *space, __isl_take isl_id *id)
{
int pos;
isl_local_space *ls;
if (!space || !id)
goto error;
pos = isl_space_find_dim_by_id(space, isl_dim_param, id);
if (pos < 0)
isl_die(isl_space_get_ctx(space), isl_error_invalid,
"parameter not found in space", goto error);
isl_id_free(id);
ls = isl_local_space_from_space(space);
return isl_aff_var_on_domain(ls, isl_dim_param, pos);
error:
isl_space_free(space);
isl_id_free(id);
return NULL;
}
__isl_give isl_aff *isl_aff_copy(__isl_keep isl_aff *aff)
{
if (!aff)
@ -356,6 +379,59 @@ __isl_give isl_local_space *isl_aff_get_local_space(__isl_keep isl_aff *aff)
return ls;
}
/* Return the local space of the domain of "aff".
* This may be either a copy or the local space itself
* if there is only one reference to "aff".
* This allows the local space to be modified inplace
* if both the expression and its local space have only a single reference.
* The caller is not allowed to modify "aff" between this call and
* a subsequent call to isl_aff_restore_domain_local_space.
* The only exception is that isl_aff_free can be called instead.
*/
__isl_give isl_local_space *isl_aff_take_domain_local_space(
__isl_keep isl_aff *aff)
{
isl_local_space *ls;
if (!aff)
return NULL;
if (aff->ref != 1)
return isl_aff_get_domain_local_space(aff);
ls = aff->ls;
aff->ls = NULL;
return ls;
}
/* Set the local space of the domain of "aff" to "ls",
* where the local space of "aff" may be missing
* due to a preceding call to isl_aff_take_domain_local_space.
* However, in this case, "aff" only has a single reference and
* then the call to isl_aff_cow has no effect.
*/
__isl_give isl_aff *isl_aff_restore_domain_local_space(
__isl_keep isl_aff *aff, __isl_take isl_local_space *ls)
{
if (!aff || !ls)
goto error;
if (aff->ls == ls) {
isl_local_space_free(ls);
return aff;
}
aff = isl_aff_cow(aff);
if (!aff)
goto error;
isl_local_space_free(aff->ls);
aff->ls = ls;
return aff;
error:
isl_aff_free(aff);
isl_local_space_free(ls);
return NULL;
}
/* Externally, an isl_aff has a map space, but internally, the
* ls field corresponds to the domain of that space.
*/
@ -565,21 +641,6 @@ __isl_give isl_val *isl_aff_get_denominator_val(__isl_keep isl_aff *aff)
return isl_val_int_from_isl_int(ctx, aff->v->el[0]);
}
/* Return the constant term of "aff" in "v".
*
* We cannot return anything meaningful in case of a NaN.
*/
int isl_aff_get_constant(__isl_keep isl_aff *aff, isl_int *v)
{
if (!aff)
return -1;
if (isl_aff_is_nan(aff))
isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
"cannot get constant term of NaN", return -1);
isl_int_set(*v, aff->v->el[1]);
return 0;
}
/* Return the constant term of "aff".
*/
__isl_give isl_val *isl_aff_get_constant_val(__isl_keep isl_aff *aff)
@ -597,37 +658,6 @@ __isl_give isl_val *isl_aff_get_constant_val(__isl_keep isl_aff *aff)
return isl_val_normalize(v);
}
/* Return the coefficient of the variable of type "type" at position "pos"
* of "aff" in "v".
*
* We cannot return anything meaningful in case of a NaN.
*/
int isl_aff_get_coefficient(__isl_keep isl_aff *aff,
enum isl_dim_type type, int pos, isl_int *v)
{
if (!aff)
return -1;
if (type == isl_dim_out)
isl_die(aff->v->ctx, isl_error_invalid,
"output/set dimension does not have a coefficient",
return -1);
if (type == isl_dim_in)
type = isl_dim_set;
if (pos >= isl_local_space_dim(aff->ls, type))
isl_die(aff->v->ctx, isl_error_invalid,
"position out of bounds", return -1);
if (isl_aff_is_nan(aff))
isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
"cannot get coefficient of NaN", return -1);
pos += isl_local_space_offset(aff->ls, type);
isl_int_set(*v, aff->v->el[1 + pos]);
return 0;
}
/* Return the coefficient of the variable of type "type" at position "pos"
* of "aff".
*/
@ -686,29 +716,6 @@ int isl_aff_coefficient_sgn(__isl_keep isl_aff *aff, enum isl_dim_type type,
return isl_int_sgn(aff->v->el[1 + pos]);
}
/* Replace the denominator of "aff" by "v".
*
* A NaN is unaffected by this operation.
*/
__isl_give isl_aff *isl_aff_set_denominator(__isl_take isl_aff *aff, isl_int v)
{
if (!aff)
return NULL;
if (isl_aff_is_nan(aff))
return aff;
aff = isl_aff_cow(aff);
if (!aff)
return NULL;
aff->v = isl_vec_cow(aff->v);
if (!aff->v)
return isl_aff_free(aff);
isl_int_set(aff->v->el[0], v);
return aff;
}
/* Replace the numerator of the constant term of "aff" by "v".
*
* A NaN is unaffected by this operation.
@ -1548,23 +1555,6 @@ __isl_give isl_aff *isl_aff_floor(__isl_take isl_aff *aff)
return aff;
}
/* Compute
*
* aff mod m = aff - m * floor(aff/m)
*/
__isl_give isl_aff *isl_aff_mod(__isl_take isl_aff *aff, isl_int m)
{
isl_aff *res;
res = isl_aff_copy(aff);
aff = isl_aff_scale_down(aff, m);
aff = isl_aff_floor(aff);
aff = isl_aff_scale(aff, m);
res = isl_aff_sub(res, aff);
return res;
}
/* Compute
*
* aff mod m = aff - m * floor(aff/m)
@ -2488,6 +2478,20 @@ __isl_give isl_aff *isl_aff_project_domain_on_params(__isl_take isl_aff *aff)
return aff;
}
/* Convert an affine expression defined over a parameter domain
* into one that is defined over a zero-dimensional set.
*/
__isl_give isl_aff *isl_aff_from_range(__isl_take isl_aff *aff)
{
isl_local_space *ls;
ls = isl_aff_take_domain_local_space(aff);
ls = isl_local_space_set_from_params(ls);
aff = isl_aff_restore_domain_local_space(aff, ls);
return aff;
}
__isl_give isl_aff *isl_aff_insert_dims(__isl_take isl_aff *aff,
enum isl_dim_type type, unsigned first, unsigned n)
{
@ -3829,6 +3833,7 @@ error:
#include <isl_multi_templ.c>
#include <isl_multi_apply_set.c>
#include <isl_multi_cmp.c>
#include <isl_multi_dims.c>
#include <isl_multi_floor.c>
#include <isl_multi_gist.c>
@ -6272,6 +6277,7 @@ error:
#include <isl_multi_templ.c>
#include <isl_multi_apply_set.c>
#include <isl_multi_coalesce.c>
#include <isl_multi_dims.c>
#include <isl_multi_gist.c>
#include <isl_multi_hash.c>
#include <isl_multi_intersect.c>
@ -7540,7 +7546,7 @@ static isl_stat reset_params(__isl_take isl_pw_aff *pa, void *user)
isl_space *space;
space = isl_pw_aff_get_space(pa);
space = isl_space_replace(space, isl_dim_param, data->space);
space = isl_space_replace_params(space, data->space);
pa = isl_pw_aff_reset_space(pa, space);
data->res = isl_union_pw_aff_add_pw_aff(data->res, pa);
@ -7626,36 +7632,6 @@ error:
return NULL;
}
/* Internal data structure for isl_union_pw_aff_aff_on_domain.
* "aff" is the symbolic value that the resulting isl_union_pw_aff
* needs to attain.
* "res" collects the results.
*/
struct isl_union_pw_aff_aff_on_domain_data {
isl_aff *aff;
isl_union_pw_aff *res;
};
/* Construct a piecewise affine expression that is equal to data->aff
* on "domain" and add the result to data->res.
*/
static isl_stat pw_aff_aff_on_domain(__isl_take isl_set *domain, void *user)
{
struct isl_union_pw_aff_aff_on_domain_data *data = user;
isl_pw_aff *pa;
isl_aff *aff;
int dim;
aff = isl_aff_copy(data->aff);
dim = isl_set_dim(domain, isl_dim_set);
aff = isl_aff_add_dims(aff, isl_dim_in, dim);
aff = isl_aff_reset_domain_space(aff, isl_set_get_space(domain));
pa = isl_pw_aff_alloc(domain, aff);
data->res = isl_union_pw_aff_add_pw_aff(data->res, pa);
return data->res ? isl_stat_ok : isl_stat_error;
}
/* Internal data structure for isl_union_pw_multi_aff_get_union_pw_aff.
* pos is the output position that needs to be extracted.
* res collects the results.
@ -7719,33 +7695,129 @@ __isl_give isl_union_pw_aff *isl_union_pw_multi_aff_get_union_pw_aff(
/* Return a union piecewise affine expression
* that is equal to "aff" on "domain".
*
* Construct an isl_pw_aff on each of the sets in "domain" and
* collect the results.
*/
__isl_give isl_union_pw_aff *isl_union_pw_aff_aff_on_domain(
__isl_take isl_union_set *domain, __isl_take isl_aff *aff)
{
struct isl_union_pw_aff_aff_on_domain_data data;
isl_space *space;
isl_pw_aff *pa;
if (!domain || !aff)
goto error;
if (!isl_local_space_is_params(aff->ls))
isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
"expecting parametric expression", goto error);
pa = isl_pw_aff_from_aff(aff);
return isl_union_pw_aff_pw_aff_on_domain(domain, pa);
}
/* Return a union piecewise affine expression
* that is equal to the parameter identified by "id" on "domain".
*
* Make sure the parameter appears in the space passed to
* isl_aff_param_on_domain_space_id.
*/
__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_space *space;
isl_aff *aff;
space = isl_union_set_get_space(domain);
space = isl_space_add_param_id(space, isl_id_copy(id));
aff = isl_aff_param_on_domain_space_id(space, id);
return isl_union_pw_aff_aff_on_domain(domain, aff);
}
/* Internal data structure for isl_union_pw_aff_pw_aff_on_domain.
* "pa" is the piecewise symbolic value that the resulting isl_union_pw_aff
* needs to attain.
* "res" collects the results.
*/
struct isl_union_pw_aff_pw_aff_on_domain_data {
isl_pw_aff *pa;
isl_union_pw_aff *res;
};
/* Construct a piecewise affine expression that is equal to data->pa
* on "domain" and add the result to data->res.
*/
static isl_stat pw_aff_on_domain(__isl_take isl_set *domain, void *user)
{
struct isl_union_pw_aff_pw_aff_on_domain_data *data = user;
isl_pw_aff *pa;
int dim;
pa = isl_pw_aff_copy(data->pa);
dim = isl_set_dim(domain, isl_dim_set);
pa = isl_pw_aff_from_range(pa);
pa = isl_pw_aff_add_dims(pa, isl_dim_in, dim);
pa = isl_pw_aff_reset_domain_space(pa, isl_set_get_space(domain));
pa = isl_pw_aff_intersect_domain(pa, domain);
data->res = isl_union_pw_aff_add_pw_aff(data->res, pa);
return data->res ? isl_stat_ok : isl_stat_error;
}
/* Return a union piecewise affine expression
* that is equal to "pa" on "domain", assuming "domain" and "pa"
* have been aligned.
*
* Construct an isl_pw_aff on each of the sets in "domain" and
* collect the results.
*/
static __isl_give isl_union_pw_aff *isl_union_pw_aff_pw_aff_on_domain_aligned(
__isl_take isl_union_set *domain, __isl_take isl_pw_aff *pa)
{
struct isl_union_pw_aff_pw_aff_on_domain_data data;
isl_space *space;
space = isl_union_set_get_space(domain);
data.res = isl_union_pw_aff_empty(space);
data.aff = aff;
if (isl_union_set_foreach_set(domain, &pw_aff_aff_on_domain, &data) < 0)
data.pa = pa;
if (isl_union_set_foreach_set(domain, &pw_aff_on_domain, &data) < 0)
data.res = isl_union_pw_aff_free(data.res);
isl_union_set_free(domain);
isl_aff_free(aff);
isl_pw_aff_free(pa);
return data.res;
}
/* Return a union piecewise affine expression
* that is equal to "pa" on "domain".
*
* Check that "pa" is a parametric expression,
* align the parameters if needed and call
* isl_union_pw_aff_pw_aff_on_domain_aligned.
*/
__isl_give isl_union_pw_aff *isl_union_pw_aff_pw_aff_on_domain(
__isl_take isl_union_set *domain, __isl_take isl_pw_aff *pa)
{
isl_bool is_set;
isl_bool equal_params;
isl_space *domain_space, *pa_space;
pa_space = isl_pw_aff_peek_space(pa);
is_set = isl_space_is_set(pa_space);
if (is_set < 0)
goto error;
if (!is_set)
isl_die(isl_pw_aff_get_ctx(pa), isl_error_invalid,
"expecting parametric expression", goto error);
domain_space = isl_union_set_get_space(domain);
pa_space = isl_pw_aff_get_space(pa);
equal_params = isl_space_has_equal_params(domain_space, pa_space);
if (equal_params >= 0 && !equal_params) {
isl_space *space;
space = isl_space_align_params(domain_space, pa_space);
pa = isl_pw_aff_align_params(pa, isl_space_copy(space));
domain = isl_union_set_align_params(domain, space);
} else {
isl_space_free(domain_space);
isl_space_free(pa_space);
}
if (equal_params < 0)
goto error;
return isl_union_pw_aff_pw_aff_on_domain_aligned(domain, pa);
error:
isl_union_set_free(domain);
isl_aff_free(aff);
isl_pw_aff_free(pa);
return NULL;
}
@ -7993,7 +8065,6 @@ error:
#define DOMBASE union_set
#define NO_MOVE_DIMS
#define NO_DIMS
#define NO_DOMAIN
#define NO_PRODUCT
#define NO_SPLICE
@ -8014,14 +8085,22 @@ error:
*
* Since there is no canonical zero value for
* a union piecewise affine expression, we can only construct
* zero-dimensional "zero" value.
* a zero-dimensional "zero" value.
*/
__isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_zero(
__isl_take isl_space *space)
{
isl_bool params;
if (!space)
return NULL;
params = isl_space_is_params(space);
if (params < 0)
goto error;
if (params)
isl_die(isl_space_get_ctx(space), isl_error_invalid,
"expecting proper set space", goto error);
if (!isl_space_is_set(space))
isl_die(isl_space_get_ctx(space), isl_error_invalid,
"expecting set space", goto error);
@ -8261,66 +8340,81 @@ error:
return NULL;
}
/* Return a multiple union piecewise affine expression
* that is equal to "ma" on "domain", assuming "domain" and "ma"
* have been aligned.
*/
static __isl_give isl_multi_union_pw_aff *
isl_multi_union_pw_aff_multi_aff_on_domain_aligned(
__isl_take isl_union_set *domain, __isl_take isl_multi_aff *ma)
{
int i, n;
isl_space *space;
isl_multi_union_pw_aff *mupa;
if (!domain || !ma)
goto error;
n = isl_multi_aff_dim(ma, isl_dim_set);
space = isl_multi_aff_get_space(ma);
mupa = isl_multi_union_pw_aff_alloc(space);
for (i = 0; i < n; ++i) {
isl_aff *aff;
isl_union_pw_aff *upa;
aff = isl_multi_aff_get_aff(ma, i);
upa = isl_union_pw_aff_aff_on_domain(isl_union_set_copy(domain),
aff);
mupa = isl_multi_union_pw_aff_set_union_pw_aff(mupa, i, upa);
}
isl_union_set_free(domain);
isl_multi_aff_free(ma);
return mupa;
error:
isl_union_set_free(domain);
isl_multi_aff_free(ma);
return NULL;
}
/* Return a multiple union piecewise affine expression
* that is equal to "ma" on "domain".
*/
__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_bool equal_params;
isl_pw_multi_aff *pma;
if (!domain || !ma)
pma = isl_pw_multi_aff_from_multi_aff(ma);
return isl_multi_union_pw_aff_pw_multi_aff_on_domain(domain, pma);
}
/* Return a multiple union piecewise affine expression
* that is equal to "pma" on "domain", assuming "domain" and "pma"
* have been aligned.
*/
static __isl_give isl_multi_union_pw_aff *
isl_multi_union_pw_aff_pw_multi_aff_on_domain_aligned(
__isl_take isl_union_set *domain, __isl_take isl_pw_multi_aff *pma)
{
int i, n;
isl_space *space;
isl_multi_union_pw_aff *mupa;
if (!domain || !pma)
goto error;
equal_params = isl_space_has_equal_params(domain->dim, ma->space);
n = isl_pw_multi_aff_dim(pma, isl_dim_set);
space = isl_pw_multi_aff_get_space(pma);
mupa = isl_multi_union_pw_aff_alloc(space);
for (i = 0; i < n; ++i) {
isl_pw_aff *pa;
isl_union_pw_aff *upa;
pa = isl_pw_multi_aff_get_pw_aff(pma, i);
upa = isl_union_pw_aff_pw_aff_on_domain(
isl_union_set_copy(domain), pa);
mupa = isl_multi_union_pw_aff_set_union_pw_aff(mupa, i, upa);
}
isl_union_set_free(domain);
isl_pw_multi_aff_free(pma);
return mupa;
error:
isl_union_set_free(domain);
isl_pw_multi_aff_free(pma);
return NULL;
}
/* Return a multiple union piecewise affine expression
* that is equal to "pma" on "domain".
*/
__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_bool equal_params;
isl_space *space;
space = isl_pw_multi_aff_peek_space(pma);
equal_params = isl_union_set_space_has_equal_params(domain, space);
if (equal_params < 0)
goto error;
if (equal_params)
return isl_multi_union_pw_aff_multi_aff_on_domain_aligned(
domain, ma);
return isl_multi_union_pw_aff_pw_multi_aff_on_domain_aligned(
domain, pma);
domain = isl_union_set_align_params(domain,
isl_multi_aff_get_space(ma));
ma = isl_multi_aff_align_params(ma, isl_union_set_get_space(domain));
return isl_multi_union_pw_aff_multi_aff_on_domain_aligned(domain, ma);
isl_pw_multi_aff_get_space(pma));
pma = isl_pw_multi_aff_align_params(pma,
isl_union_set_get_space(domain));
return isl_multi_union_pw_aff_pw_multi_aff_on_domain_aligned(domain,
pma);
error:
isl_union_set_free(domain);
isl_multi_aff_free(ma);
isl_pw_multi_aff_free(pma);
return NULL;
}

View File

@ -73,7 +73,6 @@ __isl_give isl_aff *isl_aff_reset_domain_space(__isl_take isl_aff *aff,
__isl_give isl_aff *isl_aff_realign_domain(__isl_take isl_aff *aff,
__isl_take isl_reordering *r);
int isl_aff_get_constant(__isl_keep isl_aff *aff, isl_int *v);
__isl_give isl_aff *isl_aff_set_constant(__isl_take isl_aff *aff, isl_int v);
__isl_give isl_aff *isl_aff_set_coefficient(__isl_take isl_aff *aff,
enum isl_dim_type type, int pos, isl_int v);
@ -102,6 +101,7 @@ __isl_give isl_pw_aff *isl_pw_aff_set_rational(__isl_take isl_pw_aff *pwaff);
__isl_give isl_pw_aff_list *isl_pw_aff_list_set_rational(
__isl_take isl_pw_aff_list *list);
__isl_give isl_aff *isl_aff_scale_down(__isl_take isl_aff *aff, isl_int f);
__isl_give isl_pw_aff *isl_pw_aff_scale(__isl_take isl_pw_aff *pwaff,
isl_int f);
__isl_give isl_pw_aff *isl_pw_aff_scale_down(__isl_take isl_pw_aff *pwaff,

View File

@ -9,6 +9,7 @@
#include <string.h>
#include <isl/val.h>
#include <isl_ast_private.h>
#undef BASE

View File

@ -10,6 +10,8 @@
* B.P. 105 - 78153 Le Chesnay, France
*/
#include <isl/val.h>
#include <isl/space.h>
#include <isl/map.h>
#include <isl/aff.h>
#include <isl/constraint.h>
@ -93,7 +95,7 @@ static __isl_give isl_id *generate_name(isl_ctx *ctx, int i,
__isl_keep isl_ast_build *build)
{
int j;
char name[16];
char name[23];
isl_set *dom = build->domain;
snprintf(name, sizeof(name), "c%d", i);
@ -1180,9 +1182,14 @@ __isl_give isl_space *isl_ast_build_get_space(__isl_keep isl_ast_build *build,
dim = isl_set_dim(build->domain, isl_dim_set);
space = isl_space_drop_dims(space, isl_dim_set,
build->depth, dim - build->depth);
for (i = build->depth - 1; i >= 0; --i)
if (isl_ast_build_has_affine_value(build, i))
for (i = build->depth - 1; i >= 0; --i) {
isl_bool affine = isl_ast_build_has_affine_value(build, i);
if (affine < 0)
return isl_space_free(space);
if (affine)
space = isl_space_drop_dims(space, isl_dim_set, i, 1);
}
return space;
}
@ -1254,30 +1261,6 @@ __isl_give isl_id *isl_ast_build_get_iterator_id(
/* Set the stride and offset of the current dimension to the given
* value and expression.
*
* If we had already found a stride before, then the two strides
* are combined into a single stride.
*
* In particular, if the new stride information is of the form
*
* i = f + s (...)
*
* and the old stride information is of the form
*
* i = f2 + s2 (...)
*
* then we compute the extended gcd of s and s2
*
* a s + b s2 = g,
*
* with g = gcd(s,s2), multiply the first equation with t1 = b s2/g
* and the second with t2 = a s1/g.
* This results in
*
* i = (b s2 + a s1)/g i = t1 f + t2 f2 + (s s2)/g (...)
*
* so that t1 f + t2 f2 is the combined offset and (s s2)/g = lcm(s,s2)
* is the combined stride.
*/
static __isl_give isl_ast_build *set_stride(__isl_take isl_ast_build *build,
__isl_take isl_val *stride, __isl_take isl_aff *offset)
@ -1290,25 +1273,6 @@ static __isl_give isl_ast_build *set_stride(__isl_take isl_ast_build *build,
pos = build->depth;
if (isl_ast_build_has_stride(build, pos)) {
isl_val *stride2, *a, *b, *g;
isl_aff *offset2;
stride2 = isl_vec_get_element_val(build->strides, pos);
g = isl_val_gcdext(isl_val_copy(stride), isl_val_copy(stride2),
&a, &b);
a = isl_val_mul(a, isl_val_copy(stride));
a = isl_val_div(a, isl_val_copy(g));
stride2 = isl_val_div(stride2, g);
b = isl_val_mul(b, isl_val_copy(stride2));
stride = isl_val_mul(stride, stride2);
offset2 = isl_multi_aff_get_aff(build->offsets, pos);
offset2 = isl_aff_scale_val(offset2, a);
offset = isl_aff_scale_val(offset, b);
offset = isl_aff_add(offset, offset2);
}
build->strides = isl_vec_set_element_val(build->strides, pos, stride);
build->offsets = isl_multi_aff_set_aff(build->offsets, pos, offset);
if (!build->strides || !build->offsets)
@ -1424,134 +1388,44 @@ __isl_give isl_ast_build *isl_ast_build_include_stride(
return build;
}
/* Information used inside detect_stride.
*
* "build" may be updated by detect_stride to include stride information.
* "pos" is equal to build->depth.
*/
struct isl_detect_stride_data {
isl_ast_build *build;
int pos;
};
/* Check if constraint "c" imposes any stride on dimension data->pos
* and, if so, update the stride information in data->build.
*
* In order to impose a stride on the dimension, "c" needs to be an equality
* and it needs to involve the dimension. Note that "c" may also be
* a div constraint and thus an inequality that we cannot use.
*
* Let c be of the form
*
* h(p) + g * v * i + g * stride * f(alpha) = 0
*
* with h(p) an expression in terms of the parameters and outer dimensions
* and f(alpha) an expression in terms of the existentially quantified
* variables. Note that the inner dimensions have been eliminated so
* they do not appear in "c".
*
* If "stride" is not zero and not one, then it represents a non-trivial stride
* on "i". We compute a and b such that
*
* a v + b stride = 1
*
* We have
*
* g v i = -h(p) + g stride f(alpha)
*
* a g v i = -a h(p) + g stride f(alpha)
*
* a g v i + b g stride i = -a h(p) + g stride * (...)
*
* g i = -a h(p) + g stride * (...)
*
* i = -a h(p)/g + stride * (...)
*
* The expression "-a h(p)/g" can therefore be used as offset.
*/
static isl_stat detect_stride(__isl_take isl_constraint *c, void *user)
{
struct isl_detect_stride_data *data = user;
int i, n_div;
isl_ctx *ctx;
isl_val *v, *stride, *m;
if (!isl_constraint_is_equality(c) ||
!isl_constraint_involves_dims(c, isl_dim_set, data->pos, 1)) {
isl_constraint_free(c);
return isl_stat_ok;
}
ctx = isl_constraint_get_ctx(c);
stride = isl_val_zero(ctx);
n_div = isl_constraint_dim(c, isl_dim_div);
for (i = 0; i < n_div; ++i) {
v = isl_constraint_get_coefficient_val(c, isl_dim_div, i);
stride = isl_val_gcd(stride, v);
}
v = isl_constraint_get_coefficient_val(c, isl_dim_set, data->pos);
m = isl_val_gcd(isl_val_copy(stride), isl_val_copy(v));
stride = isl_val_div(stride, isl_val_copy(m));
v = isl_val_div(v, isl_val_copy(m));
if (!isl_val_is_zero(stride) && !isl_val_is_one(stride)) {
isl_aff *aff;
isl_val *gcd, *a, *b;
gcd = isl_val_gcdext(v, isl_val_copy(stride), &a, &b);
isl_val_free(gcd);
isl_val_free(b);
aff = isl_constraint_get_aff(c);
for (i = 0; i < n_div; ++i)
aff = isl_aff_set_coefficient_si(aff,
isl_dim_div, i, 0);
aff = isl_aff_set_coefficient_si(aff, isl_dim_in, data->pos, 0);
a = isl_val_neg(a);
aff = isl_aff_scale_val(aff, a);
aff = isl_aff_scale_down_val(aff, m);
data->build = set_stride(data->build, stride, aff);
} else {
isl_val_free(stride);
isl_val_free(m);
isl_val_free(v);
}
isl_constraint_free(c);
return isl_stat_ok;
}
/* Check if the constraints in "set" imply any stride on the current
* dimension and, if so, record the stride information in "build"
* and return the updated "build".
*
* We compute the affine hull and then check if any of the constraints
* in the hull imposes any stride on the current dimension.
*
* We assume that inner dimensions have been eliminated from "set"
* by the caller. This is needed because the common stride
* may be imposed by different inner dimensions on different parts of
* the domain.
* The assumption ensures that the lower bound does not depend
* on inner dimensions.
*/
__isl_give isl_ast_build *isl_ast_build_detect_strides(
__isl_take isl_ast_build *build, __isl_take isl_set *set)
{
isl_basic_set *hull;
struct isl_detect_stride_data data;
int pos;
isl_bool no_stride;
isl_val *stride;
isl_aff *offset;
isl_stride_info *si;
if (!build)
goto error;
data.build = build;
data.pos = isl_ast_build_get_depth(build);
hull = isl_set_affine_hull(set);
pos = isl_ast_build_get_depth(build);
si = isl_set_get_stride_info(set, pos);
stride = isl_stride_info_get_stride(si);
offset = isl_stride_info_get_offset(si);
isl_stride_info_free(si);
isl_set_free(set);
if (isl_basic_set_foreach_constraint(hull, &detect_stride, &data) < 0)
data.build = isl_ast_build_free(data.build);
isl_basic_set_free(hull);
return data.build;
no_stride = isl_val_is_one(stride);
if (no_stride >= 0 && !no_stride)
return set_stride(build, stride, offset);
isl_val_free(stride);
isl_aff_free(offset);
if (no_stride < 0)
return isl_ast_build_free(build);
return build;
error:
isl_set_free(set);
return NULL;
@ -2088,23 +1962,20 @@ __isl_give isl_aff *isl_ast_build_get_offset(
* Otherwise, it is set to the requested expression in terms of
* outer dimensions and parameters.
*/
int isl_ast_build_has_affine_value(__isl_keep isl_ast_build *build,
isl_bool isl_ast_build_has_affine_value(__isl_keep isl_ast_build *build,
int pos)
{
isl_aff *aff;
int involves;
isl_bool involves;
if (!build)
return -1;
return isl_bool_error;
aff = isl_multi_aff_get_aff(build->values, pos);
involves = isl_aff_involves_dims(aff, isl_dim_in, pos, 1);
isl_aff_free(aff);
if (involves < 0)
return -1;
return !involves;
return isl_bool_not(involves);
}
/* Plug in the known values (fixed affine expressions in terms of

View File

@ -10,8 +10,10 @@
* B.P. 105 - 78153 Le Chesnay, France
*/
#include <isl/space.h>
#include <isl/constraint.h>
#include <isl/ilp.h>
#include <isl/val.h>
#include <isl_ast_build_expr.h>
#include <isl_ast_private.h>
#include <isl_ast_build_private.h>

View File

@ -250,7 +250,8 @@ __isl_give isl_multi_aff *isl_ast_build_get_schedule_map_multi_aff(
__isl_keep isl_ast_build *build);
__isl_give isl_map *isl_ast_build_get_schedule_map(
__isl_keep isl_ast_build *build);
int isl_ast_build_has_affine_value(__isl_keep isl_ast_build *build, int pos);
isl_bool isl_ast_build_has_affine_value(__isl_keep isl_ast_build *build,
int pos);
int isl_ast_build_has_value(__isl_keep isl_ast_build *build);
__isl_give isl_id *isl_ast_build_get_iterator_id(
__isl_keep isl_ast_build *build, int pos);

View File

@ -11,6 +11,8 @@
*/
#include <limits.h>
#include <isl/val.h>
#include <isl/space.h>
#include <isl/aff.h>
#include <isl/constraint.h>
#include <isl/set.h>
@ -1453,7 +1455,8 @@ static __isl_give isl_ast_graft *create_node_scaled(
__isl_take isl_ast_build *build)
{
int depth;
int degenerate, eliminated;
int degenerate;
isl_bool eliminated;
isl_basic_set *hull;
isl_basic_set *enforced;
isl_set *guard, *hoisted;
@ -3521,6 +3524,12 @@ static __isl_give isl_ast_graft_list *generate_shifted_component_only_after(
* to the isolated domain).
* We generate an AST for each piece and concatenate the results.
*
* If the isolated domain is not convex, then it is replaced
* by a convex superset to ensure that the sets of preceding and
* following iterations are properly defined and, in particular,
* that there are no intermediate iterations that do not belong
* to the isolated domain.
*
* In the special case where at least one element of the schedule
* domain that does not belong to the isolated domain needs
* to be scheduled after this isolated domain, but none of those
@ -5171,7 +5180,7 @@ static __isl_give isl_ast_graft_list *hoist_out_of_context(
* to the domain elements executed by those iterations.
*
* The context node may introduce additional parameters as well as
* constraints on the outer schedule dimenions or original parameters.
* constraints on the outer schedule dimensions or original parameters.
*
* We add the extra parameters to a new build and the context
* constraints to both the build and (as a single disjunct)
@ -5735,6 +5744,8 @@ __isl_give isl_ast_node *isl_ast_build_node_from_schedule(
ctx = isl_ast_build_get_ctx(build);
node = isl_schedule_get_root(schedule);
if (!node)
goto error;
isl_schedule_free(schedule);
build = isl_ast_build_copy(build);

View File

@ -10,6 +10,7 @@
* B.P. 105 - 78153 Le Chesnay, France
*/
#include <isl/space.h>
#include <isl_ast_private.h>
#include <isl_ast_build_expr.h>
#include <isl_ast_build_private.h>
@ -1230,6 +1231,7 @@ __isl_give isl_ast_graft_list *isl_ast_graft_list_merge(
disjoint = isl_set_is_disjoint(graft->guard,
list1->p[j - 1]->guard);
if (disjoint < 0) {
isl_ast_graft_free(graft);
list1 = isl_ast_graft_list_free(list1);
break;
}
@ -1253,10 +1255,12 @@ __isl_give isl_ast_graft_list *isl_ast_graft_list_merge(
break;
}
if (j < 0)
if (j < 0) {
isl_ast_graft_free(graft);
isl_die(isl_ast_build_get_ctx(build),
isl_error_internal,
"element failed to get inserted", break);
}
first = j + 1;
if (!list1)

View File

@ -1,13 +0,0 @@
#include <isl/deprecated/ast_int.h>
#include <isl/deprecated/val_int.h>
#include <isl_ast_private.h>
int isl_ast_expr_get_int(__isl_keep isl_ast_expr *expr, isl_int *v)
{
if (!expr)
return -1;
if (expr->type != isl_ast_expr_int)
isl_die(isl_ast_expr_get_ctx(expr), isl_error_invalid,
"expression not an int", return -1);
return isl_val_get_num_isl_int(expr->u.v, v);
}

View File

@ -1,727 +0,0 @@
/*
* Copyright 2011 INRIA Saclay
* Copyright 2012-2013 Ecole Normale Superieure
*
* Use of this software is governed by the MIT license
*
* Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France,
* Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod,
* 91893 Orsay, France
* and Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France
*/
#include <isl_band_private.h>
#include <isl_schedule_private.h>
#undef BASE
#define BASE band
#include <isl_list_templ.c>
isl_ctx *isl_band_get_ctx(__isl_keep isl_band *band)
{
return band ? isl_union_pw_multi_aff_get_ctx(band->pma) : NULL;
}
__isl_give isl_band *isl_band_alloc(isl_ctx *ctx)
{
isl_band *band;
band = isl_calloc_type(ctx, isl_band);
if (!band)
return NULL;
band->ref = 1;
return band;
}
/* Create a duplicate of the given band. The duplicate refers
* to the same schedule and parent as the input, but does not
* increment their reference counts.
*/
__isl_give isl_band *isl_band_dup(__isl_keep isl_band *band)
{
int i;
isl_ctx *ctx;
isl_band *dup;
if (!band)
return NULL;
ctx = isl_band_get_ctx(band);
dup = isl_band_alloc(ctx);
if (!dup)
return NULL;
dup->n = band->n;
dup->coincident = isl_alloc_array(ctx, int, band->n);
if (band->n && !dup->coincident)
goto error;
for (i = 0; i < band->n; ++i)
dup->coincident[i] = band->coincident[i];
dup->pma = isl_union_pw_multi_aff_copy(band->pma);
dup->schedule = band->schedule;
dup->parent = band->parent;
if (!dup->pma)
goto error;
return dup;
error:
isl_band_free(dup);
return NULL;
}
/* We not only increment the reference count of the band,
* but also that of the schedule that contains this band.
* This ensures that the schedule won't disappear while there
* is still a reference to the band outside of the schedule.
* There is no need to increment the reference count of the parent
* band as the parent band is part of the same schedule.
*/
__isl_give isl_band *isl_band_copy(__isl_keep isl_band *band)
{
if (!band)
return NULL;
band->ref++;
band->schedule->ref++;
return band;
}
/* If this is not the last reference to the band (the one from within the
* schedule), then we also need to decrement the reference count of the
* containing schedule as it was incremented in isl_band_copy.
*/
__isl_null isl_band *isl_band_free(__isl_take isl_band *band)
{
if (!band)
return NULL;
if (--band->ref > 0) {
isl_schedule_free(band->schedule);
return NULL;
}
isl_union_pw_multi_aff_free(band->pma);
isl_band_list_free(band->children);
free(band->coincident);
free(band);
return NULL;
}
int isl_band_has_children(__isl_keep isl_band *band)
{
if (!band)
return -1;
return band->children != NULL;
}
__isl_give isl_band_list *isl_band_get_children(
__isl_keep isl_band *band)
{
if (!band)
return NULL;
if (!band->children)
isl_die(isl_band_get_ctx(band), isl_error_invalid,
"band has no children", return NULL);
return isl_band_list_dup(band->children);
}
int isl_band_n_member(__isl_keep isl_band *band)
{
return band ? band->n : 0;
}
/* Is the given scheduling dimension coincident within the band and
* with respect to the coincidence constraints.
*/
int isl_band_member_is_coincident(__isl_keep isl_band *band, int pos)
{
if (!band)
return -1;
if (pos < 0 || pos >= band->n)
isl_die(isl_band_get_ctx(band), isl_error_invalid,
"invalid member position", return -1);
return band->coincident[pos];
}
/* Return the schedule that leads up to this band.
*/
__isl_give isl_union_map *isl_band_get_prefix_schedule(
__isl_keep isl_band *band)
{
isl_union_set *domain;
isl_union_pw_multi_aff *prefix;
isl_band *a;
if (!band)
return NULL;
prefix = isl_union_pw_multi_aff_copy(band->pma);
domain = isl_union_pw_multi_aff_domain(prefix);
prefix = isl_union_pw_multi_aff_from_domain(domain);
for (a = band->parent; a; a = a->parent) {
isl_union_pw_multi_aff *partial;
partial = isl_union_pw_multi_aff_copy(a->pma);
prefix = isl_union_pw_multi_aff_flat_range_product(partial,
prefix);
}
return isl_union_map_from_union_pw_multi_aff(prefix);
}
/* Return the schedule of the band in isolation.
*/
__isl_give isl_union_pw_multi_aff *
isl_band_get_partial_schedule_union_pw_multi_aff(__isl_keep isl_band *band)
{
return band ? isl_union_pw_multi_aff_copy(band->pma) : NULL;
}
/* Return the schedule of the band in isolation.
*/
__isl_give isl_union_map *isl_band_get_partial_schedule(
__isl_keep isl_band *band)
{
isl_union_pw_multi_aff *sched;
sched = isl_band_get_partial_schedule_union_pw_multi_aff(band);
return isl_union_map_from_union_pw_multi_aff(sched);
}
__isl_give isl_union_pw_multi_aff *
isl_band_get_suffix_schedule_union_pw_multi_aff(__isl_keep isl_band *band);
/* Return the schedule for the given band list.
* For each band in the list, the schedule is composed of the partial
* and suffix schedules of that band.
*/
__isl_give isl_union_pw_multi_aff *
isl_band_list_get_suffix_schedule_union_pw_multi_aff(
__isl_keep isl_band_list *list)
{
isl_ctx *ctx;
int i, n;
isl_space *space;
isl_union_pw_multi_aff *suffix;
if (!list)
return NULL;
ctx = isl_band_list_get_ctx(list);
space = isl_space_alloc(ctx, 0, 0, 0);
suffix = isl_union_pw_multi_aff_empty(space);
n = isl_band_list_n_band(list);
for (i = 0; i < n; ++i) {
isl_band *el;
isl_union_pw_multi_aff *partial;
isl_union_pw_multi_aff *suffix_i;
el = isl_band_list_get_band(list, i);
partial = isl_band_get_partial_schedule_union_pw_multi_aff(el);
suffix_i = isl_band_get_suffix_schedule_union_pw_multi_aff(el);
suffix_i = isl_union_pw_multi_aff_flat_range_product(
partial, suffix_i);
suffix = isl_union_pw_multi_aff_union_add(suffix, suffix_i);
isl_band_free(el);
}
return suffix;
}
/* Return the schedule for the given band list.
* For each band in the list, the schedule is composed of the partial
* and suffix schedules of that band.
*/
__isl_give isl_union_map *isl_band_list_get_suffix_schedule(
__isl_keep isl_band_list *list)
{
isl_union_pw_multi_aff *suffix;
suffix = isl_band_list_get_suffix_schedule_union_pw_multi_aff(list);
return isl_union_map_from_union_pw_multi_aff(suffix);
}
/* Return the schedule for the forest underneath the given band.
*/
__isl_give isl_union_pw_multi_aff *
isl_band_get_suffix_schedule_union_pw_multi_aff(__isl_keep isl_band *band)
{
isl_union_pw_multi_aff *suffix;
if (!band)
return NULL;
if (!isl_band_has_children(band)) {
isl_union_set *domain;
suffix = isl_union_pw_multi_aff_copy(band->pma);
domain = isl_union_pw_multi_aff_domain(suffix);
suffix = isl_union_pw_multi_aff_from_domain(domain);
} else {
isl_band_list *list;
list = isl_band_get_children(band);
suffix =
isl_band_list_get_suffix_schedule_union_pw_multi_aff(list);
isl_band_list_free(list);
}
return suffix;
}
/* Return the schedule for the forest underneath the given band.
*/
__isl_give isl_union_map *isl_band_get_suffix_schedule(
__isl_keep isl_band *band)
{
isl_union_pw_multi_aff *suffix;
suffix = isl_band_get_suffix_schedule_union_pw_multi_aff(band);
return isl_union_map_from_union_pw_multi_aff(suffix);
}
/* Call "fn" on each band (recursively) in the list
* in depth-first post-order.
*/
int isl_band_list_foreach_band(__isl_keep isl_band_list *list,
int (*fn)(__isl_keep isl_band *band, void *user), void *user)
{
int i, n;
if (!list)
return -1;
n = isl_band_list_n_band(list);
for (i = 0; i < n; ++i) {
isl_band *band;
int r = 0;
band = isl_band_list_get_band(list, i);
if (isl_band_has_children(band)) {
isl_band_list *children;
children = isl_band_get_children(band);
r = isl_band_list_foreach_band(children, fn, user);
isl_band_list_free(children);
}
if (!band)
r = -1;
if (r == 0)
r = fn(band, user);
isl_band_free(band);
if (r)
return r;
}
return 0;
}
/* Internal data used during the construction of the schedule
* for the tile loops.
*
* sizes contains the tile sizes
* scale is set if the tile loops should be scaled
* tiled collects the result for a single statement
* res collects the result for all statements
*/
struct isl_band_tile_data {
isl_multi_val *sizes;
isl_union_pw_multi_aff *res;
isl_pw_multi_aff *tiled;
int scale;
};
/* Given part of the schedule of a band, construct the corresponding
* schedule for the tile loops based on the tile sizes in data->sizes
* and add the result to data->tiled.
*
* If data->scale is set, then dimension i of the schedule will be
* of the form
*
* m_i * floor(s_i(x) / m_i)
*
* where s_i(x) refers to the original schedule and m_i is the tile size.
* If data->scale is not set, then dimension i of the schedule will be
* of the form
*
* floor(s_i(x) / m_i)
*
*/
static isl_stat multi_aff_tile(__isl_take isl_set *set,
__isl_take isl_multi_aff *ma, void *user)
{
struct isl_band_tile_data *data = user;
isl_pw_multi_aff *pma;
int i, n;
isl_val *v;
n = isl_multi_aff_dim(ma, isl_dim_out);
for (i = 0; i < n; ++i) {
isl_aff *aff;
aff = isl_multi_aff_get_aff(ma, i);
v = isl_multi_val_get_val(data->sizes, i);
aff = isl_aff_scale_down_val(aff, isl_val_copy(v));
aff = isl_aff_floor(aff);
if (data->scale)
aff = isl_aff_scale_val(aff, isl_val_copy(v));
isl_val_free(v);
ma = isl_multi_aff_set_aff(ma, i, aff);
}
pma = isl_pw_multi_aff_alloc(set, ma);
data->tiled = isl_pw_multi_aff_union_add(data->tiled, pma);
return isl_stat_ok;
}
/* Given part of the schedule of a band, construct the corresponding
* schedule for the tile loops based on the tile sizes in data->sizes
* and add the result to data->res.
*/
static isl_stat pw_multi_aff_tile(__isl_take isl_pw_multi_aff *pma, void *user)
{
struct isl_band_tile_data *data = user;
data->tiled = isl_pw_multi_aff_empty(isl_pw_multi_aff_get_space(pma));
if (isl_pw_multi_aff_foreach_piece(pma, &multi_aff_tile, data) < 0)
goto error;
isl_pw_multi_aff_free(pma);
data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res,
data->tiled);
return isl_stat_ok;
error:
isl_pw_multi_aff_free(pma);
isl_pw_multi_aff_free(data->tiled);
return isl_stat_error;
}
/* Given the schedule of a band, construct the corresponding
* schedule for the tile loops based on the given tile sizes
* and return the result.
*/
static isl_union_pw_multi_aff *isl_union_pw_multi_aff_tile(
__isl_take isl_union_pw_multi_aff *sched,
__isl_keep isl_multi_val *sizes)
{
isl_ctx *ctx;
isl_space *space;
struct isl_band_tile_data data = { sizes };
ctx = isl_multi_val_get_ctx(sizes);
space = isl_union_pw_multi_aff_get_space(sched);
data.res = isl_union_pw_multi_aff_empty(space);
data.scale = isl_options_get_tile_scale_tile_loops(ctx);
if (isl_union_pw_multi_aff_foreach_pw_multi_aff(sched,
&pw_multi_aff_tile, &data) < 0)
goto error;
isl_union_pw_multi_aff_free(sched);
return data.res;
error:
isl_union_pw_multi_aff_free(sched);
isl_union_pw_multi_aff_free(data.res);
return NULL;
}
/* Extract the range space from "pma" and store it in *user.
* All entries are expected to have the same range space, so we can
* stop after extracting the range space from the first entry.
*/
static isl_stat extract_range_space(__isl_take isl_pw_multi_aff *pma,
void *user)
{
isl_space **space = user;
*space = isl_space_range(isl_pw_multi_aff_get_space(pma));
isl_pw_multi_aff_free(pma);
return isl_stat_error;
}
/* Extract the range space of "band". All entries in band->pma should
* have the same range space. Furthermore, band->pma should have at least
* one entry.
*/
static __isl_give isl_space *band_get_range_space(__isl_keep isl_band *band)
{
isl_space *space;
if (!band)
return NULL;
space = NULL;
isl_union_pw_multi_aff_foreach_pw_multi_aff(band->pma,
&extract_range_space, &space);
return space;
}
/* Construct and return an isl_multi_val in the given space, with as entries
* the first elements of "v", padded with ones if the size of "v" is smaller
* than the dimension of "space".
*/
static __isl_give isl_multi_val *multi_val_from_vec(__isl_take isl_space *space,
__isl_take isl_vec *v)
{
isl_ctx *ctx;
isl_multi_val *mv;
int i, n, size;
if (!space || !v)
goto error;
ctx = isl_space_get_ctx(space);
mv = isl_multi_val_zero(space);
n = isl_multi_val_dim(mv, isl_dim_set);
size = isl_vec_size(v);
if (n < size)
size = n;
for (i = 0; i < size; ++i) {
isl_val *val = isl_vec_get_element_val(v, i);
mv = isl_multi_val_set_val(mv, i, val);
}
for (i = size; i < n; ++i)
mv = isl_multi_val_set_val(mv, i, isl_val_one(ctx));
isl_vec_free(v);
return mv;
error:
isl_space_free(space);
isl_vec_free(v);
return NULL;
}
/* Tile the given band using the specified tile sizes.
* The given band is modified to refer to the tile loops and
* a child band is created to refer to the point loops.
* The children of this point loop band are the children
* of the original band.
*
* If the scale tile loops option is set, then the tile loops
* are scaled by the tile sizes. If the shift point loops option is set,
* then the point loops are shifted to start at zero.
* In particular, these options affect the tile and point loop schedules
* as follows
*
* scale shift original tile point
*
* 0 0 i floor(i/s) i
* 1 0 i s * floor(i/s) i
* 0 1 i floor(i/s) i - s * floor(i/s)
* 1 1 i s * floor(i/s) i - s * floor(i/s)
*/
int isl_band_tile(__isl_keep isl_band *band, __isl_take isl_vec *sizes)
{
isl_ctx *ctx;
isl_band *child;
isl_band_list *list = NULL;
isl_union_pw_multi_aff *sched = NULL, *child_sched = NULL;
isl_space *space;
isl_multi_val *mv_sizes;
if (!band || !sizes)
goto error;
ctx = isl_vec_get_ctx(sizes);
child = isl_band_dup(band);
list = isl_band_list_alloc(ctx, 1);
list = isl_band_list_add(list, child);
if (!list)
goto error;
space = band_get_range_space(band);
mv_sizes = multi_val_from_vec(space, isl_vec_copy(sizes));
sched = isl_union_pw_multi_aff_copy(band->pma);
sched = isl_union_pw_multi_aff_tile(sched, mv_sizes);
child_sched = isl_union_pw_multi_aff_copy(child->pma);
if (isl_options_get_tile_shift_point_loops(ctx)) {
isl_union_pw_multi_aff *scaled;
scaled = isl_union_pw_multi_aff_copy(sched);
if (!isl_options_get_tile_scale_tile_loops(ctx))
scaled = isl_union_pw_multi_aff_scale_multi_val(scaled,
isl_multi_val_copy(mv_sizes));
child_sched = isl_union_pw_multi_aff_sub(child_sched, scaled);
}
isl_multi_val_free(mv_sizes);
if (!sched || !child_sched)
goto error;
child->children = band->children;
band->children = list;
child->parent = band;
isl_union_pw_multi_aff_free(band->pma);
band->pma = sched;
isl_union_pw_multi_aff_free(child->pma);
child->pma = child_sched;
isl_vec_free(sizes);
return 0;
error:
isl_union_pw_multi_aff_free(sched);
isl_union_pw_multi_aff_free(child_sched);
isl_band_list_free(list);
isl_vec_free(sizes);
return -1;
}
/* Internal data structure used inside isl_union_pw_multi_aff_drop.
*
* "pos" is the position of the first dimension to drop.
* "n" is the number of dimensions to drop.
* "res" accumulates the result.
*/
struct isl_union_pw_multi_aff_drop_data {
int pos;
int n;
isl_union_pw_multi_aff *res;
};
/* Drop the data->n output dimensions starting at data->pos from "pma"
* and add the result to data->res.
*/
static isl_stat pw_multi_aff_drop(__isl_take isl_pw_multi_aff *pma, void *user)
{
struct isl_union_pw_multi_aff_drop_data *data = user;
pma = isl_pw_multi_aff_drop_dims(pma, isl_dim_out, data->pos, data->n);
data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma);
if (!data->res)
return isl_stat_error;
return isl_stat_ok;
}
/* Drop the "n" output dimensions starting at "pos" from "sched".
*/
static isl_union_pw_multi_aff *isl_union_pw_multi_aff_drop(
__isl_take isl_union_pw_multi_aff *sched, int pos, int n)
{
isl_space *space;
struct isl_union_pw_multi_aff_drop_data data = { pos, n };
space = isl_union_pw_multi_aff_get_space(sched);
data.res = isl_union_pw_multi_aff_empty(space);
if (isl_union_pw_multi_aff_foreach_pw_multi_aff(sched,
&pw_multi_aff_drop, &data) < 0)
data.res = isl_union_pw_multi_aff_free(data.res);
isl_union_pw_multi_aff_free(sched);
return data.res;
}
/* Drop the "n" dimensions starting at "pos" from "band".
*/
static int isl_band_drop(__isl_keep isl_band *band, int pos, int n)
{
int i;
isl_union_pw_multi_aff *sched;
if (!band)
return -1;
if (n == 0)
return 0;
sched = isl_union_pw_multi_aff_copy(band->pma);
sched = isl_union_pw_multi_aff_drop(sched, pos, n);
if (!sched)
return -1;
isl_union_pw_multi_aff_free(band->pma);
band->pma = sched;
for (i = pos + n; i < band->n; ++i)
band->coincident[i - n] = band->coincident[i];
band->n -= n;
return 0;
}
/* Split the given band into two nested bands, one with the first "pos"
* dimensions of "band" and one with the remaining band->n - pos dimensions.
*/
int isl_band_split(__isl_keep isl_band *band, int pos)
{
isl_ctx *ctx;
isl_band *child;
isl_band_list *list;
if (!band)
return -1;
ctx = isl_band_get_ctx(band);
if (pos < 0 || pos > band->n)
isl_die(ctx, isl_error_invalid, "position out of bounds",
return -1);
child = isl_band_dup(band);
if (isl_band_drop(child, 0, pos) < 0)
child = isl_band_free(child);
list = isl_band_list_alloc(ctx, 1);
list = isl_band_list_add(list, child);
if (!list)
return -1;
if (isl_band_drop(band, pos, band->n - pos) < 0) {
isl_band_list_free(list);
return -1;
}
child->children = band->children;
band->children = list;
child->parent = band;
return 0;
}
__isl_give isl_printer *isl_printer_print_band(__isl_take isl_printer *p,
__isl_keep isl_band *band)
{
isl_union_map *prefix, *partial, *suffix;
prefix = isl_band_get_prefix_schedule(band);
partial = isl_band_get_partial_schedule(band);
suffix = isl_band_get_suffix_schedule(band);
p = isl_printer_print_str(p, "(");
p = isl_printer_print_union_map(p, prefix);
p = isl_printer_print_str(p, ",");
p = isl_printer_print_union_map(p, partial);
p = isl_printer_print_str(p, ",");
p = isl_printer_print_union_map(p, suffix);
p = isl_printer_print_str(p, ")");
isl_union_map_free(prefix);
isl_union_map_free(partial);
isl_union_map_free(suffix);
return p;
}

View File

@ -1,47 +0,0 @@
#ifndef ISL_BAND_PRIVATE_H
#define ISL_BAND_PRIVATE_H
#include <isl/aff.h>
#include <isl/band.h>
#include <isl/list.h>
#include <isl/schedule.h>
/* Information about a band within a schedule.
*
* n is the number of scheduling dimensions within the band.
* coincident is an array of length n, indicating whether a scheduling dimension
* satisfies the coincidence constraints in the sense that
* the corresponding dependence distances are zero.
* pma is the partial schedule corresponding to this band.
* schedule is the schedule that contains this band.
* parent is the parent of this band (or NULL if the band is a root).
* children are the children of this band (or NULL if the band is a leaf).
*
* To avoid circular dependences in the reference counting,
* the schedule and parent pointers are not reference counted.
* isl_band_copy increments the reference count of schedule to ensure
* that outside references to the band keep the schedule alive.
*/
struct isl_band {
int ref;
int n;
int *coincident;
isl_union_pw_multi_aff *pma;
isl_schedule *schedule;
isl_band *parent;
isl_band_list *children;
};
#undef EL
#define EL isl_band
#include <isl_list_templ.h>
__isl_give isl_band *isl_band_alloc(isl_ctx *ctx);
__isl_give isl_union_map *isl_band_list_get_suffix_schedule(
__isl_keep isl_band_list *list);
#endif

View File

@ -196,6 +196,82 @@ struct isl_coalesce_info {
int *ineq;
};
/* Is there any (half of an) equality constraint in the description
* of the basic map represented by "info" that
* has position "status" with respect to the other basic map?
*/
static int any_eq(struct isl_coalesce_info *info, int status)
{
unsigned n_eq;
n_eq = isl_basic_map_n_equality(info->bmap);
return any(info->eq, 2 * n_eq, status);
}
/* Is there any inequality constraint in the description
* of the basic map represented by "info" that
* has position "status" with respect to the other basic map?
*/
static int any_ineq(struct isl_coalesce_info *info, int status)
{
unsigned n_ineq;
n_ineq = isl_basic_map_n_inequality(info->bmap);
return any(info->ineq, n_ineq, status);
}
/* Return the position of the first half on an equality constraint
* in the description of the basic map represented by "info" that
* has position "status" with respect to the other basic map.
* The returned value is twice the position of the equality constraint
* plus zero for the negative half and plus one for the positive half.
* Return -1 if there is no such entry.
*/
static int find_eq(struct isl_coalesce_info *info, int status)
{
unsigned n_eq;
n_eq = isl_basic_map_n_equality(info->bmap);
return find(info->eq, 2 * n_eq, status);
}
/* Return the position of the first inequality constraint in the description
* of the basic map represented by "info" that
* has position "status" with respect to the other basic map.
* Return -1 if there is no such entry.
*/
static int find_ineq(struct isl_coalesce_info *info, int status)
{
unsigned n_ineq;
n_ineq = isl_basic_map_n_inequality(info->bmap);
return find(info->ineq, n_ineq, status);
}
/* Return the number of (halves of) equality constraints in the description
* of the basic map represented by "info" that
* have position "status" with respect to the other basic map.
*/
static int count_eq(struct isl_coalesce_info *info, int status)
{
unsigned n_eq;
n_eq = isl_basic_map_n_equality(info->bmap);
return count(info->eq, 2 * n_eq, status);
}
/* Return the number of inequality constraints in the description
* of the basic map represented by "info" that
* have position "status" with respect to the other basic map.
*/
static int count_ineq(struct isl_coalesce_info *info, int status)
{
unsigned n_ineq;
n_ineq = isl_basic_map_n_inequality(info->bmap);
return count(info->ineq, n_ineq, status);
}
/* Are all non-redundant constraints of the basic map represented by "info"
* either valid or cut constraints with respect to the other basic map?
*/
@ -654,7 +730,7 @@ static enum isl_change is_adj_ineq_extension(int i, int j,
if (isl_tab_extend_cons(info[i].tab, 1 + info[j].bmap->n_ineq) < 0)
return isl_change_error;
k = find(info[i].ineq, info[i].bmap->n_ineq, STATUS_ADJ_INEQ);
k = find_ineq(&info[i], STATUS_ADJ_INEQ);
if (k < 0)
isl_die(isl_basic_map_get_ctx(info[i].bmap), isl_error_internal,
"info[i].ineq should have exactly one STATUS_ADJ_INEQ",
@ -732,16 +808,14 @@ static enum isl_change check_adj_ineq(int i, int j,
int count_i, count_j;
int cut_i, cut_j;
count_i = count(info[i].ineq, info[i].bmap->n_ineq, STATUS_ADJ_INEQ);
count_j = count(info[j].ineq, info[j].bmap->n_ineq, STATUS_ADJ_INEQ);
count_i = count_ineq(&info[i], STATUS_ADJ_INEQ);
count_j = count_ineq(&info[j], STATUS_ADJ_INEQ);
if (count_i != 1 && count_j != 1)
return isl_change_none;
cut_i = any(info[i].eq, 2 * info[i].bmap->n_eq, STATUS_CUT) ||
any(info[i].ineq, info[i].bmap->n_ineq, STATUS_CUT);
cut_j = any(info[j].eq, 2 * info[j].bmap->n_eq, STATUS_CUT) ||
any(info[j].ineq, info[j].bmap->n_ineq, STATUS_CUT);
cut_i = any_eq(&info[i], STATUS_CUT) || any_ineq(&info[i], STATUS_CUT);
cut_j = any_eq(&info[j], STATUS_CUT) || any_ineq(&info[j], STATUS_CUT);
if (!cut_i && !cut_j && count_i == 1 && count_j == 1)
return fuse(i, j, info, NULL, 0, 0);
@ -1712,8 +1786,7 @@ static enum isl_change can_wrap_in_set(int i, int j,
ISL_F_ISSET(info[j].bmap, ISL_BASIC_MAP_RATIONAL))
return isl_change_none;
n = count(info[i].eq, 2 * info[i].bmap->n_eq, STATUS_CUT);
n += count(info[i].ineq, info[i].bmap->n_ineq, STATUS_CUT);
n = count_eq(&info[i], STATUS_CUT) + count_ineq(&info[i], STATUS_CUT);
if (n == 0)
return isl_change_none;
@ -1825,9 +1898,9 @@ static enum isl_change check_single_adj_eq(int i, int j,
isl_ctx *ctx;
isl_bool try_relax;
n_cut = count(info[i].ineq, info[i].bmap->n_ineq, STATUS_CUT);
n_cut = count_ineq(&info[i], STATUS_CUT);
k = find(info[i].ineq, info[i].bmap->n_ineq, STATUS_ADJ_EQ);
k = find_ineq(&info[i], STATUS_ADJ_EQ);
if (n_cut > 0) {
ctx = isl_basic_map_get_ctx(info[i].bmap);
@ -1855,7 +1928,7 @@ static enum isl_change check_single_adj_eq(int i, int j,
}
/* At least one of the basic maps has an equality that is adjacent
* to inequality. Make sure that only one of the basic maps has
* to an inequality. Make sure that only one of the basic maps has
* such an equality and that the other basic map has exactly one
* inequality adjacent to an equality.
* If the other basic map does not have such an inequality, then
@ -1867,32 +1940,63 @@ static enum isl_change check_single_adj_eq(int i, int j,
static enum isl_change check_adj_eq(int i, int j,
struct isl_coalesce_info *info)
{
if (any(info[i].eq, 2 * info[i].bmap->n_eq, STATUS_ADJ_INEQ) &&
any(info[j].eq, 2 * info[j].bmap->n_eq, STATUS_ADJ_INEQ))
if (any_eq(&info[i], STATUS_ADJ_INEQ) &&
any_eq(&info[j], STATUS_ADJ_INEQ))
/* ADJ EQ TOO MANY */
return isl_change_none;
if (any(info[i].eq, 2 * info[i].bmap->n_eq, STATUS_ADJ_INEQ))
if (any_eq(&info[i], STATUS_ADJ_INEQ))
return check_adj_eq(j, i, info);
/* j has an equality adjacent to an inequality in i */
if (count(info[i].ineq, info[i].bmap->n_ineq, STATUS_ADJ_EQ) != 1) {
if (count_ineq(&info[i], STATUS_ADJ_EQ) != 1) {
if (all_valid_or_cut(&info[i]))
return can_wrap_in_set(i, j, info);
return isl_change_none;
}
if (any(info[i].eq, 2 * info[i].bmap->n_eq, STATUS_CUT))
if (any_eq(&info[i], STATUS_CUT))
return isl_change_none;
if (any(info[j].ineq, info[j].bmap->n_ineq, STATUS_ADJ_EQ) ||
any(info[i].ineq, info[i].bmap->n_ineq, STATUS_ADJ_INEQ) ||
any(info[j].ineq, info[j].bmap->n_ineq, STATUS_ADJ_INEQ))
if (any_ineq(&info[j], STATUS_ADJ_EQ) ||
any_ineq(&info[i], STATUS_ADJ_INEQ) ||
any_ineq(&info[j], STATUS_ADJ_INEQ))
/* ADJ EQ TOO MANY */
return isl_change_none;
return check_single_adj_eq(i, j, info);
}
/* Disjunct "j" lies on a hyperplane that is adjacent to disjunct "i".
* In particular, disjunct "i" has an inequality constraint that is adjacent
* to a (combination of) equality constraint(s) of disjunct "j",
* but disjunct "j" has no explicit equality constraint adjacent
* to an inequality constraint of disjunct "i".
*
* Disjunct "i" is already known not to have any equality constraints
* that are adjacent to an equality or inequality constraint.
* Check that, other than the inequality constraint mentioned above,
* all other constraints of disjunct "i" are valid for disjunct "j".
* If so, try and wrap in disjunct "j".
*/
static enum isl_change check_ineq_adj_eq(int i, int j,
struct isl_coalesce_info *info)
{
int k;
if (any_eq(&info[i], STATUS_CUT))
return isl_change_none;
if (any_ineq(&info[i], STATUS_CUT))
return isl_change_none;
if (any_ineq(&info[i], STATUS_ADJ_INEQ))
return isl_change_none;
if (count_ineq(&info[i], STATUS_ADJ_EQ) != 1)
return isl_change_none;
k = find_ineq(&info[i], STATUS_ADJ_EQ);
return can_wrap_in_facet(i, j, k, info, 0);
}
/* The two basic maps lie on adjacent hyperplanes. In particular,
* basic map "i" has an equality that lies parallel to basic map "j".
* Check if we can wrap the facets around the parallel hyperplanes
@ -1925,10 +2029,10 @@ static enum isl_change check_eq_adj_eq(int i, int j,
struct isl_vec *bound = NULL;
unsigned total = isl_basic_map_total_dim(info[i].bmap);
if (count(info[i].eq, 2 * info[i].bmap->n_eq, STATUS_ADJ_EQ) != 1)
if (count_eq(&info[i], STATUS_ADJ_EQ) != 1)
detect_equalities = 1;
k = find(info[i].eq, 2 * info[i].bmap->n_eq, STATUS_ADJ_EQ);
k = find_eq(&info[i], STATUS_ADJ_EQ);
set_i = set_from_updated_bmap(info[i].bmap, info[i].tab);
set_j = set_from_updated_bmap(info[j].bmap, info[j].tab);
@ -2134,7 +2238,7 @@ static enum isl_change separating_equality(int i, int j,
* => the pair can be replaced by the basic map containing
* the inequality, with the inequality relaxed.
*
* 6. there is a single adjacent pair of an inequality and an equality,
* 6. there is a single inequality adjacent to an equality,
* the other constraints of the basic map containing the inequality are
* "valid". Moreover, the facets corresponding to both
* the inequality and the equality can be wrapped around their
@ -2168,34 +2272,34 @@ static enum isl_change coalesce_local_pair_reuse(int i, int j,
set_ineq_status_in(&info[i], info[j].tab);
if (info[i].bmap->n_ineq && !info[i].ineq)
goto error;
if (any(info[i].ineq, info[i].bmap->n_ineq, STATUS_ERROR))
if (any_ineq(&info[i], STATUS_ERROR))
goto error;
if (any(info[i].ineq, info[i].bmap->n_ineq, STATUS_SEPARATE))
if (any_ineq(&info[i], STATUS_SEPARATE))
goto done;
set_ineq_status_in(&info[j], info[i].tab);
if (info[j].bmap->n_ineq && !info[j].ineq)
goto error;
if (any(info[j].ineq, info[j].bmap->n_ineq, STATUS_ERROR))
if (any_ineq(&info[j], STATUS_ERROR))
goto error;
if (any(info[j].ineq, info[j].bmap->n_ineq, STATUS_SEPARATE))
if (any_ineq(&info[j], STATUS_SEPARATE))
goto done;
set_eq_status_in(&info[i], info[j].tab);
if (info[i].bmap->n_eq && !info[i].eq)
goto error;
if (any(info[i].eq, 2 * info[i].bmap->n_eq, STATUS_ERROR))
if (any_eq(&info[i], STATUS_ERROR))
goto error;
set_eq_status_in(&info[j], info[i].tab);
if (info[j].bmap->n_eq && !info[j].eq)
goto error;
if (any(info[j].eq, 2 * info[j].bmap->n_eq, STATUS_ERROR))
if (any_eq(&info[j], STATUS_ERROR))
goto error;
if (any(info[i].eq, 2 * info[i].bmap->n_eq, STATUS_SEPARATE))
if (any_eq(&info[i], STATUS_SEPARATE))
return separating_equality(i, j, info);
if (any(info[j].eq, 2 * info[j].bmap->n_eq, STATUS_SEPARATE))
if (any_eq(&info[j], STATUS_SEPARATE))
return separating_equality(j, i, info);
if (all(info[i].eq, 2 * info[i].bmap->n_eq, STATUS_VALID) &&
@ -2206,23 +2310,23 @@ static enum isl_change coalesce_local_pair_reuse(int i, int j,
all(info[j].ineq, info[j].bmap->n_ineq, STATUS_VALID)) {
drop(&info[i]);
change = isl_change_drop_first;
} else if (any(info[i].eq, 2 * info[i].bmap->n_eq, STATUS_ADJ_EQ)) {
} else if (any_eq(&info[i], STATUS_ADJ_EQ)) {
change = check_eq_adj_eq(i, j, info);
} else if (any(info[j].eq, 2 * info[j].bmap->n_eq, STATUS_ADJ_EQ)) {
} else if (any_eq(&info[j], STATUS_ADJ_EQ)) {
change = check_eq_adj_eq(j, i, info);
} else if (any(info[i].eq, 2 * info[i].bmap->n_eq, STATUS_ADJ_INEQ) ||
any(info[j].eq, 2 * info[j].bmap->n_eq, STATUS_ADJ_INEQ)) {
} else if (any_eq(&info[i], STATUS_ADJ_INEQ) ||
any_eq(&info[j], STATUS_ADJ_INEQ)) {
change = check_adj_eq(i, j, info);
} else if (any(info[i].ineq, info[i].bmap->n_ineq, STATUS_ADJ_EQ) ||
any(info[j].ineq, info[j].bmap->n_ineq, STATUS_ADJ_EQ)) {
/* Can't happen */
/* BAD ADJ INEQ */
} else if (any(info[i].ineq, info[i].bmap->n_ineq, STATUS_ADJ_INEQ) ||
any(info[j].ineq, info[j].bmap->n_ineq, STATUS_ADJ_INEQ)) {
} else if (any_ineq(&info[i], STATUS_ADJ_EQ)) {
change = check_ineq_adj_eq(i, j, info);
} else if (any_ineq(&info[j], STATUS_ADJ_EQ)) {
change = check_ineq_adj_eq(j, i, info);
} else if (any_ineq(&info[i], STATUS_ADJ_INEQ) ||
any_ineq(&info[j], STATUS_ADJ_INEQ)) {
change = check_adj_ineq(i, j, info);
} else {
if (!any(info[i].eq, 2 * info[i].bmap->n_eq, STATUS_CUT) &&
!any(info[j].eq, 2 * info[j].bmap->n_eq, STATUS_CUT))
if (!any_eq(&info[i], STATUS_CUT) &&
!any_eq(&info[j], STATUS_CUT))
change = check_facets(i, j, info);
if (change == isl_change_none)
change = check_wrap(i, j, info);
@ -2968,20 +3072,21 @@ static enum isl_change coalesce_with_expanded_divs(
if (!bmap)
goto error;
info_local.bmap = bmap;
info_i->eq = eq_status_in(bmap, info[j].tab);
if (bmap->n_eq && !info_i->eq)
goto error;
if (any(info_i->eq, 2 * bmap->n_eq, STATUS_ERROR))
if (any_eq(info_i, STATUS_ERROR))
goto error;
if (any(info_i->eq, 2 * bmap->n_eq, STATUS_SEPARATE))
if (any_eq(info_i, STATUS_SEPARATE))
goto done;
info_i->ineq = ineq_status_in(bmap, NULL, info[j].tab);
if (bmap->n_ineq && !info_i->ineq)
goto error;
if (any(info_i->ineq, bmap->n_ineq, STATUS_ERROR))
if (any_ineq(info_i, STATUS_ERROR))
goto error;
if (any(info_i->ineq, bmap->n_ineq, STATUS_SEPARATE))
if (any_ineq(info_i, STATUS_SEPARATE))
goto done;
if (all(info_i->eq, 2 * bmap->n_eq, STATUS_VALID) &&

View File

@ -34,9 +34,6 @@
/* Define if clang/Basic/DiagnosticOptions.h exists */
#undef HAVE_BASIC_DIAGNOSTICOPTIONS_H
/* define if the compiler supports basic C++11 syntax */
#undef HAVE_CXX11
/* Define if Driver constructor takes CXXIsProduction argument */
#undef HAVE_CXXISPRODUCTION

View File

@ -18,7 +18,6 @@
#include <isl_local_space_private.h>
#include <isl_val_private.h>
#include <isl_vec_private.h>
#include <isl/deprecated/constraint_int.h>
#include <bset_to_bmap.c>
#include <bset_from_bmap.c>

View File

@ -25,10 +25,5 @@ void isl_constraint_get_constant(__isl_keep isl_constraint *constraint,
isl_int *v);
void isl_constraint_get_coefficient(__isl_keep isl_constraint *constraint,
enum isl_dim_type type, int pos, isl_int *v);
__isl_give isl_constraint *isl_constraint_set_constant(
__isl_take isl_constraint *constraint, isl_int v);
__isl_give isl_constraint *isl_constraint_set_coefficient(
__isl_take isl_constraint *constraint,
enum isl_dim_type type, int pos, isl_int v);
#endif

View File

@ -85,13 +85,27 @@ void *isl_realloc_or_die(isl_ctx *ctx, void *ptr, size_t size)
return ctx ? check_non_null(ctx, realloc(ptr, size), size) : NULL;
}
/* Keep track of all information about the current error ("error", "msg",
* "file", "line") in "ctx".
*/
void isl_ctx_set_full_error(isl_ctx *ctx, enum isl_error error, const char *msg,
const char *file, int line)
{
if (!ctx)
return;
ctx->error = error;
ctx->error_msg = msg;
ctx->error_file = file;
ctx->error_line = line;
}
void isl_handle_error(isl_ctx *ctx, enum isl_error error, const char *msg,
const char *file, int line)
{
if (!ctx)
return;
isl_ctx_set_error(ctx, error);
isl_ctx_set_full_error(ctx, error, msg, file, line);
switch (ctx->opt->on_error) {
case ISL_ON_ERROR_WARN:
@ -202,7 +216,7 @@ isl_ctx *isl_ctx_alloc_with_options(struct isl_args *args, void *user_opt)
ctx->n_cached = 0;
ctx->n_miss = 0;
ctx->error = isl_error_none;
isl_ctx_reset_error(ctx);
ctx->operations = 0;
isl_ctx_set_max_operations(ctx, ctx->opt->max_operations);
@ -278,18 +292,43 @@ struct isl_options *isl_ctx_options(isl_ctx *ctx)
enum isl_error isl_ctx_last_error(isl_ctx *ctx)
{
return ctx->error;
return ctx ? ctx->error : isl_error_invalid;
}
/* Return the error message of the last error in "ctx".
*/
const char *isl_ctx_last_error_msg(isl_ctx *ctx)
{
return ctx ? ctx->error_msg : NULL;
}
/* Return the file name where the last error in "ctx" occurred.
*/
const char *isl_ctx_last_error_file(isl_ctx *ctx)
{
return ctx ? ctx->error_file : NULL;
}
/* Return the line number where the last error in "ctx" occurred.
*/
int isl_ctx_last_error_line(isl_ctx *ctx)
{
return ctx ? ctx->error_line : -1;
}
void isl_ctx_reset_error(isl_ctx *ctx)
{
if (!ctx)
return;
ctx->error = isl_error_none;
ctx->error_msg = NULL;
ctx->error_file = NULL;
ctx->error_line = -1;
}
void isl_ctx_set_error(isl_ctx *ctx, enum isl_error error)
{
if (ctx)
ctx->error = error;
isl_ctx_set_full_error(ctx, error, NULL, NULL, -1);
}
void isl_ctx_abort(isl_ctx *ctx)

View File

@ -1,6 +1,13 @@
#include <isl/ctx.h>
#include <isl_blk.h>
/* "error" stores the last error that has occurred.
* It is reset to isl_error_none by isl_ctx_reset_error.
* "error_msg" stores the error message of the last error,
* while "error_file" and "error_line" specify where the last error occurred.
* "error_msg" and "error_file" always point to statically allocated
* strings (if not NULL).
*/
struct isl_ctx {
int ref;
@ -24,6 +31,9 @@ struct isl_ctx {
struct isl_hash_table id_table;
enum isl_error error;
const char *error_msg;
const char *error_file;
int error_line;
int abort;

View File

@ -1,14 +1,4 @@
#include <isl/constraint.h>
#include <isl/set.h>
/* This function was never documented and has been replaced by
* isl_basic_set_add_dims.
*/
__isl_give isl_basic_set *isl_basic_set_add(__isl_take isl_basic_set *bset,
enum isl_dim_type type, unsigned n)
{
return isl_basic_set_add_dims(bset, type, n);
}
/* This function was replaced by isl_constraint_alloc_equality.
*/

View File

@ -16,6 +16,8 @@
* and Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France
*/
#include <isl/val.h>
#include <isl/space.h>
#include <isl/set.h>
#include <isl/map.h>
#include <isl/union_set.h>

View File

@ -20,7 +20,6 @@
#include <isl_val_private.h>
#include <isl_vec_private.h>
#include <isl_config.h>
#include <isl/deprecated/polynomial_int.h>
enum isl_fold isl_fold_type_negate(enum isl_fold type)
{

View File

@ -1,52 +0,0 @@
#define isl_aff_get_constant isl_gmp_aff_get_constant
#define isl_aff_get_coefficient isl_gmp_aff_get_coefficient
#define isl_aff_get_denominator isl_gmp_aff_get_denominator
#define isl_aff_set_constant isl_gmp_aff_set_constant
#define isl_aff_set_coefficient isl_gmp_aff_set_coefficient
#define isl_aff_set_denominator isl_gmp_aff_set_denominator
#define isl_aff_add_constant isl_gmp_aff_add_constant
#define isl_aff_add_constant_num isl_gmp_aff_add_constant_num
#define isl_aff_add_coefficient isl_gmp_aff_add_coefficient
#define isl_aff_mod isl_gmp_aff_mod
#define isl_aff_scale isl_gmp_aff_scale
#define isl_aff_scale_down isl_gmp_aff_scale_down
#define isl_pw_aff_mod isl_gmp_pw_aff_mod
#define isl_pw_aff_scale isl_gmp_pw_aff_scale
#define isl_pw_aff_scale_down isl_gmp_pw_aff_scale_down
#define isl_multi_aff_scale isl_gmp_multi_aff_scale
#define isl_ast_expr_get_int isl_gmp_ast_expr_get_int
#define isl_constraint_get_constant isl_gmp_constraint_get_constant
#define isl_constraint_get_coefficient isl_gmp_constraint_get_coefficient
#define isl_constraint_set_constant isl_gmp_constraint_set_constant
#define isl_constraint_set_coefficient isl_gmp_constraint_set_coefficient
#define isl_basic_set_max isl_gmp_basic_set_max
#define isl_set_min isl_gmp_set_min
#define isl_set_max isl_gmp_set_max
#define isl_gmp_hash isl_gmp_gmp_hash
#define isl_basic_map_plain_is_fixed isl_gmp_basic_map_plain_is_fixed
#define isl_map_fix isl_gmp_map_fix
#define isl_map_plain_is_fixed isl_gmp_map_plain_is_fixed
#define isl_map_fixed_power isl_gmp_map_fixed_power
#define isl_mat_get_element isl_gmp_mat_get_element
#define isl_mat_set_element isl_gmp_mat_set_element
#define isl_point_get_coordinate isl_gmp_point_get_coordinate
#define isl_point_set_coordinate isl_gmp_point_set_coordinate
#define isl_qpolynomial_rat_cst_on_domain isl_gmp_qpolynomial_rat_cst_on_domain
#define isl_qpolynomial_is_cst isl_gmp_qpolynomial_is_cst
#define isl_qpolynomial_scale isl_gmp_qpolynomial_scale
#define isl_term_get_num isl_gmp_term_get_num
#define isl_term_get_den isl_gmp_term_get_den
#define isl_qpolynomial_fold_scale isl_gmp_qpolynomial_fold_scale
#define isl_pw_qpolynomial_fold_fix_dim isl_gmp_pw_qpolynomial_fold_fix_dim
#define isl_basic_set_fix isl_gmp_basic_set_fix
#define isl_set_lower_bound isl_gmp_set_lower_bound
#define isl_set_upper_bound isl_gmp_set_upper_bound
#define isl_set_fix isl_gmp_set_fix
#define isl_set_plain_is_fixed isl_gmp_set_plain_is_fixed
#define isl_union_map_fixed_power isl_gmp_union_map_fixed_power
#define isl_val_int_from_isl_int isl_gmp_val_int_from_isl_int
#define isl_val_get_num_isl_int isl_gmp_val_get_num_isl_int
#define isl_vec_get_element isl_gmp_vec_get_element
#define isl_vec_set_element isl_gmp_vec_set_element
#define isl_vec_set isl_gmp_vec_set
#define isl_vec_fdiv_r isl_gmp_vec_fdiv_r

View File

@ -21,7 +21,6 @@
#include <isl_vec_private.h>
#include <isl_lp_private.h>
#include <isl_ilp_private.h>
#include <isl/deprecated/ilp_int.h>
/* Given a basic set "bset", construct a basic set U such that for
* each element x in U, the whole unit box positioned at x is inside
@ -506,24 +505,6 @@ enum isl_lp_result isl_set_opt(__isl_keep isl_set *set, int max,
return res;
}
enum isl_lp_result isl_basic_set_max(__isl_keep isl_basic_set *bset,
__isl_keep isl_aff *obj, isl_int *opt)
{
return isl_basic_set_opt(bset, 1, obj, opt);
}
enum isl_lp_result isl_set_max(__isl_keep isl_set *set,
__isl_keep isl_aff *obj, isl_int *opt)
{
return isl_set_opt(set, 1, obj, opt);
}
enum isl_lp_result isl_set_min(__isl_keep isl_set *set,
__isl_keep isl_aff *obj, isl_int *opt)
{
return isl_set_opt(set, 0, obj, opt);
}
/* Convert the result of a function that returns an isl_lp_result
* to an isl_val. The numerator of "v" is set to the optimal value
* if lp_res is isl_lp_ok. "max" is set if a maximum was computed.
@ -835,3 +816,33 @@ __isl_give isl_multi_val *isl_union_set_min_multi_union_pw_aff(
{
return isl_union_set_opt_multi_union_pw_aff(uset, 0, obj);
}
/* Return the maximal value attained by the given set dimension,
* independently of the parameter values and of any other dimensions.
*
* Return infinity if the optimal value is unbounded and
* NaN if "bset" is empty.
*/
__isl_give isl_val *isl_basic_set_dim_max_val(__isl_take isl_basic_set *bset,
int pos)
{
isl_local_space *ls;
isl_aff *obj;
isl_val *v;
if (!bset)
return NULL;
if (pos < 0 || pos >= isl_basic_set_dim(bset, isl_dim_set))
isl_die(isl_basic_set_get_ctx(bset), isl_error_invalid,
"position out of bounds", goto error);
ls = isl_local_space_from_space(isl_basic_set_get_space(bset));
obj = isl_aff_var_on_domain(ls, isl_dim_set, pos);
v = isl_basic_set_max_val(bset, obj);
isl_aff_free(obj);
isl_basic_set_free(bset);
return v;
error:
isl_basic_set_free(bset);
return NULL;
}

View File

@ -3122,7 +3122,7 @@ static __isl_give isl_set *read_aff_domain(__isl_keep isl_stream *s,
tok = isl_stream_next_token(s);
if (tok && (tok->type == ISL_TOKEN_IDENT || tok->is_keyword)) {
isl_stream_push_token(s, tok);
return read_map_tuple(s, dom, isl_dim_set, v, 1, 0);
return read_map_tuple(s, dom, isl_dim_set, v, 0, 0);
}
if (!tok || tok->type != '[') {
isl_stream_error(s, tok, "expecting '['");
@ -3134,7 +3134,7 @@ static __isl_give isl_set *read_aff_domain(__isl_keep isl_stream *s,
isl_stream_push_token(s, tok2);
if (is_empty || next_is_tuple(s) || next_is_fresh_ident(s, v)) {
isl_stream_push_token(s, tok);
dom = read_map_tuple(s, dom, isl_dim_set, v, 1, 0);
dom = read_map_tuple(s, dom, isl_dim_set, v, 0, 0);
} else
isl_stream_push_token(s, tok);

View File

@ -1,8 +1,6 @@
#ifndef ISL_INT_IMATH_H
#define ISL_INT_IMATH_H
#include "isl_hide_deprecated.h"
#include <isl_imath.h>
/* isl_int is the basic integer type, implemented with imath's mp_int. */

View File

@ -15,6 +15,7 @@
#include <isl_sort.h>
#include <isl_tarjan.h>
#include <isl/printer.h>
#define xCAT(A,B) A ## B
#define CAT(A,B) xCAT(A,B)

View File

@ -371,6 +371,57 @@ __isl_give isl_space *isl_local_space_get_space(__isl_keep isl_local_space *ls)
return isl_space_copy(ls->dim);
}
/* Return the space of "ls".
* This may be either a copy or the space itself
* if there is only one reference to "ls".
* This allows the space to be modified inplace
* if both the local space and its space have only a single reference.
* The caller is not allowed to modify "ls" between this call and
* a subsequent call to isl_local_space_restore_space.
* The only exception is that isl_local_space_free can be called instead.
*/
__isl_give isl_space *isl_local_space_take_space(__isl_keep isl_local_space *ls)
{
isl_space *space;
if (!ls)
return NULL;
if (ls->ref != 1)
return isl_local_space_get_space(ls);
space = ls->dim;
ls->dim = NULL;
return space;
}
/* Set the space of "ls" to "space", where the space of "ls" may be missing
* due to a preceding call to isl_local_space_take_space.
* However, in this case, "ls" only has a single reference and
* then the call to isl_local_space_cow has no effect.
*/
__isl_give isl_local_space *isl_local_space_restore_space(
__isl_take isl_local_space *ls, __isl_take isl_space *space)
{
if (!ls || !space)
goto error;
if (ls->dim == space) {
isl_space_free(space);
return ls;
}
ls = isl_local_space_cow(ls);
if (!ls)
goto error;
isl_space_free(ls->dim);
ls->dim = space;
return ls;
error:
isl_local_space_free(ls);
isl_space_free(space);
return NULL;
}
/* Replace the identifier of the tuple of type "type" by "id".
*/
__isl_give isl_local_space *isl_local_space_set_tuple_id(
@ -420,6 +471,20 @@ error:
return NULL;
}
/* Construct a zero-dimensional local space with the given parameter domain.
*/
__isl_give isl_local_space *isl_local_space_set_from_params(
__isl_take isl_local_space *ls)
{
isl_space *space;
space = isl_local_space_take_space(ls);
space = isl_space_set_from_params(space);
ls = isl_local_space_restore_space(ls, space);
return ls;
}
__isl_give isl_local_space *isl_local_space_reset_space(
__isl_take isl_local_space *ls, __isl_take isl_space *dim)
{

View File

@ -43,8 +43,6 @@
#include <isl_options_private.h>
#include <isl_morph.h>
#include <isl_val_private.h>
#include <isl/deprecated/map_int.h>
#include <isl/deprecated/set_int.h>
#include <bset_to_bmap.c>
#include <bset_from_bmap.c>
@ -5924,34 +5922,34 @@ error:
return NULL;
}
__isl_give isl_basic_map *isl_basic_map_empty(__isl_take isl_space *dim)
__isl_give isl_basic_map *isl_basic_map_empty(__isl_take isl_space *space)
{
struct isl_basic_map *bmap;
bmap = isl_basic_map_alloc_space(dim, 0, 1, 0);
bmap = isl_basic_map_alloc_space(space, 0, 1, 0);
bmap = isl_basic_map_set_to_empty(bmap);
return bmap;
}
__isl_give isl_basic_set *isl_basic_set_empty(__isl_take isl_space *dim)
__isl_give isl_basic_set *isl_basic_set_empty(__isl_take isl_space *space)
{
struct isl_basic_set *bset;
bset = isl_basic_set_alloc_space(dim, 0, 1, 0);
bset = isl_basic_set_alloc_space(space, 0, 1, 0);
bset = isl_basic_set_set_to_empty(bset);
return bset;
}
__isl_give isl_basic_map *isl_basic_map_universe(__isl_take isl_space *dim)
__isl_give isl_basic_map *isl_basic_map_universe(__isl_take isl_space *space)
{
struct isl_basic_map *bmap;
bmap = isl_basic_map_alloc_space(dim, 0, 0, 0);
bmap = isl_basic_map_alloc_space(space, 0, 0, 0);
bmap = isl_basic_map_finalize(bmap);
return bmap;
}
__isl_give isl_basic_set *isl_basic_set_universe(__isl_take isl_space *dim)
__isl_give isl_basic_set *isl_basic_set_universe(__isl_take isl_space *space)
{
struct isl_basic_set *bset;
bset = isl_basic_set_alloc_space(dim, 0, 0, 0);
bset = isl_basic_set_alloc_space(space, 0, 0, 0);
bset = isl_basic_set_finalize(bset);
return bset;
}
@ -5991,33 +5989,33 @@ __isl_give isl_set *isl_set_nat_universe(__isl_take isl_space *dim)
return isl_map_nat_universe(dim);
}
__isl_give isl_map *isl_map_empty(__isl_take isl_space *dim)
__isl_give isl_map *isl_map_empty(__isl_take isl_space *space)
{
return isl_map_alloc_space(dim, 0, ISL_MAP_DISJOINT);
return isl_map_alloc_space(space, 0, ISL_MAP_DISJOINT);
}
__isl_give isl_set *isl_set_empty(__isl_take isl_space *dim)
__isl_give isl_set *isl_set_empty(__isl_take isl_space *space)
{
return isl_set_alloc_space(dim, 0, ISL_MAP_DISJOINT);
return isl_set_alloc_space(space, 0, ISL_MAP_DISJOINT);
}
__isl_give isl_map *isl_map_universe(__isl_take isl_space *dim)
__isl_give isl_map *isl_map_universe(__isl_take isl_space *space)
{
struct isl_map *map;
if (!dim)
if (!space)
return NULL;
map = isl_map_alloc_space(isl_space_copy(dim), 1, ISL_MAP_DISJOINT);
map = isl_map_add_basic_map(map, isl_basic_map_universe(dim));
map = isl_map_alloc_space(isl_space_copy(space), 1, ISL_MAP_DISJOINT);
map = isl_map_add_basic_map(map, isl_basic_map_universe(space));
return map;
}
__isl_give isl_set *isl_set_universe(__isl_take isl_space *dim)
__isl_give isl_set *isl_set_universe(__isl_take isl_space *space)
{
struct isl_set *set;
if (!dim)
if (!space)
return NULL;
set = isl_set_alloc_space(isl_space_copy(dim), 1, ISL_MAP_DISJOINT);
set = isl_set_add_basic_set(set, isl_basic_set_universe(dim));
set = isl_set_alloc_space(isl_space_copy(space), 1, ISL_MAP_DISJOINT);
set = isl_set_add_basic_set(set, isl_basic_set_universe(space));
return set;
}
@ -6867,59 +6865,22 @@ static __isl_give isl_set *isl_basic_set_lexmin_compute_divs(
return isl_basic_set_lexopt(bset, ISL_OPT_QE);
}
/* Extract the first and only affine expression from list
* and then add it to *pwaff with the given dom.
* This domain is known to be disjoint from other domains
* because of the way isl_basic_map_foreach_lexmax works.
*/
static isl_stat update_dim_opt(__isl_take isl_basic_set *dom,
__isl_take isl_aff_list *list, void *user)
{
isl_ctx *ctx = isl_basic_set_get_ctx(dom);
isl_aff *aff;
isl_pw_aff **pwaff = user;
isl_pw_aff *pwaff_i;
if (!list)
goto error;
if (isl_aff_list_n_aff(list) != 1)
isl_die(ctx, isl_error_internal,
"expecting single element list", goto error);
aff = isl_aff_list_get_aff(list, 0);
pwaff_i = isl_pw_aff_alloc(isl_set_from_basic_set(dom), aff);
*pwaff = isl_pw_aff_add_disjoint(*pwaff, pwaff_i);
isl_aff_list_free(list);
return isl_stat_ok;
error:
isl_basic_set_free(dom);
isl_aff_list_free(list);
return isl_stat_error;
}
/* Given a basic map with one output dimension, compute the minimum or
* maximum of that dimension as an isl_pw_aff.
*
* The isl_pw_aff is constructed by having isl_basic_map_foreach_lexopt
* call update_dim_opt on each leaf of the result.
* Compute the optimum as a lexicographic optimum over the single
* output dimension and extract the single isl_pw_aff from the result.
*/
static __isl_give isl_pw_aff *basic_map_dim_opt(__isl_keep isl_basic_map *bmap,
int max)
{
isl_space *dim = isl_basic_map_get_space(bmap);
isl_pw_multi_aff *pma;
isl_pw_aff *pwaff;
isl_stat r;
dim = isl_space_from_domain(isl_space_domain(dim));
dim = isl_space_add_dims(dim, isl_dim_out, 1);
pwaff = isl_pw_aff_empty(dim);
r = isl_basic_map_foreach_lexopt(bmap, max, &update_dim_opt, &pwaff);
if (r < 0)
return isl_pw_aff_free(pwaff);
bmap = isl_basic_map_copy(bmap);
pma = isl_basic_map_lexopt_pw_multi_aff(bmap, max ? ISL_OPT_MAX : 0);
pwaff = isl_pw_multi_aff_get_pw_aff(pma, 0);
isl_pw_multi_aff_free(pma);
return pwaff;
}
@ -9407,12 +9368,6 @@ __isl_give isl_val *isl_set_plain_get_val_if_fixed(__isl_keep isl_set *set,
return isl_map_plain_get_val_if_fixed(set, type, pos);
}
isl_bool isl_set_plain_is_fixed(__isl_keep isl_set *set,
enum isl_dim_type type, unsigned pos, isl_int *val)
{
return isl_map_plain_is_fixed(set, type, pos, val);
}
/* Check if dimension dim has fixed value and if so and if val is not NULL,
* then return this fixed value in *val.
*/

View File

@ -476,11 +476,6 @@ isl_bool isl_map_align_params_map_map_and_test(__isl_keep isl_map *map1,
__isl_keep isl_map *map2,
isl_bool (*fn)(__isl_keep isl_map *map1, __isl_keep isl_map *map2));
isl_stat isl_basic_map_foreach_lexopt(__isl_keep isl_basic_map *bmap, int max,
isl_stat (*fn)(__isl_take isl_basic_set *dom,
__isl_take isl_aff_list *list, void *user),
void *user);
__isl_give isl_set *isl_set_substitute(__isl_take isl_set *set,
enum isl_dim_type type, unsigned pos, __isl_keep isl_aff *subs);
@ -536,8 +531,6 @@ __isl_give isl_basic_map *isl_basic_map_shift_div(
__isl_give isl_basic_map_list *isl_map_get_basic_map_list(
__isl_keep isl_map *map);
__isl_give isl_map *isl_map_fixed_power(__isl_take isl_map *map, isl_int exp);
int isl_basic_set_count_upto(__isl_keep isl_basic_set *bset,
isl_int max, isl_int *count);
int isl_set_count_upto(__isl_keep isl_set *set, isl_int max, isl_int *count);

View File

@ -1,11 +1,15 @@
/*
* Copyright 2008-2009 Katholieke Universiteit Leuven
* Copyright 2010 INRIA Saclay
* Copyright 2014 Ecole Normale Superieure
* Copyright 2017 Sven Verdoolaege
*
* Use of this software is governed by the MIT license
*
* Written by Sven Verdoolaege, K.U.Leuven, Departement
* Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
* and INRIA Saclay - Ile-de-France, Parc Club Orsay Universite,
* ZAC des vignes, 4 rue Jacques Monod, 91893 Orsay, France
* and Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France
*/
@ -17,7 +21,6 @@
#include <isl_vec_private.h>
#include <isl_space_private.h>
#include <isl_val_private.h>
#include <isl/deprecated/mat_int.h>
isl_ctx *isl_mat_get_ctx(__isl_keep isl_mat *mat)
{
@ -283,6 +286,34 @@ static isl_stat check_row(__isl_keep isl_mat *mat, int row)
return isl_stat_ok;
}
/* Check that there are "n" columns starting at position "first" in "mat".
*/
static isl_stat check_col_range(__isl_keep isl_mat *mat, unsigned first,
unsigned n)
{
if (!mat)
return isl_stat_error;
if (first + n > mat->n_col || first + n < first)
isl_die(isl_mat_get_ctx(mat), isl_error_invalid,
"column position or range out of bounds",
return isl_stat_error);
return isl_stat_ok;
}
/* Check that there are "n" rows starting at position "first" in "mat".
*/
static isl_stat check_row_range(__isl_keep isl_mat *mat, unsigned first,
unsigned n)
{
if (!mat)
return isl_stat_error;
if (first + n > mat->n_row || first + n < first)
isl_die(isl_mat_get_ctx(mat), isl_error_invalid,
"row position or range out of bounds",
return isl_stat_error);
return isl_stat_ok;
}
int isl_mat_get_element(__isl_keep isl_mat *mat, int row, int col, isl_int *v)
{
if (check_row(mat, row) < 0)
@ -786,9 +817,51 @@ __isl_give isl_mat *isl_mat_lexnonneg_rows(__isl_take isl_mat *mat)
return mat;
}
struct isl_mat *isl_mat_right_kernel(struct isl_mat *mat)
/* Given a matrix "H" is column echelon form, what is the first
* zero column? That is how many initial columns are non-zero?
* Start looking at column "first_col" and only consider
* the columns to be of size "n_row".
* "H" is assumed to be non-NULL.
*
* Since "H" is in column echelon form, the first non-zero entry
* in a column is always in a later position compared to the previous column.
*/
static int hermite_first_zero_col(__isl_keep isl_mat *H, int first_col,
int n_row)
{
int i, rank;
int row, col;
for (col = first_col, row = 0; col < H->n_col; ++col) {
for (; row < n_row; ++row)
if (!isl_int_is_zero(H->row[row][col]))
break;
if (row == n_row)
return col;
}
return H->n_col;
}
/* Return the rank of "mat", or -1 in case of error.
*/
int isl_mat_rank(__isl_keep isl_mat *mat)
{
int rank;
isl_mat *H;
H = isl_mat_left_hermite(isl_mat_copy(mat), 0, NULL, NULL);
if (!H)
return -1;
rank = hermite_first_zero_col(H, 0, H->n_row);
isl_mat_free(H);
return rank;
}
__isl_give isl_mat *isl_mat_right_kernel(__isl_take isl_mat *mat)
{
int rank;
struct isl_mat *U = NULL;
struct isl_mat *K;
@ -796,12 +869,7 @@ struct isl_mat *isl_mat_right_kernel(struct isl_mat *mat)
if (!mat || !U)
goto error;
for (i = 0, rank = 0; rank < mat->n_col; ++rank) {
while (i < mat->n_row && isl_int_is_zero(mat->row[i][rank]))
++i;
if (i >= mat->n_row)
break;
}
rank = hermite_first_zero_col(mat, 0, mat->n_row);
K = isl_mat_alloc(U->ctx, U->n_row, U->n_col - rank);
if (!K)
goto error;
@ -1161,17 +1229,13 @@ __isl_give isl_mat *isl_mat_swap_cols(__isl_take isl_mat *mat,
int r;
mat = isl_mat_cow(mat);
if (!mat)
return NULL;
isl_assert(mat->ctx, i < mat->n_col, goto error);
isl_assert(mat->ctx, j < mat->n_col, goto error);
if (check_col_range(mat, i, 1) < 0 ||
check_col_range(mat, j, 1) < 0)
return isl_mat_free(mat);
for (r = 0; r < mat->n_row; ++r)
isl_int_swap(mat->row[r][i], mat->row[r][j]);
return mat;
error:
isl_mat_free(mat);
return NULL;
}
__isl_give isl_mat *isl_mat_swap_rows(__isl_take isl_mat *mat,
@ -1182,8 +1246,10 @@ __isl_give isl_mat *isl_mat_swap_rows(__isl_take isl_mat *mat,
if (!mat)
return NULL;
mat = isl_mat_cow(mat);
if (!mat)
return NULL;
if (check_row_range(mat, i, 1) < 0 ||
check_row_range(mat, j, 1) < 0)
return isl_mat_free(mat);
t = mat->row[i];
mat->row[i] = mat->row[j];
mat->row[j] = t;
@ -1438,8 +1504,8 @@ __isl_give isl_mat *isl_mat_drop_cols(__isl_take isl_mat *mat,
return mat;
mat = isl_mat_cow(mat);
if (!mat)
return NULL;
if (check_col_range(mat, col, n) < 0)
return isl_mat_free(mat);
if (col != mat->n_col-n) {
for (r = 0; r < mat->n_row; ++r)
@ -1456,8 +1522,8 @@ __isl_give isl_mat *isl_mat_drop_rows(__isl_take isl_mat *mat,
int r;
mat = isl_mat_cow(mat);
if (!mat)
return NULL;
if (check_row_range(mat, row, n) < 0)
return isl_mat_free(mat);
for (r = row; r+n < mat->n_row; ++r)
mat->row[r] = mat->row[r+n];
@ -1471,8 +1537,8 @@ __isl_give isl_mat *isl_mat_insert_cols(__isl_take isl_mat *mat,
{
isl_mat *ext;
if (!mat)
return NULL;
if (check_col_range(mat, col, 0) < 0)
return isl_mat_free(mat);
if (n == 0)
return mat;
@ -1521,8 +1587,8 @@ __isl_give isl_mat *isl_mat_insert_rows(__isl_take isl_mat *mat,
{
isl_mat *ext;
if (!mat)
return NULL;
if (check_row_range(mat, row, 0) < 0)
return isl_mat_free(mat);
if (n == 0)
return mat;
@ -1952,3 +2018,82 @@ int isl_mat_initial_non_zero_cols(__isl_keep isl_mat *mat)
return i;
}
/* Return a basis for the space spanned by the rows of "mat".
* Any basis will do, so simply perform Gaussian elimination and
* remove the empty rows.
*/
__isl_give isl_mat *isl_mat_row_basis(__isl_take isl_mat *mat)
{
return isl_mat_reverse_gauss(mat);
}
/* Return rows that extend a basis of "mat1" to one
* that covers both "mat1" and "mat2".
* The Hermite normal form of the concatenation of the two matrices is
*
* [ Q1 ]
* [ M1 ] = [ H1 0 0 ] [ Q2 ]
* [ M2 ] = [ H2 H3 0 ] [ Q3 ]
*
* The number of columns in H1 and H3 determine the number of rows
* in Q1 and Q2. Q1 is a basis for M1, while Q2 extends this basis
* to also cover M2.
*/
__isl_give isl_mat *isl_mat_row_basis_extension(
__isl_take isl_mat *mat1, __isl_take isl_mat *mat2)
{
int n_row;
int r1, r, n1;
isl_mat *H, *Q;
n1 = isl_mat_rows(mat1);
H = isl_mat_concat(mat1, mat2);
H = isl_mat_left_hermite(H, 0, NULL, &Q);
if (!H || !Q)
goto error;
r1 = hermite_first_zero_col(H, 0, n1);
r = hermite_first_zero_col(H, r1, H->n_row);
n_row = isl_mat_rows(Q);
Q = isl_mat_drop_rows(Q, r, n_row - r);
Q = isl_mat_drop_rows(Q, 0, r1);
isl_mat_free(H);
return Q;
error:
isl_mat_free(H);
isl_mat_free(Q);
return NULL;
}
/* Are the rows of "mat1" linearly independent of those of "mat2"?
* That is, is there no linear dependence among the combined rows
* that is not already present in either "mat1" or "mat2"?
* In other words, is the rank of "mat1" and "mat2" combined equal
* to the sum of the ranks of "mat1" and "mat2"?
*/
isl_bool isl_mat_has_linearly_independent_rows(__isl_keep isl_mat *mat1,
__isl_keep isl_mat *mat2)
{
int r1, r2, r;
isl_mat *mat;
r1 = isl_mat_rank(mat1);
if (r1 < 0)
return isl_bool_error;
if (r1 == 0)
return isl_bool_true;
r2 = isl_mat_rank(mat2);
if (r2 < 0)
return isl_bool_error;
if (r2 == 0)
return isl_bool_true;
mat = isl_mat_concat(isl_mat_copy(mat1), isl_mat_copy(mat2));
r = isl_mat_rank(mat);
isl_mat_free(mat);
if (r < 0)
return isl_bool_error;
return r == r1 + r2;
}

View File

@ -23,6 +23,8 @@ struct isl_mat {
uint32_t isl_mat_get_hash(__isl_keep isl_mat *mat);
__isl_give isl_mat *isl_mat_zero(isl_ctx *ctx, unsigned n_row, unsigned n_col);
__isl_give isl_mat *isl_mat_dup(__isl_keep isl_mat *mat);
__isl_give isl_mat *isl_mat_cow(__isl_take isl_mat *mat);
__isl_give isl_mat *isl_mat_sub_alloc(__isl_keep isl_mat *mat,
unsigned first_row, unsigned n_row, unsigned first_col, unsigned n_col);
__isl_give isl_mat *isl_mat_sub_alloc6(isl_ctx *ctx, isl_int **row,

View File

@ -543,7 +543,7 @@ __isl_give isl_morph *isl_basic_set_parameter_compression(
/* Add stride constraints to "bset" based on the inverse mapping
* that was plugged in. In particular, if morph maps x' to x,
* the the constraints of the original input
* the constraints of the original input
*
* A x' + b >= 0
*

105
polly/lib/External/isl/isl_multi_dims.c vendored Normal file
View File

@ -0,0 +1,105 @@
/*
* Copyright 2011 Sven Verdoolaege
* Copyright 2012-2013 Ecole Normale Superieure
*
* Use of this software is governed by the MIT license
*
* Written by Sven Verdoolaege,
* Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France
*/
#include <isl_space_private.h>
#include <isl_multi_macro.h>
/* Check whether "multi" has non-zero coefficients for any dimension
* in the given range or if any of these dimensions appear
* with non-zero coefficients in any of the integer divisions involved.
*/
isl_bool FN(MULTI(BASE),involves_dims)(__isl_keep MULTI(BASE) *multi,
enum isl_dim_type type, unsigned first, unsigned n)
{
int i;
if (!multi)
return isl_bool_error;
if (multi->n == 0 || n == 0)
return isl_bool_false;
for (i = 0; i < multi->n; ++i) {
isl_bool involves;
involves = FN(EL,involves_dims)(multi->p[i], type, first, n);
if (involves < 0 || involves)
return involves;
}
return isl_bool_false;
}
__isl_give MULTI(BASE) *FN(MULTI(BASE),insert_dims)(
__isl_take MULTI(BASE) *multi,
enum isl_dim_type type, unsigned first, unsigned n)
{
int i;
if (!multi)
return NULL;
if (type == isl_dim_out)
isl_die(FN(MULTI(BASE),get_ctx)(multi), isl_error_invalid,
"cannot insert output/set dimensions",
return FN(MULTI(BASE),free)(multi));
if (n == 0 && !isl_space_is_named_or_nested(multi->space, type))
return multi;
multi = FN(MULTI(BASE),cow)(multi);
if (!multi)
return NULL;
multi->space = isl_space_insert_dims(multi->space, type, first, n);
if (!multi->space)
return FN(MULTI(BASE),free)(multi);
for (i = 0; i < multi->n; ++i) {
multi->p[i] = FN(EL,insert_dims)(multi->p[i], type, first, n);
if (!multi->p[i])
return FN(MULTI(BASE),free)(multi);
}
return multi;
}
__isl_give MULTI(BASE) *FN(MULTI(BASE),add_dims)(__isl_take MULTI(BASE) *multi,
enum isl_dim_type type, unsigned n)
{
unsigned pos;
pos = FN(MULTI(BASE),dim)(multi, type);
return FN(MULTI(BASE),insert_dims)(multi, type, pos, n);
}
/* Project the domain of "multi" onto its parameter space.
* "multi" may not involve any of the domain dimensions.
*/
__isl_give MULTI(BASE) *FN(MULTI(BASE),project_domain_on_params)(
__isl_take MULTI(BASE) *multi)
{
unsigned n;
isl_bool involves;
isl_space *space;
n = FN(MULTI(BASE),dim)(multi, isl_dim_in);
involves = FN(MULTI(BASE),involves_dims)(multi, isl_dim_in, 0, n);
if (involves < 0)
return FN(MULTI(BASE),free)(multi);
if (involves)
isl_die(FN(MULTI(BASE),get_ctx)(multi), isl_error_invalid,
"expression involves some of the domain dimensions",
return FN(MULTI(BASE),free)(multi));
multi = FN(MULTI(BASE),drop_dims)(multi, isl_dim_in, 0, n);
space = FN(MULTI(BASE),get_domain_space)(multi);
space = isl_space_params(space);
multi = FN(MULTI(BASE),reset_domain_space)(multi, space);
return multi;
}

View File

@ -129,75 +129,6 @@ __isl_null MULTI(BASE) *FN(MULTI(BASE),free)(__isl_take MULTI(BASE) *multi)
return NULL;
}
#ifndef NO_DIMS
/* Check whether "multi" has non-zero coefficients for any dimension
* in the given range or if any of these dimensions appear
* with non-zero coefficients in any of the integer divisions involved.
*/
isl_bool FN(MULTI(BASE),involves_dims)(__isl_keep MULTI(BASE) *multi,
enum isl_dim_type type, unsigned first, unsigned n)
{
int i;
if (!multi)
return isl_bool_error;
if (multi->n == 0 || n == 0)
return isl_bool_false;
for (i = 0; i < multi->n; ++i) {
isl_bool involves;
involves = FN(EL,involves_dims)(multi->p[i], type, first, n);
if (involves < 0 || involves)
return involves;
}
return isl_bool_false;
}
__isl_give MULTI(BASE) *FN(MULTI(BASE),insert_dims)(
__isl_take MULTI(BASE) *multi,
enum isl_dim_type type, unsigned first, unsigned n)
{
int i;
if (!multi)
return NULL;
if (type == isl_dim_out)
isl_die(FN(MULTI(BASE),get_ctx)(multi), isl_error_invalid,
"cannot insert output/set dimensions",
return FN(MULTI(BASE),free)(multi));
if (n == 0 && !isl_space_is_named_or_nested(multi->space, type))
return multi;
multi = FN(MULTI(BASE),cow)(multi);
if (!multi)
return NULL;
multi->space = isl_space_insert_dims(multi->space, type, first, n);
if (!multi->space)
return FN(MULTI(BASE),free)(multi);
for (i = 0; i < multi->n; ++i) {
multi->p[i] = FN(EL,insert_dims)(multi->p[i], type, first, n);
if (!multi->p[i])
return FN(MULTI(BASE),free)(multi);
}
return multi;
}
__isl_give MULTI(BASE) *FN(MULTI(BASE),add_dims)(__isl_take MULTI(BASE) *multi,
enum isl_dim_type type, unsigned n)
{
unsigned pos;
pos = FN(MULTI(BASE),dim)(multi, type);
return FN(MULTI(BASE),insert_dims)(multi, type, pos, n);
}
#endif
unsigned FN(MULTI(BASE),dim)(__isl_keep MULTI(BASE) *multi,
enum isl_dim_type type)
{
@ -333,7 +264,7 @@ error:
/* 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,
* which we pass along to the element function since we don't how
* which we pass along to the element function since we don't know how
* that is represented either.
*/
__isl_give MULTI(BASE) *FN(MULTI(BASE),reset_space_and_domain)(
@ -1326,7 +1257,7 @@ __isl_give MULTI(BASE) *FN(MULTI(BASE),mod_multi_val)(
multi = FN(MULTI(BASE),cow)(multi);
if (!multi)
return NULL;
goto error;
for (i = 0; i < multi->n; ++i) {
isl_val *v;

View File

@ -13,6 +13,7 @@
* B.P. 105 - 78153 Le Chesnay, France
*/
#include <isl/val.h>
#include <isl/aff.h>
#include <isl/set.h>
#include <isl/map.h>

View File

@ -35,6 +35,7 @@
#include <bset_to_bmap.c>
#include <set_to_map.c>
#include <uset_to_umap.c>
static const char *s_to[2] = { " -> ", " \\to " };
static const char *s_and[2] = { " and ", " \\wedge " };
@ -49,6 +50,7 @@ static const char *s_such_that[2] = { " : ", " \\mid " };
static const char *s_open_exists[2] = { "exists (", "\\exists \\, " };
static const char *s_close_exists[2] = { ")", "" };
static const char *s_div_prefix[2] = { "e", "\\alpha_" };
static const char *s_mod[2] = { "mod", "\\bmod" };
static const char *s_param_prefix[2] = { "p", "p_" };
static const char *s_input_prefix[2] = { "i", "i_" };
static const char *s_output_prefix[2] = { "o", "o_" };
@ -316,15 +318,20 @@ static __isl_give isl_printer *print_affine_of_len(__isl_keep isl_space *dim,
return p;
}
/* Print an affine expression "c" corresponding to a constraint in "bmap"
/* Print an affine expression "c"
* to "p", with the variable names taken from "space" and
* the integer division definitions taken from "div".
*/
static __isl_give isl_printer *print_affine(__isl_keep isl_basic_map *bmap,
__isl_keep isl_space *space, __isl_keep isl_mat *div,
__isl_take isl_printer *p, isl_int *c)
static __isl_give isl_printer *print_affine(__isl_take isl_printer *p,
__isl_keep isl_space *space, __isl_keep isl_mat *div, isl_int *c)
{
unsigned len = 1 + isl_basic_map_total_dim(bmap);
unsigned n_div;
unsigned len;
if (!space || !div)
return isl_printer_free(p);
n_div = isl_mat_rows(div);
len = 1 + isl_space_dim(space, isl_dim_all) + n_div;
return print_affine_of_len(space, div, p, c, len);
}
@ -493,7 +500,7 @@ static const char *constraint_op(int sign, int strict, int latex)
return s_ge[latex];
}
/* Print one side of a constraint "c" from "bmap" to "p", with
/* Print one side of a constraint "c" to "p", with
* the variable names taken from "space" and the integer division definitions
* taken from "div".
* "last" is the position of the last non-zero coefficient.
@ -503,20 +510,13 @@ static const char *constraint_op(int sign, int strict, int latex)
* c' op
*
* is printed.
* "first_constraint" is set if this is the first constraint
* in the conjunction.
*/
static __isl_give isl_printer *print_half_constraint(
__isl_keep isl_basic_map *bmap,
static __isl_give isl_printer *print_half_constraint(__isl_take isl_printer *p,
__isl_keep isl_space *space, __isl_keep isl_mat *div,
__isl_take isl_printer *p, isl_int *c, int last, const char *op,
int first_constraint, int latex)
isl_int *c, int last, const char *op, int latex)
{
if (!first_constraint)
p = isl_printer_print_str(p, s_and[latex]);
isl_int_set_si(c[last], 0);
p = print_affine(bmap, space, div, p, c);
p = print_affine(p, space, div, c);
p = isl_printer_print_str(p, " ");
p = isl_printer_print_str(p, op);
@ -525,7 +525,7 @@ static __isl_give isl_printer *print_half_constraint(
return p;
}
/* Print a constraint "c" from "bmap" to "p", with the variable names
/* Print a constraint "c" to "p", with the variable names
* taken from "space" and the integer division definitions taken from "div".
* "last" is the position of the last non-zero coefficient, which is
* moreover assumed to be negative.
@ -533,18 +533,11 @@ static __isl_give isl_printer *print_half_constraint(
* the constraint is printed in the form
*
* -c[last] op c'
*
* "first_constraint" is set if this is the first constraint
* in the conjunction.
*/
static __isl_give isl_printer *print_constraint(__isl_keep isl_basic_map *bmap,
static __isl_give isl_printer *print_constraint(__isl_take isl_printer *p,
__isl_keep isl_space *space, __isl_keep isl_mat *div,
__isl_take isl_printer *p,
isl_int *c, int last, const char *op, int first_constraint, int latex)
isl_int *c, int last, const char *op, int latex)
{
if (!first_constraint)
p = isl_printer_print_str(p, s_and[latex]);
isl_int_abs(c[last], c[last]);
p = print_term(space, div, c[last], last, p, latex);
@ -554,11 +547,147 @@ static __isl_give isl_printer *print_constraint(__isl_keep isl_basic_map *bmap,
p = isl_printer_print_str(p, " ");
isl_int_set_si(c[last], 0);
p = print_affine(bmap, space, div, p, c);
p = print_affine(p, space, div, c);
return p;
}
/* Given an integer division
*
* floor(f/m)
*
* at position "pos" in "div", print the corresponding modulo expression
*
* (f) mod m
*
* to "p". The variable names are taken from "space", while any
* nested integer division definitions are taken from "div".
*/
static __isl_give isl_printer *print_mod(__isl_take isl_printer *p,
__isl_keep isl_space *space, __isl_keep isl_mat *div, int pos,
int latex)
{
if (!p || !div)
return isl_printer_free(p);
p = isl_printer_print_str(p, "(");
p = print_affine_of_len(space, div, p,
div->row[pos] + 1, div->n_col - 1);
p = isl_printer_print_str(p, ") ");
p = isl_printer_print_str(p, s_mod[latex]);
p = isl_printer_print_str(p, " ");
p = isl_printer_print_isl_int(p, div->row[pos][0]);
return p;
}
/* Can the equality constraints "c" be printed as a modulo constraint?
* In particular, is of the form
*
* f - a m floor(g/m) = 0,
*
* with c = -a m the coefficient at position "pos"?
* Return the position of the corresponding integer division if so.
* Return the number of integer divisions if not.
* Return -1 on error.
*
* Modulo constraints are currently not printed in C format.
* Other than that, "pos" needs to correspond to an integer division
* with explicit representation and "c" needs to be a multiple
* of the denominator of the integer division.
*/
static int print_as_modulo_pos(__isl_keep isl_printer *p,
__isl_keep isl_space *space, __isl_keep isl_mat *div, unsigned pos,
isl_int c)
{
isl_bool can_print;
unsigned n_div;
enum isl_dim_type type;
if (!p)
return -1;
n_div = isl_mat_rows(div);
if (p->output_format == ISL_FORMAT_C)
return n_div;
type = pos2type(space, &pos);
if (type != isl_dim_div)
return n_div;
can_print = can_print_div_expr(p, div, pos);
if (can_print < 0)
return -1;
if (!can_print)
return n_div;
if (!isl_int_is_divisible_by(c, div->row[pos][0]))
return n_div;
return pos;
}
/* Print equality constraint "c" to "p" as a modulo constraint,
* with the variable names taken from "space" and
* the integer division definitions taken from "div".
* "last" is the position of the last non-zero coefficient, which is
* moreover assumed to be negative and a multiple of the denominator
* of the corresponding integer division. "div_pos" is the corresponding
* position in the sequence of integer divisions.
*
* The equality is of the form
*
* f - a m floor(g/m) = 0.
*
* Print it as
*
* a (g mod m) = -f + a g
*/
static __isl_give isl_printer *print_eq_mod_constraint(
__isl_take isl_printer *p, __isl_keep isl_space *space,
__isl_keep isl_mat *div, unsigned div_pos,
isl_int *c, int last, int latex)
{
isl_ctx *ctx;
int multiple;
ctx = isl_printer_get_ctx(p);
isl_int_divexact(c[last], c[last], div->row[div_pos][0]);
isl_int_abs(c[last], c[last]);
multiple = !isl_int_is_one(c[last]);
if (multiple) {
p = isl_printer_print_isl_int(p, c[last]);
p = isl_printer_print_str(p, "*(");
}
p = print_mod(p, space, div, div_pos, latex);
if (multiple)
p = isl_printer_print_str(p, ")");
p = isl_printer_print_str(p, " = ");
isl_seq_combine(c, ctx->negone, c,
c[last], div->row[div_pos] + 1, last);
isl_int_set_si(c[last], 0);
p = print_affine(p, space, div, c);
return p;
}
/* Print equality constraint "c" to "p", with the variable names
* taken from "space" and the integer division definitions taken from "div".
* "last" is the position of the last non-zero coefficient, which is
* moreover assumed to be negative.
*
* If possible, print the equality constraint as a modulo constraint.
*/
static __isl_give isl_printer *print_eq_constraint(__isl_take isl_printer *p,
__isl_keep isl_space *space, __isl_keep isl_mat *div, isl_int *c,
int last, int latex)
{
unsigned n_div;
int div_pos;
n_div = isl_mat_rows(div);
div_pos = print_as_modulo_pos(p, space, div, last, c[last]);
if (div_pos < 0)
return isl_printer_free(p);
if (div_pos < n_div)
return print_eq_mod_constraint(p, space, div, div_pos,
c, last, latex);
return print_constraint(p, space, div, c, last, "=", latex);
}
/* Print the constraints of "bmap" to "p".
* The names of the variables are taken from "space" and
* the integer division definitions are taken from "div".
@ -632,12 +761,13 @@ static __isl_give isl_printer *print_constraints(__isl_keep isl_basic_map *bmap,
p = isl_printer_print_str(p, "0 = 0");
continue;
}
if (!first)
p = isl_printer_print_str(p, s_and[latex]);
if (isl_int_is_neg(bmap->eq[i][l]))
isl_seq_cpy(c->el, bmap->eq[i], 1 + total);
else
isl_seq_neg(c->el, bmap->eq[i], 1 + total);
p = print_constraint(bmap, space, div, p, c->el, l,
"=", first, latex);
p = print_eq_constraint(p, space, div, c->el, l, latex);
first = 0;
}
for (i = 0; i < bmap->n_ineq; ++i) {
@ -657,6 +787,8 @@ static __isl_give isl_printer *print_constraints(__isl_keep isl_basic_map *bmap,
if (is_div)
continue;
}
if (!first)
p = isl_printer_print_str(p, s_and[latex]);
s = isl_int_sgn(bmap->ineq[i][l]);
strict = !rational && isl_int_is_negone(bmap->ineq[i][0]);
if (s < 0)
@ -667,13 +799,13 @@ static __isl_give isl_printer *print_constraints(__isl_keep isl_basic_map *bmap,
isl_int_set_si(c->el[0], 0);
if (!dump && next_is_opposite(bmap, i, l)) {
op = constraint_op(-s, strict, latex);
p = print_half_constraint(bmap, space, div, p, c->el, l,
op, first, latex);
p = print_half_constraint(p, space, div, c->el, l,
op, latex);
first = 1;
} else {
op = constraint_op(s, strict, latex);
p = print_constraint(bmap, space, div, p, c->el, l,
op, first, latex);
p = print_constraint(p, space, div, c->el, l,
op, latex);
first = 0;
}
}
@ -787,6 +919,21 @@ static __isl_give isl_printer *open_exists(__isl_take isl_printer *p,
return p;
}
/* Remove the explicit representations of all local variables in "div".
*/
static __isl_give isl_mat *mark_all_unknown(__isl_take isl_mat *div)
{
int i, n_div;
if (!div)
return NULL;
n_div = isl_mat_rows(div);
for (i = 0; i < n_div; ++i)
div = isl_mat_set_element_si(div, i, 0, 0);
return div;
}
/* Print the constraints of "bmap" to "p".
* The names of the variables are taken from "space".
* "latex" is set if the constraints should be printed in LaTeX format.
@ -808,7 +955,7 @@ static __isl_give isl_printer *print_disjunct(__isl_keep isl_basic_map *bmap,
p = open_exists(p, space, div, latex);
if (dump)
div = isl_mat_free(div);
div = mark_all_unknown(div);
p = print_constraints(bmap, space, div, p, latex);
isl_mat_free(div);
@ -928,7 +1075,7 @@ static __isl_give isl_printer *print_disjuncts_core(__isl_keep isl_map *map,
int i;
if (map->n == 0)
p = isl_printer_print_str(p, "1 = 0");
p = isl_printer_print_str(p, "false");
for (i = 0; i < map->n; ++i) {
if (i)
p = isl_printer_print_str(p, s_or[latex]);
@ -1488,9 +1635,9 @@ __isl_give isl_printer *isl_printer_print_union_set(__isl_take isl_printer *p,
goto error;
if (p->output_format == ISL_FORMAT_ISL)
return isl_union_map_print_isl((isl_union_map *)uset, p);
return isl_union_map_print_isl(uset_to_umap(uset), p);
if (p->output_format == ISL_FORMAT_LATEX)
return isl_union_map_print_latex((isl_union_map *)uset, p);
return isl_union_map_print_latex(uset_to_umap(uset), p);
isl_die(p->ctx, isl_error_invalid,
"invalid output format for isl_union_set", goto error);
@ -2985,7 +3132,7 @@ static __isl_give isl_printer *print_dim_mpa(__isl_take isl_printer *p,
pa = mpa->p[pos];
if (pa->n == 0)
return isl_printer_print_str(p, "(0 : 1 = 0)");
return isl_printer_print_str(p, "(0 : false)");
need_parens = pa->n != 1 || !isl_set_plain_is_universe(pa->p[0].set);
if (need_parens)

View File

@ -9,7 +9,6 @@
#include <isl_val_private.h>
#include <isl_vec_private.h>
#include <isl_output_private.h>
#include <isl/deprecated/point_int.h>
#include <set_to_map.c>
@ -133,23 +132,6 @@ isl_bool isl_point_is_void(__isl_keep isl_point *pnt)
return pnt->vec->size == 0;
}
int isl_point_get_coordinate(__isl_keep isl_point *pnt,
enum isl_dim_type type, int pos, isl_int *v)
{
if (!pnt || isl_point_is_void(pnt))
return -1;
if (pos < 0 || pos >= isl_space_dim(pnt->dim, type))
isl_die(isl_point_get_ctx(pnt), isl_error_invalid,
"position out of bounds", return -1);
if (type == isl_dim_set)
pos += isl_space_dim(pnt->dim, isl_dim_param);
isl_int_set(*v, pnt->vec->el[1 + pos]);
return 0;
}
/* Return the value of coordinate "pos" of type "type" of "pnt".
*/
__isl_give isl_val *isl_point_get_coordinate_val(__isl_keep isl_point *pnt,
@ -177,30 +159,6 @@ __isl_give isl_val *isl_point_get_coordinate_val(__isl_keep isl_point *pnt,
return isl_val_normalize(v);
}
__isl_give isl_point *isl_point_set_coordinate(__isl_take isl_point *pnt,
enum isl_dim_type type, int pos, isl_int v)
{
if (!pnt || isl_point_is_void(pnt))
return pnt;
pnt = isl_point_cow(pnt);
if (!pnt)
return NULL;
pnt->vec = isl_vec_cow(pnt->vec);
if (!pnt->vec)
goto error;
if (type == isl_dim_set)
pos += isl_space_dim(pnt->dim, isl_dim_param);
isl_int_set(pnt->vec->el[1 + pos], v);
return pnt;
error:
isl_point_free(pnt);
return NULL;
}
/* Replace coordinate "pos" of type "type" of "pnt" by "v".
*/
__isl_give isl_point *isl_point_set_coordinate_val(__isl_take isl_point *pnt,

View File

@ -28,7 +28,6 @@
#include <isl_aff_private.h>
#include <isl_val_private.h>
#include <isl_config.h>
#include <isl/deprecated/polynomial_int.h>
static unsigned pos(__isl_keep isl_space *dim, enum isl_dim_type type)
{
@ -3856,13 +3855,6 @@ void isl_term_get_num(__isl_keep isl_term *term, isl_int *n)
isl_int_set(*n, term->n);
}
void isl_term_get_den(__isl_keep isl_term *term, isl_int *d)
{
if (!term)
return;
isl_int_set(*d, term->d);
}
/* Return the coefficient of the term "term".
*/
__isl_give isl_val *isl_term_get_coefficient_val(__isl_keep isl_term *term)

View File

@ -251,6 +251,9 @@ __isl_give isl_qpolynomial *isl_qpolynomial_mul_isl_int(
__isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_mul_isl_int(
__isl_take isl_pw_qpolynomial *pwqp, isl_int v);
__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_scale(
__isl_take isl_qpolynomial_fold *fold, isl_int v);
__isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_mul_isl_int(
__isl_take isl_qpolynomial_fold *fold, isl_int v);
__isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_mul_isl_int(

View File

@ -100,6 +100,41 @@ error:
return NULL;
}
/* Does the space of "set" correspond to that of the domain of "el".
*/
static isl_bool FN(PW,compatible_domain)(__isl_keep EL *el,
__isl_keep isl_set *set)
{
isl_bool ok;
isl_space *el_space, *set_space;
if (!set || !el)
return isl_bool_error;
set_space = isl_set_get_space(set);
el_space = FN(EL,get_space)(el);
ok = isl_space_is_domain_internal(set_space, el_space);
isl_space_free(el_space);
isl_space_free(set_space);
return ok;
}
/* Check that the space of "set" corresponds to that of the domain of "el".
*/
static isl_stat FN(PW,check_compatible_domain)(__isl_keep EL *el,
__isl_keep isl_set *set)
{
isl_bool ok;
ok = FN(PW,compatible_domain)(el, set);
if (ok < 0)
return isl_stat_error;
if (!ok)
isl_die(isl_set_get_ctx(set), isl_error_invalid,
"incompatible spaces", return isl_stat_error);
return isl_stat_ok;
}
#ifdef HAS_TYPE
__isl_give PW *FN(PW,alloc)(enum isl_fold type,
__isl_take isl_set *set, __isl_take EL *el)
@ -1464,9 +1499,16 @@ __isl_give isl_val *FN(PW,min)(__isl_take PW *pw)
}
#endif
/* Return the space of "pw".
*/
__isl_keep isl_space *FN(PW,peek_space)(__isl_keep PW *pw)
{
return pw ? pw->dim : NULL;
}
__isl_give isl_space *FN(PW,get_space)(__isl_keep PW *pw)
{
return pw ? isl_space_copy(pw->dim) : NULL;
return isl_space_copy(FN(PW,peek_space)(pw));
}
__isl_give isl_space *FN(PW,get_domain_space)(__isl_keep PW *pw)

View File

@ -1,4 +1,5 @@
#include <isl_ctx_private.h>
#include <isl/val.h>
#include <isl_constraint_private.h>
#include <isl/set.h>
#include <isl_polynomial_private.h>

View File

@ -167,20 +167,20 @@ error:
}
__isl_give isl_reordering *isl_reordering_extend_space(
__isl_take isl_reordering *exp, __isl_take isl_space *dim)
__isl_take isl_reordering *exp, __isl_take isl_space *space)
{
isl_reordering *res;
if (!exp || !dim)
if (!exp || !space)
goto error;
res = isl_reordering_extend(isl_reordering_copy(exp),
isl_space_dim(dim, isl_dim_all) - exp->len);
isl_space_dim(space, isl_dim_all) - exp->len);
res = isl_reordering_cow(res);
if (!res)
goto error;
isl_space_free(res->dim);
res->dim = isl_space_replace(dim, isl_dim_param, exp->dim);
res->dim = isl_space_replace_params(space, exp->dim);
isl_reordering_free(exp);
@ -190,7 +190,7 @@ __isl_give isl_reordering *isl_reordering_extend_space(
return res;
error:
isl_reordering_free(exp);
isl_space_free(dim);
isl_space_free(space);
return NULL;
}

View File

@ -24,7 +24,7 @@ __isl_give isl_reordering *isl_parameter_alignment_reordering(
__isl_give isl_reordering *isl_reordering_copy(__isl_keep isl_reordering *exp);
void *isl_reordering_free(__isl_take isl_reordering *exp);
__isl_give isl_reordering *isl_reordering_extend_space(
__isl_take isl_reordering *exp, __isl_take isl_space *dim);
__isl_take isl_reordering *exp, __isl_take isl_space *space);
__isl_give isl_reordering *isl_reordering_extend(__isl_take isl_reordering *exp,
unsigned extra);

View File

@ -12,16 +12,17 @@
*/
#include <isl/ctx.h>
#include <isl/val.h>
#include <isl_aff_private.h>
#include <isl/map.h>
#include <isl/set.h>
#include <isl/schedule.h>
#include <isl/schedule_node.h>
#include <isl_sort.h>
#include <isl/printer.h>
#include <isl_schedule_private.h>
#include <isl_schedule_tree.h>
#include <isl_schedule_node_private.h>
#include <isl_band_private.h>
/* Return a schedule encapsulating the given schedule tree.
*
@ -100,9 +101,6 @@ __isl_give isl_schedule *isl_schedule_copy(__isl_keep isl_schedule *sched)
/* Return an isl_schedule that is equal to "schedule" and that has only
* a single reference.
*
* We only need and support this function when the schedule is represented
* as a schedule tree.
*/
__isl_give isl_schedule *isl_schedule_cow(__isl_take isl_schedule *schedule)
{
@ -115,10 +113,6 @@ __isl_give isl_schedule *isl_schedule_cow(__isl_take isl_schedule *schedule)
return schedule;
ctx = isl_schedule_get_ctx(schedule);
if (!schedule->root)
isl_die(ctx, isl_error_internal,
"only for schedule tree based schedules",
return isl_schedule_free(schedule));
schedule->ref--;
tree = isl_schedule_tree_copy(schedule->root);
return isl_schedule_from_schedule_tree(ctx, tree);
@ -132,7 +126,6 @@ __isl_null isl_schedule *isl_schedule_free(__isl_take isl_schedule *sched)
if (--sched->ref > 0)
return NULL;
isl_band_list_free(sched->band_forest);
isl_schedule_tree_free(sched->root);
isl_schedule_tree_free(sched->leaf);
free(sched);
@ -202,10 +195,6 @@ __isl_give isl_space *isl_schedule_get_space(
if (!schedule)
return NULL;
if (!schedule->root)
isl_die(isl_schedule_get_ctx(schedule), isl_error_invalid,
"schedule tree representation not available",
return NULL);
type = isl_schedule_tree_get_type(schedule->root);
if (type != isl_schedule_node_domain)
isl_die(isl_schedule_get_ctx(schedule), isl_error_internal,
@ -230,11 +219,6 @@ __isl_give isl_schedule_node *isl_schedule_get_root(
if (!schedule)
return NULL;
if (!schedule->root)
isl_die(isl_schedule_get_ctx(schedule), isl_error_invalid,
"schedule tree representation not available",
return NULL);
ctx = isl_schedule_get_ctx(schedule);
tree = isl_schedule_tree_copy(schedule->root);
schedule = isl_schedule_copy(schedule);
@ -242,76 +226,6 @@ __isl_give isl_schedule_node *isl_schedule_get_root(
return isl_schedule_node_alloc(schedule, tree, ancestors, NULL);
}
/* Set max_out to the maximal number of output dimensions over
* all maps.
*/
static isl_stat update_max_out(__isl_take isl_map *map, void *user)
{
int *max_out = user;
int n_out = isl_map_dim(map, isl_dim_out);
if (n_out > *max_out)
*max_out = n_out;
isl_map_free(map);
return isl_stat_ok;
}
/* Internal data structure for map_pad_range.
*
* "max_out" is the maximal schedule dimension.
* "res" collects the results.
*/
struct isl_pad_schedule_map_data {
int max_out;
isl_union_map *res;
};
/* Pad the range of the given map with zeros to data->max_out and
* then add the result to data->res.
*/
static isl_stat map_pad_range(__isl_take isl_map *map, void *user)
{
struct isl_pad_schedule_map_data *data = user;
int i;
int n_out = isl_map_dim(map, isl_dim_out);
map = isl_map_add_dims(map, isl_dim_out, data->max_out - n_out);
for (i = n_out; i < data->max_out; ++i)
map = isl_map_fix_si(map, isl_dim_out, i, 0);
data->res = isl_union_map_add_map(data->res, map);
if (!data->res)
return isl_stat_error;
return isl_stat_ok;
}
/* Pad the ranges of the maps in the union map with zeros such they all have
* the same dimension.
*/
static __isl_give isl_union_map *pad_schedule_map(
__isl_take isl_union_map *umap)
{
struct isl_pad_schedule_map_data data;
if (!umap)
return NULL;
if (isl_union_map_n_map(umap) <= 1)
return umap;
data.max_out = 0;
if (isl_union_map_foreach_map(umap, &update_max_out, &data.max_out) < 0)
return isl_union_map_free(umap);
data.res = isl_union_map_empty(isl_union_map_get_space(umap));
if (isl_union_map_foreach_map(umap, &map_pad_range, &data) < 0)
data.res = isl_union_map_free(data.res);
isl_union_map_free(umap);
return data.res;
}
/* Return the domain of the root domain node of "schedule".
*/
__isl_give isl_union_set *isl_schedule_get_domain(
@ -319,10 +233,6 @@ __isl_give isl_union_set *isl_schedule_get_domain(
{
if (!schedule)
return NULL;
if (!schedule->root)
isl_die(isl_schedule_get_ctx(schedule), isl_error_invalid,
"schedule tree representation not available",
return NULL);
return isl_schedule_tree_domain_get_domain(schedule->root);
}
@ -539,17 +449,10 @@ error:
return NULL;
}
/* Return an isl_union_map representation of the schedule.
* If we still have access to the schedule tree, then we return
* an isl_union_map corresponding to the subtree schedule of the child
/* Return an isl_union_map representation of the schedule. In particular,
* return an isl_union_map corresponding to the subtree schedule of the child
* of the root domain node. That is, we do not intersect the domain
* of the returned isl_union_map with the domain constraints.
* Otherwise, we must have removed it because we created a band forest.
* If so, we extract the isl_union_map from the forest.
* This reconstructed schedule map
* then needs to be padded with zeros to unify the schedule space
* since the result of isl_band_list_get_suffix_schedule may not have
* a unified schedule space.
*/
__isl_give isl_union_map *isl_schedule_get_map(__isl_keep isl_schedule *sched)
{
@ -559,376 +462,17 @@ __isl_give isl_union_map *isl_schedule_get_map(__isl_keep isl_schedule *sched)
if (!sched)
return NULL;
type = isl_schedule_tree_get_type(sched->root);
if (type != isl_schedule_node_domain)
isl_die(isl_schedule_get_ctx(sched), isl_error_internal,
"root node not a domain node", return NULL);
if (sched->root) {
type = isl_schedule_tree_get_type(sched->root);
if (type != isl_schedule_node_domain)
isl_die(isl_schedule_get_ctx(sched), isl_error_internal,
"root node not a domain node", return NULL);
node = isl_schedule_get_root(sched);
node = isl_schedule_node_child(node, 0);
umap = isl_schedule_node_get_subtree_schedule_union_map(node);
isl_schedule_node_free(node);
return umap;
}
umap = isl_band_list_get_suffix_schedule(sched->band_forest);
return pad_schedule_map(umap);
}
static __isl_give isl_band_list *construct_band_list(
__isl_take isl_schedule_node *node, __isl_take isl_union_set *domain,
__isl_keep isl_band *parent);
/* Construct an isl_band structure from the given schedule tree node,
* which may be either a band node or a leaf node.
* In the latter case, construct a zero-dimensional band.
* "domain" is the universe set of the domain elements that reach "node".
* "parent" is the parent isl_band of the isl_band constructed
* by this function.
*
* In case of a band node, we copy the properties (except tilability,
* which is implicit in an isl_band) to the isl_band.
* We assume that the band node is not zero-dimensional.
* If the child of the band node is not a leaf node,
* then we extract the children of the isl_band from this child.
*/
static __isl_give isl_band *construct_band(__isl_take isl_schedule_node *node,
__isl_take isl_union_set *domain, __isl_keep isl_band *parent)
{
int i;
isl_ctx *ctx;
isl_band *band = NULL;
isl_multi_union_pw_aff *mupa;
if (!node || !domain)
goto error;
ctx = isl_schedule_node_get_ctx(node);
band = isl_band_alloc(ctx);
if (!band)
goto error;
band->schedule = node->schedule;
band->parent = parent;
if (isl_schedule_node_get_type(node) == isl_schedule_node_leaf) {
band->n = 0;
band->pma = isl_union_pw_multi_aff_from_domain(domain);
isl_schedule_node_free(node);
return band;
}
band->n = isl_schedule_node_band_n_member(node);
if (band->n == 0)
isl_die(ctx, isl_error_unsupported,
"zero-dimensional band nodes not supported",
goto error);
band->coincident = isl_alloc_array(ctx, int, band->n);
if (band->n && !band->coincident)
goto error;
for (i = 0; i < band->n; ++i)
band->coincident[i] =
isl_schedule_node_band_member_get_coincident(node, i);
mupa = isl_schedule_node_band_get_partial_schedule(node);
band->pma = isl_union_pw_multi_aff_from_multi_union_pw_aff(mupa);
if (!band->pma)
goto error;
node = isl_schedule_get_root(sched);
node = isl_schedule_node_child(node, 0);
if (isl_schedule_node_get_type(node) == isl_schedule_node_leaf) {
isl_schedule_node_free(node);
isl_union_set_free(domain);
return band;
}
band->children = construct_band_list(node, domain, band);
if (!band->children)
return isl_band_free(band);
return band;
error:
isl_union_set_free(domain);
isl_schedule_node_free(node);
isl_band_free(band);
return NULL;
}
/* Construct a list of isl_band structures from the children of "node".
* "node" itself is a sequence or set node, so that each of the child nodes
* is a filter node and the list returned by node_construct_band_list
* consists of a single element.
* "domain" is the universe set of the domain elements that reach "node".
* "parent" is the parent isl_band of the isl_band structures constructed
* by this function.
*/
static __isl_give isl_band_list *construct_band_list_from_children(
__isl_take isl_schedule_node *node, __isl_take isl_union_set *domain,
__isl_keep isl_band *parent)
{
int i, n;
isl_ctx *ctx;
isl_band_list *list;
n = isl_schedule_node_n_children(node);
ctx = isl_schedule_node_get_ctx(node);
list = isl_band_list_alloc(ctx, 0);
for (i = 0; i < n; ++i) {
isl_schedule_node *child;
isl_band_list *list_i;
child = isl_schedule_node_get_child(node, i);
list_i = construct_band_list(child, isl_union_set_copy(domain),
parent);
list = isl_band_list_concat(list, list_i);
}
isl_union_set_free(domain);
umap = isl_schedule_node_get_subtree_schedule_union_map(node);
isl_schedule_node_free(node);
return list;
}
/* Construct an isl_band structure from the given sequence node
* (or set node that is treated as a sequence node).
* A single-dimensional band is created with as schedule for each of
* filters of the children, the corresponding child position.
* "domain" is the universe set of the domain elements that reach "node".
* "parent" is the parent isl_band of the isl_band constructed
* by this function.
*/
static __isl_give isl_band_list *construct_band_list_sequence(
__isl_take isl_schedule_node *node, __isl_take isl_union_set *domain,
__isl_keep isl_band *parent)
{
int i, n;
isl_ctx *ctx;
isl_band *band = NULL;
isl_space *space;
isl_union_pw_multi_aff *upma;
if (!node || !domain)
goto error;
ctx = isl_schedule_node_get_ctx(node);
band = isl_band_alloc(ctx);
if (!band)
goto error;
band->schedule = node->schedule;
band->parent = parent;
band->n = 1;
band->coincident = isl_calloc_array(ctx, int, band->n);
if (!band->coincident)
goto error;
n = isl_schedule_node_n_children(node);
space = isl_union_set_get_space(domain);
upma = isl_union_pw_multi_aff_empty(isl_space_copy(space));
space = isl_space_set_from_params(space);
space = isl_space_add_dims(space, isl_dim_set, 1);
for (i = 0; i < n; ++i) {
isl_schedule_node *child;
isl_union_set *filter;
isl_val *v;
isl_val_list *vl;
isl_multi_val *mv;
isl_union_pw_multi_aff *upma_i;
child = isl_schedule_node_get_child(node, i);
filter = isl_schedule_node_filter_get_filter(child);
isl_schedule_node_free(child);
filter = isl_union_set_intersect(filter,
isl_union_set_copy(domain));
v = isl_val_int_from_si(ctx, i);
vl = isl_val_list_from_val(v);
mv = isl_multi_val_from_val_list(isl_space_copy(space), vl);
upma_i = isl_union_pw_multi_aff_multi_val_on_domain(filter, mv);
upma = isl_union_pw_multi_aff_union_add(upma, upma_i);
}
isl_space_free(space);
band->pma = upma;
if (!band->pma)
goto error;
band->children = construct_band_list_from_children(node, domain, band);
if (!band->children)
band = isl_band_free(band);
return isl_band_list_from_band(band);
error:
isl_union_set_free(domain);
isl_schedule_node_free(node);
isl_band_free(band);
return NULL;
}
/* Construct a list of isl_band structures from "node" depending
* on the type of "node".
* "domain" is the universe set of the domain elements that reach "node".
* "parent" is the parent isl_band of the isl_band structures constructed
* by this function.
*
* If schedule_separate_components is set then set nodes are treated
* as sequence nodes. Otherwise, we directly extract an (implicitly
* parallel) list of isl_band structures.
*
* If "node" is a filter, then "domain" is updated by the filter.
*/
static __isl_give isl_band_list *construct_band_list(
__isl_take isl_schedule_node *node, __isl_take isl_union_set *domain,
__isl_keep isl_band *parent)
{
enum isl_schedule_node_type type;
isl_ctx *ctx;
isl_band *band;
isl_band_list *list;
isl_union_set *filter;
if (!node || !domain)
goto error;
type = isl_schedule_node_get_type(node);
switch (type) {
case isl_schedule_node_error:
goto error;
case isl_schedule_node_context:
isl_die(isl_schedule_node_get_ctx(node), isl_error_unsupported,
"context nodes not supported", goto error);
case isl_schedule_node_domain:
isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid,
"internal domain nodes not allowed", goto error);
case isl_schedule_node_expansion:
isl_die(isl_schedule_node_get_ctx(node), isl_error_unsupported,
"expansion nodes not supported", goto error);
case isl_schedule_node_extension:
isl_die(isl_schedule_node_get_ctx(node), isl_error_unsupported,
"extension nodes not supported", goto error);
case isl_schedule_node_filter:
filter = isl_schedule_node_filter_get_filter(node);
domain = isl_union_set_intersect(domain, filter);
node = isl_schedule_node_child(node, 0);
return construct_band_list(node, domain, parent);
case isl_schedule_node_guard:
isl_die(isl_schedule_node_get_ctx(node), isl_error_unsupported,
"guard nodes not supported", goto error);
case isl_schedule_node_mark:
isl_die(isl_schedule_node_get_ctx(node), isl_error_unsupported,
"mark nodes not supported", goto error);
case isl_schedule_node_set:
ctx = isl_schedule_node_get_ctx(node);
if (isl_options_get_schedule_separate_components(ctx))
return construct_band_list_sequence(node, domain,
parent);
else
return construct_band_list_from_children(node, domain,
parent);
case isl_schedule_node_sequence:
return construct_band_list_sequence(node, domain, parent);
case isl_schedule_node_leaf:
case isl_schedule_node_band:
band = construct_band(node, domain, parent);
list = isl_band_list_from_band(band);
break;
}
return list;
error:
isl_union_set_free(domain);
isl_schedule_node_free(node);
return NULL;
}
/* Return the roots of a band forest representation of the schedule.
* The band forest is constructed from the schedule tree,
* but once such a band forest is
* constructed, we forget about the original schedule tree since
* the user may modify the schedule through the band forest.
*/
__isl_give isl_band_list *isl_schedule_get_band_forest(
__isl_keep isl_schedule *schedule)
{
isl_schedule_node *node;
isl_union_set *domain;
if (!schedule)
return NULL;
if (schedule->root) {
node = isl_schedule_get_root(schedule);
domain = isl_schedule_node_domain_get_domain(node);
domain = isl_union_set_universe(domain);
node = isl_schedule_node_child(node, 0);
schedule->band_forest = construct_band_list(node, domain, NULL);
schedule->root = isl_schedule_tree_free(schedule->root);
}
return isl_band_list_dup(schedule->band_forest);
}
/* Call "fn" on each band in the schedule in depth-first post-order.
*/
int isl_schedule_foreach_band(__isl_keep isl_schedule *sched,
int (*fn)(__isl_keep isl_band *band, void *user), void *user)
{
int r;
isl_band_list *forest;
if (!sched)
return -1;
forest = isl_schedule_get_band_forest(sched);
r = isl_band_list_foreach_band(forest, fn, user);
isl_band_list_free(forest);
return r;
}
static __isl_give isl_printer *print_band_list(__isl_take isl_printer *p,
__isl_keep isl_band_list *list);
static __isl_give isl_printer *print_band(__isl_take isl_printer *p,
__isl_keep isl_band *band)
{
isl_band_list *children;
p = isl_printer_start_line(p);
p = isl_printer_print_union_pw_multi_aff(p, band->pma);
p = isl_printer_end_line(p);
if (!isl_band_has_children(band))
return p;
children = isl_band_get_children(band);
p = isl_printer_indent(p, 4);
p = print_band_list(p, children);
p = isl_printer_indent(p, -4);
isl_band_list_free(children);
return p;
}
static __isl_give isl_printer *print_band_list(__isl_take isl_printer *p,
__isl_keep isl_band_list *list)
{
int i, n;
n = isl_band_list_n_band(list);
for (i = 0; i < n; ++i) {
isl_band *band;
band = isl_band_list_get_band(list, i);
p = print_band(p, band);
isl_band_free(band);
}
return p;
return umap;
}
/* Insert a band node with partial schedule "partial" between the domain
@ -1125,29 +669,14 @@ __isl_give isl_schedule *isl_schedule_set(
}
/* Print "schedule" to "p".
*
* If "schedule" was created from a schedule tree, then we print
* the schedule tree representation. Otherwise, we print
* the band forest representation.
*/
__isl_give isl_printer *isl_printer_print_schedule(__isl_take isl_printer *p,
__isl_keep isl_schedule *schedule)
{
isl_band_list *forest;
if (!schedule)
return isl_printer_free(p);
if (schedule->root)
return isl_printer_print_schedule_tree(p, schedule->root);
forest = isl_schedule_get_band_forest(schedule);
p = print_band_list(p, forest);
isl_band_list_free(forest);
return p;
return isl_printer_print_schedule_tree(p, schedule->root);
}
#undef BASE

View File

@ -11,6 +11,8 @@
*/
#include <string.h>
#include <isl/val.h>
#include <isl/space.h>
#include <isl/map.h>
#include <isl/schedule_node.h>
#include <isl_schedule_band.h>

View File

@ -10,6 +10,7 @@
#include <isl_schedule_constraints.h>
#include <isl/schedule.h>
#include <isl/space.h>
#include <isl/set.h>
#include <isl/map.h>
#include <isl/union_set.h>
@ -479,10 +480,21 @@ static char *key_str[] = {
};
/* Print a key, value pair for the edge of type "type" in "sc" to "p".
*
* If the edge relation is empty, then it is not printed since
* an empty relation is the default value.
*/
static __isl_give isl_printer *print_constraint(__isl_take isl_printer *p,
__isl_keep isl_schedule_constraints *sc, enum isl_edge_type type)
{
isl_bool empty;
empty = isl_union_map_plain_is_empty(sc->constraint[type]);
if (empty < 0)
return isl_printer_free(p);
if (empty)
return p;
p = isl_printer_print_str(p, key_str[type]);
p = isl_printer_yaml_next(p);
p = isl_printer_print_union_map(p, sc->constraint[type]);
@ -494,10 +506,14 @@ static __isl_give isl_printer *print_constraint(__isl_take isl_printer *p,
/* Print "sc" to "p"
*
* In particular, print the isl_schedule_constraints object as a YAML document.
* Fields with values that are (obviously) equal to their default values
* are not printed.
*/
__isl_give isl_printer *isl_printer_print_schedule_constraints(
__isl_take isl_printer *p, __isl_keep isl_schedule_constraints *sc)
{
isl_bool universe;
if (!sc)
return isl_printer_free(p);
@ -506,10 +522,15 @@ __isl_give isl_printer *isl_printer_print_schedule_constraints(
p = isl_printer_yaml_next(p);
p = isl_printer_print_union_set(p, sc->domain);
p = isl_printer_yaml_next(p);
p = isl_printer_print_str(p, key_str[isl_sc_key_context]);
p = isl_printer_yaml_next(p);
p = isl_printer_print_set(p, sc->context);
p = isl_printer_yaml_next(p);
universe = isl_set_plain_is_universe(sc->context);
if (universe < 0)
return isl_printer_free(p);
if (!universe) {
p = isl_printer_print_str(p, key_str[isl_sc_key_context]);
p = isl_printer_yaml_next(p);
p = isl_printer_print_set(p, sc->context);
p = isl_printer_yaml_next(p);
}
p = print_constraint(p, sc, isl_edge_validity);
p = print_constraint(p, sc, isl_edge_proximity);
p = print_constraint(p, sc, isl_edge_coincidence);
@ -591,7 +612,11 @@ __isl_give isl_schedule_constraints *isl_stream_read_schedule_constraints(
if (!sc)
return NULL;
break;
default:
case isl_sc_key_validity:
case isl_sc_key_coincidence:
case isl_sc_key_condition:
case isl_sc_key_conditional_validity:
case isl_sc_key_proximity:
constraints = read_union_map(s);
sc = isl_schedule_constraints_set(sc, key, constraints);
if (!sc)

View File

@ -11,6 +11,8 @@
* B.P. 105 - 78153 Le Chesnay, France
*/
#include <isl/val.h>
#include <isl/space.h>
#include <isl/set.h>
#include <isl_schedule_band.h>
#include <isl_schedule_private.h>
@ -294,7 +296,7 @@ int isl_schedule_node_get_schedule_depth(__isl_keep isl_schedule_node *node)
*
* "initialized" is set if the filter field has been initialized.
* If "universe_domain" is not set, then the collected filter is intersected
* with the the domain of the root domain node.
* with the domain of the root domain node.
* "universe_filter" is set if we are only collecting the universes of filters
* "collect_prefix" is set if we are collecting prefixes.
* "filter" collects all outer filters and is NULL until "initialized" is set.
@ -1334,11 +1336,12 @@ static __isl_give isl_schedule_node *preorder_leave(
/* Traverse the descendants of "node" (including the node itself)
* in depth first preorder.
*
* If "fn" returns -1 on any of the nodes, then the traversal is aborted.
* If "fn" returns 0 on any of the nodes, then the subtree rooted
* If "fn" returns isl_bool_error on any of the nodes,
* then the traversal is aborted.
* If "fn" returns isl_bool_false on any of the nodes, then the subtree rooted
* at that node is skipped.
*
* Return 0 on success and -1 on failure.
* Return isl_stat_ok on success and isl_stat_error on failure.
*/
isl_stat isl_schedule_node_foreach_descendant_top_down(
__isl_keep isl_schedule_node *node,
@ -1354,6 +1357,56 @@ isl_stat isl_schedule_node_foreach_descendant_top_down(
return node ? isl_stat_ok : isl_stat_error;
}
/* Internal data structure for isl_schedule_node_every_descendant.
*
* "test" is the user-specified callback function.
* "user" is the user-specified callback function argument.
*
* "failed" is initialized to 0 and set to 1 if "test" fails
* on any node.
*/
struct isl_union_map_every_data {
isl_bool (*test)(__isl_keep isl_schedule_node *node, void *user);
void *user;
int failed;
};
/* isl_schedule_node_foreach_descendant_top_down callback
* that sets data->failed if data->test returns false and
* subsequently aborts the traversal.
*/
static isl_bool call_every(__isl_keep isl_schedule_node *node, void *user)
{
struct isl_union_map_every_data *data = user;
isl_bool r;
r = data->test(node, data->user);
if (r < 0)
return isl_bool_error;
if (r)
return isl_bool_true;
data->failed = 1;
return isl_bool_error;
}
/* Does "test" succeed on every descendant of "node" (including "node" itself)?
*/
isl_bool isl_schedule_node_every_descendant(__isl_keep isl_schedule_node *node,
isl_bool (*test)(__isl_keep isl_schedule_node *node, void *user),
void *user)
{
struct isl_union_map_every_data data = { test, user, 0 };
isl_stat r;
r = isl_schedule_node_foreach_descendant_top_down(node, &call_every,
&data);
if (r >= 0)
return isl_bool_true;
if (data.failed)
return isl_bool_false;
return isl_bool_error;
}
/* Internal data structure for isl_schedule_node_map_descendant_bottom_up.
*
* "fn" is the user-specified callback function.
@ -1960,7 +2013,7 @@ __isl_give isl_schedule_node *isl_schedule_node_band_sink(
* dimensions and one with the remaining dimensions.
* The schedules of the two band nodes live in anonymous spaces.
* The loop AST generation type options and the isolate option
* are split over the the two band nodes.
* are split over the two band nodes.
*/
__isl_give isl_schedule_node *isl_schedule_node_band_split(
__isl_take isl_schedule_node *node, int pos)
@ -4286,6 +4339,8 @@ static __isl_give isl_schedule_node *isl_schedule_node_graft_before_or_after(
if (isl_schedule_node_get_type(graft) == isl_schedule_node_domain)
graft = extension_from_domain(graft, node);
if (!graft)
goto error;
if (isl_schedule_node_get_type(graft) != isl_schedule_node_extension)
isl_die(isl_schedule_node_get_ctx(node), isl_error_invalid,
"expecting domain or extension as root of graft",

View File

@ -7,11 +7,7 @@
/* A complete schedule tree.
*
* band_forest points to a band forest representation of the schedule
* and may be NULL if the forest hasn't been created yet.
*
* "root" is the root of the schedule tree and may be NULL if we
* have created a band forest corresponding to the schedule.
* "root" is the root of the schedule tree.
*
* "leaf" may be used to represent a leaf of the schedule.
* It should not appear as a child to any other isl_schedule_tree objects,
@ -21,7 +17,6 @@
struct isl_schedule {
int ref;
isl_band_list *band_forest;
isl_schedule_tree *root;
struct isl_schedule_tree *leaf;

View File

@ -1,3 +1,4 @@
#include <isl/val.h>
#include <isl/schedule.h>
#include <isl/stream.h>
#include <isl_schedule_private.h>

View File

@ -13,6 +13,8 @@
* CS 42112, 75589 Paris Cedex 12, France
*/
#include <isl/val.h>
#include <isl/space.h>
#include <isl/map.h>
#include <isl_schedule_band.h>
#include <isl_schedule_private.h>
@ -2265,7 +2267,7 @@ static __isl_give isl_set *isolate_final(__isl_keep isl_set *isolate,
* The tree is itself positioned at schedule depth "depth".
*
* The loop AST generation type options and the isolate option
* are split over the the two band nodes.
* are split over the two band nodes.
*/
__isl_give isl_schedule_tree *isl_schedule_tree_band_split(
__isl_take isl_schedule_tree *tree, int pos, int depth)

View File

@ -31,7 +31,7 @@ ISL_DECLARE_LIST(schedule_tree)
* reaching domain element. It does not involve any domain constraints.
*
* The "extension" field is valid when the is isl_schedule_node_extension
* maps outer schedule dimenions (the flat product of the outer band nodes)
* maps outer schedule dimensions (the flat product of the outer band nodes)
* to additional iteration domains.
*
* The "filter" field is valid when type is isl_schedule_node_filter

View File

@ -43,6 +43,9 @@
* The scheduling algorithm implemented in this file was inspired by
* Bondhugula et al., "Automatic Transformations for Communication-Minimized
* Parallelization and Locality Optimization in the Polyhedral Model".
*
* For a detailed description of the variant implemented in isl,
* see Verdoolaege and Janssens, "Scheduling for PPCG" (2017).
*/
@ -66,7 +69,7 @@
* linearly independent of previously computed schedule rows.
* start is the first variable in the LP problem in the sequences that
* represents the schedule coefficients of this node
* nvar is the dimension of the domain
* nvar is the dimension of the (compressed) domain
* nparam is the number of parameters or 0 if we are not constructing
* a parametric schedule
*
@ -285,6 +288,18 @@ static int is_conditional_validity(struct isl_sched_edge *edge)
return is_type(edge, isl_edge_conditional_validity);
}
/* Is "edge" of a type that can appear multiple times between
* the same pair of nodes?
*
* Condition edges and conditional validity edges may have tagged
* dependence relations, in which case an edge is added for each
* pair of tags.
*/
static int is_multi_edge_type(struct isl_sched_edge *edge)
{
return is_condition(edge) || is_conditional_validity(edge);
}
/* Internal information about the dependence graph used during
* the construction of the schedule.
*
@ -308,7 +323,7 @@ static int is_conditional_validity(struct isl_sched_edge *edge)
* rows in the node schedules
* n_total_row is the current number of rows in the node schedules
* band_start is the starting row in the node schedules of the current band
* root is set to the the original dependence graph from which this graph
* root is set to the original dependence graph from which this graph
* is derived through splitting. If this graph is not the result of
* splitting, then the root field points to the graph itself.
*
@ -406,7 +421,7 @@ static int graph_init_table(isl_ctx *ctx, struct isl_sched_graph *graph)
}
/* Return a pointer to the node that lives within the given space,
* or NULL if there is no such node.
* an invalid node if there is no such node, or NULL in case of error.
*/
static struct isl_sched_node *graph_find_node(isl_ctx *ctx,
struct isl_sched_graph *graph, __isl_keep isl_space *space)
@ -414,11 +429,14 @@ static struct isl_sched_node *graph_find_node(isl_ctx *ctx,
struct isl_hash_table_entry *entry;
uint32_t hash;
if (!space)
return NULL;
hash = isl_space_get_tuple_hash(space);
entry = isl_hash_table_find(ctx, graph->node_table, hash,
&node_has_tuples, space, 0);
return entry ? entry->data : NULL;
return entry ? entry->data : graph->node + graph->n;
}
/* Is "node" a node in "graph"?
@ -458,6 +476,24 @@ static isl_stat graph_edge_table_add(isl_ctx *ctx,
return isl_stat_ok;
}
/* Add "edge" to all relevant edge tables.
* That is, for every type of the edge, add it to the corresponding table.
*/
static isl_stat graph_edge_tables_add(isl_ctx *ctx,
struct isl_sched_graph *graph, struct isl_sched_edge *edge)
{
enum isl_edge_type t;
for (t = isl_edge_first; t <= isl_edge_last; ++t) {
if (!is_type(edge, t))
continue;
if (graph_edge_table_add(ctx, graph, t, edge) < 0)
return isl_stat_error;
}
return isl_stat_ok;
}
/* Allocate the edge_tables based on the maximal number of edges of
* each type.
*/
@ -623,7 +659,11 @@ static isl_bool graph_has_validity_edge(struct isl_sched_graph *graph,
return graph_has_edge(graph, isl_edge_conditional_validity, src, dst);
}
static int graph_alloc(isl_ctx *ctx, struct isl_sched_graph *graph,
/* Perform all the required memory allocations for a schedule graph "graph"
* with "n_node" nodes and "n_edge" edge and initialize the corresponding
* fields.
*/
static isl_stat graph_alloc(isl_ctx *ctx, struct isl_sched_graph *graph,
int n_node, int n_edge)
{
int i;
@ -643,12 +683,35 @@ static int graph_alloc(isl_ctx *ctx, struct isl_sched_graph *graph,
if (!graph->node || !graph->region || (graph->n_edge && !graph->edge) ||
!graph->sorted)
return -1;
return isl_stat_error;
for(i = 0; i < graph->n; ++i)
graph->sorted[i] = i;
return 0;
return isl_stat_ok;
}
/* Free the memory associated to node "node" in "graph".
* The "coincident" field is shared by nodes in a graph and its subgraph.
* It therefore only needs to be freed for the original dependence graph,
* i.e., one that is not the result of splitting.
*/
static void clear_node(struct isl_sched_graph *graph,
struct isl_sched_node *node)
{
isl_space_free(node->space);
isl_set_free(node->hull);
isl_multi_aff_free(node->compress);
isl_multi_aff_free(node->decompress);
isl_mat_free(node->sched);
isl_map_free(node->sched_map);
isl_mat_free(node->indep);
isl_mat_free(node->vmap);
if (graph->root == graph)
free(node->coincident);
isl_multi_val_free(node->sizes);
isl_basic_set_free(node->bounds);
isl_vec_free(node->max);
}
static void graph_free(isl_ctx *ctx, struct isl_sched_graph *graph)
@ -660,21 +723,8 @@ static void graph_free(isl_ctx *ctx, struct isl_sched_graph *graph)
isl_map_to_basic_set_free(graph->inter_hmap);
if (graph->node)
for (i = 0; i < graph->n; ++i) {
isl_space_free(graph->node[i].space);
isl_set_free(graph->node[i].hull);
isl_multi_aff_free(graph->node[i].compress);
isl_multi_aff_free(graph->node[i].decompress);
isl_mat_free(graph->node[i].sched);
isl_map_free(graph->node[i].sched_map);
isl_mat_free(graph->node[i].indep);
isl_mat_free(graph->node[i].vmap);
if (graph->root == graph)
free(graph->node[i].coincident);
isl_multi_val_free(graph->node[i].sizes);
isl_basic_set_free(graph->node[i].bounds);
isl_vec_free(graph->node[i].max);
}
for (i = 0; i < graph->n; ++i)
clear_node(graph, &graph->node[i]);
free(graph->node);
free(graph->sorted);
if (graph->edge)
@ -842,6 +892,7 @@ error:
/* Compute and return the size of "set" in dimension "dim".
* The size is taken to be the difference in values for that variable
* for fixed values of the other variables.
* This assumes that "set" is convex.
* In particular, the variable is first isolated from the other variables
* in the range of a map
*
@ -886,6 +937,10 @@ static __isl_give isl_val *compute_size(__isl_take isl_set *set, int dim)
* the bounds need to be set and this is done in set_max_coefficient.
* Otherwise, compress the domain if needed, compute the size
* in each direction and store the results in node->size.
* If the domain is not convex, then the sizes are computed
* on a convex superset in order to avoid picking up sizes
* that are valid for the individual disjuncts, but not for
* the domain as a whole.
* Finally, set the bounds on the coefficients based on the sizes
* and the schedule_max_coefficient option in compute_max_coefficient.
*/
@ -903,6 +958,7 @@ static isl_stat compute_sizes_and_max(isl_ctx *ctx, struct isl_sched_node *node,
if (node->compressed)
set = isl_set_preimage_multi_aff(set,
isl_multi_aff_copy(node->decompress));
set = isl_set_from_basic_set(isl_set_simple_hull(set));
mv = isl_multi_val_zero(isl_set_get_space(set));
n = isl_set_dim(set, isl_dim_set);
for (j = 0; j < n; ++j) {
@ -1178,8 +1234,8 @@ static __isl_give isl_map *map_intersect_domains(__isl_take isl_map *tagged,
return tagged;
}
/* Return a pointer to the node that lives in the domain space of "map"
* or NULL if there is no such node.
/* Return a pointer to the node that lives in the domain space of "map",
* an invalid node if there is no such node, or NULL in case of error.
*/
static struct isl_sched_node *find_domain_node(isl_ctx *ctx,
struct isl_sched_graph *graph, __isl_keep isl_map *map)
@ -1194,8 +1250,8 @@ static struct isl_sched_node *find_domain_node(isl_ctx *ctx,
return node;
}
/* Return a pointer to the node that lives in the range space of "map"
* or NULL if there is no such node.
/* Return a pointer to the node that lives in the range space of "map",
* an invalid node if there is no such node, or NULL in case of error.
*/
static struct isl_sched_node *find_range_node(isl_ctx *ctx,
struct isl_sched_graph *graph, __isl_keep isl_map *map)
@ -1210,6 +1266,18 @@ static struct isl_sched_node *find_range_node(isl_ctx *ctx,
return node;
}
/* Refrain from adding a new edge based on "map".
* Instead, just free the map.
* "tagged" is either a copy of "map" with additional tags or NULL.
*/
static isl_stat skip_edge(__isl_take isl_map *map, __isl_take isl_map *tagged)
{
isl_map_free(map);
isl_map_free(tagged);
return isl_stat_ok;
}
/* Add a new edge to the graph based on the given map
* and add it to data->graph->edge_table[data->type].
* If a dependence relation of a given type happens to be identical
@ -1235,6 +1303,7 @@ static struct isl_sched_node *find_range_node(isl_ctx *ctx,
*/
static isl_stat extract_edge(__isl_take isl_map *map, void *user)
{
isl_bool empty;
isl_ctx *ctx = isl_map_get_ctx(map);
struct isl_extract_edge_data *data = user;
struct isl_sched_graph *graph = data->graph;
@ -1255,11 +1324,10 @@ static isl_stat extract_edge(__isl_take isl_map *map, void *user)
src = find_domain_node(ctx, graph, map);
dst = find_range_node(ctx, graph, map);
if (!src || !dst) {
isl_map_free(map);
isl_map_free(tagged);
return isl_stat_ok;
}
if (!src || !dst)
goto error;
if (!is_node(graph, src) || !is_node(graph, dst))
return skip_edge(map, tagged);
if (src->compressed || dst->compressed) {
isl_map *hull;
@ -1269,6 +1337,12 @@ static isl_stat extract_edge(__isl_take isl_map *map, void *user)
map = isl_map_intersect(map, hull);
}
empty = isl_map_plain_is_empty(map);
if (empty < 0)
goto error;
if (empty)
return skip_edge(map, tagged);
graph->edge[graph->n_edge].src = src;
graph->edge[graph->n_edge].dst = dst;
graph->edge[graph->n_edge].map = map;
@ -1293,9 +1367,13 @@ static isl_stat extract_edge(__isl_take isl_map *map, void *user)
&graph->edge[graph->n_edge++]);
if (merge_edge(edge, &graph->edge[graph->n_edge]) < 0)
return -1;
return isl_stat_error;
return graph_edge_table_add(ctx, graph, data->type, edge);
error:
isl_map_free(map);
isl_map_free(tagged);
return isl_stat_error;
}
/* Initialize the schedule graph "graph" from the schedule constraints "sc".
@ -1393,7 +1471,7 @@ static isl_bool node_follows_strong(int i, int j, void *user)
/* Use Tarjan's algorithm for computing the strongly connected components
* in the dependence graph only considering those edges defined by "follows".
*/
static int detect_ccs(isl_ctx *ctx, struct isl_sched_graph *graph,
static isl_stat detect_ccs(isl_ctx *ctx, struct isl_sched_graph *graph,
isl_bool (*follows)(int i, int j, void *user))
{
int i, n;
@ -1401,7 +1479,7 @@ static int detect_ccs(isl_ctx *ctx, struct isl_sched_graph *graph,
g = isl_tarjan_graph_init(ctx, graph->n, follows, graph);
if (!g)
return -1;
return isl_stat_error;
graph->scc = 0;
i = 0;
@ -1418,14 +1496,14 @@ static int detect_ccs(isl_ctx *ctx, struct isl_sched_graph *graph,
isl_tarjan_graph_free(g);
return 0;
return isl_stat_ok;
}
/* Apply Tarjan's algorithm to detect the strongly connected components
* in the dependence graph.
* Only consider the (conditional) validity dependences and clear "weak".
*/
static int detect_sccs(isl_ctx *ctx, struct isl_sched_graph *graph)
static isl_stat detect_sccs(isl_ctx *ctx, struct isl_sched_graph *graph)
{
graph->weak = 0;
return detect_ccs(ctx, graph, &node_follows_strong);
@ -1435,7 +1513,7 @@ static int detect_sccs(isl_ctx *ctx, struct isl_sched_graph *graph)
* in the dependence graph.
* Consider all dependences and set "weak".
*/
static int detect_wccs(isl_ctx *ctx, struct isl_sched_graph *graph)
static isl_stat detect_wccs(isl_ctx *ctx, struct isl_sched_graph *graph)
{
graph->weak = 1;
return detect_ccs(ctx, graph, &node_follows_weak);
@ -1739,7 +1817,7 @@ static __isl_give isl_dim_map *intra_dim_map(isl_ctx *ctx,
unsigned total;
isl_dim_map *dim_map;
if (!node)
if (!node || !graph->lp)
return NULL;
total = isl_basic_set_total_dim(graph->lp);
@ -1779,7 +1857,7 @@ static __isl_give isl_dim_map *inter_dim_map(isl_ctx *ctx,
unsigned total;
isl_dim_map *dim_map;
if (!src || !dst)
if (!src || !dst || !graph->lp)
return NULL;
total = isl_basic_set_total_dim(graph->lp);
@ -2940,20 +3018,28 @@ static __isl_give isl_aff *extract_schedule_row(__isl_take isl_local_space *ls,
isl_int_init(v);
aff = isl_aff_zero_on_domain(ls);
isl_mat_get_element(node->sched, row, 0, &v);
if (isl_mat_get_element(node->sched, row, 0, &v) < 0)
goto error;
aff = isl_aff_set_constant(aff, v);
for (j = 0; j < node->nparam; ++j) {
isl_mat_get_element(node->sched, row, 1 + j, &v);
if (isl_mat_get_element(node->sched, row, 1 + j, &v) < 0)
goto error;
aff = isl_aff_set_coefficient(aff, isl_dim_param, j, v);
}
for (j = 0; j < node->nvar; ++j) {
isl_mat_get_element(node->sched, row, 1 + node->nparam + j, &v);
if (isl_mat_get_element(node->sched, row,
1 + node->nparam + j, &v) < 0)
goto error;
aff = isl_aff_set_coefficient(aff, isl_dim_in, j, v);
}
isl_int_clear(v);
return aff;
error:
isl_int_clear(v);
isl_aff_free(aff);
return NULL;
}
/* Convert the "n" rows starting at "first" of node->sched into a multi_aff
@ -3066,8 +3152,15 @@ static __isl_give isl_union_map *intersect_domains(
* If the dependence is carried completely by the current schedule, then
* it is removed from the edge_tables. It is kept in the list of edges
* as otherwise all edge_tables would have to be recomputed.
*
* If the edge is of a type that can appear multiple times
* between the same pair of nodes, then it is added to
* the edge table (again). This prevents the situation
* where none of these edges is referenced from the edge table
* because the one that was referenced turned out to be empty and
* was therefore removed from the table.
*/
static int update_edge(struct isl_sched_graph *graph,
static isl_stat update_edge(isl_ctx *ctx, struct isl_sched_graph *graph,
struct isl_sched_edge *edge)
{
int empty;
@ -3094,14 +3187,18 @@ static int update_edge(struct isl_sched_graph *graph,
empty = isl_map_plain_is_empty(edge->map);
if (empty < 0)
goto error;
if (empty)
if (empty) {
graph_remove_edge(graph, edge);
} else if (is_multi_edge_type(edge)) {
if (graph_edge_tables_add(ctx, graph, edge) < 0)
goto error;
}
isl_map_free(id);
return 0;
return isl_stat_ok;
error:
isl_map_free(id);
return -1;
return isl_stat_error;
}
/* Does the domain of "umap" intersect "uset"?
@ -3260,8 +3357,8 @@ static int update_edges(isl_ctx *ctx, struct isl_sched_graph *graph)
sink = isl_union_set_union(sink, uset);
}
for (i = graph->n_edge - 1; i >= 0; --i) {
if (update_edge(graph, &graph->edge[i]) < 0)
for (i = 0; i < graph->n_edge; ++i) {
if (update_edge(ctx, graph, &graph->edge[i]) < 0)
goto error;
}
@ -3357,7 +3454,8 @@ static __isl_give isl_union_set_list *extract_split(isl_ctx *ctx,
/* Copy nodes that satisfy node_pred from the src dependence graph
* to the dst dependence graph.
*/
static int copy_nodes(struct isl_sched_graph *dst, struct isl_sched_graph *src,
static isl_stat copy_nodes(struct isl_sched_graph *dst,
struct isl_sched_graph *src,
int (*node_pred)(struct isl_sched_node *node, int data), int data)
{
int i;
@ -3388,14 +3486,14 @@ static int copy_nodes(struct isl_sched_graph *dst, struct isl_sched_graph *src,
dst->n++;
if (!dst->node[j].space || !dst->node[j].sched)
return -1;
return isl_stat_error;
if (dst->node[j].compressed &&
(!dst->node[j].hull || !dst->node[j].compress ||
!dst->node[j].decompress))
return -1;
return isl_stat_error;
}
return 0;
return isl_stat_ok;
}
/* Copy non-empty edges that satisfy edge_pred from the src dependence graph
@ -3404,12 +3502,11 @@ static int copy_nodes(struct isl_sched_graph *dst, struct isl_sched_graph *src,
* graph, then it must be a backward proximity edge and it should simply
* be ignored.
*/
static int copy_edges(isl_ctx *ctx, struct isl_sched_graph *dst,
static isl_stat copy_edges(isl_ctx *ctx, struct isl_sched_graph *dst,
struct isl_sched_graph *src,
int (*edge_pred)(struct isl_sched_edge *edge, int data), int data)
{
int i;
enum isl_edge_type t;
dst->n_edge = 0;
for (i = 0; i < src->n_edge; ++i) {
@ -3427,11 +3524,13 @@ static int copy_edges(isl_ctx *ctx, struct isl_sched_graph *dst,
dst_src = graph_find_node(ctx, dst, edge->src->space);
dst_dst = graph_find_node(ctx, dst, edge->dst->space);
if (!dst_src || !dst_dst) {
if (!dst_src || !dst_dst)
return isl_stat_error;
if (!is_node(dst, dst_src) || !is_node(dst, dst_dst)) {
if (is_validity(edge) || is_conditional_validity(edge))
isl_die(ctx, isl_error_internal,
"backward (conditional) validity edge",
return -1);
return isl_stat_error);
continue;
}
@ -3448,21 +3547,16 @@ static int copy_edges(isl_ctx *ctx, struct isl_sched_graph *dst,
dst->n_edge++;
if (edge->tagged_condition && !tagged_condition)
return -1;
return isl_stat_error;
if (edge->tagged_validity && !tagged_validity)
return -1;
return isl_stat_error;
for (t = isl_edge_first; t <= isl_edge_last; ++t) {
if (edge !=
graph_find_edge(src, t, edge->src, edge->dst))
continue;
if (graph_edge_table_add(ctx, dst, t,
if (graph_edge_tables_add(ctx, dst,
&dst->edge[dst->n_edge - 1]) < 0)
return -1;
}
return isl_stat_error;
}
return 0;
return isl_stat_ok;
}
/* Compute the maximal number of variables over all nodes.
@ -3491,11 +3585,11 @@ static int compute_maxvar(struct isl_sched_graph *graph)
return 0;
}
/* Extract the subgraph of "graph" that consists of the node satisfying
/* Extract the subgraph of "graph" that consists of the nodes satisfying
* "node_pred" and the edges satisfying "edge_pred" and store
* the result in "sub".
*/
static int extract_sub_graph(isl_ctx *ctx, struct isl_sched_graph *graph,
static isl_stat extract_sub_graph(isl_ctx *ctx, struct isl_sched_graph *graph,
int (*node_pred)(struct isl_sched_node *node, int data),
int (*edge_pred)(struct isl_sched_edge *edge, int data),
int data, struct isl_sched_graph *sub)
@ -3510,24 +3604,24 @@ static int extract_sub_graph(isl_ctx *ctx, struct isl_sched_graph *graph,
if (edge_pred(&graph->edge[i], data))
++n_edge;
if (graph_alloc(ctx, sub, n, n_edge) < 0)
return -1;
return isl_stat_error;
sub->root = graph->root;
if (copy_nodes(sub, graph, node_pred, data) < 0)
return -1;
return isl_stat_error;
if (graph_init_table(ctx, sub) < 0)
return -1;
return isl_stat_error;
for (t = 0; t <= isl_edge_last; ++t)
sub->max_edge[t] = graph->max_edge[t];
if (graph_init_edge_tables(ctx, sub) < 0)
return -1;
return isl_stat_error;
if (copy_edges(ctx, sub, graph, edge_pred, data) < 0)
return -1;
return isl_stat_error;
sub->n_row = graph->n_row;
sub->max_row = graph->max_row;
sub->n_total_row = graph->n_total_row;
sub->band_start = graph->band_start;
return 0;
return isl_stat_ok;
}
static __isl_give isl_schedule_node *compute_schedule(isl_schedule_node *node,
@ -3588,7 +3682,7 @@ static int edge_src_scc_at_least(struct isl_sched_edge *edge, int scc)
/* Reset the current band by dropping all its schedule rows.
*/
static int reset_band(struct isl_sched_graph *graph)
static isl_stat reset_band(struct isl_sched_graph *graph)
{
int i;
int drop;
@ -3607,10 +3701,10 @@ static int reset_band(struct isl_sched_graph *graph)
graph->band_start, drop);
if (!node->sched)
return -1;
return isl_stat_error;
}
return 0;
return isl_stat_ok;
}
/* Split the current graph into two parts and compute a schedule for each
@ -3869,6 +3963,8 @@ static void isl_carry_clear(struct isl_carry *carry)
/* Return a pointer to the node in "graph" that lives in "space".
* If the requested node has been compressed, then "space"
* corresponds to the compressed space.
* The graph is assumed to have such a node.
* Return NULL in case of error.
*
* First try and see if "space" is the space of an uncompressed node.
* If so, return that node.
@ -3889,7 +3985,9 @@ static struct isl_sched_node *graph_find_compressed_node(isl_ctx *ctx,
return NULL;
node = graph_find_node(ctx, graph, space);
if (node)
if (!node)
return NULL;
if (is_node(graph, node))
return node;
id = isl_space_get_tuple_id(space, isl_dim_set);
@ -3904,6 +4002,9 @@ static struct isl_sched_node *graph_find_compressed_node(isl_ctx *ctx,
"space points to invalid node", return NULL);
if (graph != graph->root)
node = graph_find_node(ctx, graph, node->space);
if (!is_node(graph, node))
isl_die(ctx, isl_error_internal,
"unable to find node", return NULL);
return node;
}
@ -4441,8 +4542,9 @@ static __isl_give isl_vec *non_neg_lexmin(struct isl_sched_graph *graph,
int i, pos, cut;
isl_ctx *ctx;
isl_tab_lexmin *tl;
isl_vec *sol, *prev = NULL;
isl_vec *sol = NULL, *prev;
int treat_coalescing;
int try_again;
if (!lp)
return NULL;
@ -4454,8 +4556,10 @@ static __isl_give isl_vec *non_neg_lexmin(struct isl_sched_graph *graph,
do {
int integral;
try_again = 0;
if (cut)
tl = isl_tab_lexmin_cut_to_integer(tl);
prev = sol;
sol = non_empty_solution(tl);
if (!sol)
goto error;
@ -4471,7 +4575,7 @@ static __isl_give isl_vec *non_neg_lexmin(struct isl_sched_graph *graph,
prev = isl_vec_free(prev);
cut = want_integral && !integral;
if (cut)
prev = sol;
try_again = 1;
if (!treat_coalescing)
continue;
for (i = 0; i < graph->n; ++i) {
@ -4484,11 +4588,11 @@ static __isl_give isl_vec *non_neg_lexmin(struct isl_sched_graph *graph,
break;
}
if (i < graph->n) {
prev = sol;
try_again = 1;
tl = zero_out_node_coef(tl, &graph->node[i], pos);
cut = 0;
}
} while (prev);
} while (try_again);
isl_tab_lexmin_free(tl);
@ -5451,22 +5555,26 @@ error:
* In each case, we first insert a band node in the schedule tree
* if any rows have been computed.
*
* If the caller managed to complete the schedule, we insert a band node
* (if any schedule rows were computed) and we finish off by topologically
* If the caller managed to complete the schedule and the current band
* is empty, then finish off by topologically
* sorting the statements based on the remaining dependences.
* If, on the other hand, the current band has at least one row,
* then continue with the next band. Note that this next band
* will necessarily be empty, but the graph may still be split up
* into weakly connected components before arriving back here.
*/
static __isl_give isl_schedule_node *compute_schedule_finish_band(
__isl_take isl_schedule_node *node, struct isl_sched_graph *graph,
int initialized)
{
int insert;
int empty;
if (!node)
return NULL;
empty = graph->n_total_row == graph->band_start;
if (graph->n_row < graph->maxvar) {
isl_ctx *ctx;
int empty = graph->n_total_row == graph->band_start;
ctx = isl_schedule_node_get_ctx(node);
if (!ctx->opt->schedule_maximize_band_depth && !empty)
@ -5484,16 +5592,9 @@ static __isl_give isl_schedule_node *compute_schedule_finish_band(
return carry_dependences(node, graph);
}
insert = graph->n_total_row > graph->band_start;
if (insert) {
node = insert_current_band(node, graph, 1);
node = isl_schedule_node_child(node, 0);
}
node = sort_statements(node, graph, initialized);
if (insert)
node = isl_schedule_node_parent(node);
return node;
if (!empty)
return compute_next_band(node, graph, 1);
return sort_statements(node, graph, initialized);
}
/* Construct a band of schedule rows for a connected dependence graph.
@ -6332,12 +6433,15 @@ static __isl_give isl_map *extract_node_transformation(isl_ctx *ctx,
isl_multi_aff *ma, *ma2;
scc_node = graph_find_node(ctx, &c->scc[node->scc], node->space);
if (scc_node && !is_node(&c->scc[node->scc], scc_node))
isl_die(ctx, isl_error_internal, "unable to find node",
return NULL);
start = c->scc[node->scc].band_start;
n = c->scc[node->scc].n_total_row - start;
ma = node_extract_partial_schedule_multi_aff(scc_node, start, n);
space = cluster_space(&c->scc[node->scc], c->scc_cluster[node->scc]);
cluster_node = graph_find_node(ctx, merge_graph, space);
if (space && !cluster_node)
if (cluster_node && !is_node(merge_graph, cluster_node))
isl_die(ctx, isl_error_internal, "unable to find cluster",
space = isl_space_free(space));
id = isl_space_get_tuple_id(space, isl_dim_set);
@ -6684,11 +6788,11 @@ static isl_stat merge(isl_ctx *ctx, struct isl_clustering *c,
if (cluster < 0)
cluster = i;
space = cluster_space(&c->scc[i], c->scc_cluster[i]);
if (!space)
return isl_stat_error;
node = graph_find_node(ctx, merge_graph, space);
isl_space_free(space);
if (!node)
return isl_stat_error;
if (!is_node(merge_graph, node))
isl_die(ctx, isl_error_internal,
"unable to find cluster",
return isl_stat_error);
@ -7171,6 +7275,14 @@ static __isl_give isl_schedule_node *compute_schedule_wcc(
* weakly connected component in the dependence graph so that
* there is no need for compute_sub_schedule to look for weakly
* connected components.
*
* If a set node would be introduced and if the number of components
* is equal to the number of nodes, then check if the schedule
* is already complete. If so, a redundant set node would be introduced
* (without any further descendants) stating that the statements
* can be executed in arbitrary order, which is also expressed
* by the absence of any node. Refrain from inserting any nodes
* in this case and simply return.
*/
static __isl_give isl_schedule_node *compute_component_schedule(
__isl_take isl_schedule_node *node, struct isl_sched_graph *graph,
@ -7182,8 +7294,15 @@ static __isl_give isl_schedule_node *compute_component_schedule(
if (!node)
return NULL;
ctx = isl_schedule_node_get_ctx(node);
if (graph->weak && graph->scc == graph->n) {
if (compute_maxvar(graph) < 0)
return isl_schedule_node_free(node);
if (graph->n_row >= graph->maxvar)
return node;
}
ctx = isl_schedule_node_get_ctx(node);
filters = extract_sccs(ctx, graph);
if (graph->weak)
node = isl_schedule_node_insert_set(node, filters);

View File

@ -821,15 +821,6 @@ isl_bool isl_space_tuple_is_equal(__isl_keep isl_space *space1,
return isl_bool_true;
}
/* This is the old, undocumented, name for isl_space_tuple_is_equal.
* It will be removed at some point.
*/
int isl_space_tuple_match(__isl_keep isl_space *space1, enum isl_dim_type type1,
__isl_keep isl_space *space2, enum isl_dim_type type2)
{
return isl_space_tuple_is_equal(space1, type1, space2, type2);
}
static isl_bool match(__isl_keep isl_space *space1, enum isl_dim_type type1,
__isl_keep isl_space *space2, enum isl_dim_type type2)
{
@ -985,6 +976,33 @@ error:
return NULL;
}
/* Add a parameter with identifier "id" to "space", provided
* it does not already appear in "space".
*/
__isl_give isl_space *isl_space_add_param_id(__isl_take isl_space *space,
__isl_take isl_id *id)
{
int pos;
if (!space || !id)
goto error;
if (isl_space_find_dim_by_id(space, isl_dim_param, id) >= 0) {
isl_id_free(id);
return space;
}
pos = isl_space_dim(space, isl_dim_param);
space = isl_space_add_dims(space, isl_dim_param, 1);
space = isl_space_set_dim_id(space, isl_dim_param, pos, id);
return space;
error:
isl_space_free(space);
isl_id_free(id);
return NULL;
}
static int valid_dim_type(enum isl_dim_type type)
{
switch (type) {
@ -1157,8 +1175,8 @@ __isl_give isl_space *isl_space_move_dims(__isl_take isl_space *space,
for (i = 0; i < 2; ++i) {
if (!space->nested[i])
continue;
space->nested[i] = isl_space_replace(space->nested[i],
isl_dim_param, space);
space->nested[i] = isl_space_replace_params(space->nested[i],
space);
if (!space->nested[i])
goto error;
}
@ -1321,15 +1339,6 @@ error:
return NULL;
}
/* Given a space of the form [A -> B] -> [C -> D], return the space A -> C.
*/
__isl_give isl_space *isl_space_factor_domain(__isl_take isl_space *space)
{
space = isl_space_domain_factor_domain(space);
space = isl_space_range_factor_domain(space);
return space;
}
/* Given a space of the form [A -> B] -> C, return the space A -> C.
*/
__isl_give isl_space *isl_space_domain_factor_domain(
@ -1407,19 +1416,18 @@ error:
return NULL;
}
/* Given a space of the form A -> [B -> C], return the space A -> B.
/* Internal function that selects the domain of the map that is
* embedded in either a set space or the range of a map space.
* In particular, given a space of the form [A -> B], return the space A.
* Given a space of the form A -> [B -> C], return the space A -> B.
*/
__isl_give isl_space *isl_space_range_factor_domain(
__isl_take isl_space *space)
static __isl_give isl_space *range_factor_domain(__isl_take isl_space *space)
{
isl_space *nested;
isl_space *domain;
if (!space)
return NULL;
if (!isl_space_range_is_wrapping(space))
isl_die(isl_space_get_ctx(space), isl_error_invalid,
"range not a product", return isl_space_free(space));
nested = space->nested[1];
domain = isl_space_copy(space);
@ -1446,6 +1454,47 @@ error:
return NULL;
}
/* Given a space of the form A -> [B -> C], return the space A -> B.
*/
__isl_give isl_space *isl_space_range_factor_domain(
__isl_take isl_space *space)
{
if (!space)
return NULL;
if (!isl_space_range_is_wrapping(space))
isl_die(isl_space_get_ctx(space), isl_error_invalid,
"range not a product", return isl_space_free(space));
return range_factor_domain(space);
}
/* Given a space of the form [A -> B], return the space A.
*/
static __isl_give isl_space *set_factor_domain(__isl_take isl_space *space)
{
if (!space)
return NULL;
if (!isl_space_is_wrapping(space))
isl_die(isl_space_get_ctx(space), isl_error_invalid,
"not a product", return isl_space_free(space));
return range_factor_domain(space);
}
/* Given a space of the form [A -> B] -> [C -> D], return the space A -> C.
* Given a space of the form [A -> B], return the space A.
*/
__isl_give isl_space *isl_space_factor_domain(__isl_take isl_space *space)
{
if (!space)
return NULL;
if (isl_space_is_set(space))
return set_factor_domain(space);
space = isl_space_domain_factor_domain(space);
space = isl_space_range_factor_domain(space);
return space;
}
/* Internal function that selects the range of the map that is
* embedded in either a set space or the range of a map space.
* In particular, given a space of the form [A -> B], return the space B.
@ -2212,31 +2261,33 @@ __isl_give isl_space *isl_space_flatten(__isl_take isl_space *dim)
return dim;
}
__isl_give isl_space *isl_space_flatten_domain(__isl_take isl_space *dim)
__isl_give isl_space *isl_space_flatten_domain(__isl_take isl_space *space)
{
if (!dim)
if (!space)
return NULL;
if (!dim->nested[0])
return dim;
if (!space->nested[0])
return space;
return isl_space_reset(dim, isl_dim_in);
return isl_space_reset(space, isl_dim_in);
}
__isl_give isl_space *isl_space_flatten_range(__isl_take isl_space *dim)
__isl_give isl_space *isl_space_flatten_range(__isl_take isl_space *space)
{
if (!dim)
if (!space)
return NULL;
if (!dim->nested[1])
return dim;
if (!space->nested[1])
return space;
return isl_space_reset(dim, isl_dim_out);
return isl_space_reset(space, isl_dim_out);
}
/* Replace the dimensions of the given type of dst by those of src.
/* Replace the parameters of dst by those of src.
*/
__isl_give isl_space *isl_space_replace(__isl_take isl_space *dst,
enum isl_dim_type type, __isl_keep isl_space *src)
__isl_give isl_space *isl_space_replace_params(__isl_take isl_space *dst,
__isl_keep isl_space *src)
{
enum isl_dim_type type = isl_dim_param;
dst = isl_space_cow(dst);
if (!dst || !src)
@ -2246,13 +2297,13 @@ __isl_give isl_space *isl_space_replace(__isl_take isl_space *dst,
dst = isl_space_add_dims(dst, type, isl_space_dim(src, type));
dst = copy_ids(dst, type, 0, src, type);
if (dst && type == isl_dim_param) {
if (dst) {
int i;
for (i = 0; i <= 1; ++i) {
if (!dst->nested[i])
continue;
dst->nested[i] = isl_space_replace(dst->nested[i],
type, src);
dst->nested[i] = isl_space_replace_params(
dst->nested[i], src);
if (!dst->nested[i])
goto error;
}

View File

@ -50,11 +50,9 @@ isl_stat isl_space_check_equal_params(__isl_keep isl_space *space1,
__isl_give isl_space *isl_space_reset(__isl_take isl_space *dim,
enum isl_dim_type type);
__isl_give isl_space *isl_space_flatten(__isl_take isl_space *dim);
__isl_give isl_space *isl_space_flatten_domain(__isl_take isl_space *dim);
__isl_give isl_space *isl_space_flatten_range(__isl_take isl_space *dim);
__isl_give isl_space *isl_space_replace(__isl_take isl_space *dst,
enum isl_dim_type type, __isl_keep isl_space *src);
__isl_give isl_space *isl_space_replace_params(__isl_take isl_space *dst,
__isl_keep isl_space *src);
__isl_give isl_space *isl_space_lift(__isl_take isl_space *dim, unsigned n_local);

View File

@ -725,8 +725,11 @@ int isl_stream_eat(__isl_keep isl_stream *s, int type)
struct isl_token *tok;
tok = isl_stream_next_token(s);
if (!tok)
if (!tok) {
if (s->eof)
isl_stream_error(s, NULL, "unexpected EOF");
return -1;
}
if (tok->type == type) {
isl_token_free(tok);
return 0;

324
polly/lib/External/isl/isl_stride.c vendored Normal file
View File

@ -0,0 +1,324 @@
/*
* Copyright 2012-2013 Ecole Normale Superieure
*
* Use of this software is governed by the MIT license
*
* Written by Sven Verdoolaege,
* Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France
*/
#include <isl/val.h>
#include <isl/aff.h>
#include <isl/constraint.h>
#include <isl/set.h>
/* Stride information about a specific set dimension.
* The values of the set dimension are equal to
* "offset" plus a multiple of "stride".
*/
struct isl_stride_info {
isl_val *stride;
isl_aff *offset;
};
/* Free "si" and return NULL.
*/
__isl_null isl_stride_info *isl_stride_info_free(
__isl_take isl_stride_info *si)
{
if (!si)
return NULL;
isl_val_free(si->stride);
isl_aff_free(si->offset);
free(si);
return NULL;
}
/* Construct an isl_stride_info object with given offset and stride.
*/
__isl_give isl_stride_info *isl_stride_info_alloc(
__isl_take isl_val *stride, __isl_take isl_aff *offset)
{
struct isl_stride_info *si;
if (!stride || !offset)
goto error;
si = isl_alloc_type(isl_val_get_ctx(stride), struct isl_stride_info);
if (!si)
goto error;
si->stride = stride;
si->offset = offset;
return si;
error:
isl_val_free(stride);
isl_aff_free(offset);
return NULL;
}
/* Return the stride of "si".
*/
__isl_give isl_val *isl_stride_info_get_stride(__isl_keep isl_stride_info *si)
{
if (!si)
return NULL;
return isl_val_copy(si->stride);
}
/* Return the offset of "si".
*/
__isl_give isl_aff *isl_stride_info_get_offset(__isl_keep isl_stride_info *si)
{
if (!si)
return NULL;
return isl_aff_copy(si->offset);
}
/* Information used inside detect_stride.
*
* "pos" is the set dimension at which the stride is being determined.
* "want_offset" is set if the offset should be computed.
* "found" is set if some stride was found already.
* "stride" and "offset" contain the (combined) stride and offset
* found so far and are NULL when "found" is not set.
* If "want_offset" is not set, then "offset" remains NULL.
*/
struct isl_detect_stride_data {
int pos;
int want_offset;
int found;
isl_val *stride;
isl_aff *offset;
};
/* Set the stride and offset of data->pos to the given
* value and expression.
*
* If we had already found a stride before, then the two strides
* are combined into a single stride.
*
* In particular, if the new stride information is of the form
*
* i = f + s (...)
*
* and the old stride information is of the form
*
* i = f2 + s2 (...)
*
* then we compute the extended gcd of s and s2
*
* a s + b s2 = g,
*
* with g = gcd(s,s2), multiply the first equation with t1 = b s2/g
* and the second with t2 = a s1/g.
* This results in
*
* i = (b s2 + a s1)/g i = t1 f + t2 f2 + (s s2)/g (...)
*
* so that t1 f + t2 f2 is the combined offset and (s s2)/g = lcm(s,s2)
* is the combined stride.
*/
static isl_stat set_stride(struct isl_detect_stride_data *data,
__isl_take isl_val *stride, __isl_take isl_aff *offset)
{
int pos;
if (!stride || !offset)
goto error;
pos = data->pos;
if (data->found) {
isl_val *stride2, *a, *b, *g;
isl_aff *offset2;
stride2 = data->stride;
g = isl_val_gcdext(isl_val_copy(stride), isl_val_copy(stride2),
&a, &b);
a = isl_val_mul(a, isl_val_copy(stride));
a = isl_val_div(a, isl_val_copy(g));
stride2 = isl_val_div(stride2, g);
b = isl_val_mul(b, isl_val_copy(stride2));
stride = isl_val_mul(stride, stride2);
if (!data->want_offset) {
isl_val_free(a);
isl_val_free(b);
} else {
offset2 = data->offset;
offset2 = isl_aff_scale_val(offset2, a);
offset = isl_aff_scale_val(offset, b);
offset = isl_aff_add(offset, offset2);
}
}
data->found = 1;
data->stride = stride;
if (data->want_offset)
data->offset = offset;
else
isl_aff_free(offset);
if (!data->stride || (data->want_offset && !data->offset))
return isl_stat_error;
return isl_stat_ok;
error:
isl_val_free(stride);
isl_aff_free(offset);
return isl_stat_error;
}
/* Check if constraint "c" imposes any stride on dimension data->pos
* and, if so, update the stride information in "data".
*
* In order to impose a stride on the dimension, "c" needs to be an equality
* and it needs to involve the dimension. Note that "c" may also be
* a div constraint and thus an inequality that we cannot use.
*
* Let c be of the form
*
* h(p) + g * v * i + g * stride * f(alpha) = 0
*
* with h(p) an expression in terms of the parameters and other dimensions
* and f(alpha) an expression in terms of the existentially quantified
* variables.
*
* If "stride" is not zero and not one, then it represents a non-trivial stride
* on "i". We compute a and b such that
*
* a v + b stride = 1
*
* We have
*
* g v i = -h(p) + g stride f(alpha)
*
* a g v i = -a h(p) + g stride f(alpha)
*
* a g v i + b g stride i = -a h(p) + g stride * (...)
*
* g i = -a h(p) + g stride * (...)
*
* i = -a h(p)/g + stride * (...)
*
* The expression "-a h(p)/g" can therefore be used as offset.
*/
static isl_stat detect_stride(__isl_take isl_constraint *c, void *user)
{
struct isl_detect_stride_data *data = user;
int i, n_div;
isl_ctx *ctx;
isl_stat r = isl_stat_ok;
isl_val *v, *stride, *m;
if (!isl_constraint_is_equality(c) ||
!isl_constraint_involves_dims(c, isl_dim_set, data->pos, 1)) {
isl_constraint_free(c);
return isl_stat_ok;
}
ctx = isl_constraint_get_ctx(c);
stride = isl_val_zero(ctx);
n_div = isl_constraint_dim(c, isl_dim_div);
for (i = 0; i < n_div; ++i) {
v = isl_constraint_get_coefficient_val(c, isl_dim_div, i);
stride = isl_val_gcd(stride, v);
}
v = isl_constraint_get_coefficient_val(c, isl_dim_set, data->pos);
m = isl_val_gcd(isl_val_copy(stride), isl_val_copy(v));
stride = isl_val_div(stride, isl_val_copy(m));
v = isl_val_div(v, isl_val_copy(m));
if (!isl_val_is_zero(stride) && !isl_val_is_one(stride)) {
isl_aff *aff;
isl_val *gcd, *a, *b;
gcd = isl_val_gcdext(v, isl_val_copy(stride), &a, &b);
isl_val_free(gcd);
isl_val_free(b);
aff = isl_constraint_get_aff(c);
for (i = 0; i < n_div; ++i)
aff = isl_aff_set_coefficient_si(aff,
isl_dim_div, i, 0);
aff = isl_aff_set_coefficient_si(aff, isl_dim_in, data->pos, 0);
a = isl_val_neg(a);
aff = isl_aff_scale_val(aff, a);
aff = isl_aff_scale_down_val(aff, m);
r = set_stride(data, stride, aff);
} else {
isl_val_free(stride);
isl_val_free(m);
isl_val_free(v);
}
isl_constraint_free(c);
return r;
}
/* Check if the constraints in "set" imply any stride on set dimension "pos" and
* store the results in data->stride and data->offset.
*
* In particular, compute the affine hull and then check if
* any of the constraints in the hull impose any stride on the dimension.
* If no such constraint can be found, then the offset is taken
* to be the zero expression and the stride is taken to be one.
*/
static void set_detect_stride(__isl_keep isl_set *set, int pos,
struct isl_detect_stride_data *data)
{
isl_basic_set *hull;
hull = isl_set_affine_hull(isl_set_copy(set));
data->pos = pos;
data->found = 0;
data->stride = NULL;
data->offset = NULL;
if (isl_basic_set_foreach_constraint(hull, &detect_stride, data) < 0)
goto error;
if (!data->found) {
data->stride = isl_val_one(isl_set_get_ctx(set));
if (data->want_offset) {
isl_space *space;
isl_local_space *ls;
space = isl_set_get_space(set);
ls = isl_local_space_from_space(space);
data->offset = isl_aff_zero_on_domain(ls);
}
}
isl_basic_set_free(hull);
return;
error:
isl_basic_set_free(hull);
data->stride = isl_val_free(data->stride);
data->offset = isl_aff_free(data->offset);
}
/* Check if the constraints in "set" imply any stride on set dimension "pos" and
* return the results in the form of an offset and a stride.
*/
__isl_give isl_stride_info *isl_set_get_stride_info(__isl_keep isl_set *set,
int pos)
{
struct isl_detect_stride_data data;
data.want_offset = 1;
set_detect_stride(set, pos, &data);
return isl_stride_info_alloc(data.stride, data.offset);
}
/* Check if the constraints in "set" imply any stride on set dimension "pos" and
* return this stride.
*/
__isl_give isl_val *isl_set_get_stride(__isl_keep isl_set *set, int pos)
{
struct isl_detect_stride_data data;
data.want_offset = 0;
set_detect_stride(set, pos, &data);
return data.stride;
}

View File

@ -786,30 +786,42 @@ static void swap_rows(struct isl_tab *tab, int row1, int row2)
tab->row_sign[row2] = s;
}
static int push_union(struct isl_tab *tab,
static isl_stat push_union(struct isl_tab *tab,
enum isl_tab_undo_type type, union isl_tab_undo_val u) WARN_UNUSED;
static int push_union(struct isl_tab *tab,
/* Push record "u" onto the undo stack of "tab", provided "tab"
* keeps track of undo information.
*
* If the record cannot be pushed, then mark the undo stack as invalid
* such that a later rollback attempt will not try to undo earlier
* records without having been able to undo the current record.
*/
static isl_stat push_union(struct isl_tab *tab,
enum isl_tab_undo_type type, union isl_tab_undo_val u)
{
struct isl_tab_undo *undo;
if (!tab)
return -1;
return isl_stat_error;
if (!tab->need_undo)
return 0;
return isl_stat_ok;
undo = isl_alloc_type(tab->mat->ctx, struct isl_tab_undo);
if (!undo)
return -1;
goto error;
undo->type = type;
undo->u = u;
undo->next = tab->top;
tab->top = undo;
return 0;
return isl_stat_ok;
error:
free_undo(tab);
tab->top = NULL;
return isl_stat_error;
}
int isl_tab_push_var(struct isl_tab *tab,
isl_stat isl_tab_push_var(struct isl_tab *tab,
enum isl_tab_undo_type type, struct isl_tab_var *var)
{
union isl_tab_undo_val u;
@ -820,7 +832,7 @@ int isl_tab_push_var(struct isl_tab *tab,
return push_union(tab, type, u);
}
int isl_tab_push(struct isl_tab *tab, enum isl_tab_undo_type type)
isl_stat isl_tab_push(struct isl_tab *tab, enum isl_tab_undo_type type)
{
union isl_tab_undo_val u = { 0 };
return push_union(tab, type, u);
@ -829,20 +841,21 @@ int isl_tab_push(struct isl_tab *tab, enum isl_tab_undo_type type)
/* Push a record on the undo stack describing the current basic
* variables, so that the this state can be restored during rollback.
*/
int isl_tab_push_basis(struct isl_tab *tab)
isl_stat isl_tab_push_basis(struct isl_tab *tab)
{
int i;
union isl_tab_undo_val u;
u.col_var = isl_alloc_array(tab->mat->ctx, int, tab->n_col);
if (tab->n_col && !u.col_var)
return -1;
return isl_stat_error;
for (i = 0; i < tab->n_col; ++i)
u.col_var[i] = tab->col_var[i];
return push_union(tab, isl_tab_undo_saved_basis, u);
}
int isl_tab_push_callback(struct isl_tab *tab, struct isl_tab_callback *callback)
isl_stat isl_tab_push_callback(struct isl_tab *tab,
struct isl_tab_callback *callback)
{
union isl_tab_undo_val u;
u.callback = callback;
@ -917,12 +930,12 @@ struct isl_tab *isl_tab_drop_sample(struct isl_tab *tab, int s)
/* Record the current number of samples so that we can remove newer
* samples during a rollback.
*/
int isl_tab_save_samples(struct isl_tab *tab)
isl_stat isl_tab_save_samples(struct isl_tab *tab)
{
union isl_tab_undo_val u;
if (!tab)
return -1;
return isl_stat_error;
u.n = tab->n_sample;
return push_union(tab, isl_tab_undo_saved_samples, u);

Some files were not shown because too many files have changed in this diff Show More